为什么要模型评估?
使用train_test 分割一次,可能会因为分割数据集的偶然性影响结果,特别是小的数据集。
所以需要使用K折交叉验证(K-Fold CV)
将训练集分成K份,轮流使用K-1份训练,1份验证,重复K次,取平均性能
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import make_classification
#生成示例数据
X,y= make_classification(n_samples=1000,n_features=15,n_classes=2,random_state=100)
#创建模型
rf = RandomForestClassifier(n_estimators=100)
#5折交叉验证(一般是5折或10折交叉验证)
cv_scores = cross_val_score(rf,X,y,cv=5,scoring='accuracy')
print('CV score:',cv_scores)
print(f"mean accuracy:{cv_scores.mean():.4f} ± {cv_scores.std():.4f}")
| 方法 | 适用场景 |
|---|---|
| KFold(n_splits=5) | 默认,适用于独立同分布数据 |
| StratifiedKFold | 分类任务推荐!保持每折中类别比例一致 |
| LeaveOneOut | 极小数据集(n < 50),计算昂贵 |
| ShuffleSplit | 随机划分多次,控制训练/测试比例 |
from sklearn.model_selection import StratifiedKFold
skf = StratifiedKFold(n_splits=5,shuffle=True,random_state=100)
scores = cross_val_score(rf,X,y,cv=skf)
print('CV score:',scores)
print(f"mean accuracy:{scores.mean():.4f} ± {scores.std():.4f}")
#完整的使用K折交叉验证和混淆矩阵的例子
from sklearn.model_selection import cross_val_score,train_test_split,StratifiedKFold
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import make_classification
#引入模型评价模块混淆矩阵和可视化模块
from sklearn.metrics import confusion_matrix,accuracy_score
import seaborn as sns
import matplotlib.pyplot as plt
#生成示例数据
X,y= make_classification(n_samples=1000,n_features=15,n_classes=2,random_state=100)
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.15)
#创建模型
rf = RandomForestClassifier(n_estimators=100)
#实例化分层K折验证
skf = StratifiedKFold(n_splits=5,shuffle=True,random_state=100)
#开始K折训练
scores = cross_val_score(rf,X_train,y_train,cv=skf)
print(f"5折交叉验证训练集的准确率:,{scores.mean():.4f} ± {scores.std():.4f}")
#生成训练模型
rf.fit(X_train,y_train)
#使用模型对测试集进行验证
y_pred=rf.predict(X_test)
#计算预测的准确率
test_accuracy=accuracy_score(y_test,y_pred)
print(f"测试集的准确率:{test_accuracy:.4f}")
#计算混淆矩阵
cm= confusion_matrix(y_test,y_pred)
sns.heatmap(cm,annot=True,fmt='d',cmap='Blues')
plt.xlabel('Predicted');plt.ylabel('Actual')
plt.show()
混淆矩阵和TP,TN,FN,FP的关系
| 预测为正类(P) | 预测为负类(N) | |
|---|---|---|
| 真实为正类(P) | TP | FN |
| 真实为负类(N) | FP | TN |
|指标|公式|使用场景| |—|—|—| |准确率Accuracy|(TP+TN)/(TP+TN+FP+FN)|类别平衡时可用| |精确率Precision|TP/(TP+FP)|关注”预测为正的有多少是真的”(如垃圾邮件)| |召回率Recall/Sensiyivity|TP/(TP+FN)|关注真实的正例有多少被找出来,如疾病检测| |F1-score|(Precision * Recall)/(Precision+Recall)|精确率与召回率的调和平均|
注意区分这几个关键评价指标的区别,不同的场景下优先考虑的侧重评价指标是不一样的。
from sklearn.metrics import classification_report
print(classification_report(y_test,y_pred))
只要输入真实值和预测值,一次输出上面的准确率、精确率、召回率、F1-score
在K折交叉验证中评估多个指标的变化情况
#在K折交叉验证中评估多个指标
from sklearn.model_selection import cross_validate
scoring=['accuracy','precision','recall','f1']
scores = cross_validate(rf,X_train,y_train,cv=5,scoring=scoring)
for metric in scoring:
key = f'test_{metric}'
print(f"{metric.capitalize()}:{scores[key].mean():.4f}± {scores[key].std():.4f}")
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import (mean_squared_error,mean_absolute_error,r2_score,mean_absolute_percentage_error)
#1.生成模拟回归数据
X,y = make_regression(n_samples=1000,#样本数
n_features=1,#特征数
n_informative=1,#有效特征数
noise=20,#噪音强度
random_state=100)
#拆分训练集和测试集
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=100)
#2.训练回归模型
#初始化并实例化线性回归模型
lr=LinearRegression()
lr.fit(X_train,y_train)
#开始预测
y_pred = lr.predict(X_test)
#3.计算回归评价指标
#3.1 均方差(MSE)
mse = mean_squared_error(y_test,y_pred)
#3.2均方根误差(RMSE)
rmse = np.sqrt(mse)
#3.3平均绝对误差
mae = mean_absolute_error(y_test,y_pred)
#3.4决定系数R2,取值范围是负无穷到1.越接近1越好。和相关系数R,不是同一个东西。
r2=r2_score(y_test,y_pred)
#3.5 平均绝对百分比误差MAPE
mape=mean_absolute_percentage_error(y_test,y_pred)*100
#4.打印评价指标
print("——回归任务评价指标——")
print("MSE:",mse)
print("RMSE",rmse)
print("MAE",mae)
print("R2",r2)
print("MAPE",mape)
#5.可视化预测结果
plt.figure(figsize=(10,6))
plt.scatter(X_test,y_test,color="blue",alpha=0.6,label='真实值')
plt.plot(X_test,y_pred,color='red',linewidth=2,label='预测值')
plt.xlabel('特征X');plt.ylabel('目标y')
plt.title('线性回归预测结果与真实值')
plt.legend()
plt.grid(True,alpha=0.3)
plt.show()
| 步骤 | 建议 |
|---|---|
| 1. 划分数据 | 先 train_test_split,再在训练集上做 CV |
| 2. 选择 CV 策略 | 分类用 StratifiedKFold,回归用 KFold |
| 3. 选对指标 | 不平衡分类不用 Accuracy;回归看 MSE/R² |
| 4. 多指标评估 | 用 cross_validate 同时看多个指标 |
| 5. 报告不确定性 | 给出 均值 ± 标准差(如 0.93 ± 0.01) |
| 6. 最终评估 | 在独立测试集上报告最终性能 |