部分定义 scikit-learn K-Means 聚类的初始质心

partially define initial centroid for scikit-learn K-Means clustering

Scikit 文档指出:

Method for initialization:

‘k-means++’ : selects initial cluster centers for k-mean clustering in a smart way to speed up convergence. See section Notes in k_init for more details.

If an ndarray is passed, it should be of shape (n_clusters, n_features) and gives the initial centers.

我的数据有 10 个(预测的)聚类和 7 个特征。但是,我想传递 10 x 6 形状的数组,即我希望我预定义质心的 6 个维度,但第 7 个维度可以使用 k-mean++ 自由迭代。(换句话说,我不想指定初始质心,而是控制 6 个维度,只留下一个维度来改变初始簇)

我试图传递 10x6 维度,希望它能起作用,但它只是抛出错误。

Sklearn 不允许你进行这种精细操作。

唯一的可能性是提供第 7 个特征值,该值是随机的,或者类似于 Kmeans++ 所能达到的。

所以基本上你可以估算出一个很好的价值如下:

import numpy as np
from sklearn.cluster import KMeans

nb_clust = 10
# your data
X = np.random.randn(7*1000).reshape( (1000,7) )   

# your 6col centroids  
cent_6cols = np.random.randn(6*nb_clust).reshape( (nb_clust,6) ) 

# artificially fix your centroids
km = KMeans( n_clusters=10 )
km.cluster_centers_ = cent_6cols

# find the points laying on each cluster given your initialization
initial_prediction = km.predict(X[:,0:6])

# For the 7th column you'll provide the average value 
# of the points laying on the cluster given by your partial centroids    
cent_7cols = np.zeros( (nb_clust,7) )
cent_7cols[:,0:6] = cent_6cols
for i in range(nb_clust):
    init_7th = X[ np.where( initial_prediction == i ), 6].mean()
    cent_7cols[i,6] =  init_7th

# now you have initialized the 7th column with a Kmeans ++ alike 
# So now you can use the cent_7cols as your centroids
truekm = KMeans( n_clusters=10, init=cent_7cols )

那是 非常 的 k-means 非标准变体。所以你 不能 期望 sklearn 为每一个奇异的变化做好准备。这会让其他人的 sklearn 变慢。

事实上,您的方法更像是某些回归方法(预测聚类中心的最后一个值)而不是聚类。我也怀疑结果会比仅使用其他 6 个维度将最后一个值设置为分配给聚类中心的所有点的平均值好得多。尝试根据最近的中心(忽略最后一列)对数据进行分区,然后将最后一列设置为分配数据的算术平均值。

但是,sklearn 开源

于是拿到源码,修改k-means。随机初始化最后一个组件,而 运行 k-means 只更新最后一列。以这种方式修改它很容易 - 但很难设计一个 高效 API 以允许通过琐碎的参数进行此类自定义 - 使用源代码在他的级别进行自定义。