Python机器学习第一印象|什么是K-means
原创: JasonYe 北辰文阁 今天
本节将要介绍一种被广泛使用的直接聚类算法k-means。在给定的数据集中,将里面的对象划分到多个聚簇中,使得同一聚簇内的对象互相比较相似,而不同聚簇间的对象彼此差别较大。换而言之,就是将相似接近的对象分到同一聚簇,将不相似的对象分到不同聚簇。因此聚类归属于无监督学习算法,我们并不知道数据对象的标记,只知道它的特征如何。
K-means算法的输入是维向量空间的数据点,我们将这些点标记为S,Si指中第个数据点,每个Si属于且仅属于K个聚簇中的某一个。K是指定K-means算法聚类个数的输入参数,一般由用户指定。在实际问题上,用户往往难以给出合适最佳的K值,这时候可以先随机指定一个值,根据后面聚类情况再调整(当然有更好的处理方法)。选定K值后,我们会用适当的方法选取适当的K个初始质心,即聚簇的中心点,质心的选取也是一个关键步骤,常见的选定方法是随机初始化,一般的K-means算法也是这么设定。
选定K值和K个质心点后,我们将会遍历S,将每个点归属到离其最近的各个聚簇中心点上,一般采用欧式距离来衡量距离远近,当然也可以用余弦距离,还有其他距离,可以参考我之前写过的一篇专门讲述距离的文章《我和你的距离有多远》,因此K-means算法的关键是在于最小化如下的目标代价函数来将各个点聚到各自的聚簇上(其中M指数据点的总个数,Cj指第j个聚簇的中心点):
#设置环境包import matplotlib.pyplot as plt #可视化展示用from sklearn import datasets #datasets加载数据from sklearn.cluster import KMeans #kmeans的处理包import sklearn.metrics as sm #sm:矩阵处理import pandas as pdimport numpy as np#可视化初始化,如果没有可视化需求可以忽略 %matplotlib inline
iris = datasets.load_iris()#查看数据的维度# print(iris.data)# print(iris.target)print(iris.feature_names) print(iris.target_names)# 将数据存储为Pandas Dataframe 设置变量名x = pd.DataFrame(iris.data) x.columns = ['Sepal_Length','Sepal_Width','Petal_Length','Petal_Width'] y = pd.DataFrame(iris.target) y.columns = ['Targets']# 设置plot的区域plt.figure(figsize=(14,7))# 创造画板colormap = np.array(['red', 'lime', 'black'])# 展示花萼长宽下的具体分类plt.subplot(1, 2, 1) plt.scatter(x.Sepal_Length, x.Sepal_Width, c=colormap[y.Targets], s=40) plt.title('Sepal')# 展示花瓣长宽下的具体分类 plt.subplot(1, 2, 2) plt.scatter(x.Petal_Length, x.Petal_Width, c=colormap[y.Targets], s=40) plt.title('Petal')
['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)'] ['setosa' 'versicolor' 'virginica'] <matplotlib.text.Text at 0x5b25c50>
model = KMeans(n_clusters=3)# 设定K=3的聚类模型 model.fit(x)#开始运行,参数设置默认值,运行后会显示,也可以更改对应参数运行模型
KMeans(algorithm='auto', copy_x=True, init='k-means++', max_iter=300, n_clusters=3, n_init=10, n_jobs=1, precompute_distances='auto', random_state=None, tol=0.0001, verbose=0)
#模型结果 model.labels_
array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 2, 0, 2, 0, 2, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 2], dtype=int32)
#展示结果# 设置plot的区域plt.figure(figsize=(14,7))# 创造画板colormap = np.array(['red', 'lime', 'black','blue'])#展示原有分类结果:花瓣plt.subplot(1, 2, 1) plt.scatter(x.Petal_Length, x.Petal_Width, c=colormap[y.Targets], s=40) plt.title('Real Classification')#展示模型分类结果:花瓣 plt.subplot(1, 2, 2) plt.scatter(x.Petal_Length, x.Petal_Width, c=colormap[model.labels_], s=40) plt.title('K Mean Classification')
<matplotlib.text.Text at 0x72a5990>
# 非监督聚类结果是不确定的,所以需要调整转换predY = np.choose(model.labels_, [2, 0, 1]).astype(np.int64)print (model.labels_) print (predY)
[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 2 0 0 0 0 2 0 0 0 0 0 0 2 2 0 0 0 0 2 0 2 0 2 0 0 2 2 0 0 0 0 0 2 0 0 0 0 2 0 0 0 2 0 0 0 2 0 0 2] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 2 2 2 2 1 2 2 2 2 2 2 1 1 2 2 2 2 1 2 1 2 1 2 2 1 1 2 2 2 2 2 1 2 2 2 2 1 2 2 2 1 2 2 2 1 2 2 1]
#展示调整后的结果plt.figure(figsize=(14,7))# 创造画板colormap = np.array(['red', 'lime', 'black'])#展示原有分类结果:花瓣plt.subplot(1, 2, 1) plt.scatter(x.Petal_Length, x.Petal_Width, c=colormap[y.Targets], s=40) plt.title('Real Classification')#展示模型分类结果:花瓣 plt.subplot(1, 2, 2) plt.scatter(x.Petal_Length, x.Petal_Width, c=colormap[predY], s=40) plt.title('K Mean Classification')
<matplotlib.text.Text at 0x9141cd0>
#准确率输出 sm.accuracy_score(y, predY)
0.89333333333333331
#混淆矩阵输出 sm.confusion_matrix(y, predY)
array([[50, 0, 0], [ 0, 48, 2], [ 0, 14, 36]])
import matplotlib.pyplot as plt plt.figure(figsize=(14,7))# 创造画板#展示原有分类结果:花瓣plt.subplot(1, 2, 1) plt.scatter(1, 2, s=40) plt.title('Real Classification')
小结
k-means也有它的优缺点,感兴趣的同学可以思考一下总结出来。我这里说出两种比k-means好一点的算法,一个是k-modes,一个是s-means..
写在最后
前几天有私信小编要Python的学习资料,小编整理了一些有深度的Python教程和参考资料,从入门到高级的都有,文件已经打包好了,正在学习Python的同学可以下载学习学习。文件下载方式:点击小编头像,关注后私信回复“资料”即可下载。首先把代码撸起来!首先把代码撸起来!首先把代码撸起来!重要的事说三遍,哈哈。“编程是门手艺活”。什么意思?得练啊。