机器学习之K均值算法

机器学习的步骤

数据,模型选择,训练,测试,预测

 

安装机器学习库sklearn

pip list 查看版本

python -m pip install --upgrade pip

pip install -U scikit-learn

pip uninstall sklearn
pip uninstall numpy
pip uninstall scipy

pip install scipy
pip install numpy
pip install sklearn

参考网址: https://scikit-learn.org/stable/install.html 

 

导入sklearn的数据集

from sklearn.datasets import load_iris

iris = load_iris()
iris.keys()

X = iris.data # 获得其特征向量
y = iris.target # 获得样本标签

iris.feature_names # 特征名称

 

K均值算法

K-means是一个反复迭代的过程,算法分为四个步骤:

  (x,k,y)

1) 选取数据空间中的K个对象作为初始中心,每个对象代表一个聚类中心;

  def initcenter(x, k): kc

2) 对于样本中的数据对象,根据它们与这些聚类中心的欧氏距离,按距离最近的准则将它们分到距离它们最近的聚类中心(最相似)所对应的类;

  def nearest(kc, x[i]): j

  def xclassify(x, y, kc):y[i]=j

3) 更新聚类中心:将每个类别中所有对象所对应的均值作为该类别的聚类中心,计算目标函数的值;

  def kcmean(x, y, kc, k):

4) 判断聚类中心和目标函数的值是否发生改变,若不变,则输出结果,若改变,则返回2)。

  while flag:

      y = xclassify(x, y, kc)

      kc, flag = kcmean(x, y, kc, k)

 

参考官方文档: 

http://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html#sklearn.cluster.KMeans

 练习

扑克牌手动演练k均值聚类过程:>30张牌,3类

  聚类过程如下(这里不演示了,直接进入(2))

初始化

已知数据集合扑克牌(30张牌),及事先指定聚类的总类数(3类),在30张牌中随机选取3个对象作为初始的聚类中心。

设定迭代终止条件

通常设置最大循环次数或者聚类中心的变化误差。

更新样本对象所属类

根据距离准则将数据对象分配到距离最接近的类。

更新类的中心位置

将每一类的平均向量作为下次迭代的聚类中心。

重复步骤3~4,满足步骤2中的迭代终止条件时,停止

 自主编写K-means算法 ,以鸢尾花花瓣长度数据做聚类,并用散点图显示。(加分题)

  

"""
    @auther Rakers
    @date 2020.04.14
"""
import numpy as  np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.cluster import KMeans

plt.rcParams['font.family'] = ['sans-serif']
plt.rcParams['font.sans-serif'] = ['SimHei']


# 手动写KMeans聚类算法
def RakersKMeans(data, n_clusters=3):
    n = len(data)
    k = n_clusters
    dist = np.zeros([n, k + 1])
    # 设置中心
    center = data[:k, :]
    center_new = np.zeros([k, data.shape[1]])
    number = 0
    while True:
        for i in range(n):
            for j in range(k):
                dist[i, j] = np.sqrt(sum((data[i, :] - center[j, :]) ** 2))
            dist[i, k] =np.argmin(dist[i, :k])  # 归类
        for i in range(k):
            index = dist[:, k] == i
            center_new[i, :] = np.mean(data[index, :])

        if np.all(center == center_new):
            break
        else:
            center = center_new
        number += 1
    # print('聚类迭代次数', number)
    # 调整数字
    i = 0
    for dd in dist[:, k]:
        dist[i, k] = k-1-dd
        i+=1
    return dist[:, k].astype(np.int32)


if __name__ == "__main__":
    # 读取数据
    print('获取数据')
    iris = load_iris()
    data = iris['data']
    target = iris['target']
    print('获取数据完成')
    print('真实类\n', list(target))
    print('真实聚类图')
    plt.title('真实聚类图')
    plt.scatter(data[:, 0], data[:, 1], c=target)
    plt.xlabel(iris['target_names'][0])
    plt.ylabel(iris['target_names'][1])
    plt.savefig("../images/真实聚类图.png")


    print('自主编写K-means算法 ,以鸢尾花花瓣长度数据做聚类')
    pre_y = RakersKMeans(data[:, 0].reshape(-1, 1), n_clusters=3)
    print('自主编写K-means算法测试类\n', list(pre_y))
    plt.title('自主编写K-means算法 ,以鸢尾花花瓣长度数据做聚类')
    plt.scatter(data[:, 0], data[:, 1], c=pre_y)
    plt.xlabel(iris['target_names'][0])
    plt.ylabel(iris['target_names'][1])
    plt.savefig("../images/自主编写K-means算法 ,以鸢尾花花瓣长度数据做聚类.png")


    print('用sklearn.cluster.KMeans,鸢尾花花瓣长度数据做聚类')
    model = KMeans(n_clusters=3)
    model.fit(data[:, 0].reshape(-1, 1))
    pre_y = model.predict(data[:, 0].reshape(-1, 1))
    print('KMeans算法测试类\n', list(pre_y))
    plt.title('用sklearn.cluster.KMeans,鸢尾花花瓣长度数据做聚类')
    plt.scatter(data[:, 0], data[:, 1], c=pre_y)
    plt.xlabel(iris['target_names'][0])
    plt.ylabel(iris['target_names'][1])
    plt.savefig("../images/用sklearn.cluster.KMeans,鸢尾花花瓣长度数据做聚类.png")

    print('用sklearn.cluster.KMeans,鸢尾花完整数据做聚类')
    model = KMeans(n_clusters=3)
    model.fit(data)
    pre_y = model.predict(data)
    print('KMeans算法测试类\n', list(pre_y))
    plt.title('用sklearn.cluster.KMeans,鸢尾花完整数据做聚类')
    plt.scatter(data[:, 0], data[:, 1], c=pre_y)
    plt.xlabel(iris['target_names'][0])
    plt.ylabel(iris['target_names'][1])
    plt.savefig("../images/用sklearn.cluster.KMeans,鸢尾花完整数据做聚类.png")

真实的聚类效果图

 

 

自己编写的K-means算法

 

用sklearn.cluster.KMeans,鸢尾花花瓣长度数据做聚类,并用散点图显示.

  代码同上,这里贴上运行结果

鸢尾花完整数据做聚类并用散点图显示.

 

  可见当所有的特征都用上时聚类效果与真实的聚类效果最为接近。

 

想想k均值算法中以用来做什么?

  k均值算法是聚类算法,当然最适合用于分类了,像分类图片、文本等,能通过他们的特征,然后把相似的归类到一块,就有类别区分了。

posted @ 2020-04-14 00:52  诚哥博客  阅读(622)  评论(0编辑  收藏  举报