05. 聚类---K(k-means)均值

 一、概念    

 K均值(k-means)是聚类算法中最为简单和高效的算法,属于无监督的算法。

      核心思想:由用户指定K个初始质心(initial centroids),以作为聚类的类别(cluster),重复迭代直至算法收敛 

基本算法流程:

     1.选取K个初始质心(作为初始的cluster)

     2.repeat:

              对每个样本点,计算得到距其最近的质心,将其类别标为该质心所对应的cluster

              重新计算K个cluser对应的质心

      3.until 质心不在发生变化或迭代达到上限

二、python简单方法讲解

dist = np.array([[121,34,43,32],
                 [121,221,12,23],
                 [65,21,2,43],
                 [1,221,32,43],
                [21,0,2,3]])
c_index = np.argmin(dist)
print(c_index)
 ##输出17,把所有的二维数据当一维数据做处理,显示出最小的索引,0所在的位置在第17索引上


c_index = np.argmin(dist,axis=1)
print(c_index)
##输出 [3 2 2 0 1] axis将二维数据求最小值当一列处理,返回的是每行的最小值索引
print(c_index==2)
# [False  True  True False False]

x_new=np.array(
[[-0.02708305  5.0215929 ],
 [-5.49252256  6.27366991],
 [-5.37691608  1.51403209],
 [-5.37872006  2.16059225],
 [ 9.58333171  8.10916554]])


x_new[c_index==2]
#array([[-5.49252256,  6.27366991],
#       [-5.37691608,  1.51403209]])

np.mean(x_new[c_index==2],axis=0)
#输出 array([-5.43471932, 3.893851 ]) 列加起来求平均

三、python实现kmeans

### 0. 引入依赖
import numpy as np
import matplotlib.pyplot as plt 
# 从sklearn 中直接生成聚类数据
from sklearn.datasets import make_blobs

### 1.数据加载
# n_samples 表示生成100个样本点  centers 生成6个中心点
# cluster_std 聚类的标准差
x,y=make_blobs(n_samples=100,centers=6,random_state=1234,cluster_std=0.6)
plt.figure(figsize=(6,6))
plt.scatter(x[:,0],x[:,1],c=y)
plt.show()

 

## 2.算法实现
## 引用scipy的距离函数 默认欧式距离
from scipy.spatial.distance import cdist 

class K_Means(object):
    # 初始化,参数n_clusters(K)聚类的类别 、max_iter最大迭代次数、初始质心centroids
    def __init__(self,n_clusters=6,max_iter = 300,centroids=[]):
        self.n_clusters=n_clusters
        self.max_iter=max_iter
        self.centroids=np.array(centroids,dtype=np.float64)
    
    # 训练模型方法,k-means聚类过程,传入原始数据
    # data是个二维举证
    def fit(self,data):
        # 假如没有制定初心质心,就随机选取data中的点作为初始质心
        if(self.centroids.shape == (0,)):
            ## 随机生成n_clusters个0到len(data)的索引值从data中获取数据
            self.centroids = data[ np.random.randint(0,data.shape[0],self.n_clusters),: ]
        
        #开始迭代 
        for i in range(self.max_iter):
            # 1. 计算距离矩阵,得到的是一个100 * 6 的矩阵
            # 就是每个data的数据与不同质心点的距离
             distances = cdist(data,self.centroids)
            # 2. 对距离按由近到远排序,选取最近的质心点类别,作为当前点的分类 
             c_index = np.argmin(distances,axis=1 )
            # 3. 对每一类数据进行均值计算,更新质心点坐标 
             for i in range(self.n_clusters):
                # 首先排出掉没有出现在c_index的类别
                # 因为可能存在某个质心没有数据聚集到
                 if i in c_index:
                    # 选出所有列表是i的点,取data里面坐标的均值,更新第i个质心
                    #data[c_index==i] 布尔索引,拿出来的是true的索引的值
                     self.centroids[i] = np.mean(data[c_index==i],axis=0)
                    
    # 实现预测方法 
    def predict(self,samples):
        # 跟上面一样,先计算距离矩阵,然后选取距离最近的那个质心的类别
        distances = cdist(samples,self.centroids)
        c_index = np.argmin(distances,axis=1 )
        
        return c_index
### 3. 测试
# 定义一个绘制子图函数
def plotKMean(x,y,centroids,subplot,title):
    # 分配子图
    plt.subplot(subplot)
    plt.scatter(x[:,0],x[:,1],c='r')
    #画出质心点  s为size
    plt.scatter(centroids[:,0],centroids[:,1],c=np.array(range(6)),s=100)
    plt.title(title)
    
kmeans = K_Means(max_iter = 300,centroids=np.array([[2,1],[2,2],[2,3],[2,4],[2,5],[2,6]]))

plt.figure(figsize=(16,6))

# 121 表示 1行2列的第一个子图
plotKMean(x,y,kmeans.centroids,121,'Initial State')

# 开始聚类
kmeans.fit(x)

plotKMean(x,y,kmeans.centroids,122,'Final State')


# 预测新数据点的类别 
x_new = np.array([[0,0],[10,7]])

y_pred= kmeans.predict(x_new)

print(kmeans.centroids)
#[[ 5.76444812 -4.67941789]
# [-2.89174024 -0.22808556]
# [-5.89115978  2.33887408]
# [-4.53406813  6.11523454]
# [-1.15698106  5.63230377]
# [ 9.20551979  7.56124841]]

print(y_pred)
# [1 5]
plt.scatter(x_new[:,0],x_new[:,1],s=100,c='black')

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值