机器学习----聚类
聚类
无监督学习 (unsupervised learning) 是找出输入数据的模式。比如,它可以根据电影的各种特征做聚类,用这种方法收集数据为电影推荐系统提供标签。此外无监督学习还可以降低数据的维度,它可以帮助我们更好的理解数据。
聚类算法:
一种典型的无监督学习算法,主要用于将相似的样本自动归到一个类别中。
在聚类算法中根据样本之间的相似性,将样本划分到不同的类别中,对于不同的相似度计算方法,会得到不同的聚类结果,常用的相似度计算方法有欧式距离法。
举例
使用不同的聚类准则,会产生的聚类结果不同。
在无监督学习中,数据 = (特征,) 没有标签
以NBA球员詹姆斯的个人统计为例, 根据詹姆斯个人统计来预测骑士队输赢或者个人效率值外,我们还可以对该数据做聚类 (clustering),即将训练集中的数据分成若干组,每组成为一个簇 (cluster)。
假设聚类方法将数据聚成二个簇 A 和 B,如下图
后来发现簇 A 代表赢,簇 B 代表输。聚类的用处就是可以找到一个潜在的原因来解释为什么样例 1 和 4 可以赢球。难道真的是只要詹姆斯三双就可以赢球?
聚类算法在现实中的应用
- 用户画像,广告推荐,Data Segmentation,搜索引擎的流量推荐,恶意流量识别
- 基于位置信息的商业推送,新闻聚类,筛选排序
- 图像分割,降维,识别;离群点检测;信用卡异常消费;发掘相同功能的基因片段
k-means是聚类算法中最典型的算法
聚类算法实现流程
k-means其实包含两层内容:
- K : 初始中心点个数(计划聚类数)
- means:求中心点到其他数据点距离的平均值
k-means聚类步骤
1、随机设置K个特征空间内的点作为初始的聚类中心
2、对于其他每个点计算到K个中心的距离(3个),未知的点选择最近的一个聚类中心点作为标记类别
3、接着对着标记的聚类中心之后,重新计算出每个聚类的新中心点(平均值)
4、如果计算得出的新中心点与原中心点一样(质心不再移动),那么结束,否则重新进行第二步过程
通过下图解释实现流程:
k聚类动态效果图
案例练习
1、随机设置K个特征空间内的点作为初始的聚类中心(本案例中设置p1和p2)
2、对于其他每个点计算到K个中心的距离,未知的点选择最近的一个聚类中心点作为标记类别
3、接着对着标记的聚类中心之后,重新计算出每个聚类的新中心点(平均值)
4、如果计算得出的新中心点与原中心点一样(质心不再移动),那么结束,否则重新进行第二步过程【经过判断,需要重复上述步骤,开始新一轮迭代】
5、当每次迭代结果不变时,认为算法收敛,聚类完成,K-Means一定会停下,不可能陷入一直选质心的过程。
小结
流程:
- 事先确定常数K,常数K意味着最终的聚类类别数;
- 首先随机选定初始点为质心,并通过计算每一个样本与质心之间的相似度(这里为欧式距离),将样本点归到最相似的类中,
- 接着,重新计算每个类的质心(即为类中心),重复这样的过程,直到质心不再改变,
- 最终就确定了每个样本所属的类别以及每个类的质心。
注意:
由于每次都要计算所有的样本与每一个质心之间的相似度,故在大规模的数据集上,K-Means算法的收敛速度比较慢
api介绍
sklearn.cluster.KMeans(n_clusters=8)
参数:
n_clusters:开始的聚类中心数量
整型,缺省值=8,生成的聚类数,即产生的质心(centroids)数。
方法:
estimator.fit(x)
estimator.predict(x)
estimator.fit_predict(x)
计算聚类中心并预测每个样本属于哪个类别,相当于先调用fit(x),然后再调用predict(x)
案例实战
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
#用calinski_harabaz_score方法评价聚类效果的好坏大概是类间距除以类内距,因此这个值越大越好
from sklearn.metrics import calinski_harabasz_score
# 创建数据
X, y = make_blobs(n_samples=1000, n_features=2, centers=[
[-1, -1], [0, 0], [1, 1], [2, 2]], cluster_std=[0.4, 0.2, 0.2, 0.2], random_state=9)
X.shape, y.shape
((1000, 2), (1000,))
plt.scatter(X[:, 0], X[:, 1])
plt.show()
# kmeans训练,且可视化 聚类=2
y_predict = KMeans(n_clusters=2, random_state=9).fit_predict(X)
print(y_predict[:10])
plt.scatter(X[:, 0], X[:, 1], c=y_predict)
plt.show()
print(calinski_harabasz_score(X, y_predict))
# kmeans训练,且可视化 聚类=3
y_predict = KMeans(n_clusters=3, random_state=9).fit_predict(X)
print(y_predict[:10])
plt.scatter(X[:, 0], X[:, 1], c=y_predict)
plt.show()
print(calinski_harabasz_score(X, y_predict))
# kmeans训练,且可视化 聚类=4
y_predict = KMeans(n_clusters=4, random_state=9).fit_predict(X)
print(y_predict[:10])
plt.scatter(X[:, 0], X[:, 1], c=y_predict)
plt.show()
print(calinski_harabasz_score(X, y_predict))
案例: 探究用户对物品类别的喜好细分
地址: https://www.kaggle.com/c/instacart-market-basket-analysis/data
数据如下:
- order_products__prior.csv:订单与商品信息
字段:order_id, product_id, add_to_cart_order, reordered - products.csv:商品信息
字段:product_id, product_name, aisle_id, department_id - orders.csv:用户的订单信息
字段:order_id,user_id,eval_set,order_number,…. - aisles.csv:商品所属具体物品类别
字段: aisle_id, aisle
1.获取数据
import pandas as pd
from sklearn.decomposition import PCA
from sklearn.cluster import KMeans
## 轮廓系数取值为[-1, 1],其值越大越好,且当值为负时,
# 表明样本被分配到错误的簇中,聚类结果不可接受。对于接近0的结果,则表明聚类结果有重叠的情况
from sklearn.metrics import silhouette_score
# 1.获取数据
order_product = pd.read_csv("./data/instacart/order_products__prior.csv")
products = pd.read_csv("./data/instacart/products.csv")
orders = pd.read_csv("./data/instacart/orders.csv")
aisles = pd.read_csv("./data/instacart/aisles.csv")
order_product.head()
order_id | product_id | add_to_cart_order | reordered | |
---|---|---|---|---|
0 | 2 | 33120 | 1 | 1 |
1 | 2 | 28985 | 2 | 1 |
2 | 2 | 9327 | 3 | 0 |
3 | 2 | 45918 | 4 | 1 |
4 | 2 | 30035 | 5 | 0 |
products.head()
product_id | product_name | aisle_id | department_id | |
---|---|---|---|---|
0 | 1 | Chocolate Sandwich Cookies | 61 | 19 |
1 | 2 | All-Seasons Salt | 104 | 13 |
2 | 3 | Robust Golden Unsweetened Oolong Tea | 94 | 7 |
3 | 4 | Smart Ones Classic Favorites Mini Rigatoni Wit... | 38 | 1 |
4 | 5 | Green Chile Anytime Sauce | 5 | 13 |
orders.head()
order_id | user_id | eval_set | order_number | order_dow | order_hour_of_day | days_since_prior_order | |
---|---|---|---|---|---|---|---|
0 | 2539329 | 1 | prior | 1 | 2 | 8 | NaN |
1 | 2398795 | 1 | prior | 2 | 3 | 7 | 15.0 |
2 | 473747 | 1 | prior | 3 | 3 | 12 | 21.0 |
3 | 2254736 | 1 | prior | 4 | 4 | 7 | 29.0 |
4 | 431534 | 1 | prior | 5 | 4 | 15 | 28.0 |
aisles.head()
aisle_id | aisle | |
---|---|---|
0 | 1 | prepared soups salads |
1 | 2 | specialty cheeses |
2 | 3 | energy granola bars |
3 | 4 | instant foods |
4 | 5 | marinades meat preparation |
2.数据基本处理
# 合并表格
table1 = pd.merge(order_product, products, on=["product_id", "product_id"])
table2 = pd.merge(table1, orders, on=["order_id", "order_id"])
table = pd.merge(table2, aisles, on=["aisle_id", "aisle_id"])
print(table.shape)
(32434489, 14)
table.head()
order_id | product_id | add_to_cart_order | reordered | product_name | aisle_id | department_id | user_id | eval_set | order_number | order_dow | order_hour_of_day | days_since_prior_order | aisle | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 2 | 33120 | 1 | 1 | Organic Egg Whites | 86 | 16 | 202279 | prior | 3 | 5 | 9 | 8.0 | eggs |
1 | 26 | 33120 | 5 | 0 | Organic Egg Whites | 86 | 16 | 153404 | prior | 2 | 0 | 16 | 7.0 | eggs |
2 | 120 | 33120 | 13 | 0 | Organic Egg Whites | 86 | 16 | 23750 | prior | 11 | 6 | 8 | 10.0 | eggs |
3 | 327 | 33120 | 5 | 1 | Organic Egg Whites | 86 | 16 | 58707 | prior | 21 | 6 | 9 | 8.0 | eggs |
4 | 390 | 33120 | 28 | 1 | Organic Egg Whites | 86 | 16 | 166654 | prior | 48 | 0 | 12 | 9.0 | eggs |
# 交叉表合并 table["user_id"]为行索引, table["aisle"]为列索引
data = pd.crosstab(table["user_id"], table["aisle"])
data.head()
aisle | air fresheners candles | asian foods | baby accessories | baby bath body care | baby food formula | bakery desserts | baking ingredients | baking supplies decor | beauty | beers coolers | ... | spreads | tea | tofu meat alternatives | tortillas flat bread | trail mix snack mix | trash bags liners | vitamins supplements | water seltzer sparkling water | white wines | yogurt |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
user_id | |||||||||||||||||||||
1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
2 | 0 | 3 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | ... | 3 | 1 | 1 | 0 | 0 | 0 | 0 | 2 | 0 | 42 |
3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 4 | 1 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 0 |
4 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 |
5 | 0 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 3 |
5 rows × 134 columns
data.shape
(206209, 134)
# 数据截取
new_data = data[:1000]
# 3.特征工程 — pca
transfer = PCA(0.9)
trans_data = transfer.fit_transform(new_data)
trans_data.shape
(1000, 22)
# 4.机器学习(k-means)
estimator = KMeans(n_clusters=5)
y_pred = estimator.fit_predict(trans_data)
print(y_pred[:20])
# 5.模型评估
print(silhouette_score(trans_data, y_pred))
[3 0 3 3 3 3 0 3 3 0 3 3 3 3 3 3 3 3 3 3]
0.4585956252548508
2D数据类别划分
任务:
1、采用Kmeans算法实现2D数据自动聚类,预测V1=80,V2=60数据类别;
2、计算预测准确率,完成结果矫正
3、采用KNN、Meanshift算法,重复步骤1-2
Mean Shift算法,一般是指一个迭代的步骤,即先算出当前点的偏移均值,移动该点到其偏移均值,然后以此为新的起始点,继续移动,直到满足一定的条件结束
数据:data.csv
#load the data
import pandas as pd
import numpy as np
data = pd.read_csv('data.csv')
data.head()
V1 | V2 | labels | |
---|---|---|---|
0 | 2.072345 | -3.241693 | 0 |
1 | 17.936710 | 15.784810 | 0 |
2 | 1.083576 | 7.319176 | 0 |
3 | 11.120670 | 14.406780 | 0 |
4 | 23.711550 | 2.557729 | 0 |
#define X and y
X = data.drop(['labels'],axis=1)
y = data.loc[:,'labels']
y.head()
0 0
1 0
2 0
3 0
4 0
Name: labels, dtype: int64
pd.value_counts(y)
2 1156
1 954
0 890
Name: labels, dtype: int64
%matplotlib inline
from matplotlib import pyplot as plt
fig1 = plt.figure()
plt.scatter(X.loc[:,'V1'],X.loc[:,'V2'])
plt.title("un-labled data")
plt.xlabel('V1')
plt.ylabel('V2')
plt.show()
fig1 = plt.figure()
label0 = plt.scatter(X.loc[:,'V1'][y==0],X.loc[:,'V2'][y==0])
label1 = plt.scatter(X.loc[:,'V1'][y==1],X.loc[:,'V2'][y==1])
label2 = plt.scatter(X.loc[:,'V1'][y==2],X.loc[:,'V2'][y==2])plt.title("labled data")
plt.xlabel('V1')
plt.ylabel('V2'))
plt.legend((label0,label1,label2),('label0','label1','label2'))
plt.show()
print(X.shape,y.shape)
(3000, 2) (3000,)
from sklearn.cluster import KMeans
KM = KMeans(n_clusters=3, random_state=0)
KM.fit(X)
KMeans(n_clusters=3, random_state=0)
centers = KM.cluster_centers_
centers # 3个中心坐标
array([[ 69.92418447, -10.11964119],[ 40.68362784, 59.71589274],[ 9.4780459 , 10.686052 ]])
fig1 = plt.figure()
label0 = plt.scatter(X.loc[:,'V1'][y==0],X.loc[:,'V2'][y==0])
label1 = plt.scatter(X.loc[:,'V1'][y==1],X.loc[:,'V2'][y==1])
label2 = plt.scatter(X.loc[:,'V1'][y==2],X.loc[:,'V2'][y==2])
plt.title("labled data")
plt.xlabel('V1')
plt.ylabel('V2')
# 画中心点
plt.scatter(centers[:, 0], centers[:, 1])
plt.legend((label0,label1,label2),('label0','label1','label2'))
plt.show()
# 预测V1=80,V2=60数据类别;
y_predict = KM.predict(np.array([[80, 60]]))
y_predict
array([1], dtype=int32)
y_predict = KM.predict(X)
print(pd.value_counts(y_predict))
1 1149
0 952
2 899
dtype: int64
pd.value_counts(y)
2 1156
1 954
0 890
Name: labels, dtype: int64
from sklearn.metrics import accuracy_score
accuracy_score(y, y_predict)
0.0023333333333333335
#visualize the data and results
fig4 = plt.subplot(121)
label0 = plt.scatter(X.loc[:,'V1'][y_predict==0],X.loc[:,'V2'][y_predict==0])
label1 = plt.scatter(X.loc[:,'V1'][y_predict==1],X.loc[:,'V2'][y_predict==1])
label2 = plt.scatter(X.loc[:,'V1'][y_predict==2],X.loc[:,'V2'][y_predict==2])plt.title("predicted data")
plt.xlabel('V1')
plt.ylabel('V2')
plt.legend((label0,label1,label2),('label0','label1','label2'))
plt.scatter(centers[:,0],centers[:,1])fig5 = plt.subplot(122)
label0 = plt.scatter(X.loc[:,'V1'][y==0],X.loc[:,'V2'][y==0])
label1 = plt.scatter(X.loc[:,'V1'][y==1],X.loc[:,'V2'][y==1])
label2 = plt.scatter(X.loc[:,'V1'][y==2],X.loc[:,'V2'][y==2])plt.title("labled data")
plt.xlabel('V1')
plt.ylabel('V2')
plt.legend((label0,label1,label2),('label0','label1','label2'))
plt.scatter(centers[:,0],centers[:,1])
plt.show()
#correct the results
y_corrected = []
for i in y_predict:if i == 0:y_corrected.append(1)elif i == 1:y_corrected.append(2)else:y_corrected.append(0)
y_corrected = np.array(y_corrected)
accuracy_score(y, y_corrected)
0.997
#visualize the data and results
fig4 = plt.subplot(121)
label0 = plt.scatter(X.loc[:,'V1'][y_corrected==0],X.loc[:,'V2'][y_corrected==0])
label1 = plt.scatter(X.loc[:,'V1'][y_corrected==1],X.loc[:,'V2'][y_corrected==1])
label2 = plt.scatter(X.loc[:,'V1'][y_corrected==2],X.loc[:,'V2'][y_corrected==2])plt.title("predicted data")
plt.xlabel('V1')
plt.ylabel('V2')
plt.legend((label0,label1,label2),('label0','label1','label2'))
plt.scatter(centers[:,0],centers[:,1])fig5 = plt.subplot(122)
label0 = plt.scatter(X.loc[:,'V1'][y==0],X.loc[:,'V2'][y==0])
label1 = plt.scatter(X.loc[:,'V1'][y==1],X.loc[:,'V2'][y==1])
label2 = plt.scatter(X.loc[:,'V1'][y==2],X.loc[:,'V2'][y==2])plt.title("labled data")
plt.xlabel('V1')
plt.ylabel('V2')
plt.legend((label0,label1,label2),('label0','label1','label2'))
plt.scatter(centers[:,0],centers[:,1])
plt.show()
注意和KNN 的区别
from sklearn.neighbors import KNeighborsClassifier
KNN = KNeighborsClassifier(n_neighbors=3)
KNN.fit(X,y)
KNeighborsClassifier(n_neighbors=3)
#predict based on the test data V1=80, V2=60
y_predict_knn_test = KNN.predict([[80,60]])
y_predict_knn = KNN.predict(X)
print(y_predict_knn_test)
print('knn accuracy:',accuracy_score(y,y_predict_knn))
[2]
knn accuracy: 1.0
print(pd.value_counts(y_predict_knn),pd.value_counts(y))
2 1156
1 954
0 890
dtype: int64 2 1156
1 954
0 890
Name: labels, dtype: int64
fig6 = plt.subplot(121)
label0 = plt.scatter(X.loc[:,'V1'][y_predict_knn==0],X.loc[:,'V2'][y_predict_knn==0])
label1 = plt.scatter(X.loc[:,'V1'][y_predict_knn==1],X.loc[:,'V2'][y_predict_knn==1])
label2 = plt.scatter(X.loc[:,'V1'][y_predict_knn==2],X.loc[:,'V2'][y_predict_knn==2])plt.title("knn results")
plt.xlabel('V1')
plt.ylabel('V2')
plt.legend((label0,label1,label2),('label0','label1','label2'))
plt.scatter(centers[:,0],centers[:,1])fig7 = plt.subplot(122)
label0 = plt.scatter(X.loc[:,'V1'][y==0],X.loc[:,'V2'][y==0])
label1 = plt.scatter(X.loc[:,'V1'][y==1],X.loc[:,'V2'][y==1])
label2 = plt.scatter(X.loc[:,'V1'][y==2],X.loc[:,'V2'][y==2])plt.title("labled data")
plt.xlabel('V1')
plt.ylabel('V2')
plt.legend((label0,label1,label2),('label0','label1','label2'))
plt.scatter(centers[:,0],centers[:,1])
plt.show()
meanshift
from sklearn.cluster import MeanShift,estimate_bandwidth
# 预估带宽
bw = estimate_bandwidth(X,n_samples=500)
#establish the meanshift model-un-supervised model
ms = MeanShift(bandwidth=bw)
ms.fit(X)
MeanShift(bandwidth=30.84663454820215)
y_predict_ms = ms.predict(X)
print(pd.value_counts(y_predict_ms),pd.value_counts(y))
0 1149
1 952
2 899
dtype: int64 2 1156
1 954
0 890
Name: labels, dtype: int64
#新增代码 打印使用meanshift算法获取的聚类中心 与kmeans算法对比 中心点非常接近
centers2 = ms.cluster_centers_
print(centers2)#meanshift聚类中心
[[ 40.60158864 59.65137971][ 70.01854306 -10.11803404][ 9.56752568 10.79316266]]
centers
array([[ 69.92418447, -10.11964119],[ 40.68362784, 59.71589274],[ 9.4780459 , 10.686052 ]])
fig6 = plt.subplot(121)
label0 = plt.scatter(X.loc[:,'V1'][y_predict_ms==0],X.loc[:,'V2'][y_predict_ms==0])
label1 = plt.scatter(X.loc[:,'V1'][y_predict_ms==1],X.loc[:,'V2'][y_predict_ms==1])
label2 = plt.scatter(X.loc[:,'V1'][y_predict_ms==2],X.loc[:,'V2'][y_predict_ms==2])plt.title("ms results")
plt.xlabel('V1')
plt.ylabel('V2')
plt.legend((label0,label1,label2),('label0','label1','label2'))
plt.scatter(centers[:,0],centers[:,1])fig7 = plt.subplot(122)
label0 = plt.scatter(X.loc[:,'V1'][y==0],X.loc[:,'V2'][y==0])
label1 = plt.scatter(X.loc[:,'V1'][y==1],X.loc[:,'V2'][y==1])
label2 = plt.scatter(X.loc[:,'V1'][y==2],X.loc[:,'V2'][y==2])plt.title("labled data")
plt.xlabel('V1')
plt.ylabel('V2')
plt.legend((label0,label1,label2),('label0','label1','label2'))
plt.scatter(centers[:,0],centers[:,1])
plt.show()
#correct the results
y_corrected_ms = []
for i in y_predict_ms:if i==0:y_corrected_ms.append(2)elif i==1:y_corrected_ms.append(1)else:y_corrected_ms.append(0)
y_corrected_ms = np.array(y_corrected_ms)
print(type(y_corrected_ms))
print(pd.value_counts(y_corrected_ms),pd.value_counts(y))
<class 'numpy.ndarray'>
2 1149
1 952
0 899
dtype: int64 2 1156
1 954
0 890
Name: labels, dtype: int64
fig6 = plt.subplot(121)
label0 = plt.scatter(X.loc[:,'V1'][y_corrected_ms==0],X.loc[:,'V2'][y_corrected_ms==0])
label1 = plt.scatter(X.loc[:,'V1'][y_corrected_ms==1],X.loc[:,'V2'][y_corrected_ms==1])
label2 = plt.scatter(X.loc[:,'V1'][y_corrected_ms==2],X.loc[:,'V2'][y_corrected_ms==2])plt.title("ms corrected results")
plt.xlabel('V1')
plt.ylabel('V2')
plt.legend((label0,label1,label2),('label0','label1','label2'))
plt.scatter(centers[:,0],centers[:,1])fig7 = plt.subplot(122)
label0 = plt.scatter(X.loc[:,'V1'][y==0],X.loc[:,'V2'][y==0])
label1 = plt.scatter(X.loc[:,'V1'][y==1],X.loc[:,'V2'][y==1])
label2 = plt.scatter(X.loc[:,'V1'][y==2],X.loc[:,'V2'][y==2])plt.title("labled data")
plt.xlabel('V1')
plt.ylabel('V2')
plt.legend((label0,label1,label2),('label0','label1','label2'))
plt.scatter(centers[:,0],centers[:,1])
plt.show()
Meanshift
一般是指一个迭代的步骤,即先算出当前点的偏移均值,移动该点到其偏移均值,然后以此为新的起始点,继续移动,直到满足一定的条件结束.
Sk是一个半径为h的高维球区域,满足以下关系的y点的集合,
k表示在这n个样本点xi中,有k个点落入Sk区域中.
以上是官方的说法,在d维空间中,任选一个点,然后以这个点为圆心,h为半径做一个高维球,因为有d维,d可能大于2,所以是高维球。落在这个球内的所有点和圆心都会产生一个向量,向量是以圆心为起点落在球内的点位终点。然后把这些向量都相加。相加的结果就是Meanshift向量。
再以meanshift向量的终点为圆心,再做一个高维的球。如下图所以,重复以上步骤,就可得到一个meanshift向量。如此重复下去,meanshift算法可以收敛到概率密度最大得地方。也就是最稠密的地方。
mean shift 聚类流程:
假设在一个多维空间中有很多数据点需要进行聚类,Mean Shift的过程如下:
- 在未被标记的数据点中随机选择一个点作为中心center;
- 找出离center距离在bandwidth之内的所有点,记做集合M,认为这些点属于簇c。同时,把这些球内点属于这个类的概率加1,这个参数将用于最后步骤的分类
- 以center为中心点,计算从center开始到集合M中每个元素的向量,将这些向量相加,得到向量shift。
- center = center+shift。即center沿着shift的方向移动,移动距离是||shift||。
- 重复步骤2、3、4,直到shift的大小很小(就是迭代到收敛),记住此时的center。注意,这个迭代过程中遇到的点都应该归类到簇c。
- 如果收敛时当前簇c的center与其它已经存在的簇c2中心的距离小于阈值,那么把c2和c合并。否则,把c作为新的聚类,增加1类。 重复1、2、3、4、5直到所有的点都被标记访问。
- 分类:根据每个类,对每个点的访问频率,取访问频率最大的那个类,作为当前点集的所属类。 简单的说,mean shift就是沿着密度上升的方向寻找同属一个簇的数据点。
使用MeanShift
from sklearn.cluster import MeanShift, estimate_bandwidth
bw = estimate_bandwidth(X, n_samples=500)
print('bw = ', bw)
ms = MeanShift(bandwidth=bw)
ms.fit(X)
y_predict_ms = ms.predict(X)
centers = ms.cluster_centers_
print(centers)
fig1 = plt.subplot(121)
label0 = plt.scatter(X.loc[:, 'V1'][y_predict_ms==0], X.loc[:, 'V2'][y_predict_ms==0], color='b' )
label1 = plt.scatter(X.loc[:, 'V1'][y_predict_ms==1], X.loc[:, 'V2'][y_predict_ms==1], color='g')
label2 = plt.scatter(X.loc[:, 'V1'][y_predict_ms==2], X.loc[:, 'V2'][y_predict_ms==2], color='r')
plt.title("预测数据分布")
plt.xlabel('v1')
plt.ylabel('v2')
plt.legend((label0,label1,label2), ('标签1', '标签2','标签3'))
plt.scatter(centers[:, 0], centers[:, 1])
plt.subplot(122)
label0 = plt.scatter(X.loc[:, 'V1'][y==0], X.loc[:, 'V2'][y==0], color='b' )
label1 = plt.scatter(X.loc[:, 'V1'][y==1], X.loc[:, 'V2'][y==1], color='g')
label2 = plt.scatter(X.loc[:, 'V1'][y==2], X.loc[:, 'V2'][y==2], color='r')
plt.title("真实数据分布")
plt.xlabel('v1')
plt.ylabel('v2')
plt.legend((label0,label1,label2), ('标签1', '标签2','标签3'))
plt.scatter(centers[:, 0], centers[:, 1])plt.show()
#correct the results
y_corrected_ms = []
for i in y_predict_ms:if i==0:y_corrected_ms.append(2)elif i==1:y_corrected_ms.append(1)else:y_corrected_ms.append(0)
print(pd.value_counts(y_corrected_ms),pd.value_counts(y))
y_predict = np.array(y_corrected_ms)
fig1 = plt.subplot(121)
label0 = plt.scatter(X.loc[:, 'V1'][y_predict==0], X.loc[:, 'V2'][y_predict==0], color='b' )
label1 = plt.scatter(X.loc[:, 'V1'][y_predict==1], X.loc[:, 'V2'][y_predict==1], color='g')
label2 = plt.scatter(X.loc[:, 'V1'][y_predict==2], X.loc[:, 'V2'][y_predict==2], color='r')
plt.title("预测数据分布")
plt.xlabel('v1')
plt.ylabel('v2')
plt.legend((label0,label1,label2), ('标签1', '标签2','标签3'))
plt.scatter(centers[:, 0], centers[:, 1])
plt.subplot(122)
label0 = plt.scatter(X.loc[:, 'V1'][y==0], X.loc[:, 'V2'][y==0], color='b' )
label1 = plt.scatter(X.loc[:, 'V1'][y==1], X.loc[:, 'V2'][y==1], color='g')
label2 = plt.scatter(X.loc[:, 'V1'][y==2], X.loc[:, 'V2'][y==2], color='r')
plt.title("真实数据分布")
plt.xlabel('v1')
plt.ylabel('v2')
plt.legend((label0,label1,label2), ('标签1', '标签2','标签3'))
plt.scatter(centers[:, 0], centers[:, 1])plt.show()
实现
import random
from sklearn import datasets
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
class Kmeans():"""Kmeans聚类算法.Parameters:-----------k: int聚类的数目.max_iterations: int最大迭代次数.varepsilon: float判断是否收敛, 如果上一次的所有k个聚类中心与本次的所有k个聚类中心的差都小于varepsilon,则说明算法已经收敛"""def __init__(self, k=2, max_iterations=500, varepsilon=1e-4):self.k = kself.max_iterations = max_iterationsself.varepsilon = varepsilon# 从所有样本中随机选取self.k样本作为初始的聚类中心def init_random_centroids(self, X):n_samples, n_features = np.shape(X)centroids = np.zeros((self.k, n_features))for i in range(self.k):centroid = X[np.random.choice(range(n_samples))]centroids[i] = centroidreturn centroids# 返回距离该样本最近的一个中心索引[0, self.k)def _closest_centroid(self, sample, centroids):distances = self.euclidean_distance(sample, centroids)closest_i = np.argmin(distances)return closest_i# 将所有样本进行归类,归类规则就是将该样本归类到与其最近的中心def create_clusters(self, centroids, X):n_samples = np.shape(X)[0]clusters = [[] for _ in range(self.k)]for sample_i, sample in enumerate(X):centroid_i = self._closest_centroid(sample, centroids)clusters[centroid_i].append(sample_i)return clusters# 对中心进行更新def update_centroids(self, clusters, X):n_features = np.shape(X)[1]centroids = np.zeros((self.k, n_features))for i, cluster in enumerate(clusters):centroid = np.mean(X[cluster], axis=0)centroids[i] = centroidreturn centroids# 将所有样本进行归类,其所在的类别的索引就是其类别标签def get_cluster_labels(self, clusters, X):y_pred = np.zeros(np.shape(X)[0])for cluster_i, cluster in enumerate(clusters):for sample_i in cluster:y_pred[sample_i] = cluster_ireturn y_pred# 计算一个样本与数据集中所有样本的欧氏距离的平方def euclidean_distance(self, one_sample, X):one_sample = one_sample.reshape(1, -1)X = X.reshape(X.shape[0], -1)distances = np.power(np.tile(one_sample, (X.shape[0], 1)) - X, 2).sum(axis=1)return distances# 对整个数据集X进行Kmeans聚类,返回其聚类的标签def predict(self, X):# 从所有样本中随机选取self.k样本作为初始的聚类中心centroids = self.init_random_centroids(X)# 迭代,直到算法收敛(上一次的聚类中心和这一次的聚类中心几乎重合)或者达到最大迭代次数for _ in range(self.max_iterations):# 将所有进行归类,归类规则就是将该样本归类到与其最近的中心clusters = self.create_clusters(centroids, X)former_centroids = centroids# 计算新的聚类中心centroids = self.update_centroids(clusters, X)# 如果聚类中心几乎没有变化,说明算法已经收敛,退出迭代diff = centroids - former_centroidsif diff.any() < self.varepsilon:breakreturn self.get_cluster_labels(clusters, X)def main():# Load the datasetX, y = datasets.make_blobs(n_samples=10000,n_features=3,centers=[[3,3, 3], [0,0,0], [1,1,1], [2,2,2]],cluster_std=[0.2, 0.1, 0.2, 0.2],random_state =9)# 用Kmeans算法进行聚类clf = Kmeans(k=4)y_pred = clf.predict(X)print(y_pred)# 可视化聚类效果# fig = plt.figure(figsize=(12, 8))# ax = Axes3D(fig, rect=[0, 0, 1, 1], elev=30, azim=20)# plt.scatter(X[y==0][:, 0], X[y==0][:, 1], X[y==0][:, 2])# plt.scatter(X[y==1][:, 0], X[y==1][:, 1], X[y==1][:, 2])# plt.scatter(X[y==2][:, 0], X[y==2][:, 1], X[y==2][:, 2])# plt.scatter(X[y==3][:, 0], X[y==3][:, 1], X[y==3][:, 2])# plt.show()fig = plt.figure(figsize=(12, 8))ax = Axes3D(fig)plt.scatter(X[y_pred==0][:, 0], X[y_pred==0][:, 1], X[y_pred==0][:, 2], label='y==0', color='b')plt.scatter(X[y_pred==1][:, 0], X[y_pred==1][:, 1], X[y_pred==1][:, 2], label='y==1', color='r')plt.scatter(X[y_pred==2][:, 0], X[y_pred==2][:, 1], X[y_pred==2][:, 2], label='y==2', color='g')plt.scatter(X[y_pred==3][:, 0], X[y_pred==3][:, 1], X[y_pred==3][:, 2], label='y==3', color='purple')plt.legend()plt.show()if __name__ == "__main__":main()
实验结果
机器学习----聚类相关推荐
- 机器学习 聚类篇——DBSCAN的参数选择及其应用于离群值检测
机器学习 聚类篇--DBSCAN的算法原理.参数选择及其应用于离群值检测 摘要 1. DBSCAN算法原理 1.1 基本概念定义 1.2 算法流程 2. 参数选择 2.1 领域半径:Eps的选取方法( ...
- 机器学习 聚类篇——python实现DBSCAN(基于密度的聚类方法)
机器学习 聚类篇--python实现DBSCAN(基于密度的聚类方法) 摘要 python实现代码 计算实例 摘要 DBSCAN(Density-Based Spatial Clustering of ...
- 炼数成金数据分析课程---17、机器学习聚类算法(后面要重点看)
炼数成金数据分析课程---17.机器学习聚类算法(后面要重点看) 一.总结 一句话总结: 大纲+实例快速学习法 主要讲解常用聚类算法(比如K-means等)的原理及python代码实现:后面学习聚类的 ...
- 机器学习--聚类(五种主要聚类算法)
机器学习–聚类(五种主要聚类算法) 原博文: 聚类是一种机器学习技术,它涉及到数据点的分组.给定一组数据点,我们可以使用聚类算法将每个数据点划分为一个特定的组.理论上,同一组中的数据点应该具有相似的属 ...
- 基于机器学习聚类算法寻找美国职业篮球联赛NBA中的超级强队
聚类算法 聚类算法是机器学习中经典的非监督学习算法之一,相比于分类算法,聚类不依赖预定义的样本标签,而是让算法通过对数据的学习从而找到其内部的规律,该算法对有相同特征的样本进行聚类,聚类的时候,我们并 ...
- 机器学习——聚类算法
文章目录 聚类算法 1 k-Means算法 1.1 基本概念 1.2 k-Means算法原理 1.3 k-Means算法的可视化演示 1.4 实验 2 DBSCAN算法 2.1 基本概念 2.2 DB ...
- 机器学习-聚类之K均值(K-means)算法原理及实战
K-means算法 前言 机器学习方法主要分为监督学习和非监督学习两种.监督学习方法是在样本标签类别已知的情况下进行的,可以统计出各类样本的概率分布.特征空间分布区域等描述量,然后利用这些参数进行分类 ...
- 机器学习 | 聚类评估指标
文章目录 1. 聚类评估指标 1.1 外部评估指标 RI 兰德指数 ARI 调整兰德指数 Jaccard JC指数 FMI FMI指数 MI 互信息 NMI 归一化互信息 AMI 调整互信息 1.2 ...
- coursera机器学习-聚类,降维,主成分分析
#对coursera上Andrew Ng老师开的机器学习课程的笔记和心得: #注:此笔记是我自己认为本节课里比较重要.难理解或容易忘记的内容并做了些补充,并非是课堂详细笔记和要点: #标记为<补 ...
- 浅谈机器学习--聚类
还不了解机器学习?来看! 目录 一.聚类 二.k均值聚类算法(k-means) 1.k均值聚类算法的流程 二.k均值算法的改进 1.二分k-means算法 2.k-means++算法 3.k-medo ...
最新文章
- iOS事件处理,看我就够了~
- List集合的去除重复性练习
- vim php psr2 插件,将vim打造成c++超级ide(vim插件安装)
- 多线程-synchronized锁
- 【转】推荐两款富文本编辑器:NicEdit和Kindeditor
- 给 C# 开发者的代码审查清单
- Java Mybatis
- ble 连接成功后找不到服务_闷声发大财的BLE芯片龙头
- 宿主机使用nginx向docker容器转发https请求
- 如何使用modelarts训练海量数据
- 计算机实验报告表九,北理大学计算机实验基础实验九实验报告表-20210617084645.pdf-原创力文档...
- Linux 增加swap空间大小
- shell--字符串是否为空
- vs 2005應用2003框架
- 《Windows游戏编程大师技巧》一、学海无涯
- 鼎立测试软件能锁网吗,路测软件鼎利通信Pioneer操作培训PPT(ET128).ppt
- PC端天天生鲜页面实现
- 机器学习常用衡量标准
- 如何免费下载论文资料
- 计算机显示器的分辨率可以调节吗,电脑分辨率何如调?电脑无法调整屏幕分辨率怎么办?...