在对数据进行清洗后下一步就是使用处理好的数据采用某种预测模型进行建模,在建模后我门还需要对模型做进一步的评估
采用的数据为清洗后的泰坦尼克号数据集,和原始的数据相比有如下几点变动
“”"
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=pd.read_csv(r'E:\数据分析\clear_data.csv')
data.head()
scikit-learn 是基于 Python 语言的开源的机器学习工具,是一种简单高效的数据挖掘和数据分析工具,可建立在 NumPy ,SciPy 和 matplotlib 上
sklearn 中文文档:http://www.scikitlearn.com.cn/
划分数据集的方法有多种
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
【思考】:什么情况下切割数据集的时候不用进行随机选取
答:在数据集本身已经是随机处理之后的,或者说数据集非常大,内部已经足够随机
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或不设置,每次划分的都不一样。 |
【注】此外k折交叉验证也可以用于划分数据集
根据sklearn算法路径可以使用的算法有多种,此处以逻辑回归和随机森林为例进行训练
逻辑回归不是回归模型而是分类模型该模型利用函数, logistic function 将单次试验的可能结果输出为概率
scikit-learn 中 logistic 回归在 LogisticRegression
类中实现了二分类(binary)、一对多分类(one-vs-rest)及多项式 logistic 回归,并带有可选的 L1 和 L2 正则化,且默认为L2正则化即
在scikit-learn可以通过将C设置为很大的值实现无正则化。
对于多分类的问题,可以利用逻辑回归训练多个分类器,把其中一个当做一类,其他的作为一类
逻辑回归介绍、相关参数集使用见: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)))
好像结果也不咋地,通过调整正则化参数已经没法去提升预测精度了,考虑换一种预测方法
随机森林法所在模块为sklearn.ensemble
,该模块集成了多种方法
随机森林是一个包含多个决策树的分类器, 并且其输出的类别是由个别树输出的类别的众数而定,随机森林的过程为
随机森林相关参数见:随机森林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)))
调参后虽然训练集的值下降了,但是测试集增加了,说明还是有效的
一般监督模型在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的概率,哪个概率大,最后就把预测目标归到哪一类
模型评估是为了知道模型的泛化能力,在这里还是用的上面的基于逻辑回归的预测结果
交叉验证在sklearn中的模块为sklearn.model_selection
,交叉验证的方式有多种
(1)没指定数据切分方式,直接选用cross_val_score按默认切分方式进行交叉验证评估得分,如下图
(2)k-折交叉验证 。 k-折交叉验证将训练集划分为 k 个较小的集合(其他方法会在下面描述,主要原则基本相同)。 每一个 k 折都会遵循下面的过程:
k-折交叉验证得出的性能指标是循环计算中每个值的平均值。 该方法虽然计算代价很高,但是它不会浪费太多的数据(如固定任意测试集的情况一样), 在处理样本数据集较少的问题(例如,逆向推理)时比较有优势。
(3)此外还有留一交叉验证LeaveOneOut、乱序分割交叉验证ShuffleSplit、数据与分组交叉验证GroupKFold
其他交叉验证方法详见:Python机器学习库sklearn网格搜索与交叉验证
***
任务一
基于逻辑回归进行k折交叉验证
***
#进行交叉验证
from sklearn.model_selection import cross_val_score
lr=LogisticRegression(C=100)
scores=cross_val_score(lr,X_train,y_train,cv=10)
#k折交叉验证分数
scores
#平均交叉验证次数
print('平均交叉验证分数为:{:.2f}'.format(scores.mean()))
【思考】k折越多的情况下会带来什么样的影响
考虑极端情况,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)
【注意】
在不同的应用场景下,我们的关注点不同,例如,在预测股票的时候,我们更关心精准率
,即我们预测升的那些股票里,真的升了有多少,因为那些我们预测升的股票都是我们投钱的。而在预测病患的场景下,我们更关注召回率
,即真的患病的那些人里我们预测错了情况应该越少越好,因为真的患病如果没有检测出来,结果其实是很严重的,之前那个无脑的算法,召回率就是 0。
精准率和召回率是此消彼长
的,即精准率高了,召回率就下降,在一些场景下要兼顾精准率和召回率,就有 F1 score。
FPR(假正率)+TNR(真负率)=1;FNR(假负率)+TPR(真正率)=1
求出真正率/召回率和真负率/特异度,就可以得到假正率和假负率。
sklearn中的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 | 若真,评估结果以字典形式返回返回字符串或者字典 |
精确度:precision
召回率: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))
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 | 正样本的标签。 |
roc_curve() 函数有3个返回值:假阳率FPR、真阳率TPR、阈值thresholds
阈值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)
AUC(Area Under Curve)就是ROC曲线下的面积大小,它能够量化地反映基于ROC曲线衡量出的模型性能。AUC的取值一般在0.5和1之间,AUC越大越好
,说明分类器越可能把实际为正的样本排在实际为负的样本的前面,即正确做出预测。