random python聚类python中k-means⼏种初始化质⼼的⽅式
def k_means(X, n_clusters, init='k-means++', precompute_distances='auto',
n_init=10, max_iter=300, verbose=False,
tol=1e-4, random_state=None, copy_x=True, n_jobs=1,
algorithm="auto", return_n_iter=False):
init : {'k-means++', 'random', or ndarray, or a callable}, optional
Method for initialization, default to 'k-means++':
'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.
'random': generate k centroids from a Gaussian with mean and
variance estimated from the data.
If an ndarray is passed, it should be of shape (n_clusters, n_features)
and gives the initial centers.
If a callable is passed, it should take arguments X, k and
and a random state and return an initialization.
if n_clusters == 1:
# elkan doesn't make sense for a single cluster, full will produce
# the right result.
algorithm = "full"
if algorithm == "auto":
algorithm = "full" if sp.issparse(X) else 'elkan'
if algorithm == "full":
kmeans_single = _kmeans_single_lloyd
elif algorithm == "elkan":
kmeans_single = _kmeans_single_elkan
else:
raise ValueError("Algorithm must be 'auto', 'full' or 'elkan', got"
" %s" % str(algorithm))
def _kmeans_single_elkan(X, n_clusters, max_iter=300, init='k-means++',
verbose=False, x_squared_norms=None,
random_state=None, tol=1e-4,
precompute_distances=True):
centers = _init_centroids(X, n_clusters, init, random_state=random_state,
x_squared_norms=x_squared_norms)
centers = np.ascontiguousarray(centers)
def _init_centroids(X, k, init, random_state=None, x_squared_norms=None,
init_size=None):
"""Compute the initial centroids
init : {'k-means++', 'random' or ndarray or callable} optional Method for initialization
if isinstance(init, string_types) and init == 'k-means++':
centers = _k_init(X, k, random_state=random_state,
x_squared_norms=x_squared_norms)
elif isinstance(init, string_types) and init == 'random':
seeds = random_state.permutation(n_samples)[:k]
centers = X[seeds]
elif hasattr(init, '__array__'): #如果init是数组,则⽤此数组初始化质⼼
# ensure that the centers have the same dtype as X
# this is a requirement of fused types of cython
centers = np.array(init, dtype=X.dtype)
elif callable(init): #如果init是可调⽤的函数,可直接调⽤该函数去⽣成初始化质⼼。
centers = init(X, k, random_state=random_state)
centers = np.asarray(centers, dtype=X.dtype)
else:
raise ValueError("the init parameter for the k-means should "
"be 'k-means++' or 'random' or an ndarray, "
"'%s' (type '%s') was passed." % (init, type(init)))
下⾯的转载⾃博客的⼀个例⼦
1、K均值聚类
K-Means算法思想简单,效果却很好,是最有名的聚类算法。聚类算法的步骤如下:
1:初始化K个样本作为初始聚类中⼼;
2:计算每个样本点到K个中⼼的距离,选择最近的中⼼作为其分类,直到所有样本点分类完毕;
3:分别计算K个类中所有样本的质⼼,作为新的中⼼点,完成⼀轮迭代。
通常的迭代结束条件为新的质⼼与之前的质⼼偏移值⼩于⼀个给定阈值。
下⾯给⼀个简单的例⼦来加深理解。如下图有4个样本点,坐标分别为A(-1,-1),B(1,-1),C(-1,1),D(1,1)。现在要将他们聚成2类,指定A、B作为初始聚类中⼼(聚类中⼼A0, B0),指定阈值0.1。K-Means迭代过程如下:
step 1.1:计算各样本距离聚类中⼼的距离:
样本A:d(A,A0) = 0; d(A,B0) = 2;因此样本A属于A0所在类;
样本B:d(B,A0) = 2; d(B,B0) = 0;因此样本B属于B0所在类;
样本C:d(C,A0) = 2; d(C,B0) = 2.8;;因此样本C属于A0所在类;
样本C:d(D,A0) = 2.8; d(D,B0) = 2;;因此样本C属于B0所在类;
step 1.2:全部样本分类完毕,现在计算A0类(包含样本AC)和B0类(包含样本BD)的新的聚类中⼼:
A1 = (-1, 0); B1 = (1,0);
step 1.3:计算聚类中⼼的偏移值是否满⾜终⽌条件:
|A1-A0| = |(-1,0)-(-1,-1) | = |(0,1)| = 1 >0.1,因此继续迭代。
此时的状态如下图所⽰:
step 2.1:计算各样本距离聚类中⼼的距离:
样本A :d(A,A1) = 1; d(A,B1) = 2.2;因此样本A 属于A1所在类;
样本B :d(B,A1) = 2.2; d(B,B1) = 1;因此样本B 属于B1所在类;
样本C :d(C,A1) = 1; d(C,B1) = 2.2;;因此样本C 属于A1所在类;
样本D :d(D,A1) = 2.2; d(D,B1) = 1;;因此样本C 属于B1所在类;
step 2.2:全部样本分类完毕,现在计算A1类(包含样本AC )和B1类(包含样本BD )的新的聚类中⼼:
A2 = (-1, 0); B2 = (1,0);
step 2.3:计算聚类中⼼的偏移值是否满⾜终⽌条件:
|A2-A1| = |B2-B1| = 0 <0.1,因此迭代终⽌。
2、测试数据
下⾯这个测试数据有点类似SNS 中的好友关系,假设是10个来⾃2个不同的圈⼦的同学的SNS 聊天记录。显然,同⼀个圈⼦内的同学会有更密切的关系和互动。
数据如下所⽰,每⼀⾏代表⼀个好友关系。如第⼀⾏表⽰同学0与同学1的亲密程度为9(越⾼表⽰联系越密切)。
显然,这个数据中并没有告知我们这10个同学分别属于哪个圈⼦。因此我们的⽬标是使⽤K-Means 聚类算法,将他们聚成2类。
这个例⼦设计的很简单。我们使⽤上⼀篇⽂章中提到的关系矩阵,将其可视化出来,会看到如下结果:
这是个上三⾓矩阵,因为这个数据中认为好友关系是对称的。上图其实很快能发现,0,1,2,3,4⽤户紧密联系在⼀起,⽽5,6,7,8,9组成了另外⼀个圈⼦。
下⾯我们看看K-Means 算法能否出这个答案。
3、代码与分析
K-Means 算法的Python 代码如下:[plain]
1. 0 1 9
2. 0 2 5
3. 0 3 6
4. 0 4 3
5. 1 2 8
6. ......
输出结果如下:
Initialization complete
Iteration 0, inertia 581.000
Iteration 1, inertia 417.643
Converged at iteration 1
[0 0 1 1 1 1 1 1 1]
[0 0 0 0 1 1 1 1 1]
可以看到,使⽤默认的K-Means 算法将使⽤随机的初始值,因此每次执⾏的结果都不⼀样。
上⾯的输出中将0,1⽤户聚类到⼀起,效果并不理想。然⽽,如果我们可以确定⽤户0与⽤户5是有很⼤区别的,就可以指定⽤户0和⽤户5作为K-Means 聚类算法的初始值。可以看到和我们的预期完全⼀致,这样效果就⾮常好了。
由于K-Means 毕竟是⽆监督学习,在很多情况下⾃然⽆法与有监督学习的算法进⾏同样标准的⽐较。但其不需要监督的特性,⼴泛应⽤与社交图谱(如本例)、相似性匹配(如搜索相似的新闻、帖⼦)等引⽤场景。[python]
1. # -*- coding: utf-8 -*-
2.
from matplotlib import pyplot 3.
import scipy as sp 4.
import numpy as np 5.
from sklearn import svm 6.
import matplotlib.pyplot as plt 7.
from sklearn.cluster import KMeans 8.
from scipy import sparse 9. 10. #数据读⼊ 11. data = np.loadtxt('2.txt') 12. x_p = data[:, :2] # 取前2列 13. y_p = data[:, 2] # 取前2列 14. x = (sparse.csc_matrix((data[:,2], x_p.T)).astype(float))[:, :].todense() 15. nUser = x.shape[0] 16. 17. #可视化矩阵 18. pyplot.imshow(x, interpolation='nearest') 19. pyplot.xlabel('⽤户') 20. pyplot.ylabel('⽤户') 21. icks(range(nUser)) 22. icks(range(nUser)) 23. pyplot.show() 24. 25. #使⽤默认的K-Means 算法 26. num_clusters = 2 27. clf = KMeans(n_clusters=num_clusters, n_init=1, verbose=1) 28. clf.fit(x) 29.
print (clf.labels_) 30. 31. #指定⽤户0与⽤户5作为初始化聚类中⼼ 32. init = np.vstack([ x[0], x[5] ]) 33. clf = KMeans(n_clusters=2, init=init) 34. clf.fit(x)
35. print (clf.labels_)
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论