Kaggle竞赛网址:https://www.kaggle.com/c/titanic
上一章:Kaggle竞赛——Titanic泰坦尼克之灾(保姆级基础版)
本次Kaggle泰坦尼克之灾分析过程大致分为:
第1步:了解数据(上一章)
第2步:分析数据之间的关系(上一章)
第3步:缺失项数据处理(上一章)
第4步:特征因子化(上一章)
第5步:处理特殊值或浮动较大的数值(上一章)
第6步:数据筛选(上一章)
第7步:数据建模(上一章)
第8步:测试集预处理(上一章)
第9步:结果预测(上一章)
第10步:模型优化(本章)
第11步:模型融合(本章)
好的,基于上一章的分析与讲解,我们大致的得到了一个简单baseline。那么我们下一步该怎么优化呢?
先思考一下:
1.如果不断地做特征工程,产生的特征越来越多,用这些特征去训练模型,会对我们的训练集拟合得越来越好,同时也可能逐步地丧失泛化能力,从而在测试集上表现不佳,也就是发生过拟合问题;
2.如果模型在测试集上表现不佳,除掉上面说的过拟合问题,也有可能是欠拟合问题,也就是说在训练集上,其实拟合的也不是那么好;
a. 对过拟合而言,通常以下策略对结果优化是有用的:做一下特征筛选,挑出较好的特征子集为训练提供更多的数据,从而弥补原始数据的bias问题,学习到的模型也会更准确;
b. 而对于欠拟合而言,通常需要更多的特征,更复杂的模型来提高模型的准确度。
第10步:逻辑回归优化
10.1 模型系数分析
# 模型系数关联分析
pd.DataFrame({
"columns":list(train_df.columns)[1:], "coef":list(clf.coef_.T)}) # LR模型系数
从上表格可以看出:
- SibSp和Parch一定程度上呈现的是一个负相关,这个需要看看进一步验证;
- 有Cabin(客舱)值会很大程度拉升最后获救概率;(但事实上从最上面的有无Cabin记录的Survived分布图上看出,即使有Cabin记录的乘客也有一部分遇难了,估计这个属性上我们挖掘还不够。)
- 登船港口S会有一定程度拉低获救的概率,另外俩港口没啥作用;(但我们从之前的统计图上并没有看到S港口的获救率非常低,可以考虑把登船港口这个feature去掉试试)
- Sex属性,如果是female会极大提高最后获救的概率,而male会很大程度拉低这个概率;
- Pclass属性,头等舱乘客最后获救的概率会上升,而乘客等级为3会极大地拉低这个概率;
- Age是一个负相关,意味着在我们的模型里,年龄越小,越有获救的优先权;(需要看看原数据上是否合理)
- 船票Fare有小幅度的正相关。(并不意味着这个feature作用不大,有可能是细化的程度还不够)
10.2 交叉验证
把交叉验证里面的bad case拿出来,看看人眼审核是否能发现什么蛛丝马迹,是忽略了哪些信息,使得这些乘客被判定错了?再把bad case上得到的想法和前头系数分析的合在一起,然后逐个试试。
# 交叉验证
from sklearn.model_selection import cross_val_score, train_test_split
# 简单看看打分情况
clf = linear_model.LogisticRegression(C=1.0, penalty='l1', tol=1e-6, solver='liblinear')
all_data = df.filter(regex='Survived|Age_.*|SibSp|Parch|Fare_.*|Cabin_.*|Embarked_.*|Sex_.*|Pclass_.*')
X = all_data.values[:,1:]
y = all_data.values[:,0]
cross_val_score = cross_val_score(clf, X, y, cv=5)
cross_val_score
10.3 特征挖掘
# 分割数据
split_train, split_cv = train_test_split(df, test_size=0.3, random_state=0)
train_df = split_train.filter(regex='Survived|Age_.*|SibSp|Parch|Fare_.*|Cabin_.*|Embarked_.*|Sex_.*|Pclass_.*')
# 生成模型
clf = linear_model.LogisticRegression(C=1.0, penalty='l1', tol=1e-6, solver='liblinear')
clf.fit(train_df.values[:,1:], train_df.values[:,0])
# 对cross validation数据进行预测
cv_df = split_cv.filter(regex='Survived|Age_.*|SibSp|Parch|Fare_.*|Cabin_.*|Embarked_.*|Sex_.*|Pclass_.*')
predictions = clf.predict(cv_df.values[:,1