动手学数据分析5-数据建模及模型评估

数据建模及模型评估

数据分析的目的就是,运用数据结合业务来得到得到或评估我们需要知道的结果。经过前面的学习,我们学会了数据清洗,可视化等操作。下面我们来进行数据建模,搭建一个预测模型或者其他模型,从这个模型的到结果,我们还要分析模型是不是足够的可靠,也就是评估这个模型。

我们利用泰坦尼克号的数据集,来完成泰坦尼克号存活预测任务。

数据建模
# 读取原数据数集
train = pd.read_csv('train.csv')
train.shape

在这里插入图片描述
我们利用前面数据清洗的方法对原始数据进行清洗
去除无用的Name、Ticket、Cabin,对Sex、Emarked进行One-hot编码
因为我们要做的就是对Survived的预测,所以我们清洗的数据是作为数据集特征x,单独提出Survived数据则做为数据集标签
经过清洗我们得到清洗后的数据clear_data.csv(数据清洗方法参见之前的文章略)

# 载入清洗过的数据, 作为数据集特征
data_x = pd.read_csv('clear_data.csv')
data_x

在这里插入图片描述

下一步是选择合适模型
在进行模型选择之前我们需要先知道数据集最终是进行监督学习还是无监督学习。模型的选择一方面是通过我们的任务来决定的。除了根据我们任务来选择模型外,还可以根据数据样本量以及特征的稀疏性来决定。刚开始我们总是先尝试使用一个基本的模型来作为其baseline,进而再训练其他模型做对比,最终选择泛化能力或性能比较好的模型。

  • 我们本次建模使用的工具是sklearn
# 提出Survived作为数据集标签y
y = train['Survived']
# 使用sklearn拆分数据集为训练集和测试集
from sklearn.model_selection import train_test_split
# stratify参数是为了保证分布均匀,random_state是为了复现结果,使得每次拆分结果一样
X_train, X_test, y_train, y_test = train_test_split(data_x, y, stratify=y, random_state=0)
# 查看一下拆分后的数据集大小
print(X_train.shape, X_test.shape)
(668, 11) (223, 11)

我们首先用逻辑回归训练,看看效果

# 默认参数逻辑回归模型
lr = LogisticRegression()
lr.fit(X_train, y_train)
# 查看训练集和测试集分数
train_score = lr.score(X_train, y_train)
test_score = lr.score(X_test, y_test)
print(f"train score: {train_score:.2f}")
print(f"test score: {test_score:.2f}")

得到分数如下

train score: 0.80
test score: 0.79

我们再用随机森林分类模型来训练看看效果

# 随机森林分类模型
rf = RandomForestClassifier()
rf.fit(X_train, y_train)
# 查看训练集和测试集分数
train_score = rf.score(X_train, y_train)
test_score = rf.score(X_test, y_test)
print(f"train score: {train_score:.2f}")
print(f"test score: {test_score:.2f}")

得到分数如下

train score: 1.00
test score: 0.83
模型评估
  • 模型评估是为了知道模型的泛化能力。
  • 交叉验证(cross-validation)是一种评估泛化性能的统计学方法,它比单次划分训练集和测试集的方法更加稳定、全面。
  • 在交叉验证中,数据被多次划分,并且需要训练多个模型。
    最常用的交叉验证是 k 折交叉验证(k-fold cross-validation),其中 k 是由用户指定的数字,通常取 5 或 10。
  • 精确率(precision)度量的是被预测为正例的样本中有多少是真正的正例
  • 召回率(recall)度量的是正类样本中有多少被预测为正类
    f-分数是准确率与召回率的调和平均

交叉验证
我们用交叉验证来评估之前的模型,将数据集分类为N折交叉做训练集和验证集,计算交叉验证精度的平均值

  • cross_val_score是sklearn中用作交叉验证的方法

我们这里用10折交叉验证验证

from sklearn.model_selection import cross_val_score
lr = LogisticRegression(C=100)
scores = cross_val_score(lr, X_train, y_train, cv=10)
# 交叉验证所有分数
print(scores)
# 交叉验证平均分
print(f"Average cross-validation score: {scores.mean():.3f}")

交叉验证得分及平均分如下

[0.82089552 0.74626866 0.74626866 0.79104478 0.86567164 0.8358209
 0.76119403 0.80597015 0.74242424 0.75757576]
Average cross-validation score: 0.787

同样的我们来试试随机森林的交叉验证

rf = RandomForestClassifier()
scores = cross_val_score(rf, X_train, y_train, cv=10)
# 交叉验证所有分数
print(scores)
# 交叉验证平均分
print(f"Average cross-validation score: {scores.mean():.3f}")
[0.89552239 0.79104478 0.85074627 0.79104478 0.80597015 0.8358209
 0.80597015 0.8358209  0.78787879 0.8030303 ]
Average cross-validation score: 0.820
混淆矩阵

混淆矩阵是用来总结一个分类器结果的矩阵。其实就是把所有类别的预测结果与真实结果按按行列组合放置到了同一个表里,这样可以清楚直观的看到每个类别正确识别的数量和错误识别的数量。
在这里插入图片描述

  • 混淆矩阵的方法在sklearn中的sklearn.metrics模块
  • 混淆矩阵需要输入真实标签和预测标签
from sklearn.metrics import confusion_matrix
# 训练模型
lr = LogisticRegression(C=100)
lr.fit(X_train, y_train)
# 模型预测结果
pred = lr.predict(X_train)
# 混淆矩阵
print(confusion_matrix(y_train, pred))
[[354  58]
 [ 83 173]]
  • 精确率、召回率以及f-分数可使用classification_report模块
from sklearn.metrics import classification_report
# 精确率、召回率以及f1-score
print(classification_report(y_train, pred))
              precision    recall  f1-score   support

           0       0.81      0.86      0.83       412
           1       0.75      0.68      0.71       256

    accuracy                           0.79       668
   macro avg       0.78      0.77      0.77       668
weighted avg       0.79      0.79      0.79       668

ROC曲线

受试者工作特征曲线 (receiver operating characteristic curve,简称ROC曲线),又称为感受性曲线(sensitivity curve)。得此名的原因在于曲线上各点反映着相同的感受性,它们都是对同一信号刺激的反应,只不过是在几种不同的判定标准下所得的结果而已。
我们把ROC曲线看成无数个点,每个点都代表一个分类器,其横纵坐标表征了这个分类器的性能,无数个分类标准构成了这条曲线。

AUC(Area Under Curve),被定义为ROC曲线下的面积,显然这个面积小于1,又因为ROC曲线一般都处于y=x这条直线的上方,所以AUC一般在0.5到1之间。使用AUC值作为评价标准是因为很多时候ROC曲线并不能清晰的说明哪个分类器的效果更好,而作为一个数值,对应AUC更大的分类器效果更好。

  • ROC曲线在sklearn中的模块为sklearn.metrics
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)

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值