首先给大家介绍一个很好用的学习地址:https://cloudstudio.net/columns

在上一章节中,我们重点探讨了聚类的可视化分析方法,帮助我们更好地理解数据之间的关系和结构。今天,我们将直接进入实际应用,使用聚类算法中的经典方法——k-means,对数据进行训练和预测。好的,我们直接开始。

构建模型

在进行数据清洗之前,我们首先回顾一下K-means聚类算法的核心概念。K-means聚类的主要目标是通过不断迭代优化质心,使得同一簇内的样本之间更加相似,而不同簇之间的样本差异则显著增加,从而实现有效的聚类效果。然而,这种算法也存在明显的缺点:首先,它对异常值极为敏感,异常值可能会对质心的计算产生较大影响;其次,K-means算法需要事先设定K个质心的数量,而这个预定的K值会直接影响模型的聚类效果。

尽管存在这些挑战,幸运的是,我们有一些方法可以帮助我们更好地分析和选择适合的K值。接下来,我们将开始清洗数据,为K-means聚类算法的应用做好准备。

数据准备

首先,我们需要对数据进行清理,去除那些不必要的字段以及包含大量异常值的特征。因为在K-means训练过程中,无用的特征和异常值会对模型的效果产生干扰,影响聚类的准确性和有效性。为此,我们将采用箱型图分析,这是一种直观有效的工具,可以帮助我们识别和处理异常值。

箱型图

箱型图由五个重要的数值点构成,分别是最小观察值(下边缘)、25%分位数(Q1)、中位数、75%分位数(Q3)以及最大观察值(上边缘)。这些统计指标能够有效地概括数据的分布特征,帮助我们了解数据的集中趋势和离散程度。

在分析数据时,如果存在离群点,即异常值,它们的数值会超出最大或最小观察值的范围。在箱型图中,这些离群点通常以“圆点”的形式呈现,便于我们直观识别和处理。这些异常值需要特别关注,因为它们可能会对后续的K-means聚类分析产生负面影响。而对于箱型图中其他的数值点,如分位数和中位数,目前我们可以暂时不做过多关注,重点放在识别和处理这些离群点上,以确保数据的质量和聚类分析的有效性。

数据清洗

在开始清洗数据之前,首先请确保已安装所有相关的依赖包,以便顺利进行后续操作。

pip install seaborn scikit-learn

import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
from sklearn.preprocessing import LabelEncoder df = pd.read_csv("../data/nigerian-songs.csv")
df = df[(df['artist_top_genre'] == 'afro dancehall') | (df['artist_top_genre'] == 'afropop') | (df['artist_top_genre'] == 'nigerian pop')]
df = df[(df['popularity'] > 0)]

这段代码的编写主要是基于我们在上一章节的分析结果,发现头三个流派的数据量最多。因此,我们决定直接保留这三个流派的相关数据,而不再保留其他流派的数据,以便更集中地进行后续分析和处理。

plt.figure(figsize=(20,20), dpi=200)

plt.subplot(4,3,1)
sns.boxplot(x = 'popularity', data = df) plt.subplot(4,3,2)
sns.boxplot(x = 'acousticness', data = df) plt.subplot(4,3,3)
sns.boxplot(x = 'energy', data = df) plt.subplot(4,3,4)
sns.boxplot(x = 'instrumentalness', data = df) plt.subplot(4,3,5)
sns.boxplot(x = 'liveness', data = df) plt.subplot(4,3,6)
sns.boxplot(x = 'loudness', data = df) plt.subplot(4,3,7)
sns.boxplot(x = 'speechiness', data = df) plt.subplot(4,3,8)
sns.boxplot(x = 'tempo', data = df) plt.subplot(4,3,9)
sns.boxplot(x = 'time_signature', data = df) plt.subplot(4,3,10)
sns.boxplot(x = 'danceability', data = df) plt.subplot(4,3,11)
sns.boxplot(x = 'length', data = df) plt.subplot(4,3,12)
sns.boxplot(x = 'release_date', data = df)

我们可以直接根据各列的数据绘制箱型图,这样能够有效地展示数据的分布情况和离群值。如图所示:

接下来,我们将删除那些显示异常值的箱型图,以便更好地集中于数据的主要趋势和特征。最终,我们将只保留如下所示的箱型图:

接下来,我们都知道数值特征在模型训练中起着至关重要的作用,因此有必要对这些特征进行适当的转换。此前我们已经讨论过相关的转换方法,这里就不再详细赘述。下面是实现该转换的代码:

from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
X = df.loc[:, ('artist_top_genre','popularity','danceability','acousticness','loudness','energy')]
y = df['artist_top_genre']
X['artist_top_genre'] = le.fit_transform(X['artist_top_genre'])
y = le.transform(y)

KMeans 聚类

由于数据来源于上一章节的观察与分析,尽管我们对其进行了初步的审视,但在具体的数据特征上,数据本身并不清楚其中存在三种不同的流派。因此,为了确定最佳的质心数量,我们需要借助肘部图进行深入分析,以便找到最合适的聚类设置。

肘部图

肘部法则(Elbow Method)是一种常用的技术,用于确定 K-Means 聚类中簇的数量 (K)。该方法通过分析不同 K 值下的聚类效果,帮助我们找到一个合适的簇数。其优点在于直观易懂,能够有效地指导聚类数的选择。

通常,随着 K 值的增加,总平方误差(SSE)会逐渐降低,但在某个特定的 K 值之后,误差减少的幅度会显著减小。这一转折点被称为“肘部”,它标志着增加 K 值所带来的收益逐渐减小,从而帮助我们识别出最佳的簇数。接下来,我们将绘制肘部图,以便直观地展示这一过程。

from sklearn.cluster import KMeans
wcss = [] for i in range(1, 11):
kmeans = KMeans(n_clusters = i, init = 'k-means++', random_state = 42)
kmeans.fit(X)
wcss.append(kmeans.inertia_)
plt.figure(figsize=(10,5))
sns.lineplot(x=range(1, 11), y=wcss,marker='o',color='red')
plt.title('Elbow')
plt.xlabel('Number of clusters')
plt.ylabel('WCSS')
plt.show()

接下来,我将对这段代码进行简单的解释。其主要目的是通过遍历不同的 K 值,计算并存储每个 K 对应的组内平方和(WCSS, Within-Cluster Sum of Squares),以便后续绘制肘部图,帮助选择最佳的簇数。

  • 设置一个循环,从 1 到 10(包含 1,但不包含 11),即测试 1 到 10 个簇。
  • init = 'k-means++':使用 K-means++ 初始化方法,以提高聚类结果的质量。
  • random_state = 42:设置随机种子,确保每次运行结果可重现。否则,就算是同样的数据,每次跑出来的结果也不一样。
  • 将当前模型的 inertia_ 属性(表示簇内平方和)添加到 wcss 列表中。inertia_ 是 KMeans 类的一个属性,表示所有簇内的距离平方和,越小表示聚类效果越好。

在成功绘制肘部图之后,如图所示,我们可以清晰地观察到 WCSS 随着 K 值变化的趋势。通过分析这张图,可以明显看出,当 K 值为 3 时,误差的减少幅度显著减小,形成了一个明显的转折点。这个转折点表明,选择 K 为 3 是最优的,因为在此点之后,增加簇的数量对聚类效果的改善不再显著。

训练模型

接下来,我们将应用 K-Means 聚类算法,并设置质心的数量为 3,以评估模型的准确性和聚类效果。下面是实现这一过程的代码:

from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters = 3, init = 'k-means++', random_state = 42)
kmeans.fit(X)
labels = kmeans.labels_
correct_labels = sum(y == labels)
print("Result: %d out of %d samples were correctly labeled." % (correct_labels, y.size))
print('Accuracy score: {0:0.2f}'. format(correct_labels/float(y.size)))

Result: 105 out of 286 samples were correctly labeled.

Accuracy score: 0.37

令人失望的是,模型的准确性竟然不如随机猜测。这一结果促使我们回顾之前分析的箱型图,除了识别出一些明显不正常的特征外,我们还注意到许多保留下来的特征同样存在异常值。这些异常值无疑会对 K-Means 聚类的结果产生负面影响,因此,我们决定对这些特征进行标准化处理,以提高模型的稳定性和准确性:

from sklearn.preprocessing import StandardScaler
kmeans = KMeans(n_clusters = 3, init = 'k-means++', random_state = 42)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
kmeans.fit(X_scaled)
labels = kmeans.labels_
correct_labels = sum(y == labels)
print("Result: %d out of %d samples were correctly labeled." % (correct_labels, y.size))
print('Accuracy score: {0:0.2f}'. format(correct_labels/float(y.size)))

Result: 163 out of 286 samples were correctly labeled.

Accuracy score: 0.57

在使用 K-Means 聚类时,采用 StandardScaler 进行数据标准化通常能够显著提升聚类效果。这主要是因为 StandardScaler 会将每个特征的均值调整为 0,标准差调整为 1,从而使得所有特征在同一尺度上进行比较。这种处理方式有效地消除了不同特征之间因尺度差异而导致的影响,避免了某些特征因其数值范围较大而在距离计算中占据主导地位的情况。

因此,通过标准化,我们能够更公平地评估每个特征对聚类结果的贡献,从而提升 K-Means 算法的整体性能和准确性。

总结

在本文中,我们深入探讨了K-means聚类算法及其在数据分析中的应用,特别是如何有效清洗和准备数据以提高聚类效果。通过利用箱型图,我们识别并处理了异常值,为后续的聚类分析奠定了坚实的基础。在确定适合的质心数量时,我们运用了肘部法则,成功找到了最佳的K值。

虽然初步模型的准确性并不理想,但通过数据标准化,我们显著提升了聚类效果,准确率达到了57%。这一过程不仅展示了K-means聚类的基本原理,也强调了数据预处理的重要性。清晰的数据不仅可以提高模型的可靠性,还能为数据分析提供更有意义的洞察。


我是努力的小雨,一名 Java 服务端码农,潜心研究着 AI 技术的奥秘。我热爱技术交流与分享,对开源社区充满热情。同时也是一位腾讯云创作之星、阿里云专家博主、华为云云享专家、掘金优秀作者。

我将不吝分享我在技术道路上的个人探索与经验,希望能为你的学习与成长带来一些启发与帮助。

欢迎关注努力的小雨!

从零开始学机器学习——K-Means 聚类的更多相关文章

  1. 吴裕雄 python 机器学习——K均值聚类KMeans模型

    import numpy as np import matplotlib.pyplot as plt from sklearn import cluster from sklearn.metrics ...

  2. 机器学习算法与Python实践之(五)k均值聚类(k-means)

    机器学习算法与Python实践这个系列主要是参考<机器学习实战>这本书.因为自己想学习Python,然后也想对一些机器学习算法加深下了解,所以就想通过Python来实现几个比较常用的机器学 ...

  3. 机器学习算法与Python实践之(六)二分k均值聚类

    http://blog.csdn.net/zouxy09/article/details/17590137 机器学习算法与Python实践之(六)二分k均值聚类 zouxy09@qq.com http ...

  4. 机器学习实战5:k-means聚类:二分k均值聚类+地理位置聚簇实例

    k-均值聚类是非监督学习的一种,输入必须指定聚簇中心个数k.k均值是基于相似度的聚类,为没有标签的一簇实例分为一类. 一 经典的k-均值聚类 思路: 1 随机创建k个质心(k必须指定,二维的很容易确定 ...

  5. 机器学习之路:python k均值聚类 KMeans 手写数字

    python3 学习使用api 使用了网上的数据集,我把他下载到了本地 可以到我的git中下载数据集: https://github.com/linyi0604/MachineLearning 代码: ...

  6. 机器学习之K均值聚类

      聚类的核心概念是相似度或距离,有很多相似度或距离的方法,比如欧式距离.马氏距离.相关系数.余弦定理.层次聚类和K均值聚类等 1. K均值聚类思想   K均值聚类的基本思想是,通过迭代的方法寻找K个 ...

  7. 100天搞定机器学习|day44 k均值聚类数学推导与python实现

    [如何正确使用「K均值聚类」? 1.k均值聚类模型 给定样本,每个样本都是m为特征向量,模型目标是将n个样本分到k个不停的类或簇中,每个样本到其所属类的中心的距离最小,每个样本只能属于一个类.用C表示 ...

  8. 机器学习实战---K均值聚类算法

    一:一般K均值聚类算法实现 (一)导入数据 import numpy as np import matplotlib.pyplot as plt def loadDataSet(filename): ...

  9. 从零开始学数据分析,什么程度可以找到工作?( 内附20G、5000分钟数据分析工具教程大合集 )

    从零开始学数据分析,什么程度可以找到工作?( 内附20G.5000分钟数据分析工具教程大合集 )   我现在在Coursera上面学data science 中的R programming,过去很少接 ...

  10. 从零开始学Bootstrap(3)

    首先让我们回顾一下系列内容. 从零开始学Bootstrap(1)介绍了BootStrap最简单的模板,逐条解释了每行代码的含义. 从零开始学Bootstrap(2)强调了边学边做,通过实际的例子,讲解 ...

随机推荐

  1. Python3.11二进制AI项目程序打包为苹果Mac App(DMG)-应用程序pyinstaller制作流程(AppleSilicon)

    众所周知,苹果MacOs系统虽然贵为Unix内核系统,但由于系统不支持N卡,所以如果想在本地跑AI项目,还需要对相关的AI模块进行定制化操作,本次我们演示一下如何将基于Python3.11的AI项目程 ...

  2. 【Docker学习系列】Docker学习2-docker设置阿里云镜像加速器

    在上一篇中,我们学会了在centos中安装docer.我们知道,镜像都是外网的,镜像一般都是比较大的,因为种种原因,我们知道,从外网下载比较慢的.所以,本文,凯哥就介绍怎么将docker的镜像拉取设置 ...

  3. c++ push_back()和emplace_back()区别

    c++ push_back()和emplace_back()区别 References C++中push_back和emplace_back的区别 push_back v.s. emplace_bac ...

  4. Angular 18+ 高级教程 – Library

    前言 当你需要管理超过一个项目时,你就需要知道怎么使用 Angular Library. 你可以把多个项目共享的组件放到这个 Library 了,就像 Angular Material 那样. 参考 ...

  5. 柳婼 の PAT甲级题解

      1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 102 ...

  6. Spring —— 核心概念

    IoC (Inversion of Control) 控制反转 使用对象时,由主动new产生对象转换为由外部提供对象,对象的创建控制权由程序转移至外部,这种思想成为控制反转 Spring技术对IoC思 ...

  7. linux下UsbMon-WireShark之USB协议抓取分析

    usbmon配置 使用usbmon抓包分的,是需要 内核开启CONFIG_USB_MON=m, 重新编译内核, 编译ko : make ARCH=arm64 CROSS_COMPILE=aarch64 ...

  8. 墨天轮访谈 | SelectDB 衣国垒:Apache Doris(incubating)1.0版本特性解析与未来规划

    分享嘉宾:衣国垒 Apache Doris Committer.SelectDB 联合创始人&CTO 整理:墨天轮社区 导读 大家好,我是来自Apache Doris社区的衣国垒,也是Sele ...

  9. element的图片上传预处理函数

    /** 图片格式和大小的控制 */ beforeAvatarUpload (file) { // 允许上传 jpg 和 png 格式的图片 const isJPG = file.type === &q ...

  10. ajax异步请求数据还没有返回,页面时空白的如何处理

    使用骨架屏,给用户一种正在解析数据的感觉 : element-ui的骨架屏 :https://element.eleme.cn/#/zh-CN/component/skeleton