第三章
第一节 建立模型
任务:完成泰坦尼克号的存活预测
复习:
库的作用;
matplotlib-绘图,开源MatLab;seaborn-基于Python,在matplotlib的基础上进行了更高一级的封装,作图更方便;
数据清洗的结果
清洗后数据和原数据的不同:shape不一样;没有survived(结果值)、name(无关变量)两栏;文本数据都转变为数值数据;。
模型选择
首先需要知道是监督学习还是无监督学习。
- 监督学习:对数据进行标记,据此进行训练
- 无监督学习:用未经标记和分类的数据进行训练
清洗后的数据不含survived标签,不适合监督学习。
还可以根据数据样本量及特征的稀疏性来决定。
一般都是选取多个模型,对比决定采用哪个模型用于最终训练。
数据集的哪些差异会导致模型在拟合数据时发生变化?
- 异常值:若不除去,会使模型的复杂度增加;需要判断是否拟合(有的可以直接去除,有的要做异常挖掘)
切割数据集
训练集+测试集
-
留出法
- 将数据集分为自变量和因变量;
- 按比例分割训练集和测试集
- 使用分层采样
- 设置随机数种子(此处为数据分割时的随机种子)以便结果能复现
from sklearn.model_selection import train_test_split # 使用 train_test_split? 来查看函数使用文档 # 参数 # arrays: 被分隔的自变量和因变量的长度需要相同,需要一一对应 # train_size、train_size:训练集和测试集的样本大小(?若为浮点数,表示占比;若为int,表示实际数量) # random_state:随机种子。如何每次填的数值相同,则每次模型训练中使用的随机数组就是相同的。保证实验可重复。 # shuffle:是否先打乱数据的顺序再进行划分。(默认会先打乱) # stratify:表示按某一列进行分层采样
X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, random_state=42) # 默认测试集选取总数据量的25%
-
交叉验证法
-
自助法
模型创建
-
创建基于线性模型的分类模型(逻辑回归)
-
创建基于树的分类模型(决策树、随机森林)
-
分别使用这些模型进行训练,分别得到训练集和测试集的得分
-
查看模型的参数,并更改参数值,观察模型变化
-
逻辑回归不是回归模型而是分类模型,不要与
LinearRegression
(线性回归)混淆逻辑回归是分类模型,常用于二分类。
-
随机森林其实是决策树集成为了降低决策树过拟合的情况
随机森林属于继承学习中的Bagging方法。
随机森林是由很多决策树构成的,不同决策树之间没有关联。
当我们进行分类任务时,新的输入样本进入,就让森林中的每一棵决策树分别进行判断和分类,每个决策树会得到一个自己的分类结果,决策树的分类结果中哪一个分类最多,那么随机森林就会把这个结果当做最终的结果。
随机森林其实是决策树集成为了降低决策树过拟合的情况
-
线性模型所在的模块为
sklearn.linear_model
-
树模型所在的模块为
sklearn.ensemble
# 导入库
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
fit(X, y, sample_weight=None)
根据给定的数据去拟合模型。
- sample_weight:样本权重。假定存在二分类样本数据,正样本有95条,负样本5条。这种情况称为样本失衡,此时需要提高负样本的权重。
predict(X)
:使用fit()
训练之后,使用predict()
进行预测。对给定的
predict_proba(X)
:用于概率估计,返回样本为某个标签的概率
score(X, y, sample_weight=None)
:根据X和y返回平均准确度。即将预测的结果与真实的标签值进行对比,计算平均准确度。
-
创建逻辑回归模型
# clf = LogisticRegression().fit(X_train, y_train) # clf:classifier,分类器 lr = LogisticRegression().fit(X_train, y_train) # lr:logistic regression,逻辑回归 # 创建一个LogisticRegression模型,并将数据集放入训练。将返回一个逻辑回归的模型
lr.score(X_train, y_train) # 0.7994011976047904(得分情况) print('训练集得分:{:.3f}'.format(lr.score(X_train, y_train))) # 训练集得分:0.799 print('测试集得分:{:.3f}'.format(lr.score(X_test, y_test))) # 测试集得分:0.771
score()
的参数:penalty
:正则化,解决过拟合问题。限制模型的复杂度。常用l1
、l2
两种方法。dual
:只适用于l2
的惩罚项上使用,当样本数量大于特征数量时设置为False。tol
:迭代停止的条件,默认小于0.0001时停止迭代。C
:默认为1.0,正则化系数的倒数,越小,正则化效果越强,越能限制模型的复杂度。class_weight
:类别权重,跟sample_weight
差不多。-
设置参数
C
# 限制为简单模型 lr1 = LogisticRegression(C=0.01).fit(X_train, y_train) # C=0.01 print('训练集得分:{:.3f}'.format(lr1.score(X_train, y_train))) # 训练集得分:0.759 print('测试集得分:{:.3f}'.format(lr1.score(X_test, y_test))) # 测试集得分:0.717 # 两个得分都降低,说明模型变得简单,欠拟合
# 提高模型复杂度 lr2 = LogisticRegression(C=1000).fit(X_train, y_train) # C=1000 print('训练集得分:{:.3f}'.format(lr2.score(X_train, y_train))) # 训练集得分:0.802 print('测试集得分:{:.3f}'.format(lr2.score(X_test, y_test))) # 测试集得分:0.776
-
设置
class_weight
lr3 = LogisticRegression(class_weight='balanced').fit(X_train, y_train) # class_weight='balanced'
-
-
创建树的模型(随机森林 Random Forest)
分类器,包含多个决策树的分类器
使用多个决策树进行分类,然后使用平均值提高决策的精度。可以提高噪声处理方面的稳定性。
rf = RandomForestClassifier().fit(X_train, y_train) print('训练集得分:{:.3f}'.format(rf.score(X_train, y_train))) # 训练集得分:1.000 print('测试集得分:{:.3f}'.format(rf.score(X_test, y_test))) # 测试集得分:0.789
n_estimators:森林中树的数量,默认为100。数量太少,欠拟合;数量过多,性能不佳。
max_depth:最大深度,默认是None,不设置,每个叶节点只有一个分类类别。若特征过多,建议进行限制。
min_sample_split:内部节点默认的最小可分数。默认为2。
bootstrap:是否对数据集进行放回抽样来构建决策树,默认放回。
obb_score:袋外数据的影响。当使用bootstrap方法时,会将没有被用到的数据用于评估。
-
n_estimators
rf = RandomForestClassifier(n_estimators=5).fit(X_train, y_train) # 分数降低 rf = RandomForestClassifier(n_estimators=1000).fit(X_train, y_train) # 分数略提升,但计算速度降低很多
-
max_depth
rf = RandomForestClassifier(max_depth=5).fit(X_train, y_train) # 训练集得分有显著下降
-
bootstrap
rf = RandomForestClassifier(bootstrap=False).fit(X_train, y_train) # 分数降低,而且性能不稳定
-
-
输出模型预测结果
- 输出模型预测分类标签
- 输出不同分类标签的概率预测
- predict()、predict_proba()
# lr 逻辑回归模型 lr.predict(X_train)
lr.predict_proba(X_train) # 对于第一个乘客,其被预测为死亡的概率为0.08,被预测为存活的概率为0.91. # 综合其预测结果,最终被预测为存活。
第二节 模型评估
- 模型评估是为了知道模型的泛化能力。
- 交叉验证(cross-validation)是一种评估泛化性能的统计学方法,它比单次划分训练集和测试集的方法更加稳定、全面。
- 在交叉验证中,数据被多次划分,并且需要训练多个模型。
- 最常用的交叉验证是 k 折交叉验证(k-fold cross-validation),其中 k 是由用户指定的数字,通常取 5 或 10。
- 准确率(precision)度量的是被预测为正例的样本中有多少是真正的正例
- 召回率(recall)度量的是正类样本中有多少被预测为正类
- f-分数是准确率与召回率的调和平均
-
交叉验证
- k 折交叉验证,一般 k 取5-10
- 提高模型的泛化能力
sklearn.model.cross_val_score
estimator
X
y
scoring:指定评分标准
cv:交叉验证的数据集如何划分,默认为 5 折交叉验证(cv=5)
lr = LogisticRegression() score = cross_val_score(lr, X_train, y_train, cv=10) score.mean() # 0.797
-
混淆矩阵(二元分类)
-
混淆矩阵(误差矩阵)
-
探讨使用什么方法评价矩阵
-
准确率(precision)度量的是被预测为正例的样本中有多少是真正的正例
-
召回率(recall)度量的是正类样本中有多少被预测为正类
**对于多分类问题,**其核心思想是将多分类问题转化为二分类问题,然后分别评估其性能。
-
混淆矩阵需要输入真实标签和预测标签
from sklearn.metrics import confusion_matrix # 训练模型 lr = LogisticRegression(C=100) lr.fit(X_train, y_train) # 模型预测结果 pred = lr.predict(X_train) # 混淆矩阵 confusion_matrix(y_train, pred) # 混淆矩阵需要输入真实标签和预测标签 # array([[354, 58],[ 83, 173]]) from sklearn.metrics import classification_report # 精确率、召回率以及f1-score print(classification_report(y_train, pred))
-
-
ROC曲线
接收者操作特征(
receiveroperating characteristic
), ROC曲线上每个点反映着对同一信号刺激的感受性。- ROC曲线在sklearn中的模块为
sklearn.metrics
- ROC曲线下面所包围的面积越大越好
from sklearn.metrics import roc_curve 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)
- ROC曲线在sklearn中的模块为
the end.