KMeans算法-手写数字图像识别
2017-08-23 14:09
543 查看
数据聚类是无监督学习的主流应用。最经典并易用的聚类模型,是K-means算法。该算法要求我们预设聚类的个数,然后不断更新聚类中心;经过几轮迭代后,让所有数据点到其所属聚类中心距离的平方和趋于稳定。
K-means算法
模型介绍:
算法执行过程:
1.随机设K个特征空间内的点作为初始的聚类中心;
2.对于根据每个数据的特征向量,从K个聚类中心中寻找距离最近的一个,并把该数据标记为从属于这个聚类中心
3.在所有的数据都被标记过聚类中心后,根据这些数据新分配的类簇,重新对K个聚类中心进行计算
4.如果一轮下来,所有数据点从属对聚类中心与上一次的分配的类簇没有变化,停止迭代,否则回到步骤2继续执行
前面在支持向量机(分类)采用了scikit-learn内部集成的手写数字图像数据,是原始数据集合的一部分。而本次,我们使用该数据的完整版本:https://archive.ics.uci.edu/ml/machine-learning-databases/optdigits/
Python源码:
#coding=utf-8
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
#-------------
from sklearn.cluster import KMeans
#-------------
from sklearn import metrics
#-------------
from sklearn.metrics import silhouette_score
#-------------load data
digits_train=pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/optdigits/optdigits.tra',header=None)
digits_test=pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/optdigits/optdigits.tes',header=None)
#sperate 64 dimens picutre pixels features with 1 dimen target number
X_train=digits_train[np.arange(64)]
y_train=digits_train[64]
X_test=digits_test[np.arange(64)]
y_test=digits_test[64]
#-------------training
#initialize,and set cluster nums
kmeans=KMeans(n_clusters=10)
kmeans.fit(X_train)
y_pred=kmeans.predict(X_test)
#-------------performance measure by ARI(Adjusted Rand Index)
print metrics.adjusted_rand_score(y_test,y_pred)
Result:
0.667773154268
完整的手写数字图像分为两个数据集合,其中训练样本3823条,测试数据1797条,图像通过8*8的像素矩阵表示,共有64个像素维度;1个目标维度涌来标记每个图像样本代表的数字类别。没有缺失的特征值,并且无论训练样本还是测试样本,在数字类别方面都采样的非常平均,非常规整。
性能评估:有两种方法
1)如果被用来评估的数据本身带有正确的类别信息,则使用Adjusted Rand Index(ARI)。ARI指标与分类问题中计算准确性(Accuracy)的方法类似,也兼顾了类簇无法和分类标记一一对应的问题。
2)如果被用于评估的数据没有所属类别,那么我们习惯使用轮廓系数(Silhouette Coefficient)来度量聚类结果的质量。轮廓系数同时兼顾来聚类的凝聚度(Cohesion)和分离度(Seperation),用于评估聚类的效果,取值范围为[-1,1]。轮廓系数值越大,表示聚类效果越好。
为了说明轮廓系数与聚类效果的关系,下面对一组简单的数据进行分析。
Python源码:
可以观察到聚类中心数量为3,轮廓系数最大,此时也符合数据的分布特点,是想对较为合理的类簇数量。
算法特点:K-Means聚类模型采用的迭代式算法,直观易懂,但有两大缺陷:1.容易收敛到局部最优解;2.需要预先设定簇的数量。
可以用一种“肘部”观察法粗略的预估想对合理的类簇个数。理想条件下,折线在不断下降并且趋于平缓的过程中有斜率的拐点,意味着从这个拐点对应的K值开始,类簇中心的增加不会过于破坏数据聚类的结构。
Python源码:
随机采样3个类簇的数据点,当类簇数量为1或者2时,样本距所属类簇的平均距离的下降速度很快,说明更改K值回让整体聚类结构有很大改变,也意味着新的聚类数量让算法有更大的收敛空间,这样的K值不能反映真实的类簇数量。当K=3时,平均距离的下降有了显著放缓,意味着进一步增加K值不再会有利于算法的收敛,K=3时想对最佳的类簇数量。
K-means算法
模型介绍:
算法执行过程:
1.随机设K个特征空间内的点作为初始的聚类中心;
2.对于根据每个数据的特征向量,从K个聚类中心中寻找距离最近的一个,并把该数据标记为从属于这个聚类中心
3.在所有的数据都被标记过聚类中心后,根据这些数据新分配的类簇,重新对K个聚类中心进行计算
4.如果一轮下来,所有数据点从属对聚类中心与上一次的分配的类簇没有变化,停止迭代,否则回到步骤2继续执行
前面在支持向量机(分类)采用了scikit-learn内部集成的手写数字图像数据,是原始数据集合的一部分。而本次,我们使用该数据的完整版本:https://archive.ics.uci.edu/ml/machine-learning-databases/optdigits/
Python源码:
#coding=utf-8
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
#-------------
from sklearn.cluster import KMeans
#-------------
from sklearn import metrics
#-------------
from sklearn.metrics import silhouette_score
#-------------load data
digits_train=pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/optdigits/optdigits.tra',header=None)
digits_test=pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/optdigits/optdigits.tes',header=None)
#sperate 64 dimens picutre pixels features with 1 dimen target number
X_train=digits_train[np.arange(64)]
y_train=digits_train[64]
X_test=digits_test[np.arange(64)]
y_test=digits_test[64]
#-------------training
#initialize,and set cluster nums
kmeans=KMeans(n_clusters=10)
kmeans.fit(X_train)
y_pred=kmeans.predict(X_test)
#-------------performance measure by ARI(Adjusted Rand Index)
print metrics.adjusted_rand_score(y_test,y_pred)
Result:
0.667773154268
完整的手写数字图像分为两个数据集合,其中训练样本3823条,测试数据1797条,图像通过8*8的像素矩阵表示,共有64个像素维度;1个目标维度涌来标记每个图像样本代表的数字类别。没有缺失的特征值,并且无论训练样本还是测试样本,在数字类别方面都采样的非常平均,非常规整。
性能评估:有两种方法
1)如果被用来评估的数据本身带有正确的类别信息,则使用Adjusted Rand Index(ARI)。ARI指标与分类问题中计算准确性(Accuracy)的方法类似,也兼顾了类簇无法和分类标记一一对应的问题。
2)如果被用于评估的数据没有所属类别,那么我们习惯使用轮廓系数(Silhouette Coefficient)来度量聚类结果的质量。轮廓系数同时兼顾来聚类的凝聚度(Cohesion)和分离度(Seperation),用于评估聚类的效果,取值范围为[-1,1]。轮廓系数值越大,表示聚类效果越好。
为了说明轮廓系数与聚类效果的关系,下面对一组简单的数据进行分析。
Python源码:
#coding=utf-8 import numpy as np from sklearn.cluster import KMeans import matplotlib.pyplot as plt from sklearn.metrics import silhouette_score #-------------performance measure by Silhouette Coefficient #cut 3*2=6,6 maps, and draw on map 1 plt.subplot(3,2,1) #initialize data x1=np.array([1,2,3,1,5,6,5,5,6,7,8,9,7,9]) x2=np.array([1,3,2,2,8,6,7,6,7,1,2,1,1,3]) X=np.array(zip(x1,x2)).reshape(len(x1),2) # plt.xlim([0,10]) plt.xlim([0,10]) plt.title('Instances') plt.scatter(x1,x2) colors=['b','g','r','c','m','y','k','b'] markers=['o','s','D','v','^','p','*','+'] clusters=[2,3,4,5,8] subplot_counter=1 sc_scores=[] for t in clusters: subplot_counter+=1 plt.subplot(3,2,subplot_counter) kmeans_model=KMeans(n_clusters=t).fit(X) for i,l in enumerate(kmeans_model.labels_): plt.plot(x1[i],x2[i],color=colors[1],marker=markers[1],ls='None') plt.xlim([0,10]) plt.ylim([0,10]) sc_score=silhouette_score(X,kmeans_model.labels_,metric='euclidean') sc_scores.append(sc_score) plt.title('K=%s,silhouette coefficient=%0.03f'%(t,sc_score)) plt.figure() plt.plot(clusters,sc_scores,'*-') plt.xlabel('Number of Clusters') plt.ylabel('Silhouette Coefficient Score') plt.show()Result:
可以观察到聚类中心数量为3,轮廓系数最大,此时也符合数据的分布特点,是想对较为合理的类簇数量。
算法特点:K-Means聚类模型采用的迭代式算法,直观易懂,但有两大缺陷:1.容易收敛到局部最优解;2.需要预先设定簇的数量。
可以用一种“肘部”观察法粗略的预估想对合理的类簇个数。理想条件下,折线在不断下降并且趋于平缓的过程中有斜率的拐点,意味着从这个拐点对应的K值开始,类簇中心的增加不会过于破坏数据聚类的结构。
Python源码:
#coding=utf-8 import numpy as np from sklearn.cluster import KMeans import matplotlib.pyplot as plt from scipy.spatial.distance import cdist #random generate 3 clusters,each cluster has 10 datas cluster1=np.random.uniform(0.5,1.5,(2,10)) cluster2=np.random.uniform(5.5,6.5,(2,10)) cluster3=np.random.uniform(3.0,4.0,(2,10)) #draw the picture X=np.hstack((cluster1,cluster2,cluster3)).T plt.scatter(X[:,0],X[:,1]) plt.xlabel('x1') plt.xlabel('x2') plt.show() # K=range(1,10) meandistortions=[] for k in K: kmeans=KMeans(n_clusters=k) kmeans.fit(X) meandistortions.append(sum(np.min(cdist(X,kmeans.cluster_centers_,'euclidean'),axis=1))/X.shape[0]) plt.plot(K,meandistortions,'bx-') plt.xlabel('k') plt.ylabel('Average Dispersion') plt.title('Selecting k with the Elbow Method') plt.show()Result:
随机采样3个类簇的数据点,当类簇数量为1或者2时,样本距所属类簇的平均距离的下降速度很快,说明更改K值回让整体聚类结构有很大改变,也意味着新的聚类数量让算法有更大的收敛空间,这样的K值不能反映真实的类簇数量。当K=3时,平均距离的下降有了显著放缓,意味着进一步增加K值不再会有利于算法的收敛,K=3时想对最佳的类簇数量。
相关文章推荐
- Caffe学习总结(四)——使用mnist训练模型识别一张手写数字图像
- 通过摄像头捕获图像用tensorflow做手写数字识别
- python实现识别手写数字 python图像识别算法
- 基于机器学习多种方法的kaggle竞赛入门之手写数字的图像识别预测
- 手写数字识别系统之图像分割
- 手写数字识别——数据降维(PCA)技术在图像识别中的应用
- Java分布式神经网络库Deeplearning4j之上手实践手写数字图像识别与模型训练
- 图像基础21 手写数字识别
- 手写数字识别(二)----SVM 实现Mnist-image 手写数字图像识别
- 数字图像中手写阿拉伯数字的识别技术概览
- tensorflow构建手写数字图像识别---softmax算法
- 手写数字识别
- 【机器学习】k-近邻算法应用之手写数字识别
- 摄像头识别手写数字
- 使用k-近邻算法识别手写数字。
- NN:神经网络实现识别手写的10个数字—Jason niu
- 【机器学习】Knn算法实现手写数字识别
- 【深度学习】笔记3_caffe自带的第一个例子,Mnist手写数字识别所使用的LeNet网络模型的详细解释
- 从0开始训练识别手写数字的神经网络
- LeNet识别自己的手写数字