第三章 模型建立和评估

项目源码地址:https://github.com/datawhalechina/hands-on-data-analysis

前期准备

#库的导入
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from IPython.display import Image

%matplotlib inline#防止无法正常输出图片

plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
plt.rcParams['figure.figsize'] = (10, 6)  # 设置输出图片大小
#读取数据
data = pd.read_csv('clear_data.csv')#清洗过的数据
train = pd.read_csv('train.csv')#需要训练的数据

3.1建模

3.1.1数据集的划分

from sklearn.model_selection import train_test_split
# 将数据集分为自变量和因变量
X = data
y = train['Survived']

X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, random_state=42)
#划分训练集和测试集,函数会根据目标变量 y 的类别分布,确保在划分后的数据集中存在相同类别分布

X_train.shape,X_test.shape#查看训练集和测试集行列数

3.1.2模型创建

3.1.2.1逻辑回归模型
#库的导入
from sklearn.linear_model import LogisticRegression#逻辑回归模型

#模型选择(逻辑回归模型)
lr = LogisticRegression(penalty='l2',#正则化类型,默认为l2
                         dual=False,#是否使用对偶损失函数
                         tol=0.0001,#优化算法的收敛容差
                         C=1.0,#正则化强度的倒数,越小越能限制模型的复杂程度,但可能会导致欠拟合
                         fit_intercept=True,#是否计算截距
                         intercept_scaling=1,#截距缩放因子
                         class_weight=None,#类别权重,可选参数'balanced'
                         random_state=None,#随机种子
                         solver='lbfgs',#优化算法选择
                         max_iter=100,#最大迭代次数
                         multi_class='auto',#多分类问题的处理方式
                         verbose=0,#不输出详细信息
                         warm_start=False,#是否使用前一次调用的解决方案作为起点
                         n_jobs=None,#并行运行的作业数
                         l1_ratio=None)#L1正则化和L2正则化之间的比例

#模型训练
lr.fit(X_train,y_train)

print('训练集得分:{:.3f}'.format(lr.score(X_train,y_train)))
print('测试集得分:{:.3f}'.format(lr.score(X_test,y_test)))
3.1.2.2随机森林模型
# 库的导入
from sklearn.ensemble import RandomForestClassifier#随机森林模型

# 创建决策树分类器
rf = RandomForestClassifier(n_estimators=100,#森林中决策树的数量
                             criterion='gini',#划分标准,还可以选择'entropy',表示使用信息增益作为划分标准
                             max_depth=None,#最大深度限制
                             min_samples_split=2,#拆分内部节点所需的最小样本数,至少有2个样本才能对内部节点进行划分
                             min_samples_leaf=1,#叶节点上所需的最小样本数,至少有1个样本才能作为叶节点
                             min_weight_fraction_leaf=0.0,#叶结点上所需的最小样本数,叶节点上的所有样本权重总和必须超过等于0
                             max_features='sqrt',#寻找最佳拆分时要考虑的特征数量上限,sqrt使用总特征的平方根
                             max_leaf_nodes=None,#最大叶节点数
                             min_impurity_decrease=0.0,#内部节点的最小不纯度减少量,0.0不进行划分
                             bootstrap=True,#使用自助法采样
                             oob_score=False,#是否计算袋外得分,通过未参与训练的样本评估模型性能
                             n_jobs=None,#并行计算的任务数
                             random_state=None,#随机生成器的种子
                             verbose=0,#不输出任何信息
                             warm_start=False,#是否使用前一次调用的解决方案作为起点
                             class_weight=None,#类别权重
                             ccp_alpha=0.0,#复杂度控制参数
                             max_samples=None)#每个估计器从训练集中采样的样本数量

# 训练模型
rf.fit(X_train, y_train)

print('训练集得分:{:.3f}'.format(rf.score(X_train,y_train)))
print('测试集得分:{:.3f}'.format(rf.score(X_test,y_test)))

3.1.3输出模型预测结果

在机器学习中,模型预测通常是针对测试集进行的。这是因为在训练阶段,我们使用训练集来构建模型,然后使用该模型对测试集中的数据进行预测。通过将模型应用于测试集,我们可以评估其在新数据上的泛化能力,并判断其准确性和可靠性。

#模型预测
pred = lr.predict(X_test)
pred[:10]

# 预测标签概率
pred_proba = lr.predict_proba(X_train)
pred_proba[:10]

在这里插入图片描述
pred_proba 的作用有以下几个:

1.帮助我们了解模型的不确定性或可信程度。我们可以根据 pred_proba 的数值来判断模型对某个标签的预测是否可靠、是否有明显的误差。

2.用于生成 ROC 曲线。ROC 曲线是以不同的阈值为横轴,以真正例率 (TPR) 为纵轴得到的曲线,用来表示二分类模型的性能。pred_proba 可以用来计算 TPR 和 FPR(假正例率),从而绘制 ROC 曲线。

3.用于计算模型评估指标。例如,我们可以通过 pred_proba 计算 AUC 值,来度量二分类模型的性能。

3.2模型评估

3.2.1交叉验证

在这里插入图片描述

3.2.1.1cross_val_score()

cross_val_score(estimator, X, y=None, scoring=None, cv=None, n_jobs=None)
estimator:需要评估的机器学习模型或者管道(Pipeline)对象。
X:特征数据集。
y:目标变量。
scoring:可选参数,用于指定要使用的评分指标,默认为模型默认的评分指标。
cv:可选参数,用于指定交叉验证的折数(默认为 5)。
n_jobs:可选参数,用于指定并行运行的作业数。
函数作用如下
1.执行交叉验证
2.计算模型评分
3.提供多次性能评估

from sklearn.model_selection import cross_val_score

# cross_val_score 是使用交叉验证进行模型评估的函数
score = cross_val_score(lr,X_train,y_train,cv=10)
score.mean()
3.2.1.2KFold

kf = KFold(n_splits=5, shuffle=False, random_state=None)
n_splits:可选参数,表示将数据集分成几份,默认值为 5。
shuffle:可选参数,表示是否在分割前打乱数据,以防止数据顺序对交叉验证的结果产生影响,默认值为 False。
random_state:可选参数,用于指定随机数种子。
函数作用如下:
1.将数据集分成 K 份,其中 (K-1) 份用于训练模型,剩余 1 份用于验证模型。
2.通过 K 次交叉验证来评估模型的性能,并提供平均错误率等指标。

from sklearn.model_selection import KFold

kf = KFold(n_splits=10,shuffle=True)#10折交叉验证,划分数据集前对数据进行重新排列
for i,(train_index, test_index) in enumerate(kf.split(X,y)):
    X_train, X_test = X.iloc[train_index], X.iloc[test_index]
    y_train, y_test = y.iloc[train_index], y.iloc[test_index]
    
    lr.fit(X_train, y_train)
    score = lr.score(X_test, y_test)
score.mean()

【思考】:K折越来越多会造成什么影响?

增加 K 值(即增加折数)会导致以下情况的变化:
1.训练数据减少:随着 K 值的增加,每个训练集的样本数量减少。这意味着每个模型使用的训练数据量减少,可能会导致模型在训练过程中的性能下降。
2.验证数据增加:与训练数据减少相对应的是验证数据的增加。随着 K 值的增加,每个模型使用的验证集的样本数量增加。这可以提供更多的验证样本,从而更准确地评估模型的性能。
3.计算成本增加:增加 K 值会导致进行 K 次模型训练和验证,因此计算成本会相应增加。特别是当数据集较大时,增加 K 值可能会导致训练和验证时间增加,从而增加总体的计算时间。
4.方差与偏差的权衡:K 值的选择涉及到方差和偏差之间的权衡。较小的 K 值会导致方差较低,即模型的性能估计会更加保守。而较大的 K 值会导致方差较高,因为使用的数据集更加接近整个数据集,从而引入了更多的变化。因此,选择合适的 K 值是为了在预测模型性能和计算成本之间找到最佳平衡。

3.2.2混淆矩阵

混淆矩阵需要输入真实标签和预测标签
在这里插入图片描述
准确率,精确率,召回率,f-score
在这里插入图片描述

# 库的导入
from sklearn.metrics import confusion_matrix#混淆矩阵模块
from sklearn.metrics import classification_report#计算精确率,召回率,f-score

#训练模型
lr = LogisticRegression(C=100)#逻辑回归模型
lr.fit(X_train, y_train)#训练

# 模型预测结果
pred = lr.predict(X_train)

#混淆矩阵
confusion_matrix(y_train, pred)
>
array([[418,  67],
       [101, 216]], dtype=int64)

#计算精确率,召回率,f-score
print(classification_report(y_train,y_pred))
>
              precision    recall  f1-score   support

           0       0.81      0.86      0.83       412
           1       0.75      0.68      0.71       256

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

3.2.3ROC曲线

ROC曲线介绍
ROC 曲线是评估二元分类器性能的一种方法,它描述了真阳性率(TPR)与假阳性率(FPR)之间的关系。
在二元分类问题中,我们通常根据模型得出的分类概率值选择一个阈值,并将概率值大于该阈值的样本归为正类,将概率值小于该阈值的样本归为负类。然而,在实际应用中,阈值的选择可能会使得模型在某些性能指标上表现更好,但在其他方面表现不佳。
ROC 曲线是为了解决这种问题而存在的。通过改变阈值,我们可以得到一组不同的 (FPR, TPR) 坐标点,这些坐标点构成了ROC曲线。ROC曲线的横轴是FPR,纵轴是TPR。在ROC空间中左下角的点(0, 0)表示模型总是预测为负样本;右上角的点(1, 1)表示模型总是预测为正样本。一般情况下,ROC曲线越靠近左上角,代表模型的性能越好。

#库的导入
from sklearn.metrics import roc_curve# roc曲线模块

fpr, tpr, thresholds = roc_curve(y_test, lr.decision_function(X_test))#计算 roc 曲线所需的假正例率(FPR)、真正例率(TPR)和阈值(thresholds),roc_curve参数传入了真实的目标变量 y_test 和逻辑回归模型 lr 对测试集 X_test 的决策函数的值。

close_zero = np.argmin(np.abs(thresholds))# 将阈值取绝对值,返回最小值的索引

plt.plot(fpr,tpr,label="roc_curve")# x轴为fpr,y轴为tpr,线标签为roc_curve
plt.plot(fpr[close_zero],tpr[close_zero],'o',markersize=10, label="threshold zero", fillstyle="none", c='k', mew=2)# 最接近0的阈值
plt.title('LR ROC')# 标题设置
plt.xlabel('False Positive Rate')# x轴名称设置
plt.ylabel('True Positive Rate')# y轴名称设置
plt.legend(loc=4)# 图例设置

在这里插入图片描述

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐