楼层: 首页/ 软件技术/ Python 机器学习与深度学习/ 朴素贝叶斯与 KNN
8

朴素贝叶斯与 KNN

Naive Bayes & K-Nearest Neighbors

两个"老古董"但依然在某些场景无敌:朴素贝叶斯做文本分类快到飞起;KNN 是最直观的"看邻居是谁"。

朴素贝叶斯

论贝叶斯定理 + 条件独立假设

朴素两个字是关键:假设所有特征在给定类别时条件独立(实际不成立,但效果往往不错)。这样 P(特征 | 类别) 可以拆成每个特征的乘积,计算量从指数级降到线性。拉普拉斯平滑:避免某个词没在某类出现过导致概率为 0。

P(类别 | 特征) = P(特征 | 类别) · P(类别) / P(特征)
from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.naive_bayes import MultinomialNB from sklearn.pipeline import Pipeline from sklearn.model_selection import cross_val_score # 垃圾邮件分类:TF-IDF + 多项式朴素贝叶斯 texts = ["免费 中奖 点击 领奖", "会议 下午 项目 进度", ...] labels = [1, 0, ...] # 1=垃圾, 0=正常 clf = Pipeline([ ("tfidf", TfidfVectorizer()), ("nb", MultinomialNB(alpha=0.1)) ]) scores = cross_val_score(clf, texts, labels, cv=5, scoring="f1") print(f"F1: {scores.mean():.3f} ± {scores.std():.3f}") # F1: 0.972 ± 0.008

KNN:惰性学习

论看你邻居是谁

KNN 不训练——训练阶段啥也不干,所有数据存下来。预测时找离测试样本最近的 K 个邻居,投票决定类别(分类)或平均它们的 y(回归)。距离度量:欧氏距离、曼哈顿距离、余弦相似度。K 值选择:K 太小容易过拟合(被噪声带跑),K 太大欠拟合(把邻居都包进来)。一般交叉验证选 K。KD 树 / 球树:加速最近邻搜索,不用和所有样本算距离。

from sklearn.neighbors import KNeighborsClassifier from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler iris = load_iris() X, y = iris.data, iris.target X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) scaler = StandardScaler() X_train_s = scaler.fit_transform(X_train) X_test_s = scaler.transform(X_test) # 不同 K 值对比 for k in [1, 3, 5, 11, 21]: knn = KNeighborsClassifier(n_neighbors=k, weights="distance") knn.fit(X_train_s, y_train) print(f"K={k:2d}: 准确率 {knn.score(X_test_s, y_test):.3f}") # K= 1: 准确率 0.933 # K= 3: 准确率 1.000 # K= 5: 准确率 1.000 # K=11: 准确率 1.000 # K=21: 准确率 1.000

三种朴素贝叶斯模型对比

模型假设什么时候用
GaussianNB特征服从正态分布连续数值特征(如身高、体重)。
MultinomialNB特征是计数/频率文本分类(TF-IDF、词袋)。
BernoulliNB特征是 0/1 出现与否短文本、二值特征。

TF-IDF 原理

论为什么 TF-IDF 比词频好

TF(词频):这个词在文档里出现多少次。但"的、是、在"出现频率最高,没区分度。IDF(逆文档频率):词越少见,权重越大(log(N / df))。TF-IDF = TF × IDF,让"罕见但有信息量的词"权重高。"机器学习"在 1000 篇文档里出现 5 篇,IDF 很高;"的"在所有文档出现,IDF≈0。

本章面试题

面试 · NB / KNN

Q1. 朴素贝叶斯为什么"朴素"?

查看答案

假设特征在给定类别下条件独立,现实不成立但好用。计算上把联合概率拆成边缘概率乘积。

Q2. 拉普拉斯平滑干什么?

查看答案

某个词在某类没出现过时 P(词|类)=0,会让整个乘积变 0。拉普拉斯平滑给分子加 1、分母加词汇数,避免概率为 0。

Q3. KNN 为什么必须标准化?

查看答案

KNN 用距离,量纲大的特征会主导距离。不标准化等于让"收入(万元)"比"年龄(岁)"权重高 1000 倍。

Q4. KNN 缺点?

查看答案

预测慢(每个测试样本要和所有训练样本算距离)、内存大、高维数据效果差(维度灾难)。KD 树能加速但不解决高维问题。