一、机器学习十大常见算法
朴素贝叶斯它通过已知的标签数据,学习如何对新的样本进行分类。
K-Means聚类正是聚类算法中最核心、最常用的技术之一。
如果说朴素贝叶斯是在有标准答案的情况下做预测,那么K-Means就是在没有标准答案的情况下做探索。两者代表了机器学习的两大方向,本篇主要介绍这两种算法。
二、朴素贝叶斯(Naive Bayes)
2.1 什么是朴素贝叶斯
朴素贝叶斯是一种基于贝叶斯定理的简单而高效的概率分类算法。它的核心思想是:通过已知的某些特征,来计算某个事件发生的概率,并选择概率最高的类别作为预测结果。
朴素贝叶斯的“朴素”之处在于一个关键假设:所有特征之间是相互独立的。也就是说,在判断决策是否适合或正确时,每个特征对你的决策影响是互不相关的。虽然在现实中,特征之间常有联系,但这个简化的假设让计算变得非常高效。
2.2 核心原理:贝叶斯定理
要理解朴素贝叶斯,必须先了解它的基石——贝叶斯定理。贝叶斯定理描述了在已知一些条件的情况下,如何更新某个事件发生的概率。
贝叶斯公式如下:

公式看起来可能有点抽象,我们用判断一封邮件是否是垃圾邮件的例子来理解它:
A:邮件是“垃圾邮件”这个事件。
B:邮件中包含“免费”这个词这个特征。
P(A):先验概率——任意一封邮件是垃圾邮件的概率。比如根据历史数据,100封邮件里有20封是垃圾邮件,那么 P(垃圾邮件)=0.2P(垃圾邮件)=0.2。
P(B|A):条件概率(似然)——在已知邮件是垃圾邮件的情况下,其中出现“免费”这个词的概率。比如垃圾邮件中80%都包含“免费”,那么 P(免费∣垃圾邮件)=0.8P(免费∣垃圾邮件)=0.8。
P(B):证据——任意一封邮件中出现“免费”这个词的总概率。
P(A|B):后验概率——我们最终想求的:在已知邮件包含“免费”这个词的条件下,这封邮件是垃圾邮件的概率。
贝叶斯定理的精髓在于:它利用了我们已经知道的信息(垃圾邮件的普遍规律 P(A) 和垃圾邮件用词习惯 P(B∣A)),结合新观察到的证据(这封邮件里有“免费”),来修正我们对这个具体事件的判断(这封邮件是垃圾邮件的可能性 P(A∣B))。
2.3 “朴素”在哪里?
真正的贝叶斯分类器在计算 P(B∣A)时,需要考虑所有特征 B1,B2,B3… 的联合概率 P(B1,B2,B3…∣A),这非常复杂。
朴素贝叶斯做出了一个强大的简化假设:所有特征都相互条件独立。这意味着:

这个假设将复杂的联合概率计算,简化成了多个简单概率的乘法,极大地降低了计算成本。
2.4 朴素贝叶斯的三种常见变体
根据特征数据类型的不同,朴素贝叶斯主要有以下几种变体:
| 高斯朴素贝叶斯 | 连续型数据 | 假设每个特征在每个类别下服从高斯分布(正态分布) | 根据身高、体重分类性别;根据花瓣尺寸分类鸢尾花品种 |
| 多项式朴素贝叶斯 | 离散型计数数据 | 假设特征是由多项式分布生成的 | 垃圾邮件过滤、新闻主题分类、情感分析 |
| 伯努利朴素贝叶斯 | 二值型数据(0/1) | 假设特征是二值的,关注“是否出现”而非“出现多少次” | 文本中关键词是否出现的二值特征场景 |
2.5 多项式朴素贝叶斯实战:鸢尾花分类
下面通过鸢尾花数据集来展示如何使用 MultinomialNB(多项式朴素贝叶斯)进行分类:
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import MultinomialNB
from sklearn import metrics
# 读取数据
data = pd.read_csv("iris.csv")
x = data.iloc[:, :-1] # 特征:花萼长度、花萼宽度、花瓣长度、花瓣宽度
y = data.iloc[:, -1] # 目标:鸢尾花品种
# 划分训练集和测试集(80%训练,20%测试)
train_x, test_x, train_y, test_y = train_test_split(
x, y, test_size=0.2, random_state=0
)
# 创建多项式朴素贝叶斯模型,alpha=1 为拉普拉斯平滑参数
model = MultinomialNB(alpha=1)
model.fit(train_x, train_y)
# 训练集预测与评估
train_pred = model.predict(train_x)
print(metrics.classification_report(train_y, train_pred))
# 测试集预测与评估
test_pred = model.predict(test_x)
print(metrics.classification_report(test_y, test_pred))
数据读取:使用 pandas.read_csv 加载鸢尾花数据集。鸢尾花数据集包含150个样本,每个样本有4个连续型特征(花萼长度、花萼宽度、花瓣长度、花瓣宽度)和1个标签(Setosa、Versicolour、Virginica 三个品种)。
数据划分:train_test_split 将数据随机划分为训练集(80%)和测试集(20%),random_state=0 保证每次运行划分结果一致。
模型构建:MultinomialNB(alpha=1) 创建多项式朴素贝叶斯分类器。参数 alpha 是拉普拉斯平滑系数,用于解决某些特征值在训练集中未出现导致概率为零的问题。alpha=1 是常用默认值,平滑程度适中。
训练:model.fit(train_x, train_y) 让模型学习训练数据中特征与标签的关系。对于多项式朴素贝叶斯,它会统计每个类别下各特征的计数,并计算相应的条件概率。
预测:model.predict() 对训练集和测试集分别进行预测,返回预测类别标签。
评估:classification_report 输出精确率(Precision)、召回率(Recall)、F1-score 等详细指标,帮助我们全面了解模型的分类性能。
三、K-Means聚类
3.1 什么是聚类
在机器学习中,聚类要做的是完全靠特征自发地分出类别。它是一种无监督学习方法,目标是在没有预先标注答案(即没有“标签”)的数据中,发现其内在的结构和分组。
聚类的核心思想是:将数据集中的样本划分成若干个互不相交的子集(称为簇),使得同一个簇内的样本彼此相似,而不同簇中的样本彼此不相似。这里的“相似”通常通过数学上的距离来衡量(如欧氏距离),距离越近,相似度越高。
3.2 K-Means算法原理
K-Means是最著名、最常用的聚类算法之一,其思想直观,实现相对简单。
我们可以把K-Means的过程想象成竞选代表并重新划区:
第一步:确定簇的数量 K
首先,你需要决定想把数据分成几类。这个 K 值需要预先指定,这是 K-Means 的一个关键参数。
第二步:初始化代表(质心)
随机在数据空间中选取 K 个点,作为每个簇的初始“中心点”,我们称之为质心。
第三步:分配居民(样本)
计算数据集中每一个样本点到这 K 个质心的距离。遵循“近者归其类”的原则,将每个样本分配给距离它最近的那个质心所在的簇。
第四步:改选新代表(更新质心)
现在,每个簇里都有了一批样本。重新计算每个簇的质心,新的质心就是该簇内所有样本点的平均值(均值点)。
第五步:重复与收敛
重复第三步和第四步,直到质心的位置不再发生显著变化(即算法收敛)。
3.3 K-Means的关键参数
在 sklearn 的 KMeans 中,以下参数最为关键:
| n_clusters | 簇的数量 K | 最重要的参数,需要预先指定 |
| init | 初始化方法 | 可选 'k-means++'(默认)、'random' |
| n_init | 初始化次数 | 算法会运行多次并选择最优结果,默认10次 |
| max_iter | 最大迭代次数 | 默认300次 |
| random_state | 随机种子 | 设置后可保证结果可复现 |
3.4 如何选择最佳K值?
选择最佳的 K 值是 K-Means 中最关键的问题之一。常用的方法有:
-
肘部法则(Elbow Method):计算不同 K 值下的簇内误差平方和(SSE),随着 K 增大,SSE 会逐渐减小。当 SSE 的下降速度突然变缓时,对应的 K 值就是“肘部”点,通常被认为是最佳 K 值。
-
轮廓系数(Silhouette Coefficient):衡量样本与其所在簇的相似度与其他簇的差异度,取值范围在 [-1, 1] 之间,值越大表示聚类效果越好。
3.5 K-Means聚类实战:酒品种自动分群
下面通过一个实际数据集来演示如何利用轮廓系数自动选择最佳K值,并进行聚类:
import pandas as pd
import numpy as np
from sklearn.cluster import KMeans
from sklearn import metrics
from sklearn.model_selection import train_test_split
# 1. 读取数据(假设数据文件为 data.txt,用空格分隔,包含'name'列和若干特征列)
data = pd.read_table("data.txt", sep=" ", encoding="utf-8", engine="python")
# 去掉'name'列(非数值特征),剩余列为特征数据
x = data.drop("name", axis=1)
# 2. 划分训练集和测试集(用于验证聚类模型的稳定性)
train_x, test_x = train_test_split(x, test_size=0.2, random_state=0)
# 3. 通过轮廓系数选择最佳K值(K范围2~9)
scores = []
for i in range(2, 10):
model = KMeans(n_clusters=i, random_state=0)
# 计算训练集的轮廓系数,metric='euclidean'表示使用欧氏距离
score = metrics.silhouette_score(train_x, model.fit_predict(train_x), metric='euclidean')
scores.append(score)
# 4. 选出轮廓系数最高的K值
best_k = [2, 3, 4, 5, 6, 7, 8, 9][np.argmax(scores)]
print(f"最佳K值为:{best_k}")
# 5. 使用最佳K值重新训练模型
model = KMeans(n_clusters=best_k, random_state=0)
model.fit(train_x)
# 6. 对训练集和测试集进行预测
train_pred = model.predict(train_x)
test_pred = model.predict(test_x)
# 7. 分别计算训练集和测试集的轮廓系数,评估聚类效果
train_score = metrics.silhouette_score(train_x, train_pred)
test_score = metrics.silhouette_score(test_x, test_pred)
print(f"训练集轮廓系数:{train_score}")
print(f"测试集轮廓系数:{test_score}")
数据加载:pd.read_table 读取以空格分隔的文本文件。data.txt 包含一列 name(可能是样本ID或名称)和若干数值特征。我们使用 drop("name", axis=1) 移除非数值列,只保留特征用于聚类。
数据划分:train_test_split 将特征数据分为训练集和测试集。虽然聚类是无监督学习,但划分测试集可以评估模型在未见样本上的稳定性——如果训练集和测试集的轮廓系数相近,说明聚类结构是稳定的。
轮廓系数(Silhouette Score):对于每个样本,轮廓系数 s(i) 定义为:

其中 a(i)a(i) 是样本与同簇其他点的平均距离(簇内凝聚度),b(i)b(i) 是样本与最近其他簇的平均距离(簇间分离度)。整体轮廓系数取所有样本的平均值,范围 [-1, 1],值越大表示聚类效果越好。
循环选择K值:在 K=2 到 9 的范围内,对每个K值训练 KMeans 模型,计算训练集的轮廓系数,保存在 scores 列表中。
选取最佳K:使用 np.argmax(scores) 找到最大轮廓系数对应的索引,再从预定义的K值列表 [2,3,4,5,6,7,8,9] 中取出对应的K值。
最终模型训练与评估:用最佳K值重新训练 KMeans 模型,对训练集和测试集分别预测聚类标签,并计算各自的轮廓系数。两个分数相近且都较高,说明聚类结果稳定且有效。
3.6 K-Means的优缺点
| 算法简单,易于理解和实现 | 需要预先指定 K 值 |
| 计算效率高,适合大规模数据 | 对初始质心的选择敏感 |
| 收敛速度快 | 对异常值敏感 |
| 结果易于解释 | 只适用于球形簇,对复杂形状的簇效果不佳 |
网硕互联帮助中心
![[人工智能]Scikit-learn:Python中的实用机器学习库-网硕互联帮助中心](https://www.wsisp.com/helps/wp-content/uploads/2026/08/20260805224844-6a73bdcc07e92-220x150.png)



评论前必须登录!
注册