0013机器学习聚类算法(无监督算法)

0013机器学习聚类算法(无监督算法)

一、聚类算法

  • 聚类(Clustering)是按照某个特定标准(如距离)把一个数据集分割成不同的类或簇,使得同一个簇内的数据对象的相似性尽可能大,同时不在同一个簇中的数 据对象的差异性也尽可能地大。也即聚类后同一类的数据尽可能聚集到一起,不同类数据尽量分离。
  • 聚类算法是一种无监督算法,无监督学习(Unsupervised Learning)是指在 无标注训练数据(即数据仅包含输入特征X,无对应的输出标签 y)的情况下,通过算法自动挖掘数据内部的结构、分布、关联或异常模式的学习方法。

二、K均值聚类(K-means)

  • 虽然其思想能够追溯到1957年的Hugo Steinhaus,术语"k-均值"于1967年才被James

    MacQueen首次使用。标准算法则是在1957年被Stuart Lloyd作为一种脉冲码调制的技术所提出,但直到1982年才被贝尔实验室公开出版。在1965年,E.W.Forgy发表了本质上相同的方法,所以这一算法有时被称为Lloyd-Forgy方法。更高效的版本则被Hartigan and Wong提出 (1975/1979)

  • K-Means算法是无监督的聚类算法,算法简单,聚类效果好,即使是在巨大的数据集上也非常容易部署实施。正因为如此,它在很多领域都得到的成功的应用,如市场划分、机器视觉、地质统计学、天文学和农业等。K-Means算法有大量的变体,包括初始化优化K-Means++以及大数据应用背景下的k-means||和Mini Batch K-Mean

  • 直观理解

  • Kmeans聚类的可视化演示:https://www.naftaliharris.com/blog/visualizing-k-means-clustering/

1.1 编程实现K-means

python 复制代码
import numpy as np
import sys
if __name__ == '__main__':
    X = np.array([[1.0, 2.0], [2.0, 2.0], [6.0, 8.0], [7.0, 8.0]])
    C = np.array([[1.0, 2.0], [2.0, 2.0]])
    iters = 5 ###迭代次数
    while iters > 0:
        ###计算每个样本到每个聚类中心的距离
        A = []
        for c in C:  ##聚类中心
            a = np.sqrt(np.sum((X - c) ** 2, axis=1))
            A.append(a)
        A = np.array(A)
        print(A)
        ###将样本分配的所属的聚类中心(获取最小值的下标)
        minidx = np.argmin(A, axis=0)
        print(minidx)

        ###获取每个簇的样本
        for i in range(len(C)):
            a = X[minidx == i]  ###每个簇的样本
            print('a\n', a)
            C[i] = np.mean(a, axis=0)  ###更新我们的聚类中心
            # print(C[i])
        print("C\n", C)
        # todo: 就是C不再更新时要停止,停止
        print('---------------------------------')
        iters -= 1
    # todo:封装成类【伪代码】,加上就是C不再更新停止

2.2 调库实现K-means

python 复制代码
import numpy as np #
from sklearn.cluster import KMeans
import warnings
warnings.filterwarnings("ignore")

def demo1():
    X = np.array([[1, 2], [2, 2], [6, 8], [7, 8]])
    kmeans = KMeans(n_clusters=2, n_init='auto')
    kmeans.fit(X)
    print(kmeans.cluster_centers_)  ##簇中心
    print(kmeans.labels_)  ###簇的标签

def demo2():
    import numpy as np
    import matplotlib.pyplot as plt
    from sklearn.cluster import KMeans
    from sklearn.preprocessing import StandardScaler
    from sklearn.datasets import make_blobs  # 生成数据函数
    from sklearn import metrics

    #解决中文乱码
    plt.rcParams["font.sans-serif"] = ["SimHei"]
    plt.rcParams["axes.unicode_minus"] = False

    n_samples = 1500
    X, y = make_blobs(n_samples=n_samples, centers=4, random_state=170)
    X = StandardScaler().fit_transform(X)  # 标准化

    kmeans = KMeans(n_clusters=4, n_init='auto', random_state=170)
    kmeans.fit(X)

    # 反映同类样本类内平均距离尽可能小,类间距离尽可能大的指标。取值范围在[-1,1]之间,越大越好
    labels = kmeans.labels_
    pgjg1 = metrics.silhouette_score(X, labels, metric='euclidean')  # 轮廓系数,取值范围从-1到1
    print('聚类结果的轮廓系数=', pgjg1)

    plt.figure(figsize=(12, 6))
    plt.subplot(121)
    plt.scatter(X[:, 0], X[:, 1], c='r')
    plt.title("聚类前数据图")
    plt.subplot(122)
    plt.scatter(X[:, 0], X[:, 1], c=kmeans.labels_)
    plt.title("聚类后数据图")
    plt.show()

if __name__ == '__main__':
    demo1()
    # demo2()

3.3 鸢尾花数据K-means聚类

python 复制代码
import numpy as np
import pandas as pd
from sklearn.cluster import KMeans
import warnings
warnings.filterwarnings("ignore")

datas = pd.read_csv('data/iris.data', sep=",", header=None)
# print(datas.head())
X = datas.iloc[:, :-1]

clf = KMeans(n_clusters=3,n_init='auto')
clf.fit(X)
print(clf.cluster_centers_)
print(clf.labels_)
pre = clf.predict(X.iloc[[-1],:])
print(pre)

运行结果:

4.4 K-means缺点

  • 缺点一:聚类中心的个数K需要事先给定,但在实际中K值的选定是非常困难的, 很多时候我们并不知道给定的数据集应该聚成多少个类别才最合适
  • 缺点二:k-means算法需要随机地确定初始聚类中心,不同的初始聚类中心可能导致完全不同的聚类结果,有可能导致算法收敛很慢甚至出现聚类出错的情况
  • 针对第一个缺点:很难在k-means算法以及其改进算法中解决,一般来说,我们会根据对数据的先验经验选择一个合适的k值,如果没有什么先验知识,则可以通过 "肘方法"选择一个合适的k值
  • 针对第二个缺点:可以通过k-means++算法来解决

三、肘方法


代码实现:

python 复制代码
import numpy as np
import pandas as pd
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
import matplotlib as mpl
from sklearn.metrics import silhouette_score  ###轮廓系数

import warnings
warnings.filterwarnings("ignore")
datas = pd.read_csv('data/iris.data', sep=",", header=None)
# print(datas.head())
X = datas.iloc[:, :-1]

sses = []
S = []
for K in range(2, 10):
    kmeans = KMeans(n_clusters=K, init="k-means++", n_init=10)
    kmeans.fit(X)
    inertia = kmeans.inertia_
    sses.append(inertia)
    # labels = kmeans.labels_
    # s = silhouette_score(X, labels)
    # print(s*100)
    # S.append(s)
plt.figure(num=1)
plt.plot(range(2, 10), sses)
# plt.figure(num=2)
# plt.plot(range(2, 10), S)
plt.show()

运行结果:

四、K-means++


五、K-means||


六、Mini Batch K-Means*

七、K-Mediods聚类

  • K-means算法在迭代的过程中使用所有点的均值作为新的质点(中心点),如 果簇中存在异常点,将导致均值偏差比较严重。
  • 解决方案:使用中位数可能比使用均值的方法更好,使用中位数的聚类方式 叫做K-Mediods聚类(K中值聚类)。

八、评估方法

1、肘方法

2、轮廓系数法

九、DBSCAN聚类算法







DBSCAN聚类的可视化演示:

https://www.naftaliharris.com/blog/visualizing-dbscan-clustering/

相关推荐
cici158741 小时前
基于反向传播算法实现手写数字识别的MATLAB实现
开发语言·算法·matlab
小鱼小鱼.oO2 小时前
C++ 算法基础知识
c++·算法·哈希算法
Maxwell_li12 小时前
pandas数据合并
机器学习·数据分析·numpy·pandas·matplotlib
yong99902 小时前
LSD直线提取算法 MATLAB
开发语言·算法·matlab
MobotStone2 小时前
一文看懂AI智能体架构:工程师依赖的8种LLM,到底怎么分工?
后端·算法·llm
lengxuenong2 小时前
潍坊一中第四届编程挑战赛(初赛)题解
算法
松涛和鸣3 小时前
25、数据结构:树与二叉树的概念、特性及递归实现
linux·开发语言·网络·数据结构·算法
Han.miracle3 小时前
数据结构--初始数据结构
算法·集合·大o表示法
List<String> error_P3 小时前
C语言联合体:内存共享的妙用
算法·联合体