数据分析——第三章模型建立和评估---评价

第三章 模型搭建和评估-评估

根据之前的模型的建模,我们知道如何运用sklearn这个库来完成建模,以及我们知道了的数据集的划分等等操作。那么一个模型我们怎么知道它好不好用呢?以至于我们能不能放心的使用模型给我的结果呢?那么今天的学习的评估,就会很有帮助。

加载下面的库

1
2
3
4
5
6
7
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from IPython.display import Image
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
1
%matplotlib inline
1
2
3
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
plt.rcParams['figure.figsize'] = (10, 6) # 设置输出图片大小

任务:加载数据并分割测试集和训练集

1
2
3
#写入代码

from sklearn.model_selection import train_test_split
1
2
3
4
5
6
7
#写入代码
# 一般先取出X和y后再切割,有些情况会使用到未切割的,这时候X和y就可以用,x是清洗好的数据,y是我们要预测的存活数据'Survived'
data = pd.read_csv('clear_data.csv')
train = pd.read_csv('train.csv')
X = data
y = train['Survived']

1
2
3
4
#写入代码
# 对数据集进行切割
X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, random_state=0)

1
2
3
4
5
#写入代码
# 默认参数逻辑回归模型
lr = LogisticRegression()
lr.fit(X_train, y_train)

/root/.pyenv/versions/3.11.1/lib/python3.11/site-packages/sklearn/linear_model/_logistic.py:465: ConvergenceWarning: lbfgs failed to converge (status=1):
STOP: TOTAL NO. OF ITERATIONS REACHED LIMIT.

Increase the number of iterations (max_iter) or scale the data as shown in:
    https://scikit-learn.org/stable/modules/preprocessing.html
Please also refer to the documentation for alternative solver options:
    https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression
  n_iter_i = _check_optimize_result(

模型评估

  • 模型评估是为了知道模型的泛化能力。
  • 交叉验证(cross-validation)是一种评估泛化性能的统计学方法,它比单次划分训练集和测试集的方法更加稳定、全面。
  • 在交叉验证中,数据被多次划分,并且需要训练多个模型。
  • 最常用的交叉验证是 k 折交叉验证(k-fold cross-validation),其中 k 是由用户指定的数字,通常取 5 或 10。
  • 准确率(precision)度量的是被预测为正例的样本中有多少是真正的正例
  • 召回率(recall)度量的是正类样本中有多少被预测为正类
  • f-分数是准确率与召回率的调和平均

【思考】:将上面的概念进一步的理解,大家可以做一下总结

1
2
3
#思考回答:


任务一:交叉验证

  • 用10折交叉验证来评估之前的逻辑回归模型
  • 计算交叉验证精度的平均值
1
2
#提示:交叉验证
Image('Snipaste_2020-01-05_16-37-56.png')
第三章模型建立和评估—评价-课程_16_0

提示4

  • 交叉验证在sklearn中的模块为sklearn.model_selection
1
2
3
#写入代码
from sklearn.model_selection import cross_val_score

1
2
3
#写入代码
lr = LogisticRegression(C=100)
scores = cross_val_score(lr, X_train, y_train, cv=10)
1
2
3
4
#写入代码
# 平均交叉验证分数
print("Average cross-validation score: {:.2f}".format(scores.mean()))

Average cross-validation score: 0.78

思考4

  • k折越多的情况下会带来什么样的影响?
1
2
3
4
5
6
#思考回答
# 当 k 越大时:
# 1. 每次训练使用的数据更多,评估偏差(bias)降低
# 2. 每次测试集样本更少,评估方差(variance)增大
# 3. 需要训练 k 个模型,计算开销显著增加

任务二:混淆矩阵

  • 计算二分类问题的混淆矩阵
  • 计算精确率、召回率以及f-分数

【思考】什么是二分类问题的混淆矩阵,理解这个概念,知道它主要是运算到什么任务中的

1
2
3
4
5
6
7
8
9
#思考回答
# 混淆矩阵(confusion matrix)是一个 2×2 的表格,用于二分类任务中展示模型预测结果与真实标签的对应关系:
# - True Positive (TP):真实为正类,预测也为正类
# - False Positive (FP):真实为负类,却被误预测为正类
# - False Negative (FN):真实为正类,却被误预测为负类
# - True Negative (TN):真实为负类,预测也为负类
# 通过混淆矩阵,可以进一步计算精确率(Precision)、召回率(Recall)、F1 分数等指标,
# 帮助我们评估模型在不同类型错误上的表现,常用于分类模型的性能评估和错误分析。

1
2
#提示:混淆矩阵
Image('Snipaste_2020-01-05_16-38-26.png')
第三章模型建立和评估—评价-课程_27_0
1
2
3
#提示:准确率 (Accuracy),精确度(Precision),Recall,f-分数计算方法
Image('Snipaste_2020-01-05_16-39-27.png')

第三章模型建立和评估—评价-课程_28_0

提示5

  • 混淆矩阵的方法在sklearn中的sklearn.metrics模块
  • 混淆矩阵需要输入真实标签和预测标签
  • 精确率、召回率以及f-分数可使用classification_report模块
1
2
3
#写入代码
from sklearn.metrics import confusion_matrix

1
2
3
4
5
#写入代码
# 训练模型
lr = LogisticRegression(C=100)
lr.fit(X_train, y_train)

/root/.pyenv/versions/3.11.1/lib/python3.11/site-packages/sklearn/linear_model/_logistic.py:465: ConvergenceWarning: lbfgs failed to converge (status=1):
STOP: TOTAL NO. OF ITERATIONS REACHED LIMIT.

Increase the number of iterations (max_iter) or scale the data as shown in:
    https://scikit-learn.org/stable/modules/preprocessing.html
Please also refer to the documentation for alternative solver options:
    https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression
  n_iter_i = _check_optimize_result(
1
2
3
#写入代码
# 模型预测结果
pred = lr.predict(X_train)
1
2
3
4
#写入代码
# 混淆矩阵
confusion_matrix(y_train, pred)

array([[355,  57],
       [ 82, 174]])
1
2
3
from sklearn.metrics import classification_report
# 精确率、召回率以及f1-score
print(classification_report(y_train, pred))
              precision    recall  f1-score   support

           0       0.81      0.86      0.84       412
           1       0.75      0.68      0.71       256

    accuracy                           0.79       668
   macro avg       0.78      0.77      0.78       668
weighted avg       0.79      0.79      0.79       668

【思考】 * 如果自己实现混淆矩阵的时候该注意什么问题

1
2
3
4
5
6
7
8
9
#思考回答
# 如果自己实现混淆矩阵,需要注意:
# 1. 明确行列含义:通常行是真实标签,列是预测标签,并保持一致。
# 2. 类别顺序要固定:最好指定 labels 列表,避免类别稀疏时错位。
# 3. 初始化大小为 n_classes×n_classes 的零矩阵。
# 4. 索引时使用整数或统一的类别映射,避免类型不一致。
# 5. 对每个样本累加到对应的 [真实, 预测] 单元格,最后矩阵元素之和应等于样本数。
# 6. 对于未出现的类别,矩阵对应行或列应保留 0。

任务三:ROC曲线

  • 绘制ROC曲线

【思考】什么是ROC曲线,OCR曲线的存在是为了解决什么问题?

1
2
3
4
5
6
7
#思考
# ROC曲线(Receiver Operating Characteristic Curve)是一条以假正例率(FPR)为横坐标、
# 真正例率(TPR)为纵坐标绘制的曲线,展示模型在不同阈值下的分类性能变化。
# 它解决了单一阈值下评估不全面的问题,通过曲线下的面积(AUC)能够衡量模型整体区分正负样本的能力;
# 对类别不平衡更稳健,可在不同模型或参数设置间进行客观比较。


提示6

  • ROC曲线在sklearn中的模块为sklearn.metrics
  • ROC曲线下面所包围的面积越大越好
1
2
3
#写入代码
from sklearn.metrics import roc_curve

1
print(lr.decision_function(X_test))
[-1.7776276  -1.68901519 -2.9343385  -2.73339993 -0.7425476   0.1771919
  0.42300886 -0.95177507 -2.19297241 -2.09492243 -2.09876666 -2.24379328
 -0.72898893 -0.74448703  1.55206252  2.26736362 -3.0615053  -1.45551632
  1.82143942  1.10174703  2.80348253  2.20862227 -2.08595792 -1.98565326
 -2.62459231  2.61608127  2.52054836  0.46386814 -2.26805651 -1.89799476
 -4.40221097 -2.45118004 -2.11507984  0.25727282  1.56507901 -3.49922092
  0.09517543  3.1727335  -0.66659502 -2.16889122 -2.31738004 -0.75154631
  1.34173247 -0.68691348 -2.38317701 -1.48352807  3.30441868  0.37836543
  0.15120699 -2.39554116  0.71230509 -2.94049784  0.0526656  -0.12124772
  0.21937853 -0.95736671 -2.91315052  1.73227025 -2.30451919 -0.11949728
 -2.40406452 -1.23217853 -3.04709277 -2.51149884 -2.91275507  0.36741872
  1.88515182 -1.73344723  1.61180838 -2.64456699 -2.82671595 -1.32885535
 -1.89201447 -2.38194062  1.14830497  0.7324757   3.41575634 -0.04718518
  1.99047031  0.71098531 -2.5002286   2.11220527  1.35687779 -4.65208202
 -0.50164169 -2.21847127 -0.27744568 -2.1098023  -2.28203956 -2.24087733
  1.49913758 -0.46745632 -1.76590269 -3.13694507 -2.48969764 -2.52447108
 -0.31359417 -2.62456277  0.10812447 -3.22505518 -0.54301462 -1.31398633
 -2.45637232 -0.9392769  -1.99910791 -0.01952273  0.16386412  1.17043699
  0.83571934 -0.30892412 -2.56236834 -2.52630696 -2.15878988  3.38005162
 -1.63316112 -2.0470374   1.16802525  1.96428556 -0.85542758 -0.84711271
 -2.3923425  -2.27467461  1.27340371 -0.16738478  2.77379952 -0.91636487
  3.49337899  2.22265823 -1.03898765 -1.79576035  3.05405598 -1.72625544
 -2.08233698  0.14427761 -2.03826492 -1.87510703 -2.43040363  0.88364821
 -2.31722422  1.21479438 -2.19509856 -1.96948465  2.90456606  1.22909197
 -0.60993113 -2.40508898  1.79832298 -2.33619419 -1.76964851  0.54894164
  0.56920781 -1.65544357 -2.18783672 -2.51890544 -1.1167812   1.85506633
 -2.14366192  2.56003678  1.79741811  2.22038003 -0.93948297  2.11029939
  3.66773152  3.37255532 -1.62079149 -0.21922341 -2.93532548 -1.8851028
 -0.11223495 -0.89402373 -2.79168773  0.58319665 -1.20213471  2.11583429
 -1.78550619 -1.21648746 -2.91538781 -2.80005448 -2.74359191 -0.06775047
 -1.28645408 -1.17048578 -0.1176852  -1.59958242 -0.65901928 -2.40701243
  0.57575073 -3.0756839   1.53932753 -2.49031769 -3.03266822  0.30539932
 -0.05523861 -0.24431132 -2.36483723  3.25595248 -2.11664845 -1.97728592
 -2.04509461 -3.07727841 -1.11942703 -3.38920295 -2.59088459 -3.55978164
  0.22449105 -0.3214215   0.05735696  0.02061023 -3.01544378 -0.77973619
 -1.39798016 -3.10075724 -4.80621573 -3.01948006  3.44366918 -2.88193813
 -2.01992513 -0.09559774  0.91447527 -1.13270082 -2.45426968 -1.91415803
 -0.08403516]
1
2
3
4
5
6
7
8
9
10
11
#写入代码
# 计算ROC曲线的假正例率(FPR)、真正例率(TPR)和阈值
fpr, tpr, thresholds = roc_curve(y_test, lr.decision_function(X_test))
plt.plot(fpr, tpr, label="ROC Curve")
plt.xlabel("FPR")
plt.ylabel("TPR (recall)")
# 找到最接近于0的阈值
close_zero = np.argmin(np.abs(thresholds))
plt.plot(fpr[close_zero], tpr[close_zero], 'o', markersize=10, label="threshold zero", fillstyle="none", c='k', mew=2)
plt.legend(loc=4)

第三章模型建立和评估—评价-课程_44_3

思考6

  • 对于多分类问题如何绘制ROC曲线
1
2
3
4
#思考回答



【思考】你能从这条OCR曲线的到什么信息?这些信息可以做什么?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#思考回答
# 从ROC曲线中可以得到以下信息:
# 1. 模型整体性能:曲线下的面积 (AUC - Area Under the Curve) 是一个常用的评估指标。
# - AUC = 1:完美分类器。
# - AUC = 0.5:随机分类器(无区分能力,ROC曲线接近对角线)。
# - AUC > 0.5:模型优于随机猜测。AUC越大,模型区分正负样本的能力越强。
# - AUC < 0.5:模型表现差于随机猜测(可能标签反了或者模型非常差)。
# 2. 不同阈值下的权衡:ROC曲线展示了在所有可能的分类阈值下,真正例率 (TPR) 与假正例率 (FPR) 之间的关系。
# - 曲线上的每个点代表一个特定的阈值。
# - 曲线越靠近左上角 (FPR低, TPR高),说明模型在较低的假正例率下能达到较高的真正例率,性能越好。
# 3. 模型的区分能力:曲线的形状可以反映模型区分正负样本的能力。如果曲线显著高于对角线,说明模型具有较好的区分能力。
# 4. 阈值选择的依据:可以根据业务需求,在ROC曲线上选择一个合适的平衡点(即选择一个阈值)。
# - 例如,如果更关注减少漏报(提高TPR),可以选择曲线上TPR较高的点,即使FPR可能略高。
# - 如果更关注减少误报(降低FPR),可以选择曲线上FPR较低的点,即使TPR可能略低。
# - 图中标记的 "threshold zero" 点通常是模型默认的分类阈值对应的性能点。