1. 程式人生 > >Kaggle入門——Titanic案例

Kaggle入門——Titanic案例

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]))