【数据分析入门】Task 05 数据建模及模型评估
- 第三章 模型搭建和评估
-
- 3.1 模型搭建
-
- 3.1.1 数据导入及介绍
- 3.1.2 模型搭建
-
- 3.1.2.1 概述
- 3.1.2.2 sklearn的算法选择路径
- 3.1.2.3划分训练集和测试集
-
- (1)train_test_split方法
- (2)ShuffleSplit方法
- 3.1.2.4 模型创建
-
- (1)逻辑回归法
- (2)随机森林法
- 3.1.3输出模型预测结果
- 3.2 模型评估
-
- 3.2.1 交叉验证
- 3.2.2 混淆矩阵
- 3.2.3 准确度、精确度、召回率和F1值等
- 3.2.4 ROC曲线
- 3.2.5 AUC
第三章 模型搭建和评估 3.1 模型搭建 在对数据进行清洗后下一步就是使用处理好的数据采用某种预测模型进行建模,在建模后我门还需要对模型做进一步的评估
3.1.1 数据导入及介绍
采用的数据为清洗后的泰坦尼克号数据集,和原始的数据相比有如下几点变动
- 清洗后的数据集为11列,原数据位12列
- 少了姓名(对于预测是否存活没啥用用)、票的详细信息(对于预测是否存活没啥用用)、舱位等级(缺失太多,直接不要了)
- 性别、出发地用独立热编码表示
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from IPython.display import Image
%matplotlib inline
"""
ipython是一个python的交互式shell,比默认的python shell好用得多
,支持变量自动补全,自动缩进,支持bash shell命令,内置了许多很有
用的功能和函数。ipython将能够使我们以一种更高的效率来使用python。
同时它也是利用Python进行科学计算和交互可视化的一个最佳的平台在这里主要使用IPython来导入图片,例如:Image('sklearn.png')
"""
#Matplotlib中plt.rcParams用于设置图像细节
#更多设置见https://www.cnblogs.com/douzujun/p/10327963.html
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签,SimHei为黑体,也可以设置为其他字体
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
plt.rcParams['figure.figsize']=(10,6)#设置图片大小
#载入清洗后的数据集
data=https://www.it610.com/article/pd.read_csv(r'E:\数据分析\clear_data.csv')
data.head()
文章图片
3.1.2 模型搭建
3.1.2.1 概述
- 处理完前面的数据我们就得到建模数据,下一步是选择合适模型
- 在进行模型选择之前我们需要先知道数据集最终是进行监督学习还是无监督学习
- 模型的选择一方面是通过我们的任务来决定的。
- 除了根据我们任务来选择模型外,还可以根据数据样本量以及特征的稀疏性来决定
- 刚开始我们总是先尝试使用一个基本的模型来作为其baseline,进而再训练其他模型做对比,最终选择泛化能力或性能比较好的模型
sklearn 中文文档:http://www.scikitlearn.com.cn/
文章图片
3.1.2.3划分训练集和测试集 划分数据集的方法有多种
(1)train_test_split方法
train_test_split
是交叉验证中常用的函数,功能是从样本中随机的按比例选取训练集和测试集,需要导入包from sklearn.model_selection import train_test_split
使用方法:
X_train, X_test, y_train, y_test = train_test_split(features, result, test_size = 0.2, random_state = 0,stratify = result)
参数 | 作用 |
---|---|
train_data | 所要划分的样本特征集 |
train_target | 所要划分的样本结果 |
test_size | 样本占比,如果是整数的话就是样本的数量 |
random_state | 随机数的种子,即该组随机数的编号,在需要重复试验的时候,通过设置该参数保证得到一组一样的随机数,不填的话默认值为False,这个时候虽然每次切分的比例虽然相同,但是切分的结果不同 |
stratify | 保持测试集与整个数据集里result的数据分类比例一致,比如result中有0.3属于A类,0.7属于B类,那么切分数据集的时候,数据集例分类比例也是这样的 |
***
任务一
使用train_test_split所给数据集的切割训练集和测试集
***
#调用相关模块
from sklearn.model_selection import train_test_split# 一般先取出X和y后再切割,有些情况会使用到未切割的,这时候X和y就可以用,x是清洗好的数据,y是我们要预测的存活数据'Survived'
X = data
y = train['Survived']#对数据集进行切割
X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, random_state=0)# 查看数据形状
X_train.shape, X_test.shape
文章图片
【思考】:什么情况下切割数据集的时候不用进行随机选取(2)ShuffleSplit方法
答:在数据集本身已经是随机处理之后的,或者说数据集非常大,内部已经足够随机
sklearn.model_selection.ShuffleSplit
类用于将样本集合随机“打散”后划分为训练集、测试集,使用时需要导入包from sklearn.model_selection import ShuffleSplit
使用方法
ShuffleSplit(n_splits=10,test_size=’default’, train_size=None, random_state=None)
参数 | 作用 |
---|---|
n_splits | 代表划分训练集、测试集的次数,默认为10 |
test_size | 测试集占总数据集的比例,默认为0.1 |
train_size | 训练集占总数据集的比例,默认为None,表示总体数据集除去测试集的部分 |
random_state | (其他参数都相同时)只有设为1时,每次运行时划分的测试集与训练集都一样;设为0或不设置,每次划分的都不一样。 |
3.1.2.4 模型创建 根据sklearn算法路径可以使用的算法有多种,此处以逻辑回归和随机森林为例进行训练
(1)逻辑回归法 逻辑回归不是回归模型而是分类模型该模型利用函数, logistic function 将单次试验的可能结果输出为概率
scikit-learn 中 logistic 回归在
LogisticRegression
类中实现了二分类(binary)、一对多分类(one-vs-rest)及多项式 logistic 回归,并带有可选的 L1 和 L2 正则化,且默认为L2正则化即 文章图片
在scikit-learn可以通过将C设置为很大的值实现无正则化。
对于多分类的问题,可以利用逻辑回归训练多个分类器,把其中一个当做一类,其他的作为一类
文章图片
【【数据分析入门】Task 05 数据建模及模型评估】逻辑回归介绍、相关参数集使用见:https://www.cnblogs.com/sddai/p/9571305.html
***
任务二
使用逻辑回归模型对数据集进行预测
***
##使用默认参数的逻辑回归模型
#从sklearn中的linear_model模块调用逻辑回归模型
from sklearn.linear_model import LogisticRegression#默认参数逻辑回归模型
lr=LogisticRegression()
lr.fit(X_train,y_train)
###输出的记过便是逻辑回归的各项参数详情,可以看到此时C=1
文章图片
#查看训练集和测试集的score值,score值即为该次预测的系数R2
print('训练集的score值为:{:.2f}'.format(lr.score(X_train,y_train)))
print('测试集的score值为:{:.2f}'.format(lr.score(X_test,y_test)))
文章图片
可以看出score值并不高,因此需要对其进行调参,此处采用调整正则化参数的方法
#对逻辑回归模型进行调参
#调整正则化参数 正则化是一种为了减小测试误差的行为(有时候会增加训练误差)
lr2=LogisticRegression(C=100)
lr2.fit(X_train,y_train)print('训练集的score值为:{:.2f}'.format(lr2.score(X_train,y_train)))
print('测试集的score值为:{:.2f}'.format(lr2.score(X_test,y_test)))
好像结果也不咋地,通过调整正则化参数已经没法去提升预测精度了,考虑换一种预测方法
文章图片
(2)随机森林法 随机森林法所在模块为
sklearn.ensemble
,该模块集成了多种方法随机森林是一个包含多个决策树的分类器, 并且其输出的类别是由个别树输出的类别的众数而定,随机森林的过程为
- 用N来表示训练用例(样本)的个数,M表示特征数目。
- 输入特征数目m,用于确定决策树上一个节点的决策结果;其中m应远小于M。
- 从N个训练用例(样本)中以有放回抽样的方式,取样N次,形成一个训练集(即bootstrap取样),并用未抽到的用例(样本)作预测,评估其误差。
- 对于每一个节点,随机选择m个特征,决策树上每个节点的决定都是基于这些特征确定的。根据这m个特征,计算其最佳的分裂方式。
- 每棵树都会完整成长而不会剪枝,这有可能在建完一棵正常树状分类器后会被采用)。
文章图片
随机森林相关参数见:随机森林sklearn FandomForest,及其调参
***
任务三
使用随机森林模型对数据集进行预测
***
#从sklearn中的ensembel模块中调用
from sklearn.ensemble import RandomForestClassifier#默认参数的随机森林分类模型
rfc=RandomForestClassifier()
rfc.fit(X_train,y_train)
文章图片
print('训练集的score值为:{:.2f}'.format(rfc.score(X_train,y_train)))
print('测试集的score值为:{:.2f}'.format(rfc.score(X_test,y_test)))
训练集结果很高甚至接近于1了,但是测试集一般,说明产生了过拟合,因此需要剪枝
文章图片
#调整参数后的随机森林分类模型
#max_depth设置树的最大深度,超过的会被删除
#这是森林中树木的数量,即基评估器的数量。这个参数对随机森林模型的精确性影响是单调的,n_estimators越大,模型的效果往往越好
rfc2 = RandomForestClassifier(n_estimators=100, max_depth=5)
rfc2.fit(X_train, y_train)print('训练集的score值为:{:.2f}'.format(rfc2.score(X_train,y_train)))
print('测试集的score值为:{:.2f}'.format(rfc2.score(X_test,y_test)))
调参后虽然训练集的值下降了,但是测试集增加了,说明还是有效的
文章图片
3.1.3输出模型预测结果
一般监督模型在sklearn里面有个predict能输出预测标签,predict_proba则可以输出标签概率
***
任务四
输出逻辑回归模型预测结果
***
#输出预测标签,针对这个例子就是0或者1
pred=lr.predict(X_train)#输出前十个预测
pred[:10]
文章图片
#预测标签的概率,即为0或为1的概率
pred_proba=lr.predict_proba(X_train)#输出前10个
pred_proba[:10]
也就是0和1的概率,如果左边是0的概率,右边是1的概率,哪个概率大,最后就把预测目标归到哪一类
文章图片
3.2 模型评估 模型评估是为了知道模型的泛化能力,在这里还是用的上面的基于逻辑回归的预测结果
3.2.1 交叉验证
交叉验证在sklearn中的模块为
sklearn.model_selection
,交叉验证的方式有多种(1)没指定数据切分方式,直接选用cross_val_score按默认切分方式进行交叉验证评估得分,如下图
文章图片
(2)k-折交叉验证 。 k-折交叉验证将训练集划分为 k 个较小的集合(其他方法会在下面描述,主要原则基本相同)。 每一个 k 折都会遵循下面的过程:
- 将 k-1 份训练集子集作为 training data (训练集)训练模型,
- 将剩余的 1 份训练集子集用于模型验证(也就是把它当做一个测试集来计算模型的性能指标,例如准确率)。
(3)此外还有留一交叉验证LeaveOneOut、乱序分割交叉验证ShuffleSplit、数据与分组交叉验证GroupKFold
其他交叉验证方法详见:Python机器学习库sklearn网格搜索与交叉验证
***
任务一
基于逻辑回归进行k折交叉验证
***
#进行交叉验证
from sklearn.model_selection import cross_val_scorelr=LogisticRegression(C=100)
scores=cross_val_score(lr,X_train,y_train,cv=10)#k折交叉验证分数
scores
文章图片
#平均交叉验证次数
print('平均交叉验证分数为:{:.2f}'.format(scores.mean()))
文章图片
【思考】k折越多的情况下会带来什么样的影响3.2.2 混淆矩阵
考虑极端情况,k等于需要预测的数据的个数,这样k折就实效了
混淆矩阵也称误差矩阵,是表示精度评价的一种标准格式,用n行n列的矩阵形式来表示。具体评价指标有总体精度、制图精度、用户精度等,这些精度指标从不同的侧面反映了图像分类的精度。 在人工智能中,混淆矩阵(confusion matrix)是可视化工具,特别用于监督学习,在无监督学习一般叫做匹配矩阵。在图像精度评价中,主要用于比较分类结果和实际测得值,可以把分类结果的精度显示在一个混淆矩阵里面。混淆矩阵是通过将每个实测像元的位置和分类与分类图像中的相应位置和分类相比较计算的
二分类的混淆矩阵
文章图片
True Positive (真正, TP)被模型预测为正的正样本;
True Negative(真负 , TN)被模型预测为负的负样本 ;
False Positive (假正, FP)被模型预测为正的负样本;
False Negative(假负 , FN)被模型预测为负的正样本;
使用方法:
sklearn.metrics.confusion_matrix(y_true, y_pred, labels=None, sample_weight=None)
#y_true:是样本真实分类结果
#y_pred 是样本预测分类结果
#labels是所给出的类别,通过这个可对类别进行选择 #sample_weight 是样本权重
***
任务二
计算混淆矩阵
***
#导入混淆矩阵模块
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)
文章图片
3.2.3 准确度、精确度、召回率和F1值等
含义 | 公式 | |
---|---|---|
准确度 | 准确度表示分类正确的样本数所占比例 | 文章图片 |
精确度、精度 | 该概念是针对“预测结果”而言的。表示预测为正类的样本中有多少是真的正样本 | 文章图片 |
召回率、真正率TPR | 该概念是针对“原始样本”而言的。表示样本中的正例有多少被分类正确了 | 文章图片 |
F1 score | F1 score 是精准率和召回率的兼顾指标,F1 score 是精准率和召回率的调和平均数,调和平均数的性质就是,只有当精准率和召回率二者都非常高的时候,它们的调和平均才会高。如果其中之一很低,调和平均就会被拉得接近于那个很低的数。 | 文章图片 |
假负率(False Negative Rate)FNR | 假负率用于衡量所有真实为正的样本中,被错误判断为负的 | FNR = FN /(TP + FN) |
真负率、特异度(True Negative Rate)TNR | 特异度(Specificity)表示所有负样本中,被真实预测为负的样本所占的比例 | TNR = TN /(TN + FP) |
假正率(False Positive Rate)FPR | 假负率用于衡量所有真实为负的样本中,被错误判断为正的 | FPR = FP /(FP + TN) |
- 在不同的应用场景下,我们的关注点不同,例如,在预测股票的时候,我们更关心
精准率
,即我们预测升的那些股票里,真的升了有多少,因为那些我们预测升的股票都是我们投钱的。而在预测病患的场景下,我们更关注召回率
,即真的患病的那些人里我们预测错了情况应该越少越好,因为真的患病如果没有检测出来,结果其实是很严重的,之前那个无脑的算法,召回率就是 0。
- 精准率和召回率是
此消彼长
的,即精准率高了,召回率就下降,在一些场景下要兼顾精准率和召回率,就有 F1 score。
- FPR(假正率)+TNR(真负率)=1;FNR(假负率)+TPR(真正率)=1
- 求出真正率/召回率和真负率/特异度,就可以得到假正率和假负率。
classification_report
函数用于显示主要分类指标的文本报告.在报告中显示每个类的精确度,召回率,F1值等信息。使用方法
sklearn.metrics.classification_report(y_true, y_pred, labels=None, target_names=None, sample_weight=None, digits=2, output_dict=False)
参数 | 作用 |
---|---|
y_true | 1 维数组,真实数据的分类标签 |
y_pred | 1 维数组,模型预测的分类标签 |
labels | 列表,需要评估的标签名称 |
target_names | 列表,指定标签名称 |
sample_weight | 1 维数组,不同数据点在评估结果中所占的权重 |
digits | 评估报告中小数点的保留位数,如果 output_dict=True,此参数不起作用,返回的数值不作处理 |
output_dict | 若真,评估结果以字典形式返回返回字符串或者字典 |
召回率:recall
F1-score:精确率和召回率的调和平均数
微平均值:micro average,所有数据结果的平均值
宏平均值:macro average,所有标签结果的平均值
加权平均值:weighted average,所有标签结果的加权平均值
***
任务三
查看精确率、召回率以及f1-score
***
#精确率、召回率以及f-分数可使用classification_report模块
from sklearn.metrics import classification_report
# 精确率、召回率以及f1-score
print(classification_report(y_train,pred))
文章图片
3.2.4 ROC曲线
ROC(Receiver Operating Characteristic Curve)接受者特征曲线,是反应敏感性和特异性连续变量的综合指标,
ROC曲线下面所包围的面积越大越好
ROC曲线的横坐标为假阳性率(FPR);纵坐标为真阳性率(TPR)。在理想情况下,TPR应该越接近1越好,FPR越接近0越好。
在sklearn中
sklearn.metrics.roc_curve()
函数用于绘制ROC曲线,使用前需要调用from sklearn.metrics import roc_curve
模块参数 | 作用 |
---|---|
y_true | 真实的样本标签,默认为{0,1}或者{-1,1}。如果要设置为其它值,则 pos_label 参数要设置为特定值。例如要令样本标签为{1,2},其中2表示正样本,则pos_label=2。 |
y_score | 对每个样本的预测结果。 |
pos_label | 正样本的标签。 |
阈值thresholds为将预测结果scores从大到小排列的结果。这里的thresholds指的是大于等于这个阈值为正类,负责为负类。所以通过改变不同的阈值,预测结果也将发生变化
***
任务五
绘制ROC曲线
***
#导入相关模块
from sklearn.metrics import roc_curve#lr.decision_function(X_test)样本预测结果
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的阈值
# numpy.argmin表示最小值在数组中所在的位置 ,abs返回绝对值
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)
曲线越靠近左上角效果越好
文章图片
3.2.5 AUC
AUC(Area Under Curve)就是ROC曲线下的面积大小,它能够量化地反映基于ROC曲线衡量出的模型性能。AUC的取值一般在0.5和1之间,
AUC越大越好
,说明分类器越可能把实际为正的样本排在实际为负的样本的前面,即正确做出预测。推荐阅读
- python自动化办公|用python实现自动化办公------Excel操作
- 数据库|logstash同步mysql数据至elastic
- 市场调研|全球及中国铸造和夹板产品行业市场规模预测及未来前瞻报告2022-2028年
- 数据分析|竞品分析
- 数据分析|会员数据化运营概论
- 电商运营推广|电商运营数据分析常用分析指标--概述及流量指标
- 数据分析|一文搞懂业务中台、数据中台、AI中台区别及联系
- 市场调研|全球及中国钻杆行业市场需求及投资可行性研究报告2022-2028年
- 数据可视化|Python绘制疫情地图 超简单!