- Python机器学习中的DictVectorizer(特征向量化
- 利用sklearn进行分类2:良/恶性乳腺癌肿瘤预测(二)
- 利用sklearn进行分类:良/恶性乳腺癌肿瘤预测(一)
- 利用sklearn进行分类3:初级手写数字识别
- 《机器学习及实践——从零开始通往KAGGLE竞赛之路》读书笔记十
- PYTHON机器学习及实践_从零开始通往KAGGLE竞赛之路pd
- Python机器学习及实践_从零开始通往KAGGLE竞赛之路 高
- 《机器学习及实践——从零开始通往KAGGLE竞赛之路》读书笔记二
- 《机器学习及实践——从零开始通往KAGGLE竞赛之路》读书笔记三
- 《机器学习及实践——从零开始通往KAGGLE竞赛之路》读书笔记四
无监督学习
无监督学习(Unsupervised Learning)着重于发现数据本身的分布特点。与监督学习(Supervised Learning)不同,无监督学习不需要对数据本身进行标记。
从功能角度讲,无监督学习模型可以帮助我们发现数据的“群落”(数据聚类),也可以发现“离群”的样本;同时对于特征维度非常高的数据样本,可以通过无监督学习对数据进行降维,保留最具有区分性的低纬度特征。
数据聚类
最经典且易用的聚类模型是K均值算法(K-means)。该算法假设我们预先设定聚类的个数,然后不断更新聚类中心;经过几轮这样的迭代,最后的目标就是要让所有数据点到其所属聚类中心距离的平方和趋于稳定。
K均值算法
算法执行步骤
- 随机布设K个特征空间内的点作为初始的聚类中心。
- 对于根据每个数据的特征向量,从K个聚类中心中寻找距离最近的一个,并且把该数据标记为从属于这个聚类中心。
- 在所有的数据都被标记过聚类中心之后,根据这些数据新分配的类簇,重新对K个聚类中心做计算。
- 如果在一轮之后,所有的数据点从属的聚类中心与上一次的分配类簇没有变化,那么迭代可以停止,否则回到步骤2。
数据描述
我们使用手写字体数字图像的完整版本。
# 分别导入numpy、matplotlib以及pandas,用于数学运算、作图以及数据分析。
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
# 使用pandas分别读取训练数据与测试数据集。
digits_train = pd.read_csv('C:\\Users\\cao\\Jupyter\\Datasets\\optdigits\\optdigits.tra', header=None)
digits_test = pd.read_csv('C:\\Users\\cao\\Jupyter\\Datasets\\optdigits\\optdigits.tes', header=None)
# 从训练与测试数据集上都分离出64维度的像素特征与1维度的数字目标。
X_train = digits_train[np.arange(64)]
y_train = digits_train[64]
X_test = digits_test[np.arange(64)]
y_test = digits_test[64]
# 从sklearn.cluster中导入KMeans模型。
from sklearn.cluster import KMeans
# 初始化KMeans模型,并设置聚类中心数量为10。
kmeans = KMeans(n_clusters=10)
kmeans.fit(X_train)
# 逐条判断每个测试图像所属的聚类中心。
y_pred = kmeans.predict(X_test)
性能评测
- 如果被用来评估的数据本身带有正确的类别信息,使用Adjusted Rand Index(ARI)。ARI指标与分类问题中计算准确性(Accuracy)的方法类似。
# 从sklearn导入度量函数库metrics。
from sklearn import metrics
# 使用ARI进行KMeans聚类性能评估。
print (metrics.adjusted_rand_score(y_test, y_pred))
0.6621773801044615
- 如果被用于评估的数据没有所属类别,我们使用轮廓系数(Silhouette Coefficient)来度量聚类结果的质量。轮廓系数同时兼顾了聚类的凝聚度(Cohesion)和分离度(Separation),用于评估聚类的效果并且取值范围为
。轮廓系数数值越大,表示聚类效果越好。计算步骤如下
(1)对于已聚类数据中第个样本
,计算
与其同一个类簇内的所有其他样本距离的平均值,记作
,用于量化簇内的凝聚度(Cohesion)。
(2)选取外的一个簇
,计算
与簇
中所有样本距离的平均值,遍历所有其他簇,找到最近的这个平均距离,记作
,用于量化簇之间分离度。
(3)对于样本,轮廓系数为
。
(4)最后对所有样本求出平均值即为当前聚类结果的整体轮廓系数。
不难发现,如果小于0,说明
与其簇内元素的平均距离大于邻近其他簇,表示聚类效果不好,如果趋于1,说明聚类效果好。
python
# 导入numpy。
import numpy as np
# 从sklearn.cluster中导入KMeans算法包。
from sklearn.cluster import KMeans
# 从sklearn.metrics导入silhouette_score用于计算轮廓系数。
from sklearn.metrics import silhouette_score
import matplotlib.pyplot as plt
# 分割出3*2=6个子图,并在1号子图作图。
plt.subplot(3,2,1)
# 初始化原始数据点。
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(list(zip(x1,x2))).reshape(len(x1), 2)
# 在1号子图做出原始数据点阵的分布。
plt.xlim([0, 10])
plt.ylim([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[l], marker=markers[l], 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()
output
output
特点分析
K-means聚类模型所采用的迭代式算法,直观易懂并且非常实用。只是有两个缺陷:(1)容易收敛到局部最优解。(2)需要预先设定簇的数量。
肘部观察法
用于粗略估计相对合理的簇类个数。因为K均值模型最终期望所有的数据点到其所属的类簇距离的平方和趋于稳定,所以我们可以通过观察这个数值随着K的走势来找出最佳的类簇数量。理想条件下,这个折线在不断的下降并且趋于稳定的过程中会有斜率的拐点,同时意味着从这个拐点对应的K值开始,类簇中心的增加不会过于破坏数据聚类的结构。
# 导入必要的工具包。
import numpy as np
from sklearn.cluster import KMeans
from scipy.spatial.distance import cdist
import matplotlib.pyplot as plt
# 使用均匀分布函数随机三个簇,每个簇周围10个数据样本。
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))
# 绘制30个数据样本的分布图像。
X = np.hstack((cluster1, cluster2, cluster3)).T
plt.scatter(X[:,0], X[:, 1])
plt.xlabel('x1')
plt.ylabel('x2')
plt.show()
# 测试9种不同聚类中心数量下,每种情况的聚类质量,并作图。
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()
output
output










网友评论