K近邻聚类算法

K近邻聚类算法

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

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

基本算法流程

  • 选取k个初始质心(作为初始cluster);
  • repeat:
  • 对每个样本点,计算得到距其最近的质心,将其类别标为该质心所对应的cluster;
  • 重新计算k个cluser对应的质心;
  • until 质心不再发生变化或迭代达到上限

代码示例

# K-means代码实现

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

### 1.数据加载
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()

K近邻聚类算法_第1张图片

### 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=500, centroids=[]):
        self.n_clusters = n_clusters
        self.max_iter = max_iter
        self.centroids = np.array(centroids, dtype=np.float)
        
    #训练模型方法,k-means聚类过程,传入原始数据
    def fit(self, data):
        #假如没有指定初始质心,就随机选取data中的点作为初始质心
        if (self.centroids.shape == (0,)):
            #从data中随机生成0到data行的6个整数,作为索引值,生成6个质心
            self.centroids = data[ np.random.randint(0,data.shape[0], self.n_clusters), : ]
            
        #开始迭代
        for i in range(self.max_iter):
            #1.计算距离矩阵,得到一个100*6的矩阵
            distances = cdist(data, self.centroids)
                
            #2.对距离按照由近到远排序,选取最近的质心点的类别,作为当前点的分类
            c_ind = np.argmin(distances, axis=1)
                
            #3.对每一类数据进行均值计算,更新质心点的坐标
            for i in range(self.n_clusters):
                #排除掉没有出现在c_ind里的类别
                for i in c_ind:
                    #选出所有类别是i的点,取data里面坐标的均值,更新第i个质心
                    self.centroids[i] = np.mean( data[c_ind==i], axis=0)
        
    #实现预测方法
    def predict(self, samples):
        #先计算距离矩阵,然后选取距离最近的那个质心点的类别
        distances = cdist(samples, self.centroids)
        c_ind = np.argmin(distances, axis=1)
        
        return c_ind
    





### 3.测试
#定义一个绘制子图函数
def plotKMeans(x, y, centroids, subplot, title):
    #分配子图,121表示1行2列的子图中的第一个
    plt.subplot(subplot)
    plt.scatter(x[:,0],x[:,1],c='r')
    #画出质心点
    plt.scatter(centroids[:,0],centroids[:,1],c=np.array(range(6)),s=100)
    plt.title(title)
    
kmeans=K_Means(n_clusters=6, max_iter=300, centroids=np.array([[2,1],[2,2],[2,3],[2,4],[2,5],[2,6]]))

plt.figure(figsize=(16, 6))
plotKMeans(x,y, kmeans.centroids, 121, 'Initial State')

#开始聚类
kmeans.fit(x)

plotKMeans(x,y, kmeans.centroids, 122, 'Final State')
    
#预测新数据点的类别
x_new = np.array([[3,4],[5,6]])
y_pred = kmeans.predict(x_new)

print(kmeans.centroids)
print(y_pred)

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

K近邻聚类算法_第2张图片

你可能感兴趣的:(机器学习与算法,算法,聚类,机器学习,人工智能)