## Python—kmeans算法学习笔记

def __init__(self, n_clusters=8, init='k-means++', n_init=10, max_iter=300,tol=1e-4,precompute_distances='auto',verbose=0, random_state=None, copy_x=True, n_jobs=1):

（一）输入参数：

（1）n_clusters：要分成的簇数也是要生成的质心数

n_clusters : int, optional, default: 8
The number of clusters to form as well as the number of centroids to generate.

（2）init:初始化质心，

kmeans++：种子点选取的第二种方法。

kmedoids(PAM,Partitioning Around Medoids)

init : {'k-means++', 'random' or an ndarray}
Method for initialization, defaults 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.

（3）n_init: 设置选择质心种子次数，默认为10次。返回质心最好的一次结果（好是指计算时长短）

n_init : int, default: 10
Number of time the k-means algorithm will be run with different centroid seeds. The final results will be the best output of n_init consecutive runs in terms of inertia.

（4）max_iter：每次迭代的最大次数

max_iter : int, default: 300
Maximum number of iterations of the k-means algorithm for a

single run.

（5）tol: 容忍的最小误差，当误差小于tol就会退出迭代（算法中会依赖数据本身）

Relative tolerance with regards to inertia to declare convergence

（6）precompute_distances: 这个参数会在空间和时间之间做权衡，如果是True 会把整个距离矩阵都放到内存中，auto 会默认在数据样本大于featurs*samples 的数量大于12e6 的时候False,False时核心实现的方法是利用Cpython 来实现的

Precompute distances (faster but takes more memory).
'auto' : do not precompute distances if n_samples * n_clusters > 12 million. This corresponds to about 100MB overhead per job usingdouble precision.

（7）verbose:是否输出详细信息

verbose : boolean, optional
Verbosity mode.

（8）random_state： 随机生成器的种子 ，和初始化中心有关

random_state : integer or numpy.RandomState, optional
The generator used to initialize the centers. If an integer is given, it fixes the seed. Defaults to the global numpy random number generator.

（9）copy_x：bool 在scikit-learn 很多接口中都会有这个参数的，就是是否对输入数据继续copy 操作，以便不修改用户的输入数据。这个要理解Python 的内存机制才会比较清楚。

When pre-computing distances it is more numerically accurate to center the data first.  If copy_x is True, then the original data is not modified.  If False, the original data is modified, and put back before the function returns, but small numerical differences may be introduced by subtracting and then adding the data mean.

（10）n_jobs: 使用进程的数量，与电脑的CPU有关

The number of jobs to use for the computation. This works by computing
each of the n_init runs in parallel.
If -1 all CPUs are used. If 1 is given, no parallel computing code is used at all, which is useful for debugging. For n_jobs below -1,(n_cpus + 1 + n_jobs) are used. Thus for n_jobs = -2, all CPUs but one
are used.

（二）输出参数：

（1）label_:每个样本对应的簇类别标签

示例：r1 = pd.Series(model.labels_).value_counts() #统计各个类别的数目

（2）cluster_centers_：聚类中心

返回值：array, [n_clusters, n_features]

示例：r2 = pd.DataFrame(model.cluster_centers_) #找出聚类中心

#-*- coding: utf-8 -*-

#使用K-Means算法聚类消费行为特征数据

import pandas as pd

#参数初始化

inputfile = '../data/consumption_data.xls' #销量及其他属性数据

outputfile = '../tmp/data_type.xls' #保存结果的文件名

k = 3 #聚类的类别

iteration = 500 #聚类最大循环次数

data = pd.read_excel(inputfile, index_col = 'Id') #读取数据

data_zs = 1.0*(data - data.mean())/data.std() #数据标准化

from sklearn.cluster import KMeans

model = KMeans(n_clusters = k, n_jobs = 4, max_iter = iteration) #分为k类, 并发数4

model.fit(data_zs) #开始聚类

#简单打印结果

r1 = pd.Series(model.labels_).value_counts() #统计各个类别的数目

r2 = pd.DataFrame(model.cluster_centers_) #找出聚类中心

r = pd.concat([r2, r1], axis = 1) #横向连接(0是纵向), 得到聚类中心对应的类别下的数目

r.columns = list(data.columns) + [u'类别数目'] #重命名表头

print(r)

#详细输出原始数据及其类别

r = pd.concat([data, pd.Series(model.labels_, index = data.index)], axis = 1)  #详细

r.columns = list(data.columns) + [u'聚类类别'] #重命名表头

r.to_excel(outputfile) #保存结果

（一）实现目标：其目标是实现组内的对象相互之间是相似的（相关的），而不同组中的对象是不同的（不相关的）。组内的相似性越大，组间差别越大，聚类效果就越好。

（二）评价方法：

（1）  purity评价法：

purity方法是极为简单的一种聚类评价方法，只需计算正确聚类的文档数占总文档数的比例：

purity方法的优势是方便计算，值在0～1之间，完全错误的聚类方法值为0，完全正确的方法值为1。同时，purity方法的缺点也很明显它无法对退化的聚类方法给出正确的评价，设想如果聚类算法把每篇文档单独聚成一类，那么算法认为所有文档都被正确分类，那么purity值为1！而这显然不是想要的结果。

（2）  RI评价法：

TP＋FP ＝ C(2,6) + C(2,6) + C(2,5) = 15 + 15 + 10 = 40

TP = C(2,5) + C(2,4) + C(2,3) + C(2,2) = 20

FP = 40 - 20 = 20

TN+FN= C(1,6) * C(1,6)+ C(1,6)* C(1,5) + C(1,6)* C(1,5)=96

FN= C(1,5) * C(1,3)+ C(1,1)* C(1,4) + C(1,1)* C(1,3)+ C(1,1)* C(1,2)=24

TN=96-24=72

（三）：F值评价法

注：p是查全率，R是查准率，当β>1时查全率更有影响，当β<1时查准率更有影响，当β=1时退化为标准的F1，详细查阅机器学习P30

RI方法有个特点就是把准确率和召回率看得同等重要，事实上有时候我们可能需要某一特性更多一点，这时候就适合F值方法

Precision=TP/(TP+FP)

Recall=TP/(TP+FN)

F1=2×Recall×Precision/(Recall+Precision)

Precision=20/40=0.5

Recall=20/44=0.455

F1=(2*0.5*0.455)/(0.5+0.455)=0.48

#-*- coding: utf-8 -*-
#接k_means.py
from sklearn.manifold import TSNE
tsne = TSNE()
tsne.fit_transform(data_zs) #进行数据降维
tsne = pd.DataFrame(tsne.embedding_, index = data_zs.index) #转换数据格式
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False #用来正常显示负号
#不同类别用不同颜色和样式绘图
d = tsne[r[u'聚类类别'] == 0]
plt.plot(d[0], d[1], 'r.')
d = tsne[r[u'聚类类别'] == 1]
plt.plot(d[0], d[1], 'go')
d = tsne[r[u'聚类类别'] == 2]
plt.plot(d[0], d[1], 'b*')
plt.show()

posted on 2016-12-24 21:31  金秀  阅读(61042)  评论(6编辑  收藏  举报