通过前两章的学习,我们目前拥有的是经过清洗后的泰坦尼克号的数据集,那么我们这次的目的就是,完成泰坦尼克号存活预测这个任务。
载入我们提供清洗之后的数据(clear_data.csv),大家也将原始数据载入(train.csv),说说他们有什么不同
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from IPython.display import Image
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
data = pd.read_csv('clear_data.csv')
data
不同在于:清洗之后的数据更简洁,而且数据的形式已经被转化为了计算机可以处理的形式。
模型搭建
这里采用的是sklearn库
# sklearn模型算法选择路径图
Image('sklearn.png')
【思考】数据集哪些差异会导致模型在拟合数据是发生变化?
1、样本的数量
2、是否是分类问题
3、是否有已标记的数据
4、如果是分类问题,类别数目是否已知
5、是否是数量预测问题
6、数据是否只有少量的重要特征
7、是否要做结构分析
这里使用留出法划分数据集
思考
#写入代码
from sklearn.model_selection import train_test_split
# 一般先取出X和y后再切割,有些情况会使用到未切割的
X=data
y=train['Survived']
# 对数据集进行切割
X_train,X_test,y_train,y_test=train_test_split(X,y,stratify=y,random_state=0)#stratify=y表示对y进行分层
# 查看数据形状
X_train.shape,X_test.shape
【思考】
数据之间差别特别大的时候就不可以进行随机选取,否则会导致数据的预测存在重大误差
模型一:逻辑回归
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
# 默认参数逻辑回归模型
lr=LogisticRegression()
lr.fit(X_train,y_train)
# 查看训练集和测试集score值
print("Testing set score: {:.2f}".format(lr.score(X_train, y_train)))
print("testing set score:{:.2f}".format(lr.score(X_test,y_test)))
# 调整参数后的逻辑回归模型
#C:float 默认:1.0 正则化强度, 与支持向量机一样,较小的值指定更强的正则化。
lr2=LogisticRegression(C=100)
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)))
模型二:随机森林
随机森林本质上是许多以不同方式过拟合的决策树的集合,我们可以对这些互不相同的树的结果取平均值来降低过拟合,这样既能减少过拟合又能保持树的预测能力。
构造随机森林的步骤:
①确定用于构造的树的个数
②对数据进行自助采样
③基于新数据集构造决策树
n_estimators是构造的决策树的数量,n_estimators越大越好,但占用的内存与训练和预测的时间也会相应增长,且边际效益是递减的,所以要在可承受的内存/时间内选取尽可能大的n_estimators。而在sklearn中,n_estimators默认为10。
选取的特征子集中特征的个数通过max_features参数来控制,max_features越小,随机森林中的树就越不相同,但过小(取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=100, max_depth=5)
rfc2.fit(X_train, y_train)
# 查看训练集和测试集score值
print("Training set score: {:.2f}".format(rfc2.score(X_train, y_train)))
print("Testing set score: {:.2f}".format(rfc2.score(X_test, y_test)))
【思考】
线性回归是可以用来做分类任务的,只需要对结果设置一个阈值就可以进行分类。
对于多分类的问题,可以利用逻辑回归训练多个分类器,把其中一个当做一类,其他的作为一类
pred=lr.predict(X_train)
pred[:10]
pred_proba=lr.predict_proba(X_train)
pred_proba[:10]
思考:预测标签的概率对我们有什么帮助
可以让我们知道分类前的预测情况,并借此可以根据我们的需要改变分类的阈值
Image('Snipaste_2020-01-05_16-37-56.png')
from sklearn.model_selection import cross_val_score
lr = LogisticRegression(C=100)
scores=cross_val_score(lr,X_train,y_train,cv=10)
scores
print("Average cross-validation score: {:.2f}".format(scores.mean()))
思考
数据有限,单一的把数据都用来做训练模型,容易导致过拟合。(反过来,如果数据足够多,完全可以不使用交叉验证。)较小的k值会导致可用于建模的数据量太小,所以小数据集的交叉验证结果需要格外注意,建议选择较大的k值.但较大的k值也意味着将耗用更多的内存和时间,所以原则上我们经常选择k值为10
【思考】什么是二分类问题的混淆矩阵,理解这个概念,知道它主要是运算到什么任务中的
混淆矩阵就是将预测的情况和实际情况结合在一起,总共有四种情况,分别为预测真-实际真,预测真-实际假,预测假-实际真,预测假-实际假,混淆矩阵经常用于评价模型预测结果的精确度。
Image('Snipaste_2020-01-05_16-38-26.png')
#提示:准确率 (Accuracy),精确度(Precision),Recall,f-分数计算方法
Image('Snipaste_2020-01-05_16-39-27.png')
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)
from sklearn.metrics import classification_report
print(classification_report(y_train, pred))
思考:
要确保你设置的混淆矩阵具有现实意义。
思考:什么是OCR曲线,OCR曲线的存在是为了解决什么问题?
ROC的全名叫做Receiver Operating Characteristic,中文名字叫“受试者工作特征曲线”,其主要分析工具是一个画在二维平面上的曲线——ROC 曲线。
平面的横坐标是false positive rate(FPR),纵坐标是true positive rate(TPR)。对某个分类器而言,我们可以根据其在测试样本上的表现得到一个TPR和FPR点对。这样,此分类器就可以映射成ROC平面上的一个点。顾名思义,AUC的值就是处于ROC 曲线下方的那部分面积的大小。通常,AUC的值介于0.5到1.0之间,较大的AUC代表了较好的性能。AUC(Area Under roc Curve)是一种用来度量分类模型好坏的一个标准。
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曲线的获取主要有两种方法:
假设测试样本个数为m,类别个数为n。在训练完成后,计算出每个测试样本的在各类别下的概率或置信度,得到一个[m, n]形状的矩阵P,每一行表示一个测试样本在各类别下概率值(按类别标签排序)。相应地,将每个测试样本的标签转换为类似二进制的形式,每个位置用来标记是否属于对应的类别(也按标签排序,这样才和前面对应),由此也可以获得一个[m, n]的标签矩阵L。
①方法一:每种类别下,都可以得到m个测试样本为该类别的概率(矩阵P中的列)。所以,根据概率矩阵P和标签矩阵L中对应的每一列,可以计算出各个阈值下的假正例率(FPR)和真正例率(TPR),从而绘制出一条ROC曲线。这样总共可以绘制出n条ROC曲线。最后对n条ROC曲线取平均,即可得到最终的ROC曲线。
②方法二:
首先,对于一个测试样本:1)标签只由0和1组成,1的位置表明了它的类别(可对应二分类问题中的‘’正’’),0就表示其他类别(‘’负‘’);2)要是分类器对该测试样本分类正确,则该样本标签中1对应的位置在概率矩阵P中的值是大于0对应的位置的概率值的。基于这两点,将标签矩阵L和概率矩阵P分别按行展开,转置后形成两列,这就得到了一个二分类的结果。所以,此方法经过计算后可以直接得到最终的ROC曲线。
【思考】你能从这条OCR曲线的到什么信息?这些信息可以做什么?
roc曲线下方的面积明显大于0.5,我们可以得知该模型的分类结果很好。