机器学习(二):k-means算法(基础篇)

本文围绕K-means算法展开,介绍其作为迭代求解的聚类分析算法的实现原理,包括计算距离的方法、损失函数SSE及算法步骤。还通过Iris数据集进行实践,涵盖数据集分析、算法聚类实现,最后探讨了K-means参数值优化,采用肘部图选k值,但存在一定问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

机器学习(二):k-means算法(基础篇)

在这里插入图片描述
k均值聚类算法(k-means clustering algorithm)是一种迭代求解的聚类分析算法,其步骤是随机选取K个对象作为初始的聚类中心,然后计算每个对象与各个种子聚类中心之间的距离,把每个对象分配给距离它最近的聚类中心。聚类中心以及分配给它们的对象就代表一个聚类。每分配一个样本,聚类的聚类中心会根据聚类中现有的对象被重新计算。这个过程将不断重复直到满足某个终止条件。终止条件可以是没有(或最小数目)对象被重新分配给不同的聚类,没有(或最小数目)聚类中心再发生变化,误差平方和局部最小。

K-means算法的实现原理

计算距离的方法

每种距离的计算方式都有自己的限制,再具体使用中需要结合样本的特点和场景不同合理选择描述样本之间相似性的算法,在这里我们说一下常见的几种算法。
在这里插入图片描述

  • 欧式距离
    上面公式是一个通用公式,当p=2时即欧式距离,欧氏距离是我们最常用的距离计算方式,也成为几何距离,表示两个点的距离差平方和,简单直观
  • 曼哈顿距离
    当p=1时表示这个距离,计算的是两个点之间的实地走的距离,欧式距离时两点之间的空间直线距离,不考虑其它影响
  • 切比雪夫距离
    当p趋于无穷大时,公式如下:
    在这里插入图片描述
  • 向量內积
    向量的內积在很多场合都在使用,向量內积是在向量空间里面,公式如下:
    在这里插入图片描述
    內积的结果是一个标量,大小没有限制,上下没有界限因此不好表示两个向量的相关性,于是有人提出来使用余弦来表示相似性,它有大小限制容易表示相似性。
    在这里插入图片描述

损失函数(目标函数)SSE

在这里插入图片描述
误差平方和(SSE):表示样本中的每个样本点到质心的距离的平方和,最优解为:聚类结果应使 SSE 达到最小值。用通俗易懂的话讲:就是每个样本中有一个质心,当样本中的点到质心的距离平方和最小的时候,该质心为我们所求的质心。

算法实现步骤

  1. List item选择合适 k 值,从数据集可以得出 k=3
  2. 随机生成 k 个质点作为起始质点
  3. 将数据集中的每一个点分配到每一个簇,即每一个点找到距离近的质心作为所对应的簇
  4. 对每一个簇,计算簇中所有点的均值将其作为新的质心
  5. 重复 cd 两个过程直到分配的所有点不再改变

K-means算法的实践

基本任务

  1. 理解 k-means 算法的思想。
  2. 使用 Python 实现 k-means 算法。
  3. 使用 UCI 上面的 Iris 数据集进行算法测试。
  4. 对参数 k 进行调整,记录结果。

扩展任务

  1. 现二分 K-means 代码并进行测试(会在下一节中提到)

数据集

第一步:对数据集进行分析:

1) 数据集介绍:
Iris.data 数据集主要有如下:

sl 花萼长度
sw 花萼宽度
pl 花瓣长度
pw 花瓣宽度
variety 花的品种

2)数据特征相关分析:
采用Preson相关系数对四个特征值进行两两之间的相关性分析
3)数据特征画图:
使用python对数据之间两两关系图画出来

代码如下:

# -*- coding:utf-8 -*-
import math
import warnings
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.lines as mlines
import matplotlib.patches as mpatchs

warnings.filterwarnings('ignore')   #忽略警告
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

def loadDataSet(filename):
    """
    函数说明:从文件中下载数据,并将分离除连续型变量和标签变量
    :parameter:
            data - Iris数据集
            attributes - 鸢尾花的属性
            type - 鸢尾花的类别
            sl-花萼长度 , sw-花萼宽度, pl-花瓣长度, pw-花瓣宽度
    :return:
    """
    iris_data = pd.read_csv(filename)   #打开文件
    iris_data = pd.DataFrame(data=np.array(iris_data), columns=['sl', 'sw', 'pl', 'pw', 'type'], index=range(149))   #给数据集添加列名,方便后面的操作
    attributes = iris_data[['sl', 'sw', 'pl', 'pw']]   #分离出花的属性
    iris_data['type'] = iris_data['type'].apply(lambda x: x.split('-')[1])  # 最后类别一列,感觉前面的'Iris-'有点多余即把class这一列的数据按'-'进行切分取切分后的第二个数据
    labels = iris_data['type']            #分理出花的类别
    return attributes, labels

def showdatas(attributes, datinglabels):
    """
    函数说明:画出花的属性两两之间的关系图
    :parameter:
            attributes - 花的属性
            datinglabels - 花的类别
    :return:none
    """
    fig, axs = plt.subplots(nrows=3, ncols=2, figsize=(20, 8))   #定义一个32列的画布
    LabelsColors = []    #建立一个颜色标签列表
    for i in datinglabels:   #遍历花的类型
        if i == 'setosa':    #setosa类型的花画成黑色的点
            LabelsColors.append('black')
        if i == 'versicolor':   #versicolor类型的花画成橙色的点
            LabelsColors.append('orange')
        if i == 'virginica':    #virginica类型的花画成红色的点
            LabelsColors.append('red')

    #在画板第一行第一列的位置绘制花萼长度和花萼宽度之间的关系
    axs[0][0].scatter(x=attributes['sl'], y=attributes['sw'], color=LabelsColors, s=15, alpha=.5) #x轴为花萼长度,y轴为花萼宽度, 点大小为15, 透明度为0.5
    axs0_title_text = axs[0][0].set_title(u'花萼长度和花萼宽度')     #设置title
    axs0_xlabel_text = axs[0][0].set_xlabel(u'花萼长度')            #设置x轴的标签
    axs0_ylabel_text = axs[0][0].set_ylabel(u'花萼宽度')            #设置y轴的标签
    plt.setp(axs0_title_text, size=9, weight='bold', color='red')
    plt.setp(axs0_xlabel_text, size=7, weight='bold', color='black')
    plt.setp(axs0_ylabel_text, size=7, weight='bold', color='black')

    #在画板第一行第二列的位置绘制花萼长度和花瓣长度之间的关系
    axs[0][1].scatter(x=attributes['sl'], y=attributes
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值