You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Scikit-learn中实现概念聚类?维基百科文章层级构建

Memory-Efficient Hierarchical Clustering for Large Wikipedia Article Datasets

Great question—dealing with hierarchical clustering on large datasets is tricky because of that O(n²) memory bottleneck from full distance matrices. Let’s break down practical, memory-efficient solutions tailored to your Wikipedia article use case (where you want top-level clusters to map to broad categories like Programming Languages → Functional Languages → Haskell):

1. Use Scikit-Learn's AgglomerativeClustering (Optimized for Large Data)

Scikit-learn's AgglomerativeClustering avoids storing a full pairwise distance matrix when using the ward linkage method (perfect for your L2-normalized data, since it relies on Euclidean distance). It uses an optimized algorithm based on minimum spanning trees, cutting memory usage down to O(n) instead of O(n²).

You can build your hierarchy recursively: start with top-level broad clusters, then cluster each sub-cluster to create deeper levels. Here's how:

from sklearn.cluster import AgglomerativeClustering
import numpy as np

# Assume your preprocessed data (TF-IDF → Truncated SVD → L2 norm) is stored in X (shape: [n_samples, n_components])
# Step 1: Create top-level broad clusters (adjust n_clusters to match your desired number of root categories)
top_clustering = AgglomerativeClustering(
    n_clusters=20,  # Example: 20 broad top-level categories
    linkage='ward',
    compute_full_tree=True  # Preserve the full clustering tree for later hierarchy building
)
top_labels = top_clustering.fit_predict(X)

# Step 2: Recursively cluster each top-level sub-cluster to build deeper hierarchy
cluster_hierarchy = {}
for cluster_id in np.unique(top_labels):
    # Extract data points in the current top-level cluster
    sub_cluster_data = X[top_labels == cluster_id]
    # Cluster this sub-group into smaller, more specific categories
    sub_clustering = AgglomerativeClustering(
        n_clusters=5,  # Example: 5 sub-categories per top-level cluster
        linkage='ward'
    )
    sub_labels = sub_clustering.fit_predict(sub_cluster_data)
    cluster_hierarchy[cluster_id] = sub_labels

If you want to visualize the full hierarchy, you can use scipy.cluster.hierarchy.dendrogram with the children_ attribute of the clustering object.

2. Incremental Hierarchical Clustering with KD-Tree

Since you already experimented with KD-Tree, you can use it to build an incremental hierarchical clusterer that avoids computing all pairwise distances. The idea is to start with each sample as its own cluster, then repeatedly merge the closest pair of clusters (found via KD-Tree) until you reach your desired hierarchy level.

Here's a simplified implementation:

from sklearn.neighbors import KDTree
import numpy as np

# Initialize: each sample is a cluster, with its own center (the sample itself)
cluster_centers = X.copy()
cluster_members = [[i] for i in range(len(X))]
kdtree = KDTree(cluster_centers, leaf_size=30)

# Merge clusters until we reach the desired number of top-level categories
target_top_clusters = 20
while len(cluster_centers) > target_top_clusters:
    # Find the nearest neighbor for each cluster center (exclude self)
    distances, nearest_indices = kdtree.query(cluster_centers, k=2)
    # Find the pair of clusters with the smallest distance
    min_distance = np.min(distances[:, 1])
    pair_idx = np.where(distances[:, 1] == min_distance)[0][0]
    cluster_a_idx = pair_idx
    cluster_b_idx = nearest_indices[pair_idx, 1]

    # Merge the two clusters: combine members and compute new center
    merged_members = cluster_members[cluster_a_idx] + cluster_members[cluster_b_idx]
    merged_center = np.mean(X[merged_members], axis=0)

    # Clean up old clusters and add the new one
    # Delete higher index first to avoid shifting issues
    del cluster_members[max(cluster_a_idx, cluster_b_idx)]
    del cluster_members[min(cluster_a_idx, cluster_b_idx)]
    cluster_members.append(merged_members)

    # Update cluster centers and rebuild KD-Tree
    cluster_centers = np.delete(cluster_centers, [cluster_a_idx, cluster_b_idx], axis=0)
    cluster_centers = np.vstack([cluster_centers, merged_center])
    kdtree = KDTree(cluster_centers, leaf_size=30)

This approach uses O(n) memory (storing only cluster centers and member lists) and is much faster than full distance matrix methods for large datasets. Note that it's an approximate method (since it merges locally closest pairs instead of globally optimal ones), but it's a practical tradeoff for scale.

3. Optimized Linkage with fastcluster

If you prefer a more traditional hierarchical clustering approach but need better memory efficiency than scipy's hierarchy.linkage, use the fastcluster library. It's a drop-in replacement for scipy's linkage functions but uses optimized algorithms that reduce memory usage and speed up computation—especially for the ward linkage method (which uses O(n) memory instead of O(n²)).

Example usage:

import fastcluster
from scipy.cluster.hierarchy import dendrogram

# Generate the linkage matrix with fastcluster (memory-efficient for large n)
linkage_matrix = fastcluster.linkage(X, method='ward', metric='euclidean')

# Visualize the dendrogram (optional, for small enough subsets)
dendrogram(linkage_matrix)

For datasets with 10,000+ samples, fastcluster will handle the linkage computation without hitting memory limits, unlike scipy's default implementation.

4. Post-Processing: Map Clusters to Semantic Labels

Once you have your hierarchy, you'll want to label each cluster with meaningful, human-readable names (like Programming Languages). A simple way to do this is:

  • For each cluster, extract the top TF-IDF weighted terms from all articles in the cluster.
  • Use these top terms to assign a descriptive label (e.g., if the top terms are "programming", "language", "code", the cluster label could be Programming Languages).
  • If you have access to Wikipedia's category metadata for the articles, you can also use that to align clusters with existing Wikipedia categories for more accurate labels.

内容的提问来源于stack exchange,提问作者michaelsnowden

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:38:38