别再死记硬背了!用Python+Scikit-learn实战复现机器学习期末考点(决策树/神经网络/SVM)
·
用Python代码破解机器学习期末考:决策树、神经网络与SVM实战指南
期末考试临近,面对满屏的算法公式和抽象概念,你是否感到无从下手?传统的死记硬背不仅效率低下,更容易在考场上遇到变式题时束手无策。本文将带你用Python和Scikit-learn构建三个核心算法的可视化实验,把枯燥的理论转化为可运行的代码。通过 DecisionTreeClassifier 观察预剪枝效果,用 MLPClassifier 调试神经网络层数,再用 SVC 绘制决策边界——这些实战操作不仅能帮你理解考试重点,更能培养真正的工程思维。
1. 决策树:从信息增益到剪枝实战
决策树在考试中常考划分属性和剪枝处理。我们先通过代码生成一个模拟数据集:
from sklearn.datasets import make_classification
X, y = make_classification(n_samples=500, n_features=4,
n_informative=3, n_redundant=1,
random_state=42)
1.1 三种划分标准对比
Scikit-learn支持三种划分标准,对应不同算法:
- 信息增益(ID3) :
criterion="entropy" - 基尼指数(CART) :
criterion="gini"(默认) - 增益率(C4.5) :需自定义实现
比较不同标准的效果:
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score
criteria = ["gini", "entropy"]
for c in criteria:
clf = DecisionTreeClassifier(criterion=c, random_state=42)
scores = cross_val_score(clf, X, y, cv=5)
print(f"{c}平均准确率: {scores.mean():.3f}")
1.2 预剪枝与后剪枝实验
考试常考剪枝的区别和效果。预剪枝通过参数控制:
| 参数 | 作用 | 对应考题 |
|---|---|---|
max_depth |
限制树的最大深度 | 预剪枝实现方式 |
min_samples_split |
节点分裂最小样本数 | 过拟合控制 |
min_impurity_decrease |
分裂最小增益阈值 | 停止条件 |
# 未剪枝的树
full_tree = DecisionTreeClassifier(random_state=42)
full_tree.fit(X, y)
print("未剪枝树深度:", full_tree.get_depth())
# 预剪枝的树
pruned_tree = DecisionTreeClassifier(max_depth=3, random_state=42)
pruned_tree.fit(X, y)
print("剪枝后深度:", pruned_tree.get_depth())
可视化决策边界对比:
import matplotlib.pyplot as plt
from sklearn.inspection import DecisionBoundaryDisplay
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
DecisionBoundaryDisplay.from_estimator(
full_tree, X[:, :2], response_method="predict", ax=ax1,
alpha=0.5, cmap=plt.cm.Paired
)
ax1.scatter(X[:, 0], X[:, 1], c=y, edgecolor="k")
ax1.set_title("未剪枝决策边界")
DecisionBoundaryDisplay.from_estimator(
pruned_tree, X[:, :2], response_method="predict", ax=ax2,
alpha=0.5, cmap=plt.cm.Paired
)
ax2.scatter(X[:, 0], X[:, 1], c=y, edgecolor="k")
ax2.set_title("预剪枝决策边界")
plt.show()
2. 神经网络:从感知机到BP算法
2.1 单层感知机的局限性
考试常考感知机无法解决异或问题。用代码验证:
from sklearn.linear_model import Perceptron
X_xor = [[0,0], [0,1], [1,0], [1,1]]
y_xor = [0, 1, 1, 0]
perceptron = Perceptron(random_state=42)
perceptron.fit(X_xor, y_xor)
print("感知机在异或问题的准确率:", perceptron.score(X_xor, y_xor))
2.2 多层神经网络实现
使用 MLPClassifier 演示BP算法:
from sklearn.neural_network import MLPClassifier
mlp = MLPClassifier(hidden_layer_sizes=(4,),
activation="relu",
solver="adam",
learning_rate_init=0.01,
max_iter=500,
random_state=42)
mlp.fit(X, y)
# 观察训练过程中的损失变化
plt.plot(mlp.loss_curve_)
plt.xlabel("迭代次数")
plt.ylabel("损失值")
plt.title("BP算法训练过程")
plt.show()
关键参数对应考试重点:
hidden_layer_sizes:隐层神经元数量(网络结构)activation:激活函数类型(sigmoid/tanh/relu)learning_rate_init:初始学习率(影响收敛性)
2.3 过拟合控制实验
对比不同隐层大小的效果:
hidden_layers = [(2,), (10,), (50,50)]
for layers in hidden_layers:
mlp = MLPClassifier(hidden_layer_sizes=layers, random_state=42)
scores = cross_val_score(mlp, X, y, cv=5)
print(f"{layers}层结构准确率: {scores.mean():.3f}")
3. SVM:从线性可分到核技巧
3.1 三种SVM对比实现
考试重点区分三类支持向量机:
from sklearn.svm import SVC
# 线性可分SVM(硬间隔)
linear_svc = SVC(kernel="linear", C=1000)
linear_svc.fit(X[:, :2], y)
# 线性SVM(软间隔)
soft_svc = SVC(kernel="linear", C=0.1)
soft_svc.fit(X[:, :2], y)
# 非线性SVM(RBF核)
rbf_svc = SVC(kernel="rbf", gamma=1, C=1)
rbf_svc.fit(X[:, :2], y)
3.2 决策边界可视化
理解支持向量的概念:
fig, axes = plt.subplots(1, 3, figsize=(18, 5))
titles = ["硬间隔线性SVM", "软间隔线性SVM", "RBF核SVM"]
for ax, model, title in zip(axes, [linear_svc, soft_svc, rbf_svc], titles):
DecisionBoundaryDisplay.from_estimator(
model, X[:, :2], response_method="predict", ax=ax,
alpha=0.5, cmap=plt.cm.Paired
)
ax.scatter(X[:, 0], X[:, 1], c=y, edgecolor="k")
# 标记支持向量
sv = model.support_vectors_
ax.scatter(sv[:, 0], sv[:, 1], facecolors="none", edgecolors="r", s=100)
ax.set_title(title)
plt.show()
3.3 正则化参数C的影响
考试常考正则化参数的作用:
C_values = [0.001, 0.1, 1, 10, 100]
for C in C_values:
svc = SVC(kernel="linear", C=C)
scores = cross_val_score(svc, X[:, :2], y, cv=5)
print(f"C={C}时的准确率: {scores.mean():.3f}")
4. 综合复习策略与代码模板
4.1 高频考点代码模板
收藏这些代码片段应对考试大题:
# 模型评估模板(留出法+k折交叉验证)
from sklearn.model_selection import train_test_split, cross_val_score
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)
model = DecisionTreeClassifier(max_depth=3)
model.fit(X_train, y_train)
print("留出法测试集准确率:", model.score(X_test, y_test))
scores = cross_val_score(model, X, y, cv=5)
print("5折交叉验证平均准确率:", scores.mean())
# 混淆矩阵与分类报告
from sklearn.metrics import classification_report, confusion_matrix
y_pred = model.predict(X_test)
print("混淆矩阵:\n", confusion_matrix(y_test, y_pred))
print("分类报告:\n", classification_report(y_test, y_pred))
4.2 常见考题破解技巧
- 过拟合/欠拟合判断 :观察训练集和测试集表现差距
- 算法对比题 :用
cross_val_score快速比较多个模型 - 参数分析题 :网格搜索可视化参数影响
# 参数搜索可视化示例
import numpy as np
from sklearn.model_selection import validation_curve
param_range = np.logspace(-3, 3, 7)
train_scores, test_scores = validation_curve(
SVC(kernel="rbf"), X[:, :2], y,
param_name="gamma", param_range=param_range,
cv=5
)
plt.plot(param_range, train_scores.mean(axis=1), label="训练得分")
plt.plot(param_range, test_scores.mean(axis=1), label="验证得分")
plt.xscale("log")
plt.xlabel("gamma参数")
plt.ylabel("准确率")
plt.legend()
plt.show()
把这份代码保存为Jupyter Notebook,遇到相关考题时快速调试验证。比如当题目问"增大gamma参数对RBF核SVM有什么影响"时,直接运行最后一个代码块就能得到直观答案。
更多推荐



所有评论(0)