Python 如何使用Sklearn Kmeans对稀疏数据进行集群

Python 如何使用Sklearn Kmeans对稀疏数据进行集群,python,scipy,scikit-learn,k-means,Python,Scipy,Scikit Learn,K Means,如何使用Sklearn的实现对稀疏数据进行集群 为了使他们的示例适合我自己的用例,我尝试: from sklearn.feature_extraction import DictVectorizer from sklearn.cluster import KMeans mydata = [ (1, {'word1': 2, 'word3': 6, 'word7': 4}), (2, {'word11': 1, 'word7': 9, 'word3': 2}), (3,

如何使用Sklearn的实现对稀疏数据进行集群

为了使他们的示例适合我自己的用例,我尝试:

from sklearn.feature_extraction import DictVectorizer
from sklearn.cluster import KMeans

mydata = [
    (1, {'word1': 2, 'word3': 6, 'word7': 4}),
    (2, {'word11': 1, 'word7': 9, 'word3': 2}),
    (3, {'word5': 7, 'word1': 3, 'word9': 8}),
]

kmeans_data = []
for index, raw_data in mydata:
    cnt_sum = float(sum(raw_data.values()))
    freqs = dict((k, v/cnt_sum) for k, v in raw_data.items())
    v = DictVectorizer(sparse=True)
    X = v.fit_transform(freqs)
    kmeans_data.append(X)

kmeans = KMeans(n_clusters=2, random_state=0).fit(kmeans_data)
但这引发了一个例外:

  File "/myproject/.env/lib/python3.5/site-packages/sklearn/cluster/k_means_.py", line 854, in _check_fit_data
    X = check_array(X, accept_sparse='csr', dtype=[np.float64, np.float32])
  File "/myproject/.env/lib/python3.5/site-packages/sklearn/utils/validation.py", line 382, in check_array
    array = np.array(array, dtype=dtype, order=order, copy=copy)
ValueError: setting an array element with a sequence.

大概我没有正确构造稀疏输入矩阵X,因为它是一个稀疏矩阵列表,而不是一个包含列表的稀疏矩阵。如何构造适当的输入矩阵?

您正在以增量方式构建稀疏矩阵。我不确定你是否能以增量的方式使用DictVectorizer。只需将元素逐个添加到矩阵中就更简单了。请参见scipy.sparse.csr_矩阵中的最后一个示例

增量建设

考虑以下双循环:

数据=[] 行=[] cols=[] 词汇={} 对于索引,mydata中的原始_数据: cnt_sum=floatsumraw_data.values 对于原始数据项中的k,v: f=v/cnt_和 i=词汇表。setdefaultk,Len词汇表 阑尾科尔斯菌 行。追加索引-1 数据附录F kmeans\u data=csr\u矩阵扩展数据、行、列 然后kmeans_数据是一个稀疏矩阵,适合用作K-均值分类器的输入

直接构造

使用DictVectorizer,您可以从元组列表构造数据矩阵,然后使用稀疏线性代数例程执行行的规范化

# 1. Construct the sparse matrix with numbers_of_occurrences
D = [d[1] for d in mydata]
v = DictVectorizer(sparse=True)
kmeans_data = v.fit_transform(D)
# 2. Normalize by computing sums for each row and dividing 
import numpy as np
sums = np.sum(kmeans_data,axis=1).A[:,0]
N = len(s)
divisor = csr_matrix((np.reciprocal(s),(range(N),range(N))))
kmeans_data = divisor*kmeans_data)