# 第一个代码:KNN 鸢尾花分类
使用 sklearn 库
# 基础库   | |
import matplotlib.pyplot as plt  | |
import matplotlib   | |
matplotlib.rcParams['font.sans-serif'] = ['SimHei']  | |
matplotlib.rcParams['axes.unicode_minus'] = False  | |
# sklearn 模块   | |
from sklearn import datasets  | |
from sklearn.model_selection import train_test_split  | |
from sklearn.preprocessing import StandardScaler  | |
from sklearn.neighbors import KNeighborsClassifier  | |
from sklearn.metrics import accuracy_score, confusion_matrix  | |
# 加载内置数据集(鸢尾花)   | |
iris = datasets.load_iris()  | |
X = iris.data # 特征 (150 个样本 x 4 个特征)  | |
y = iris.target # 标签 (0,1,2 对应三种花)  | |
# 查看数据   | |
print("特征名:", iris.feature_names)  | |
print("标签名:", iris.target_names)  | |
# 划分训练集 / 测试集 (70% 训练,30% 测试)   | |
X_train, X_test, y_train, y_test = train_test_split(  | |
X, y, test_size=0.3, random_state=42  | |
)   | |
# 特征标准化(重要!)   | |
scaler = StandardScaler()  | |
X_train = scaler.fit_transform(X_train)  | |
X_test = scaler.transform(X_test) # 注意:使用相同的 scaler 转换  | |
# 初始化 KNN 分类器(k=3)   | |
model = KNeighborsClassifier(n_neighbors=3)  | |
# 训练模型   | |
model.fit(X_train, y_train)  | |
# 预测测试集   | |
y_pred = model.predict(X_test)  | |
# 计算准确率   | |
accuracy = accuracy_score(y_test, y_pred)  | |
print(f"模型准确率: {accuracy:.2%}")  | |
# 混淆矩阵(可视化错误)   | |
cm = confusion_matrix(y_test, y_pred)  | |
print("混淆矩阵:\n", cm)  | |
# 选择两个特征进行二维可视化(可选)   | |
plt.scatter(X_test[:, 0], X_test[:, 1], c=y_pred, cmap='viridis', s=50)  | |
plt.xlabel(iris.feature_names[0])  | |
plt.ylabel(iris.feature_names[1])  | |
plt.title("鸢尾花分类结果 (KNN)")  | |
plt.colorbar(ticks=[0,1,2], label='花种类')  | |
plt.show()  | 
这个代码是 ds 写的。
# 简要流程
# 1. 数据集引入与划分
- 需要导入特征与标签。以本代码为例,特征有四个维度,标签有三类:
 
特征名: ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']  | |
标签名: ['setosa' 'versicolor' 'virginica']  | 
- 此外,还需要进行训练集与测试集的划分。我们使用 
train_test_split函数random_state:机器学习中控制随机性的关键参数。核心作用:保证结果可复现性- 就相当于一个种子,你固定了这个种子,那它后面划分训练集与测试集就只会以这种方式划分。
 
 
# 2. 特征标准化
scaler = StandardScaler() # 创建标准化器  | |
X_train = scaler.fit_transform(X_train) # 训练并转换训练集  | |
X_test = scaler.transform(X_test) # 转换测试集(使用训练集的参数)  | 
- 中心化处理(Centering):
- 将每个特征的均值变为 0
 - 计算公式: 
x_new = (x - μ) - 其中 μ 是特征的均值
 
 - 缩放处理(Scaling):
- 将每个特征的标准差变为 1
 - 计算公式: 
x_new = (x - μ) / σ - 其中 σ 是特征的标准差
 
 
标准化后的特征满足:
- 均值 = 0
 - 标准差 = 1
 - 分布形状不变(只是平移和缩放)
 
为什么需要标准化?
- 解决特征尺度不一致问题:
- 例如鸢尾花数据集中:
- 萼片长度:4.3-7.9 cm
 - 萼片宽度:2.0-4.4 cm
 
 - 若不标准化,范围大的特征会主导距离计算
 
 - 例如鸢尾花数据集中:
 - 提高算法性能:
- 基于距离的算法(KNN、SVM):避免大范围特征主导距离计算
 - 基于梯度的算法(线性回归、神经网络):加速收敛,避免振荡
 - 正则化模型:使正则化项对所有特征公平作用
 
 - 提高数值稳定性:
- 防止计算中出现极大或极小的数值
 - 减少浮点数计算误差
 
 
步骤分解:
1.  scaler = StandardScaler()
- 创建一个标准化转换器对象
 - 此时尚未计算任何统计量
2.X_train = scaler.fit_transform(X_train) - 两步操作合二为一:
fit():计算训练集的统计量- 计算每个特征的均值 (μ) 和标准差 (σ)
 - 公式:
 
transform():应用转换- 对每个特征值:
 - 转换后:每个特征的均值 = 0,标准差 = 1
3.X_test = scaler.transform(X_test) 
 - 仅使用训练集计算的参数:
- 使用训练集计算出的 μ 和 σ
 - 不对测试集重新计算统计量(根本原因:防止数据泄露)
 
 
# 3. 模型训练
model = KNeighborsClassifier(n_neighbors=3)  | |
model.fit(X_train, y_train)  | 
- 作用:创建 KNN 分类器并训练模型
 - 对应环节:模型训练
 - 关键点:
- KNN 算法原理:根据最近邻的 K 个样本投票决定分类
 n_neighbors=3是超参数(可调整)fit()方法学习训练数据的特征模式
 
# 4. 模型评估
- 作用:评估模型在未知数据上的表现
 - 对应环节:模型评估
 - 关键点:
- 准确率 = 正确预测数 / 总样本数
 - 混淆矩阵显示:
- 行:真实类别
 - 列:预测类别
 - 对角线:正确分类的样本
比如: 
 
 
预测类别  | |
类0 类1 类2  | |
真 类0 [ 19, 0, 0 ]  | |
实 类1 [ 0, 13, 0 ]  | |
类 类2 [ 0, 0, 13 ]  | 
# 第二个代码:乳腺癌判断
还是 ds 写的代码。
# === 1. 导入库 ===import numpy as np   | |
import pandas as pd  | |
import matplotlib.pyplot as plt  | |
import matplotlib   | |
# 设置中文字体   | |
matplotlib.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei']  | |
matplotlib.rcParams['axes.unicode_minus'] = False  | |
from sklearn.datasets import load_breast_cancer  | |
from sklearn.model_selection import train_test_split, cross_val_score  | |
from sklearn.preprocessing import StandardScaler  | |
from sklearn.svm import SVC  | |
from sklearn.naive_bayes import GaussianNB # PGM 的代表(朴素贝叶斯)  | |
from sklearn.tree import DecisionTreeClassifier, plot_tree  | |
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report  | |
from mlxtend.plotting import plot_decision_regions # 决策边界可视化  | |
# === 2. 加载和探索数据 ===data = load_breast_cancer () # 数据集   | |
X = data.data # 特征  | |
y = data.target # 标签  | |
feature_names = data.feature_names # 特征名  | |
target_names = data.target_names # 标签名  | |
print(f"数据集形状: {X.shape}")  | |
print(f"特征数: {len(feature_names)}")  | |
print(f"类别分布: {np.bincount(y)} (0={target_names[0]}, 1={target_names[1]})")  | |
# 创建 DataFrame 便于分析   | |
df = pd.DataFrame(X, columns=feature_names) #  | |
df['target'] = y  | |
print("\n特征统计信息:")  | |
print(df.describe())  | |
# === 3. 数据预处理 ===# 划分训练集 / 测试集   | |
# stratify=y 表示在划分数据时保持每个类别的比例与原数据集一致   | |
X_train, X_test, y_train, y_test = train_test_split(  | |
X, y, test_size=0.2, random_state=42, stratify=y  | |
)   | |
# 特征标准化   | |
scaler = StandardScaler()  | |
X_train_scaled = scaler.fit_transform(X_train)  | |
X_test_scaled = scaler.transform(X_test)  | |
# 选择两个主要特征进行可视化 (平均半径和平均纹理)   | |
X_train_vis = X_train_scaled[:, :2] # 前两个特征  | |
X_test_vis = X_test_scaled[:, :2]  | |
# === 4. 训练多种模型 ===# 向量机,朴素贝叶斯,决策树   | |
models = {  | |
"SVM": SVC(kernel='rbf', C=1.0, gamma='scale', probability=True, random_state=42),  | |
"Naive Bayes (PGM)": GaussianNB(),  | |
"Decision Tree": DecisionTreeClassifier(max_depth=3, random_state=42)  | |
}   | |
# 训练并评估每个模型   | |
results = {}  | |
for name, model in models.items():  | |
    # 训练模型   | |
model.fit(X_train_scaled, y_train)  | |
    # 预测   | |
y_pred = model.predict(X_test_scaled)  | |
    # 评估   | |
accuracy = accuracy_score(y_test, y_pred)  | |
cm = confusion_matrix(y_test, y_pred)  | |
report = classification_report(y_test, y_pred, target_names=target_names)  | |
    # 存储结果   | |
results[name] = {  | |
'model': model,  | |
'accuracy': accuracy,  | |
'confusion_matrix': cm,  | |
'report': report  | |
    }   | |
    # 交叉验证   | |
cv_scores = cross_val_score(model, X_train_scaled, y_train, cv=5)  | |
print(f"\n=== {name} ===")  | |
print(f"测试集准确率: {accuracy:.2%}")  | |
print(f"5折交叉验证平均准确率: {np.mean(cv_scores):.2%} ± {np.std(cv_scores):.2%}")  | |
print("分类报告:\n", report)  | |
# === 5. 可视化比较 ===plt.figure (figsize=(18, 12))   | |
# 绘制决策边界   | |
for i, (name, result) in enumerate(results.items(), 1):  | |
model = result['model']  | |
    # 为可视化重新训练只使用前 2 个特征的模型   | |
if name == "SVM":  | |
model_vis = SVC(kernel='rbf', C=1.0, gamma='scale', probability=True, random_state=42)  | |
model_vis.fit(X_train_vis, y_train)  | |
elif name == "Naive Bayes (PGM)":  | |
model_vis = GaussianNB()  | |
model_vis.fit(X_train_vis, y_train)  | |
elif name == "Decision Tree":  | |
model_vis = DecisionTreeClassifier(max_depth=3, random_state=42)  | |
model_vis.fit(X_train_vis, y_train)  | |
plt.subplot(2, 3, i)  | |
plot_decision_regions(X_train_vis, y_train, clf=model_vis, legend=2)  | |
plt.title(f"{name} 决策边界")  | |
plt.xlabel(feature_names[0])  | |
plt.ylabel(feature_names[1])  | |
    # 添加测试集点   | |
plt.scatter(X_test_vis[:, 0], X_test_vis[:, 1], c=y_test,  | |
edgecolors='k', alpha=0.7, marker='o', s=80,  | |
cmap=plt.cm.coolwarm, label='测试集')  | |
# 绘制决策树结构   | |
plt.subplot(2, 3, 4)  | |
plot_tree(models["Decision Tree"],  | |
feature_names=feature_names,  | |
class_names=target_names,  | |
filled=True, rounded=True,  | |
fontsize=10)  | |
plt.title("决策树结构")  | |
# 绘制特征重要性 (决策树)   | |
plt.subplot(2, 3, 5)  | |
tree_model = models["Decision Tree"]  | |
importances = tree_model.feature_importances_  | |
indices = np.argsort(importances)[::-1][:10] # 取前 10 个重要特征  | |
plt.barh(range(len(indices)), importances[indices], align='center')  | |
plt.yticks(range(len(indices)), [feature_names[i] for i in indices])  | |
plt.xlabel('特征重要性')  | |
plt.title('决策树 - 特征重要性 (Top 10)')  | |
# 绘制 SVM 支持向量   | |
plt.subplot(2, 3, 6)  | |
svm_model = models["SVM"]  | |
plt.scatter(X_train_scaled[:, 0], X_train_scaled[:, 1], c=y_train, cmap=plt.cm.coolwarm, s=30)  | |
plt.scatter(svm_model.support_vectors_[:, 0], svm_model.support_vectors_[:, 1],  | |
s=100, facecolors='none', edgecolors='k', label='支持向量')  | |
plt.title("SVM支持向量")  | |
plt.xlabel(feature_names[0])  | |
plt.ylabel(feature_names[1])  | |
plt.legend()  | |
plt.tight_layout()  | |
plt.show()  | |
# === 6. 模型比较总结 ===print ("\n=== 模型性能总结 ===")   | |
for name, result in results.items():  | |
print(f"{name}: 准确率 = {result['accuracy']:.2%}")  | 
几个注意点:
# 数据集构成
print(f"数据集形状: {X.shape}")  | |
print(f"特征数: {len(feature_names)}")  | |
print(f"类别分布: {np.bincount(y)} (0={target_names[0]}, 1={target_names[1]})")  | 
数据集形状: (569, 30) 表示该数据集共有 569 条样本,每条样本有 30 个特征。类别分布: [212 357] 表示分类结果的分布情况:
0(恶性肿瘤):212 例1(良性肿瘤):357 例
# dataframe 表示
# 创建 DataFrame 便于分析   | |
df = pd.DataFrame(X, columns=feature_names) #  | |
df['target'] = y  | |
print("\n特征统计信息:")  | |
print(df.describe())  | 
DataFrame 结构
df = pd.DataFrame(  | |
data=X, # 原始数据矩阵  | |
columns=feature_names # 列名称列表  | |
) | 
- 结果:创建一个二维表格
- 行:每个样本(569 行)
 - 列:每个特征(30 列)
 
 
df['target'] = y # y是标签向量
- 添加新列 'target'
 - 包含每个样本的类别标签(0 = 恶性,1 = 良性)
 
结果 DataFrame 示例:
| mean radius | mean texture | ... | worst fractal dimension | target | 
|---|---|---|---|---|
| 17.99 | 10.38 | ... | 0.1189 | 0 | 
| 20.57 | 17.77 | ... | 0.0890 | 0 | 
| 19.69 | 21.25 | ... | 0.0876 | 0 | 
| ... | ... | ... | ... | ... | 
| 7.76 | 24.54 | ... | 0.0703 | 1 | 
统计分析功能: print(df.describe())describe() 生成描述性统计信息,包括:
- count: 非缺失值数量
 - mean: 平均值
 - std: 标准差
 - min: 最小值
 - 25%: 第一四分位数
 - 50%: 中位数
 - 75%: 第三四分位数
 - max: 最大值
 
describe () 输出示例:
mean radius mean texture ... worst fractal dimension target  | |
count 569.000000 569.000000 ... 569.000000 569.0000  | |
mean 14.127292 19.289649 ... 0.083946 0.6274  | |
std 3.524049 4.301036 ... 0.018061 0.4839  | |
min 6.981000 9.710000 ... 0.055040 0.0000  | |
25% 11.700000 16.170000 ... 0.071460 0.0000  | |
50% 13.370000 18.840000 ... 0.080040 1.0000  | |
75% 15.780000 21.800000 ... 0.092080 1.0000  | |
max 28.110000 39.280000 ... 0.207500 1.0000  | 
列是特征,行代表由 569 个样本算出来的各个指标。
# 数据预处理
# === 3. 数据预处理 ===# 划分训练集 / 测试集   | |
# stratify=y 表示在划分数据时保持每个类别的比例与原数据集一致   | |
X_train, X_test, y_train, y_test = train_test_split(  | |
X, y, test_size=0.2, random_state=42, stratify=y  | |
)   | |
# 特征标准化   | |
scaler = StandardScaler()  | |
X_train_scaled = scaler.fit_transform(X_train)  | |
X_test_scaled = scaler.transform(X_test)  | |
# 选择两个主要特征进行可视化 (平均半径和平均纹理)   | |
X_train_vis = X_train_scaled[:, :2] # 前两个特征  | |
X_test_vis = X_test_scaled[:, :2]  | 
- stratify 是用于分层抽样的参数
 - 使用 stratify=y 后,训练集和测试集中恶性 / 良性肿瘤的比例会保持与原始数据集相同
 - 这有助于避免因随机划分导致的类别分布偏差,尤其适用于不平衡数据集
 - 例如:如果原始数据集中有 60% 的良性样本,在测试集中也会保持大约 60% 的良性样本
 
X_train_vis = X_train_scaled[:, :2] # 前两个特征X_test_vis = X_test_scaled[:, :2]
这两行代码的作用是: 从标准化后的训练集和测试集特征中,只选取前两个特征(即 “平均半径” 和 “平均纹理”),
用于后续的二维可视化(比如决策边界图)。 这样做可以让模型在二维空间中展示分类效果,便于直观观察和比较不同算法的决策边界。
# 模型训练
# 向量机,朴素贝叶斯,决策树   | |
models = {  | |
"SVM": SVC(kernel='rbf', C=1.0, gamma='scale', probability=True, random_state=42),  | |
"Naive Bayes (PGM)": GaussianNB(),  | |
"Decision Tree": DecisionTreeClassifier(max_depth=3, random_state=42)  | |
} | 
这里定义了三个模型及其参数,具体解释如下:
SVC(kernel='rbf', C=1.0, gamma='scale', probability=True, random_state=42)kernel='rbf':使用径向基函数(高斯核)作为核函数,适合非线性分类。C=1.0:正则化参数,控制误差容忍度,值越大越倾向于拟合训练集。gamma='scale':核函数的系数,自动根据特征数和方差调整。probability=True:支持概率输出(如predict_proba方法)。random_state=42:随机种子,保证结果可复现。
GaussianNB()- 朴素贝叶斯分类器,假设特征服从高斯分布。无特殊参数,默认设置即可。
 
DecisionTreeClassifier(max_depth=3, random_state=42)max_depth=3:决策树最大深度,限制树的复杂度,防止过拟合。random_state=42:随机种子,保证结果可复现。
# 模型评估
# 评估   | |
accuracy = accuracy_score(y_test, y_pred)  | |
cm = confusion_matrix(y_test, y_pred)  | |
report = classification_report(y_test, y_pred, target_names=target_names)  | |
# 存储结果   | |
results[name] = {  | |
'model': model,  | |
'accuracy': accuracy,  | |
'confusion_matrix': cm,  | |
'report': report  | |
}   | |
# 交叉验证   | |
cv_scores = cross_val_score(model, X_train_scaled, y_train, cv=5)  | |
print(f"\n=== {name} ===")  | |
print(f"测试集准确率: {accuracy:.2%}")  | |
print(f"5折交叉验证平均准确率: {np.mean(cv_scores):.2%} ± {np.std(cv_scores):.2%}")  | |
print("分类报告:\n", report)  | 
# 准确率 (Accuracy)
accuracy = accuracy_score(y_test, y_pred)
- 公式:正确预测数 / 总样本数
 - 含义:模型整体预测正确的比例
 - 解读:
- 值范围:0.0(全错)~ 1.0(全对)
 - 在乳腺癌数据集中,98.25% 准确率表示 100 个样本中有 98 个被正确分类
 
 - 优点:直观易懂
 - 局限:在类别不平衡数据中可能误导(如 99% 负样本,模型全预测负也有 99% 准确率)
 
# 混淆矩阵 (Confusion Matrix)
cm = confusion_matrix(y_test, y_pred)
上面讲过了,略
# 分类报告 (Classification Report)
report = classification_report(y_test, y_pred, target_names=target_names)
输出三个核心指标(按类别计算):
a) 精确率 (Precision)
- 公式:TP / (TP + FP)
 - 含义:预测为正的样本中,实际为正的比例
 - 业务意义:减少误报(如减少健康人被误诊为癌症)
 
b) 召回率 (Recall / 灵敏度)
- 公式:TP / (TP + FN)
 - 含义:实际为正的样本中,被正确预测的比例
 - 业务意义:减少漏诊(如确保癌症患者不被漏诊)
 
c) F1 分数
- 公式:2 × (Precision × Recall) / (Precision + Recall)
 - 含义:精确率和召回率的调和平均
 - 特点:综合衡量模型性能,特别适合不平衡数据
 
d) 分类报告示例输出
precision recall f1-score support  | |
malignant 0.98 0.96 0.97 47  | |
benign 0.97 0.99 0.98 67  | |
accuracy 0.98 114  | |
macro avg 0.98 0.97 0.97 114  | |
weighted avg 0.98 0.98 0.98 114  | 
解读
- 恶性类别 (malignant):
- 精确率 98%:预测为恶性的样本中 98% 确实恶性
 - 召回率 96%:真实恶性样本有 96% 被正确识别
 - F1 分数 97%:综合表现优秀
 
 - 良性类别 (benign):
- 精确率 97%:预测良性的样本 97% 正确
 - 召回率 99%:真实良性样本 99% 被正确识别
 
 - 整体统计:
accuracy:总体准确率 98%macro avg:各类别指标的简单平均weighted avg:按样本量加权的平均
 
support 这一列代表的是每个类别在测试集中实际的样本数量。accuracy 的 0.98 与列无关,展示的整体的准确率
# 交叉验证 (Cross Validation)
cv_scores = cross_val_score(model, X_train_scaled, y_train, cv=5)print(f"5折交叉验证平均准确率: {np.mean(cv_scores):.2%} ± {np.std(cv_scores):.2%}")
- 原理:将训练集分成 5 份,轮流用 4 份训练,1 份验证,重复 5 次
 - 输出:
- 平均准确率:模型性能的稳定估计
 - 标准差:模型性能的波动范围
 
 - 重要性:
- 减少因单次数据分割带来的随机性
 - 检测模型是否过拟合
 - 比单次测试集评估更可靠
 
 - 解读示例:
- "97.59% ± 0.82%" 表示:
- 平均准确率 97.59%
 - 波动范围在 ±0.82% 之间 → 模型稳定
 
 
 - "97.59% ± 0.82%" 表示: