0、写在前面的话
接触kaggle算起来已经快有一个学期了,断断续续做了5个(包括目前正在进行中的两个)。正好趁放假回家前这段时间回顾一下。(最近越来越体会到孔老夫子的大智慧 ”温故而知新“)
● Titanic是我接触kaggle的第一个案例。
完成Titanic,让我初步了解了一个从数据分析到模型选择的完整的比赛过程,而不再是用UCI标准机器学习库数据集去验证算法的准确率(前者偏向于工程,后者偏向于科研)。这里数据预处理可以媲美甚至超过模型选择的重要性。
● 关于模型
Titanic里虽然没有用到kaggle的神器xgboost(后面案例会用到),但是从决策树到随机森林以及GBDT的过程也深刻体会到随机森林以及以它为原型的各种改进的树模型的强大。(后面更会体会到ensemble的强大)
● 表白kaggle以及各位在forum中无私分享的大神!
1、EDA(探索性数据分析)
● EDA是对数据进行探讨,强调的是统计概括和可视化。
i) 读入数据:
titanic_data = pd.read_csv("E:/Kaggle/Titanic/train.csv")
#pandas是最常用的一个python数据分析库,读入的数据是一个dataFrame的结构。对于dataFrame结构的数据各种操作,《利用python进行数据分析》一书中有详细的介绍。
ii) 初步分析:
titanic_data.shape
Out[11]: (891, 12)
#可以看出数据有891行,12列
titanic_data.columns
Out[12]:
Index([u'PassengerId', u'Survived', u'Pclass', u'Name', u'Sex', u'Age',
u'SibSp', u'Parch', u'Ticket', u'Fare', u'Cabin', u'Embarked'],
dtype='object')
#数据的列索引有12个
titanic_data.describe()
Out[19]:
PassengerId Survived Pclass Age SibSp \
count 891.000000 891.000000 891.000000 714.000000 891.000000
mean 446.000000 0.383838 2.308642 29.699118 0.523008
std 257.353842 0.486592 0.836071 14.526497 1.102743
min 1.000000 0.000000 1.000000 0.420000 0.000000
25% 223.500000 0.000000 2.000000 20.125000 0.000000
50% 446.000000 0.000000 3.000000 28.000000 0.000000
75% 668.500000 1.000000 3.000000 38.000000 1.000000
max 891.000000 1.000000 3.000000 80.000000 8.000000
Parch Fare
count 891.000000 891.000000
mean 0.381594 32.204208
std 0.806057 49.693429
min 0.000000 0.000000
25% 0.000000 7.910400
50% 0.000000 14.454200
75% 0.000000 31.000000
max 6.000000 512.329200
#显示的是数据的统计信息
#12列中只显示了数值型的8个,其中Age列中统计只有714个,原因是缺失值的存在
2、数据预处理
- 冗余信息删除
- 缺失值处理
- 非数值型数据转换成数据值
- 异常值处理
#分析数据每一列,可知'PassengerId'是冗余信息,以及'Name','Ticket','Cabin'三者较为复杂,选择删除四列
titanic_data = titanic_data.drop(['Name','PassengerId','Ticket','Cabin'],1)
############################'Sex'二值化
titanic_data.loc[titanic_data['Sex']=='male','Sex'] = 0
titanic_data.loc[titanic_data['Sex']=='female','Sex'] = 1
###########################'Age'缺失值处理
#i)用中位数填充缺失值
titanic_data['Age'] = titanic_data['Age'].fillna(titanic_data['Age'].median())
#ii)用回归预测填充缺失值
age_df = titanic_data[['Age','Sex','Fare', 'Parch', 'SibSp', 'Pclass']]
age_df_notnull = age_df.loc[(titanic_data.Age.notnull())]
age_df_isnull = age_df.loc[(titanic_data.Age.isnull())]
X = age_df_notnull.values[:, 1:]
Y = age_df_notnull.values[:, 0]
rfr = RandomForestRegressor(n_estimators=1000, n_jobs=-1)
rfr.fit(X, Y)
predictAges = rfr.predict(age_df_isnull.values[:, 1:])
titanic_data.loc[(titanic_data.Age.isnull()), 'Age'] = predictAges
###########################'Embarked'
titanic_data['Embarked'] = titanic_data['Embarked'].fillna('S')
#i)用数值代替
titanic_data.loc[titanic_data['Embarked']=='S','Embarked'] = 0
titanic_data.loc[titanic_data['Embarked']=='C','Embarked'] = 1
titanic_data.loc[titanic_data['Embarked']=='Q','Embarked'] = 2
#ii)用二元值代替
dummies_titanic_data = pd.get_dummies(titanic_data.Embarked)
dummies_titanic_data = dummies_titanic_data.rename(columns=lambda x:'Embarked_'+str(x))
titanic_data = pd.concat([titanic_data,dummies_titanic_data],axis=1)
#########################'Fare'
#titanic_data['Fare'][np.where(titanic_data['Fare']==0)[0] ] = titanic_data['Fare'][ titanic_data['Fare'].nonzero()[0] ].min() / 10
3、模型选择
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import GradientBoostingClassifier
from sklearn import cross_validation
######################RandomForest调参、交叉验证
results = []
sample_leaf_options = list(range(1, 50, 3))
n_estimators_options = list(range(50, 300,5))
for leaf_size in sample_leaf_options:
for n_estimators_size in n_estimators_options:
titanic_forest = RandomForestClassifier(min_samples_leaf=leaf_size, n_estimators=n_estimators_size, random_state=50)
#titanic_forest.fit(train_data[0::,1::],train_data[0::,0].astype(int))
#print titanic_forest.feature_importances_
scores = cross_validation.cross_val_score(titanic_forest,train_data[0::,1::],train_data[0::,0].astype(int),cv=5)
print scores.mean()
results.append((leaf_size, n_estimators_size,scores.mean() ))
print(max(results, key=lambda x: x[2]))
####################GBDT调参、交叉验证
results = []
n_estimators_options = list(range(10, 1000,10))
for n_estimators_size in n_estimators_options:
titanic_forest = GradientBoostingClassifier(n_estimators=n_estimators_size, random_state=50)
#titanic_forest.fit(train_data[0::,1::],train_data[0::,0].astype(int))
#print titanic_forest.feature_importances_
scores = cross_validation.cross_val_score(titanic_forest,train_data[0::,1::],train_data[0::,0].astype(int),cv=5)
print scores.mean()
results.append((n_estimators_size,scores.mean() ))
print(max(results, key=lambda x: x[1]))