库的作用的了解
- numpy:多用于科学计算中存储和处理大型矩阵,是数据科学实践中最常用的模块
- pandas:数据处理模块,之前数据读入,检查重复、缺失值,分组聚合等一系列的数据预处理都是基于该库
- matplotlib:绘图模块,上一个任务数据可视化就基于该库完成
- seaborn:绘图模块,基于Matplotlib的数据可视化库,提供了一个高级界面,用于绘制引人入胜且内容丰富的统计图形
切分训练集和数据集
- 划分数据集的方法
留出法,即本文采用的方法。具体做法是将数据集分成两个互斥的集合,其中一个作为训练集,另一个作为测试集。
-
交叉验证法:具体做法是将数据集划分成k个大小相似的互斥子集,每次用k-1个子集的并集作为训练集,余下的作为测试集,进行k次训练和测试,最终返回的是这k个训练结果的均值。
自助法:即有放回抽样,每次进行有放回抽样抽取和数据集数据量大小相同的样本。
- 分层抽样
使得训练集/测试集保持数据分布的一致性,避免因为数据划分过程引入额外的偏差而对最终结果产生影响。而封层抽样则是能够保留类别比例的采样方式,所以采用分层抽样。
*思考: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分类、决策树、集成学习、支持向量机、朴素贝叶斯、神经网络等。
- 此外,数据量的大小也影响着选择的具体算法。
模型评估
模型评估的目的是为了知道模型的泛化能力。模型评估的常用方法有:错误率与精度、查准率查全率与F1、ROC曲线和AUC.
混淆矩阵:混淆矩阵是用来总结一个分类器结果的矩阵,对于k元分类,它就是一个k*k的表格,用来记录分类器的预测结果。对于最常见的二元分类来说,混淆矩阵是2*2的,如下TP=True positive=真阳性,FP=False Positive=假阳性,FN=False Negative=假阴性,TN=True Negative=真阴性。就是下面的图。主要是用于分类任务。
查准率/准确率precesion:度量被预测为正例的样本中有多少是真正的正例。其计算公式为
查全率/召回率recall:度量的是正类样本中有多少被预测为正类。其计算公式为
一般来说,查准率高时,查全率往往偏低,查全率高时,查准率往往偏低,即两者是一对矛盾。
F1:基于查准率与查全率的调和平均。其计算公式为
ROC曲线:Receiver Operating Characteristic即受试者工作特征又称感受性曲线sesitivity curve。得名的原因在于曲线上各点反映着相同的感受性,它们都是对同一信号刺激的反应,只不过是在集中不同的判定标准下所得的结果而已。
ROC曲线也是根据混淆矩阵获得,纵轴是真正例率,即,横轴是假正例率,即.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)
# 导入需要的库
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)