机器学习之K-Means算法

K均值算法

K均值算法和KNN算法在逻辑上有些相似,但是K均值算法本身属于无监督学习算法中的聚类算法,并没有想KNN算法本身存在一个现成的训练集(分好类的点),因此需要依靠随机产生的质心,通过迭代计算周围的点与每个质心之间的距离来对周围的点进行聚类。

1.算法流程
  • 选取K个质心->将所有点按照距离质心的距离远近分到质心所属的类型->计算每个类型的平均值作为新的质心->重复之前的操作迭代。
2.代码实现
    # encoding=utf-8
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
# 引入scipy中的距离函数,默认是欧氏距离
from scipy.spatial.distance import cdist

# 1.数据加载处理

x, y = make_blobs(n_samples=100, centers=6, cluster_std=0.6, random_state=1234)

# 2.核心算法
class kMeans(object):
    def __init__(self, k_num=6, max_iter=10, centrois=[]):
        self.k_num = k_num
        self.max_iter = max_iter
        self.centrois = np.array(centrois, dtype=float)

    # 训练模型的方法k-means聚类,传入原始数据
    def fit(self, datas):
        # 假如没有指定初始质心,就随机选取一个datas中的
        if (self.centrois.shape == (0,)):
            self.centrois = datas[np.random.randint(0, len(datas), self.k_num), :]

        for i in range(self.max_iter):
            # 计算距离矩阵->得到一个100乘6的矩阵
            distance = cdist(datas, self.centrois)

            # 对距离从远到大排序
            c_index = np.argmin(distance, axis=1)

            # 对每一类数据进行均值计算,更新质心点坐标
            for i in range(self.k_num):
                if i in c_index:
                    # 选出所有类别是i的点,求平均值更新第i个质心
                    # datas[c_index==i] 布尔索引语法
                    self.centrois[i] = np.mean(datas[c_index == i], axis=0)

    def predict(self, samples):
        # 先计算距离
        distance = cdist(samples, self.centrois)
        # 选取距离最近的质心的距离
        c_index = np.argmin(distance, axis=1)
        #

        return c_index


def plotMeans(x, y, centrois, subplot, title):
    # 分配子图 121表示一行两列的子图中的第一个
    plt.subplot(subplot)
    plt.scatter(x[:, 0], x[:, 1], c='r')
    # 画出质心点
    plt.scatter(centrois[:, 0], centrois[:, 1], c=np.array(range(6)), s=100)
    plt.title(title)



# 3.测试
if __name__ == '__main__':
    kmeans = kMeans(k_num=6, max_iter=300, centrois=np.array([[2, 1], [2, 2], [2, 3], [2, 4], [2, 5], [2, 6]]))
    plt.figure(figsize=(16, 6))
    plotMeans(x, y, kmeans.centrois, 121, 'init_pic')

    # 进行聚类
    kmeans.fit(x)

    plotMeans(x, y, kmeans.centrois, 122, 'Final_pic')

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

    plt.scatter(x_new[:,0],x_new[:,1],c='g')

    plt.show()

    print(kmeans.centrois)
    print(y_pred)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值