Python—kmeans算法学习笔记
一、 什么是聚类
聚类简单的说就是要把一个文档集合根据文档的相似性把文档分成若干类,但是究竟分成多少类,这个要取决于文档集合里文档自身的性质。下面这个图就是一个简单的例子,我们可以把不同的文档聚合为3类。另外聚类是典型的无指导学习,所谓无指导学习是指不需要有人干预,无须人为文档进行标注。
二、聚类算法:from sklearn.cluster import 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:要分成的簇数也是要生成的质心数
类型:整数型(int)
默认值:8
n_clusters : int, optional, default: 8
The number of clusters to form as
well as the number of centroids to generate.
(2)init:初始化质心,
类型:可以是function 可以是array(random or ndarray)
默认值:采用k-means++(一种生成初始质心的算法)
kmeans++:种子点选取的第二种方法。
kmedoids(PAM,Partitioning
Around Medoids)
能够解决kmeans对噪声敏感的问题。kmeans寻找种子点的时候计算该类中所有样本的平均值,如果该类中具有较为明显的离群点,会造成种子点与期望偏差过大。例如,A(1,1),B(2,2),C(3,3),D(1000,1000),显然D点会拉动种子点向其偏移。这样,在下一轮迭代时,将大量不该属于该类的样本点错误的划入该类。
为了解决这个问题,kmedoids方法采取新的种子点选取方式,1)只从样本点中选;2)选取标准能够提高聚类效果,例如上述的最小化J函数,或者自定义其他的代价函数。但是,kmedoids方法提高了聚类的复杂度。
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次。返回质心最好的一次结果(好是指计算时长短)
类型:整数型(int)
默认值:10
目的:每一次算法运行时开始的centroid seeds是随机生成的, 这样得到的结果也可能有好有坏. 所以要运行算法n_init次, 取其中最好的。
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:每次迭代的最大次数
类型:整型(int)
默认值:300
max_iter : int,
default: 300
Maximum number of iterations of the k-means algorithm for a
single run.
(5)tol: 容忍的最小误差,当误差小于tol就会退出迭代(算法中会依赖数据本身)
类型:浮点型(float)
默认值:le-4(0.0001)
Relative
tolerance with regards to inertia to declare convergence
(6)precompute_distances: 这个参数会在空间和时间之间做权衡,如果是True 会把整个距离矩阵都放到内存中,auto 会默认在数据样本大于featurs*samples 的数量大于12e6 的时候False,False时核心实现的方法是利用Cpython 来实现的
类型:布尔型(auto,True,False)
默认值:“auto”
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:是否输出详细信息
类型:布尔型(True,False)
默认值:False
verbose : boolean, optional
Verbosity
mode.
(8)random_state: 随机生成器的种子 ,和初始化中心有关
类型:整型或numpy(RandomState, optional)
默认值:None
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 的内存机制才会比较清楚。
类型:布尔型(boolean,
optional)
默认值:True
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有关
类型:整数型(int)
默认值:1
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) #保存结果
三、聚类分析算法的评价
(一)实现目标:其目标是实现组内的对象相互之间是相似的(相关的),而不同组中的对象是不同的(不相关的)。组内的相似性越大,组间差别越大,聚类效果就越好。
(二)评价方法:
既然聚类是把一个包含若干文档的文档集合分成若干类,像上图如果聚类算法应该把文档集合分成3类,而不是2类或者5类,这就设计到一个如何评价聚类结果的问题。
如图认为x代表一类文档,o代表一类文档,方框代表一类文档,完美的聚类显然是应该把各种不同的图形放入一类,事实上我们很难找到完美的聚类方法,各种方法在实际中难免有偏差,所以我们才需要对聚类算法进行评价看我们采用的方法是不是好的算法。
(1) purity评价法:
purity方法是极为简单的一种聚类评价方法,只需计算正确聚类的文档数占总文档数的比例:
其中Ω = {ω1,ω2, . . . ,ωK}是聚类的集合ωK表示第k个聚类的集合。C = {c1, c2, . . . , cJ}是文档集合,cJ表示第J个文档。N表示文档总数。
如上图的purity = ( 3+ 4 + 5) / 17 = 0.71
其中第一类正确的有5个,第二个4个,第三个3个,总文档数17。
purity方法的优势是方便计算,值在0~1之间,完全错误的聚类方法值为0,完全正确的方法值为1。同时,purity方法的缺点也很明显它无法对退化的聚类方法给出正确的评价,设想如果聚类算法把每篇文档单独聚成一类,那么算法认为所有文档都被正确分类,那么purity值为1!而这显然不是想要的结果。
(2) RI评价法:
实际上这是一种用排列组合原理来对聚类进行评价的手段,公式如下:
其中TP是指被聚在一类的两个文档被正确分类了,TN是只不应该被聚在一类的两个文档被正确分开了,FP只不应该放在一类的文档被错误的放在了一类,FN指不应该分开的文档被错误的分开了。对上图
TP+FP = C(2,6) + C(2,6) + C(2,5) = 15 + 15 + 10 = 40
其中C(n,m)是指在m中任选n个的组合数。
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
所以RI = ( 20 + 72) / ( 20 + 20 + 72 +24) = 0.68
(三):F值评价法
这是基于上述RI方法衍生出的一个方法,
注: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
四、聚类分析结果的降维可视化—TSNE
我们总喜欢能够直观地展示研究结果,聚类也不例外。然而,通常来说输入的特征数是高维的(大于3维),一般难以直接以原特征对聚类结果进行展示。而TSNE提供了一种有效的数据降维方式,让我们可以在2维或者3维的空间中展示聚类结果。
示例代码:接上文示例代码
#-*- 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()
效果图:
资料来源:《Python机器学习实战》 《Python数据挖掘实战》
Python—kmeans算法学习笔记的更多相关文章
- 机器学习实战(Machine Learning in Action)学习笔记————06.k-均值聚类算法(kMeans)学习笔记
机器学习实战(Machine Learning in Action)学习笔记————06.k-均值聚类算法(kMeans)学习笔记 关键字:k-均值.kMeans.聚类.非监督学习作者:米仓山下时间: ...
- 某科学的PID算法学习笔记
最近,在某社团的要求下,自学了PID算法.学完后,深切地感受到PID算法之强大.PID算法应用广泛,比如加热器.平衡车.无人机等等,是自动控制理论中比较容易理解但十分重要的算法. 下面是博主学习过程中 ...
- Requests:Python HTTP Module学习笔记(一)(转)
Requests:Python HTTP Module学习笔记(一) 在学习用python写爬虫的时候用到了Requests这个Http网络库,这个库简单好用并且功能强大,完全可以代替python的标 ...
- C / C++算法学习笔记(8)-SHELL排序
原始地址:C / C++算法学习笔记(8)-SHELL排序 基本思想 先取一个小于n的整数d1作为第一个增量(gap),把文件的全部记录分成d1个组.所有距离为dl的倍数的记录放在同一个组中.先在各组 ...
- python网络爬虫学习笔记
python网络爬虫学习笔记 By 钟桓 9月 4 2014 更新日期:9月 4 2014 文章文件夹 1. 介绍: 2. 从简单语句中開始: 3. 传送数据给server 4. HTTP头-描写叙述 ...
- Manacher算法学习笔记 | LeetCode#5
Manacher算法学习笔记 DECLARATION 引用来源:https://www.cnblogs.com/grandyang/p/4475985.html CONTENT 用途:寻找一个字符串的 ...
- Python Built-in Function 学习笔记
Python Built-in Function 学习笔记 1. 匿名函数 1.1 什么是匿名函数 python允许使用lambda来创建一个匿名函数,匿名是因为他不需要以标准的方式来声明,比如def ...
- Johnson算法学习笔记
\(Johnson\)算法学习笔记. 在最短路的学习中,我们曾学习了三种最短路的算法,\(Bellman-Ford\)算法及其队列优化\(SPFA\)算法,\(Dijkstra\)算法.这些算法可以快 ...
- Johnson 全源最短路径算法学习笔记
Johnson 全源最短路径算法学习笔记 如果你希望得到带互动的极简文字体验,请点这里 我们来学习johnson Johnson 算法是一种在边加权有向图中找到所有顶点对之间最短路径的方法.它允许一些 ...
随机推荐
- Nagios 监控系统架构
Nagios 监控系统架设全攻略 简介: Nagios 全名为(Nagios Ain’t Goona Insist on Saintood),最初项目名字是 NetSaint.它是一款免费的开源 IT ...
- Spring基础系列-容器启动流程(1)
原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9870339.html 概述 我说的容器启动流程涉及两种情况,SSM开发模式和Spri ...
- ROS 101
https://www.clearpathrobotics.com/blog/2014/01/how-to-guide-ros-101/ 什么是ROS ROS(robot operating syst ...
- Java开发笔记(四十一)日历工具Calendar
前面的文章提到,Date是Java最早的日期工具,估计当时的设计师是个技术宅男,未经过充分调研就拍脑袋写下了Date的源码,造成该工具存在先天不足,比如getYear方法返回的不是纯正的公元纪年.ge ...
- 【代码笔记】Web-CSS-CSS Text(文本)
一,效果图. 二,代码. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...
- arcgis api 3.x for js 入门开发系列十二地图打印GP服务(附源码下载)
前言 关于本篇功能实现用到的 api 涉及类看不懂的,请参照 esri 官网的 arcgis api 3.x for js:esri 官网 api,里面详细的介绍 arcgis api 3.x 各个类 ...
- offic|集成|协同OA|移动办公|
随着互联网时代的日新月异,移动通讯技术的飞速发展,移动网络技术的更新换代,手机.平板电脑等移动设备越来越智能化.越来越多样化,人们对移动办公的需求也在日益增长.在此背景下北京博信施科技有限公司自主研发 ...
- 自定义一个全屏的AlertDialog。
........... final MyDialog dialog = new MyDialog(this); LayoutInflater inflater = getLayoutInflater( ...
- WPF:实现自定义标记扩展
标记扩展使用{标记扩展类 参数}语法,如: <TextBlock Text={x:Null}/> 为什么x:Null就可以返回一个null值呢? 其实在System.Windows.Mar ...
- Truffle 4.0、Geth 1.7.2、TestRPC在私有链上搭建智能合约
目录 目录 1.什么是 Truffle? 2.适合 Truffle 开发的客户端 3.Truffle的源代码地址 4.如何安装? 4.1.安装 Go-Ethereum 1.7.2 4.2.安装 Tru ...