阿里云大学笔记——K-Means聚类算法

0.k-means算法

1.概念

  • k-means属于无监督学习的聚类算法。
  • 适用于:簇内相似性较高,簇间相似性较低。
  • k个初始聚簇中心的选择会影响结果。

2.实现过程:

  1. 选择初始的k个聚簇中心
  2. 把除开聚簇中心之外的点,依次计算到每个聚簇中心向量的距离。选择距离最近的聚簇中心,加入该簇。
  3. 更新聚簇中心:为簇内每个点的向量的平均值。
  4. 循环2、3,直到到达最大迭代次数或者聚簇中心不再发生改变。

1. 导入数据集

import numpy as np
import pandas as pd

data=pd.read_csv("data/iris.csv")
t=data.iloc[:,:4]
t
SepalLengthSepalWidthPetalLengthPetalWidth
05.13.51.40.2
14.93.01.40.2
24.73.21.30.2
34.63.11.50.2
45.03.61.40.2
...............
1456.73.05.22.3
1466.32.55.01.9
1476.53.05.22.0
1486.23.45.42.3
1495.93.05.11.8

150 rows × 4 columns

2. K-Means算法实现

class KMeans:
    """使用python实现KMeans聚类"""
    
    def __init__(self,k,times):
        """初始化方法:
           k:int 表示聚类的个数
           times:int 表示循环迭代的最多次数
           
        """
        self.k=k
        self.times=times
        
    def fit(self,X):
        
        X=np.asarray(X)
        np.random.seed(666)
        #从数组中随机选择k个点作为初始聚类中心
        self.cluster_center_=X[np.random.randint(0,len(X),self.k)]
        self.labels_=np.zeros(len(X))#初始化所有数据标签为0
        
        for t in range(self.times):
            for index,x in enumerate(X):
                #计算每个样本中心与聚类中心的距离
                dis=np.sqrt(np.sum((x-self.cluster_center_)**2,axis=1))
                #将最小距离的索引赋值给标签数组,索引的值就是当前节点所在的簇。取值为[0,k-1]
                self.labels_[index]=dis.argmin()#dis.argmin()取值为[0,k-1]
                
            #循环遍历每一个簇
            for i in range(self.k):
                #计算每个簇内所有点的均值,跟新聚类中心
                self.cluster_center_[i]=np.mean(X[self.labels_==i],axis=0)
                
    def predict(self,X):
        """预测样本属于哪一个簇"""
        X=np.asarray(X)
        result=np.zeros(len(X))
        for index ,x in enumerate(X):
            #计算样本到每个聚类中心的距离
            dis=np.sqrt(np.sum((x-self.cluster_center_)**2,axis=1))
            #找到距离最近的聚类中心,划分类别
            result[index]=dis.argmin()
        
        return result
            

3. 创建kmeans对象,进行分类

kmeans=KMeans(3,50)
kmeans.fit(t)

kmeans.cluster_center_
array([[6.85      , 3.07368421, 5.74210526, 2.07105263],
       [5.006     , 3.418     , 1.464     , 0.244     ],
       [5.9016129 , 2.7483871 , 4.39354839, 1.43387097]])
#查看某个簇内的所有样本数据
t[kmeans.labels_==0]
SepalLengthSepalWidthPetalLengthPetalWidth
526.93.14.91.5
776.73.05.01.7
1006.33.36.02.5
1027.13.05.92.1
1036.32.95.61.8
1046.53.05.82.2
1057.63.06.62.1
1077.32.96.31.8
1086.72.55.81.8
1097.23.66.12.5
1106.53.25.12.0
1116.42.75.31.9
1126.83.05.52.1
1156.43.25.32.3
1166.53.05.51.8
1177.73.86.72.2
1187.72.66.92.3
1206.93.25.72.3
1227.72.86.72.0
1246.73.35.72.1
1257.23.26.01.8
1286.42.85.62.1
1297.23.05.81.6
1307.42.86.11.9
1317.93.86.42.0
1326.42.85.62.2
1346.12.65.61.4
1357.73.06.12.3
1366.33.45.62.4
1376.43.15.51.8
1396.93.15.42.1
1406.73.15.62.4
1416.93.15.12.3
1436.83.25.92.3
1446.73.35.72.5
1456.73.05.22.3
1476.53.05.22.0
1486.23.45.42.3
#对数据进行预测
kmeans.predict([[6.2,2.5,5.0,2.1],[5.2,4.0,5.6,2.5],[5.0,4.0,6.0,4.0]])
array([2., 0., 0.])

4. 进行可视化

#选取两个特征进行训练,方便进行可视化
t2=data.loc[:,"SepalLength":"SepalWidth"]
my_kmeans=KMeans(3,50)
my_kmeans.fit(t2)

import matplotlib as mpl
import matplotlib.pyplot as plt

mpl.rcParams["font.family"]="SimHei"
mpl.rcParams["axes.unicode_minus"]=False

plt.figure(figsize=(10,10))
#绘制每个类别的散点图
plt.scatter(t2[kmeans.labels_==0].iloc[:,0],t2[kmeans.labels_==0].iloc[:,1],label="类别1")
plt.scatter(t2[kmeans.labels_==1].iloc[:,0],t2[kmeans.labels_==1].iloc[:,1],label="类别2")
plt.scatter(t2[kmeans.labels_==2].iloc[:,0],t2[kmeans.labels_==2].iloc[:,1],label="类别3")
plt.scatter(my_kmeans.cluster_center_[:,0],my_kmeans.cluster_center_[:,1],marker="+",s=300)
plt.title("聚类分析")
plt.xlabel("SepalLength")
plt.ylabel("SepalWidth")
plt.legend()
<matplotlib.legend.Legend at 0x26005241308>

在这里插入图片描述

5. 使用sklearn包的kMeans

import numpy as np
from sklearn import datasets

iris =datasets.load_iris()

iris.feature_names
['sepal length (cm)',
 'sepal width (cm)',
 'petal length (cm)',
 'petal width (cm)']
from sklearn.cluster import KMeans
kmeans=KMeans(n_clusters=3,init='k-means++',random_state=666)
#init='k-means++'/'random'random是指随机取k个值,'k-means++'避免选择较差起始点
predict=kmeans.fit_predict(iris.data)
predict
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, 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, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 2, 2, 2, 0, 2, 2, 2,
       2, 2, 2, 0, 0, 2, 2, 2, 2, 0, 2, 0, 2, 0, 2, 2, 0, 0, 2, 2, 2, 2,
       2, 0, 2, 2, 2, 2, 0, 2, 2, 2, 0, 2, 2, 2, 0, 2, 2, 0])
plt.figure(figsize=(10,10))
import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.rcParams["font.family"]="SimHei"
mpl.rcParams["axes.unicode_minus"]=False
#将聚类结果显示
plt.scatter(iris.data[predict == 0, 0], iris.data[predict== 0, 1],label = '类型1')
#[predict == 0, 2], 类型为0的sepal length (cm)在第1的栏位,所以是0,sepal width (cm)是第2栏位,所以是1
plt.scatter(iris.data[predict == 1, 0], iris.data[predict== 1, 1], label = '类型2')
plt.scatter(iris.data[predict == 2, 0], iris.data[predict== 2, 1], label = '类型3')
plt.scatter(kmeans.cluster_centers_[:,0],kmeans.cluster_centers_[:,1],marker="+",s=300)
plt.title('鸢尾花聚簇分类')
plt.xlabel('sepalLength')
plt.ylabel('sepalWidth')
plt.legend()
<matplotlib.legend.Legend at 0x1c4d6076308>

在这里插入图片描述

©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页