建模
逻辑回归
逻辑回归算法是一种很常用的用于二分类的分类算法,我们先用逻辑回归模型试一试。scikit-learn这个包中含有绝大部分数据挖掘需要用到的算法,可以直接引用。
建模之前,我们先引入交叉验证的概念。毕竟建模是一个螺旋上升的过程,需要对每一轮的假设和分析进行评估,再基于当前的评估进行改进,因此我们需要一个评估的工具。交叉验证可用于特征选择、模型选择和参数调优,这里我们先用cross_val_score来做模型选择。
from sklearn import model_selection
from sklearn.linear_model import LogisticRegression
# 初始化逻辑回归分类器
alg = LogisticRegression(random_state=1)
# 计算accuracy score
scores = model_selection.cross_val_score(alg, titanic[predictors], titanic["Survived"],cv=3)#cv默认3倍
predictors_score=predictors_score.append({'predictors':predictors, 'scores':scores.mean(),'model':"LogisticRegression"},ignore_index=True)
#取得分的平均值
print(scores.mean())
#alg.fit(titanic[predictors],titanic["Survived"])
这次得分是:0.787878787879
到这里模型就建好了,然而探索并没有结束。当前得分对于一个二分类问题来说有点低,毕竟瞎蒙都能蒙对50%,所以下面来看看对于同一组特征,别的模型的表现。
随机森林
随机森林这个算法可以称得上人见人爱了吧,在遇到分类问题时,若是不能决断要采取什么算法,可以先试试随机森林,所以这么一个解决了选择综合症难题且表现不俗的算法,人气高点也不奇怪。下面来看看随机森林算法在这个问题中的表现。
from sklearn import model_selection
from sklearn.ensemble import RandomForestClassifier
#predictors = ["Pclass", "Sex", "Age", "SibSp", "Parch", "Fare", "Embarked"]
# 初始化随机森林分类器,参数默认
# n_estimators:树的数量
# min_samples_split:划分的最小行数
# min_samples_leaf 最小的叶子数,即树最底层的节点数
alg = RandomForestClassifier(random_state=1, n_estimators=10, min_samples_split=2, min_samples_leaf=1)
#计算accuracy
kf = cross_validation.KFold(titanic.shape[0], n_folds=3, random_state=1)
scores = model_selection.cross_val_score(alg, titanic[predictors], titanic["Survived"], cv=kf)
predictors_score=predictors_score.append({'predictors':predictors, 'scores':scores.mean(),'model':"RandomForest10_2_1"},ignore_index=True)
# 计算平均得分
print(scores.mean())
是不是更亮眼呢?然而并没有,这次的得分是:0.785634118967
这个圆不回去了,怎么办呢。这个其实是这个分类器的状态不太好,参数不太合适,我们调整下参数看看:
alg = RandomForestClassifier(random_state=1, n_estimators=100, min_samples_split=4, min_samples_leaf=2)
kf = cross_validation.KFold(titanic.shape[0], 3, random_state=1)
scores = cross_validation.cross_val_score(alg, titanic[predictors], titanic["Survived"], cv=kf)
predictors_score=predictors_score.append({'predictors':predictors, 'scores':scores.mean(),'model':"RandomForest100_4_2"},ignore_index=True)
print(scores.mean())
此次得分:0.814814814814814。终于没有抽风表现正常了一回,哈哈说笑的。参数是建模很重要的一环,良好的结果离不开最优参数的寻找,俗称参数调优,是个运筹学范畴内的议题,也是我们日常生活中经常面临的一类情景,最简单的情景就是小学课本里的那种数学应用题,找个最优解。
模型评估
模型评估其实也是个比较大的话题,一般有准确率,就是我们用的指标,还有召回率(recall)、ROC以及K-S等指标,说清楚模型评估需要较大篇幅,这里就不展开了。我们暂时就比较accuracy这个指标了。
从得分来看,分类器RandomForestClassifier(random_state=1, n_estimators=100, min_samples_split=4, min_samples_leaf=2)表现要优于 LogisticRegression(random_state=1),最后我们采用优化过参数的随机森林分类器。
对应不同的需求我们有不一样的衡量模型的标准,要结合具体的实际情况做不同的选择。
模型评估暂时就到这里,下面我们进行数据挖掘的另一个重头戏:特征工程。
特征工程
在学神经网络的时候老师曾提到了蝴蝶效应,就是想说明输入对系统的输出有很大的影响。放在数据挖掘这里也同样适用,神经网络也是数据挖掘会用到的算法之一,其他算法不一定有这么夸张,但是影响也是不容小觑的。特征的选取对成本和结果都有很大的影响,好的输入不一定有好的输出,但是要想从一堆噪音中得到好结果,那几乎是不可能的。
scikit-learn真的是一个很强大的库,特征选择我们也直接在这里引用相对应的API。
之前根据初步的分析我们选了一组特征,现在我们用SelectKBest,和f_classif来帮助我们看看前面的的特征的价值到底怎么样。
#特征价值
import numpy as np
from sklearn.feature_selection import SelectKBest, f_classif
import matplotlib.pyplot as plt
predictors = ["Pclass", "Sex", "Age", "SibSp", "Parch", "Fare", "Embarked"]
# Perform feature selection
selector = SelectKBest(f_classif, k=5)
selector.fit(titanic[predictors], titanic["Survived"])
# Get the raw p-values for each feature, and transform from p-values into scores
scores = -np.log10(selector.pvalues_)
# Plot the scores. See how "Pclass", "Sex", "Title", and "Fare" are the best?
plt.bar(range(len(predictors)), scores)
plt.xticks(range(len(predictors)), predictors, rotation='vertical')
plt.show()
可以看到Pclass、Sex和Fare表现比较突出,其他特征不那么明显是不是就一定要舍弃呢,不一定啊,说不定挖掘的方向或者说预处理方式不对呢。可以一个一个假设去试,如果再也想不到别的了或者时间不允许了或者有别的限制条件,我们再酌情放弃这些特征。
结合之前对数据的基本分析,年龄这个属性在岁数这个数值上可能区分不是那么明显,毕竟分析的时候不是说几岁就一定获救或是不获救,当时是猜测某一年龄段的人更容易获救,比如孩子,所以我们按幼儿、儿童、青少年、青年、中年和老年这种年龄阶段来区分,将年龄离散化。这里用pandas的cut来切片,生成AgeB这个特征代替Age。
可以看到Age的表现有提升,虽然不是很多。我们再来看看横向的那些放弃了的特征,比如文字类的特征。再来研究下name这个属性,逃生时会不会因为头衔不一样而享受不一样的待遇呢,和名字长度有没有关系呢,名字长度是不是在一定程度上也代表了身份地位呢,英文姓名有融合先辈的姓名,如果经济或地位不好的话,应该不会这么讲究?就像我们中国,大家族起名字会暗合辈分,但是穷苦人家可能就比较随意了。来看看数据怎么说吧。
捉到了2只表现还不错的特征。
我们来看看全部特征都用上的时候的得分:0.829405162738496
只取重要的特征时候的得分:0.81705948372615034
这个放弃特征要谨慎啊,还是先保留吧,对重要特征心里有数。
第一轮改进到这里就结束了,接下来继续第二轮改进。
【目录】