无监督学习(二)

K聚类(K-means):
K聚类的思想比较简单,其分类簇数量需要提前给定,比如取K=3,则代表当前数据会被分为3类,之后就是随机选取数据中的3个值作为初始均值向量,接下来计算每个样本距离初始均值向量的距离(欧式距离),比较每个样本距离中心的距离,选取最小的那个将样本归入该簇,运行完一轮后开始第二轮,此时的中心根据簇重新计算,直到两轮之间不再出现变化,达到收敛,聚类结束。

DBSCAN:
DBSCAN的思想是设定一个eps和min_samples,如果一个样本在设定的eps距离内有超过min_samples个样本,则判定其为样本核心,而在其eps距离内的点称为边界点,如果距离起始点的距离在eps之内的数据点个数小于min_samples,则该点为噪点。经过多轮迭代,直到某轮的聚类结果不再变化,则完成。

凝聚聚类(层次聚类):
数据集的划分可采用“自底向上”的聚合策略,也可采用“自顶向下”的分拆策略。
AGNES(AGglomerative NESting)是一种采用自底向上聚合策略的层次聚类算法,它先将数据集中的每个样本看作一个初始聚类簇,然后在算法运行的每一步中找出距离最近的两个聚类簇进行合并,该过程不断重复,直到达到预设的聚类簇个数。簇合并的准则是聚类簇之间的距离,可以采用最小距离(两个簇的最近样本)、最大距离(两个簇的最远样本)、平均距离(两个簇的所有样本)进行,该过程不断重复,两个两个合并,最后达到预设的聚类簇数。

代码实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import mglearn
import matplotlib.pyplot as plt
import numpy as np
from sklearn.datasets import make_blobs
from sklearn.datasets import make_moons
from sklearn.cluster import DBSCAN
from sklearn.preprocessing import StandardScaler
from scipy.cluster.hierarchy import dendrogram,ward
from sklearn.cluster import KMeans
from sklearn.cluster import AgglomerativeClustering

if __name__ == "__main__":
'''
mglearn.plots.plot_kmeans_algorithm()
mglearn.plots.plot_kmeans_boundaries()
plt.show()
'''
#生成模拟的二位数据
X,y = make_blobs(random_state=1)
kmeans = KMeans(n_clusters=3)
kmeans.fit(X)
print("Cluster members:\n{}".format(kmeans.labels_))
print(kmeans.predict(X))
'''
mglearn.discrete_scatter(X[:,0],X[:,1],kmeans.labels_,markers='o')
mglearn.discrete_scatter(kmeans.cluster_centers_[:,0],kmeans.cluster_centers_[:,1],[0,1,2],markers='^',markeredgewidth=2)
plt.show()
'''
'''
fig,axes = plt.subplots(1,2,figsize=(10,5))
#使用2个簇中心
kmeans = KMeans(n_clusters=2)
kmeans.fit(X)
assignments = kmeans.labels_

mglearn.discrete_scatter(X[:,0],X[:,1],assignments,ax=axes[0])
#使用5个簇中心
kmeans = KMeans(n_clusters=5)
kmeans.fit(X)
assignments = kmeans.labels_

mglearn.discrete_scatter(X[:,0],X[:,1],assignments,ax=axes[1])
plt.show()
'''
#k均值的失败案例
X_varied,y_varied = make_blobs(n_samples=200,cluster_std=[1.0,2.5,0.5],random_state=170)
y_pred = KMeans(n_clusters=3,random_state=0).fit_predict(X_varied)
'''
mglearn.discrete_scatter(X_varied[:,0],X_varied[:,1],y_pred)
plt.legend(["cluster 0","cluster 1","cluster 2"],loc="best")
plt.xlabel("Feature 0")
plt.ylabel("Feature 1")
plt.show()
'''
#生成一些随机分组数据
X,y = make_blobs(random_state=170,n_samples=600)
rng = np.random.RandomState(74)
#变换数据使其拉长
transformation = rng.normal(size=(2,2))
X = np.dot(X,transformation)
#将数据聚类成3个簇
kmeans=KMeans(n_clusters=3)
kmeans.fit(X)
y_pred=kmeans.predict(X)
'''
#画出簇分配和簇中心
plt.scatter(X[:,0],X[:,1],c=y_pred,cmap=mglearn.cm3)
plt.scatter(kmeans.cluster_centers_[:,0],kmeans.cluster_centers_[:,1],
marker='^',c=[0,1,2],s=100,linewidth=2,cmap=mglearn.cm3)
plt.xlabel("Feature 0")
plt.ylabel("Feature 1")
plt.show()
'''
#生成模拟的two_moons数据(这次的噪声较小)
X,y=make_moons(n_samples=200,noise=0.05,random_state=0)
#将数据聚类成2个簇
kmeans=KMeans(n_clusters=2)
kmeans.fit(X)
y_pred = kmeans.predict(X)
#画出簇分配和簇中心
'''
plt.scatter(X[:,0],X[:,1],c=y_pred,cmap=mglearn.cm2,s=60)
plt.scatter(kmeans.cluster_centers_[:,0],kmeans.cluster_centers_[:,1],
marker='^',c=[mglearn.cm2(0),mglearn.cm2(1)],s=100,linewidth=2)
plt.xlabel("Feature 0")
plt.ylabel("Feature 1")
plt.show()
'''
#使用凝聚聚类
'''
mglearn.plots.plot_agglomerative_algorithm()
plt.show()
'''
X,y=make_blobs(random_state=1)
agg=AgglomerativeClustering(n_clusters=3)
assignment=agg.fit_predict(X)
'''
mglearn.discrete_scatter(X[:,0],X[:,1],assignment)
plt.xlabel("Feature 0")
plt.ylabel("Feature 1")
plt.show()

X,y=make_blobs(random_state=0,n_samples=12)
#将ward聚类应用于数据数组X
#Scipy的ward函数返回一个数组,指定执行凝聚聚类时跨越的距离
linkage_array=ward(X)
#现在为包含簇之间距离的linkage_array绘制树状图
dendrogram(linkage_array)
#在树中标记划分成两个簇或三个簇的位置

ax = plt.gca()
bounds = ax.get_xbound()
ax.plot(bounds,[7.25,7.25],'--',c='k')
ax.plot(bounds,[4,4],'--',c='k')
ax.text(bounds[1],7.25,'two clusters',va='center',fontdict={'size':15})
ax.text(bounds[1],4,'three clusters',va='center',fontdict={'size':15})
plt.xlabel("Sample index")
plt.ylabel("Cluster distance")
plt.show()
'''
#DBSCAN
X,y=make_blobs(random_state=0,n_samples=12)
dbscan=DBSCAN()
clusters = dbscan.fit_predict(X)
print("Cluster memberships:\n{}".format(clusters))
'''
mglearn.plots.plot_dbscan()
plt.show()
'''
X,y=make_moons(n_samples=200,noise=0.05,random_state=0)
#将数据缩放成平均值为0,方差为1
scaler = StandardScaler()
scaler.fit(X)
X_scaled = scaler.transform(X)
dbscan = DBSCAN()
clusters = dbscan.fit_predict(X_scaled)
#绘制簇分配
'''
plt.scatter(X_scaled[:,0],X_scaled[:,1],c=clusters,cmap=mglearn.cm2,s=60)
plt.xlabel("Feature 0")
plt.ylabel("Feature 1")
plt.show()
'''