Python 机器学习四大实战案例:决策树 + 随机森林 + KNN + 可视化全解析
·
前言
在机器学习入门阶段,分类任务是最核心的学习方向,从经典的决策树、随机森林,到简单易用的 K 近邻算法,都是必须掌握的基础模型。本文将通过电信客户流失预测、垃圾邮件分类、手写数字识别三大实战场景,完整复现决策树、随机森林、KNN三大算法的建模、训练、评估、可视化全流程,代码可直接运行,适合机器学习新手入门学习。
本文所有代码基于Python,依赖库:pandas、scikit-learn、matplotlib、opencv-python,适合零基础小白快速上手。
目录
一、环境准备
首先安装所需依赖库,执行以下命令:
pip install pandas scikit-learn matplotlib opencv-python
二、案例 1:决策树实现电信客户流失预测
1. 案例背景
通过用户的特征数据,预测电信客户是否会流失,属于二分类任务。核心流程:数据读取→数据集划分→模型训练→模型评估→混淆矩阵可视化→决策树可视化。
2. 完整代码
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix, classification_report
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier, plot_tree
# 混淆矩阵可视化函数
def cm_plot(y,yp):
cm = confusion_matrix(y, yp)
plt.matshow(cm, cmap=plt.cm.Blues)
plt.colorbar()
for x in range(len(cm)):
for y in range(len(cm)):
plt.annotate(cm[x,y], xy=(y, x), horizontalalignment='center',
verticalalignment='center')
plt.ylabel('True label')
plt.xlabel('Predicted label')
return plt
# 1. 读取数据
datas=pd.read_excel("电信客户流失数据.xlsx")
data=datas.iloc[:,:-1] # 特征数据
target=datas.iloc[:,-1] # 标签数据
# 2. 划分训练集和测试集
data_train,data_test,target_train,target_test=train_test_split(
data,target,test_size=0.2,random_state=42
)
# 3. 构建决策树模型
dtr=DecisionTreeClassifier(max_depth=8,random_state=42)
dtr.fit(data_train,target_train)
# 4. 训练集评估
train_predicted=dtr.predict(data_train)
print("训练集分类报告:")
print(classification_report(target_train,train_predicted))
cm_plot(target_train,train_predicted).show()
# 5. 测试集评估
test_predicted=dtr.predict(data_test)
print("测试集分类报告:")
print(classification_report(target_test,test_predicted))
cm_plot(target_test,test_predicted).show()
# 6. 模型评分
print(f"测试集准确率:{dtr.score(data_test,target_test)}")
# 7. 决策树可视化
fig,ax=plt.subplots(figsize=(32,32))
plot_tree(dtr,filled=True,ax=ax)
plt.show()
3. 核心知识点
- 数据划分:
train_test_split按 8:2 划分训练集和测试集,保证实验可复现; - 决策树参数:
max_depth限制树深度,防止过拟合; - 模型评估:
classification_report输出精确率、召回率、F1 分数,混淆矩阵直观展示分类效果; - 可视化:
plot_tree直接绘制决策树结构,cm_plot自定义函数可视化混淆矩阵。
三、案例 2:决策树 + ROC 曲线优化评估
在基础决策树之上,增加ROC 曲线和 AUC 值评估模型性能,更全面衡量二分类模型效果。
完整代码
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix, classification_report, roc_curve, roc_auc_score
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
# 混淆矩阵可视化函数
def cm_plot(y,yp):
cm = confusion_matrix(y, yp)
plt.matshow(cm, cmap=plt.cm.Blues)
plt.colorbar()
for x in range(len(cm)):
for y in range(len(cm)):
plt.annotate(cm[x,y],xy=(y,x),horizontalalignment='center',
verticalalignment='center')
plt.ylabel('True label')
plt.xlabel('Predicted label')
return plt
# 1. 读取数据
datas = pd.read_excel("电信客户流失数据.xlsx")
data = datas.iloc[:,:-1]
target = datas.iloc[:,-1]
# 2. 数据集划分
data_train, data_test, target_train, target_test = train_test_split(
data, target, test_size=0.2, random_state=42
)
# 3. 模型训练
dtr = DecisionTreeClassifier(criterion='gini', max_depth=10, random_state=42)
dtr.fit(data_train, target_train)
# 4. 训练集评估
train_predicted = dtr.predict(data_train)
print(classification_report(target_train, train_predicted))
cm_plot(target_train, train_predicted).show()
# 5. 测试集评估
test_predicted = dtr.predict(data_test)
print(classification_report(target_test, test_predicted))
cm_plot(target_test, test_predicted).show()
# 6. ROC曲线与AUC值
y_pred_proba=dtr.predict_proba(data_test)[:,1]
auc_result=roc_auc_score(target_test,y_pred_proba)
fpr,tpr,thresholds=roc_curve(target_test,y_pred_proba)
plt.figure()
plt.plot(fpr,tpr,color='darkorange',lw=2,label=f'ROC curve(area={auc_result:.2f})')
plt.plot([0,1],[0,1],color='navy',lw=2,linestyle='--')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('ROC曲线')
plt.legend()
plt.show()
核心知识点
- 预测概率:
predict_proba获取分类概率,用于绘制 ROC 曲线; - AUC 值:衡量模型区分能力,值越接近 1 效果越好;
- ROC 曲线:直观展示模型在不同阈值下的分类性能。
四、案例 3:随机森林实现垃圾邮件分类
随机森林是集成学习模型,由多棵决策树组成,泛化能力更强,本案例用于垃圾邮件二分类。
完整代码
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix, classification_report
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
# 混淆矩阵可视化函数
def cm_plot(y, yp):
cm = confusion_matrix(y, yp)
plt.matshow(cm, cmap=plt.cm.Blues)
plt.colorbar()
for x in range(len(cm)):
for y in range(len(cm)):
plt.annotate(cm[x, y], xy=(y, x), horizontalalignment='center',
verticalalignment='center')
plt.ylabel('True label')
plt.xlabel('Predicted label')
return plt
# 1. 读取垃圾邮件数据
df = pd.read_csv('spambase.csv')
X = df.iloc[:, :-1]
y = df.iloc[:, -1]
# 2. 数据集划分
xtrain, xtest, ytrain, ytest = train_test_split(
X, y, test_size=0.2, random_state=100
)
# 3. 构建随机森林模型
rf = RandomForestClassifier(
n_estimators=100, # 决策树数量
max_features=0.8, # 特征采样比例
random_state=0
)
rf.fit(xtrain, ytrain)
# 4. 训练集评估
train_predicted = rf.predict(xtrain)
print("训练集分类报告:")
print(classification_report(ytrain, train_predicted))
cm_plot(ytrain, train_predicted).show()
# 5. 测试集评估
test_predicted = rf.predict(xtest)
print("测试集分类报告:")
print(classification_report(ytest, test_predicted))
cm_plot(ytest, test_predicted).show()
# 6. 特征重要性可视化
importances = rf.feature_importances_
im = pd.DataFrame(importances, columns=["importances"])
im['clos'] = df.columns[:-1]
im = im.sort_values(by='importances', ascending=False)[:10]
plt.barh(range(len(im)), im['importances'])
plt.yticks(range(len(im)), im['clos'])
plt.title('特征重要性Top10')
plt.show()
核心知识点
- 随机森林优势:多棵决策树投票决策,抗过拟合能力强;
- 关键参数:
n_estimators控制树的数量,max_features控制特征采样; - 特征重要性:
feature_importances_输出特征权重,直观了解哪些特征对分类影响最大。
五、案例 4:OpenCV+KNN 实现手写数字识别
K 近邻(KNN)是惰性学习算法,原理简单:通过距离最近的 K 个样本判断分类。本案例使用 OpenCV 内置 KNN 实现手写数字识别。
完整代码
import numpy as np
import cv2
# 1. 读取手写数字图片并转灰度图
img = cv2.imread('digits.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 2. 数据切分:将图像分割为20x20的数字块
cells = [np.hsplit(row,100) for row in np.vsplit(gray,50)]
x = np.array(cells) # 形状(50,100,20,20)
# 3. 划分训练集和测试集
train = x[:,:50].reshape(-1,400).astype(np.float32)
test = x[:,50:100].reshape(-1,400).astype(np.float32)
# 4. 生成标签
k = np.arange(10)
labels = np.repeat(k,250)[:,np.newaxis]
# 5. 构建KNN模型并训练
knn = cv2.ml.KNearest_create()
knn.train(train, cv2.ml.ROW_SAMPLE, labels)
# 6. 模型预测
ret,result,neighbours,dist = knn.findNearest(test,k=9)
# 7. 计算准确率
matches = result==labels
correct = np.count_nonzero(matches)
accuracy = correct*100.0/result.size
print(f"KNN手写数字识别准确率:{accuracy:.2f}%")
核心知识点
- 图像预处理:将大图切分为单个数字图像,扁平化处理为模型输入格式;
- KNN 原理:通过计算欧氏距离,选择最近的 9 个邻居投票分类;
- OpenCV 机器学习:
cv2.ml.KNearest_create快速构建 KNN 模型,无需手动实现算法。
六、四大模型对比总结
表格
| 模型 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 决策树 | 可解释性强、训练快 | 易过拟合 | 简单分类、规则可视化 |
| 随机森林 | 泛化能力强、精度高 | 训练速度较慢 | 表格数据分类、特征筛选 |
| KNN | 原理简单、无需训练 | 预测慢、对数据敏感 | 小样本、低维数据分类 |
七、总结
本文通过四个完整代码案例,覆盖了机器学习分类任务的全流程:
- 掌握了决策树的建模、评估与可视化;
- 学会用ROC 曲线 / AUC 值优化模型评估;
- 实战随机森林完成垃圾邮件分类,学习特征重要性分析;
- 使用OpenCV+KNN实现经典的手写数字识别。
所有代码均可直接运行,适合机器学习新手快速入门,后续可通过调参、数据预处理进一步提升模型精度!
更多推荐
所有评论(0)