TASL05 模型建立和评估

库的作用的了解

  • numpy:多用于科学计算中存储和处理大型矩阵,是数据科学实践中最常用的模块
  • pandas:数据处理模块,之前数据读入,检查重复、缺失值,分组聚合等一系列的数据预处理都是基于该库
  • matplotlib:绘图模块,上一个任务数据可视化就基于该库完成
  • seaborn:绘图模块,基于Matplotlib的数据可视化库,提供了一个高级界面,用于绘制引人入胜且内容丰富的统计图形

切分训练集和数据集

  • 划分数据集的方法
    • 留出法,即本文采用的方法。具体做法是将数据集分成两个互斥的集合,其中一个作为训练集,另一个作为测试集。

    • 交叉验证法:具体做法是将数据集划分成k个大小相似的互斥子集,每次用k-1个子集的并集作为训练集,余下的作为测试集,进行k次训练和测试,最终返回的是这k个训练结果的均值。


      Snipaste_2020-01-05_16-37-56.png
    • 自助法:即有放回抽样,每次进行有放回抽样抽取和数据集数据量大小相同的样本。

  • 分层抽样
    使得训练集/测试集保持数据分布的一致性,避免因为数据划分过程引入额外的偏差而对最终结果产生影响。而封层抽样则是能够保留类别比例的采样方式,所以采用分层抽样。

*思考:k折交叉验证中, k折越多的情况下会带来什么样的影响?

  • k越大,每折包含的样本数目就越少,那么k-1折的样本数目就越接近于总体。有一个特殊情况就是k=样本数量,则每折都只包含一个样本,所以k-1折的样本就非常接近于初始数据集,那么该方法就比较准确。

  • 但是k越大,在数据集比较大的时候,训练的模型数量就会变多。

  • train_test_split()

x_train,x_test,y_train,y_test = 
sklearn.model_selection.train_test_split(
    train_data,train_target,test_size,
    random_state,stratify)
  • train_data:所要划分的样本特征集,即X
  • train_target:所要划分的样本结果,即y
  • test_size:样本占比,如果是整数的话就是样本的数量
  • random_state:随机数种子
  • stratify:为了保持split前类的分布,即实现分层抽样的作用。strtify=X就是按照X中的比例,stratify=y就是按照y中的比例分配。

模型搭建

  • 首先要根据是否有标签选择有监督学习还是无监督学习,但训练集数据有标签即有Y时则选择有监督学习,否则选择无监督学习。
  • 其次当是有监督学习时要根据Y的类型即离散型或连续型来选择算法类型,是进行回归还是进行分类。一般当Y为离散型数据时则进行分类,连续型数据则进行回归。当是无监督学习时,则根据问题选择聚类、降维或推荐系统等的算法的选择。
  • 最后,回归算法一般包括线性回归、非线性回归、分位数回归、正则化回归等。分类算法一般包括Logistic分类、决策树、集成学习、支持向量机、朴素贝叶斯、神经网络等。
  • 此外,数据量的大小也影响着选择的具体算法。
sklearn.png

模型评估

  • 模型评估的目的是为了知道模型的泛化能力。模型评估的常用方法有:错误率与精度、查准率查全率与F1、ROC曲线和AUC.

  • 混淆矩阵:混淆矩阵是用来总结一个分类器结果的矩阵,对于k元分类,它就是一个k*k的表格,用来记录分类器的预测结果。对于最常见的二元分类来说,混淆矩阵是2*2的,如下TP=True positive=真阳性,FP=False Positive=假阳性,FN=False Negative=假阴性,TN=True Negative=真阴性。就是下面的图。主要是用于分类任务。

Snipaste_2020-01-05_16-38-26.png
  • 查准率/准确率precesion:度量被预测为正例的样本中有多少是真正的正例。其计算公式为P=\frac{TP}{TP+FP}

  • 查全率/召回率recall:度量的是正类样本中有多少被预测为正类。其计算公式为R=\frac{TP}{TP+FN}

  • 一般来说,查准率高时,查全率往往偏低,查全率高时,查准率往往偏低,即两者是一对矛盾。

  • F1:基于查准率与查全率的调和平均。其计算公式为F1=\frac{2\times P \times R}{P+R}

  • ROC曲线:Receiver Operating Characteristic即受试者工作特征又称感受性曲线sesitivity curve。得名的原因在于曲线上各点反映着相同的感受性,它们都是对同一信号刺激的反应,只不过是在集中不同的判定标准下所得的结果而已。

  • ROC曲线也是根据混淆矩阵获得,纵轴是真正例率,即TPR=\frac{TP}{TP+FN},横轴是假正例率,即FPR=\frac{FP}{FP+TN}.ROC曲线下的面积为AUC,该面积越大越好

  • 对于多分类问题如何绘制ROC曲线

    • 每种类别下,都可以得到m个测试样本为该类别的概率。所以根据概率矩阵和标签矩阵中对应的每一列,可以计算出各个阈值下的假正例率和真正例率,从而绘制出一条ROC曲线。这样总共可以绘制出n个(类别个数)ROC曲线,对这n条ROC曲线平均,即可得到最终的ROC曲线。

datawhale例子

数据加载

# 导入需要的库
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
%matplotlib inline
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
plt.rcParams['figure.figsize'] = (10, 6)  # 设置输出图片大小


# 载入数据
# 原始数据载入
train = pd.read_csv('./train.csv')
train
# 清洗之后的数据
clear_data = pd.read_csv('./clear_data.csv')
clear_data
  • 原始数据和清洗后数据的区别
    • PassengerId:清洗之前为1-892,清洗后为0-891
    • Survivie,Name,Ticket,Cabin:这些列没有了
    • Sex:分为两列,并进行了0-1转变,如sex_female列,若=0,则表示性别不是female,且sex_male=1.类似于One-hot编码?
    • Embarked:和Sex进行了类似的操作,只不过因为他有三个水平,所以分成了三列

数据切分

# 将clear_data.csv划分为训练集和测试集
from sklearn.model_selection import train_test_split
# 取出X和y
X = clear_data
y = train['Survived']

# 对数据集进行切割
X_train,X_test,y_train,y_test = train_test_split(X,y,random_state=1,stratify=y)
#查看数据
X_train.shape,X_test.shape
  • 什么情况下切割数据集的时候不用进行随机选取
    • 切割数据集不用进行随机选取:留一法,即Leave-one-off.即将样本集划分使得每个子集只包含一个样本。

模型创建

  • 创建基于线性模型的分类模型(逻辑回归)
  • 创建基于树的分类模型(决策树、随机森林)
  • 分别使用这些模型进行训练,分别的到训练集和测试集的得分
  • 查看模型的参数,并更改参数值,观察模型变化

提示

  • 逻辑回归不是回归模型而是分类模型,不要与LinearRegression混淆
  • 随机森林其实是决策树集成为了降低决策树过拟合的情况
  • 线性模型所在的模块为sklearn.linear_model
  • 树模型所在的模块为sklearn.ensemble
# 加载需要的库:逻辑回归和随机森林
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier

# 逻辑回归:训练集训练
lr = LogisticRegression()
lr.fit(X_train,y_train)
# 查看逻辑回归训练集和测试集score值
print("Training set score: {:.2f}".format(lr.score(X_train, y_train)))
print("Testing set score: {:.2f}".format(lr.score(X_test, y_test)))

# 逻辑回归调参
lr2 = LogisticRegression(penalty='l2',C=)
lr2.fit(X_train,y_train)

print("Training set score: {:.2f}".format(lr2.score(X_train, y_train)))
print("Testing set score: {:.2f}".format(lr2.score(X_test, y_test)))

  • 上述是逻辑回归,其默认参数下训练集score为0.81,测试集score为0.79;调参后训练集score为0.81,测试集score为0.79.

  • 为什么线性模型可以进行分类任务,背后是怎么的数学关系

    • 线性模型进行分类任务:两者的区别在于线性Y是一个从负无穷到正无穷没有限制的数字,而回归则Y则是0-1,所以只需要找到一个单调可微函数将分类任务的真实表级y与线性回归模型的预测值联系起来即可。逻辑回归中该函数就是一个logistic函数,从而将其转变到0-1之间的数
  • 对于多分类问题,线性模型是怎么进行分类的

    • 多分类问题:基本思路就是拆解法,即将多分类任务拆分成若干个二分类任务求解。即先对问题进行拆分,然后为拆出的每个二分类任务训练一个分类器,在测试时,对这些分类器的预测结果进行集成获得最终的多分类结果。
# 随机森林
rfc = RandomForestClassifier()
rfc.fit(X_train,y_train)
# 随机森林评分
print("Training set score: {:.2f}".format(rfc.score(X_train, y_train)))
print("Testing set score: {:.2f}".format(rfc.score(X_test, y_test)))
# 随机森林调参
rfc2 = RandomForestClassifier(n_estimators=500, max_depth=5)
rfc2.fit(X_train, y_train)
print("Training set score: {:.2f}".format(rfc.score(X_train, y_train)))
print("Testing set score: {:.2f}".format(rfc.score(X_test, y_test)))
  • 随机森林:默认参数训练集和测试集score分别为1.00和0.82;调参后训练集和测试集score分别为1.00,0.82。

输出模型预测结果

# 逻辑回归预测
pred = lr.predict(X_train)
pred
# 逻辑回归中属于每个标签的概率
probability = lr.predict_proba(X_train)
  • 属于每个标签的概率,哪个概率大就最终判定属于哪个标签

模型评估

# 交叉验证
from sklearn.model_selection import cross_val_score
lr = LogisticRegression(C=5)
scores = cross_val_score(lr,X_train,y_train,cv=10)   # 10折交叉验证
scores
# 平均交叉验证分数
scores.mean()
  • 10折交叉验证的平均交叉验证分数为:0.80
# 载入需要的库
from sklearn.metrics import confusion_matrix
from sklearn.metrics import classification_report
# 训练模型
lr = LogisticRegression(C=5)
lr.fit(X_train,y_train)
# 模型预测结果
prediction = lr.predict(X_train)
# 混淆矩阵
confusion_matrix(y_train,prediction)
混淆矩阵.jpg
# 导入需要的库
from sklearn.metrics import roc_curve
# 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')
# 找到最接近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曲线.jpg
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容