本篇文章的靈感來源于 han xiaoyang大神博主的博文,當(dāng)然同時運用了kaggle的有關(guān)泰坦尼克號的數(shù)據(jù)。畢竟沒有數(shù)據(jù)就沒有研究嘛。。。
??現(xiàn)在就讓我們進行本次的預(yù)測,首先說明一下本次預(yù)測的目的:通過分析原始數(shù)據(jù)集來進行預(yù)測假如當(dāng)泰坦尼克號觸礁時哪些乘客將會被救哪些乘客將會墜入大海死亡的懷抱。。。。雖然是馬后炮,(PS:我們已經(jīng)知道在泰坦尼克號觸礁之后誰還活著,但是這也是一種預(yù)測,我們可以通過已有的數(shù)據(jù)進行未來的預(yù)測。)
??老套路,首先先看一下原始數(shù)據(jù)集:

??看到這些原始數(shù)據(jù)集就感覺生活不美好。但是默默地說,,分析還是要做的。首先通過分析原始數(shù)據(jù)集:我們可以發(fā)現(xiàn)Survived,Sex,Embarked,Pclass是有分類的,譬如Survived只有存活或者不存活(0或者1),Sex只有男或者女(male or female 當(dāng)然也有其他的。。。。性別。。在此筆者就不描述了),Embarked代表出發(fā)港口(這里也只有三個港口可供選擇),Pclass則代表人群的高貴程度。。。(譬如Pclass==1代表這哥們或者姐妹起碼也是馬云級別的人物。。)所以呢,難道你們不對這些分類的存活數(shù)量感興趣嗎?????!反正我很感興趣,譬如我想知道當(dāng)Pclass==1時,存活比例是多少。。當(dāng)Pclass==3時,存活比例是多少。。。我身為一個Pclass==3的屌絲當(dāng)然關(guān)心自己的生存幾率了。。。是時候展示真正的圖表了
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
plt.subplot2grid((2,3),(0,0))
data['Survived'].value_counts().plot(kind='bar')
plt.legend()
plt.title('存活人數(shù)統(tǒng)計')
plt.subplot2grid((2,3),(0,1))
data['Pclass'].value_counts().plot(kind='bar')
plt.title('乘客等級分布')
plt.subplot2grid((2,3),(0,2))
plt.title('存活比例與年齡的關(guān)系')
sns.stripplot('Survived','Age',data=data[['Survived','Age']])
plt.subplot2grid((2,3),(1,0),colspan=2)
data[data['Pclass']==1]['Age'].plot(kind='kde')
data[data['Pclass']==2]['Age'].plot(kind='kde')
data[data['Pclass']==3]['Age'].plot(kind='kde')
plt.xlabel('年齡')
plt.ylabel('密度')
plt.legend((u'頭等艙',u'次等艙',u'低等艙'))
plt.subplot2grid((2,3),(1,2))
plt.title('登錄港口人口統(tǒng)計')
sns.countplot(x='Embarked',data=data[['Embarked']],palette='muted')
# 計算不同等級的人群獲救數(shù)量
sns.factorplot(x='Survived',col='Pclass',hue='Pclass',kind='count',data=data,col_wrap=3,legend=True,palette='husl')
最終顯示圖表如下所示:

1.通過第一個圖表可以看出存活認(rèn)識要遠(yuǎn)遠(yuǎn)低于死亡人數(shù)。
2.第二個圖表表示像我這樣的普通人還是比較多的。
3.船上低等艙和次等艙所有的人的年齡基本都在20-40歲之間,但是可以發(fā)現(xiàn)頭等艙中的年齡分布在20-60歲之間。同時可以發(fā)現(xiàn)40-60歲的上層人要高于低等艙和次等艙。。。這是不是可以表明我們在40-60歲有很大的可能性走上人生巔峰,迎娶白富美。從此步入上層生活。當(dāng)然啦。。。前提是40歲前好好努力才可以。。。。
4.最后一張圖明確的表現(xiàn)出港口S絕對是個熱門港口,因為基本一大半的游客都選擇從這個港口登陸泰坦尼克號。
??在這部偉大的作品中有這么一段臺詞:Lady and childern first!(我瞎編的臺詞),所以我想觀察一下這就話是否適用在這個預(yù)測中,那就觀察一下男女獲救比例吧:
sns.factorplot(x='Survived',col='Sex',kind='count',data=data,col_wrap=3,legend=True,palette='Set3')

??很符合常識,不是嗎?女性獲救比例很高。。。同時可以發(fā)現(xiàn)死亡的絕大多數(shù)都是男性,這個其實可以想象的到。
??接下來就是見識見識是否人人平等的時候到了。。。。。:
sns.factorplot(x='Survived',col='Pclass',hue='Pclass',kind='count',data=data,col_wrap=3,legend=True,palette='husl')

??看清楚了嗎???沒看清楚的話我再搞一個比例圖供大家欣賞一下。。。

??是不是很想說一聲:what's the fuck? 通過這兩張圖表我們可以很容易的發(fā)現(xiàn):處于上層的人的的存活比例很明顯的更高,。。同時低層的人死亡率明顯更高。。。
??接下來我們可以觀察一下每個階層等級存活的人數(shù)。
sns.factorplot(x='Pclass', col='Survived', hue='Sex', kind='count', data=data[['Pclass', 'Survived', 'Sex']],palette='Set2')
最終顯示如下所示:

??從這張圖中可以看出越有權(quán)勢的人存活幾率越大,,,對的,沒說錯。越有權(quán)勢的人存活幾率越大。
??當(dāng)然我們可以觀察一下不同港口的存活比例:
sns.factorplot(x='Embarked', col='Survived', hue='Sex', kind='count', data=data[['Embarked', 'Survived', 'Sex']], palette='Set1')
結(jié)果如下所示:

??從這張圖可以看出S港口的存活率和死亡率都比較高,,,我猜想原因可能是因為該港口人數(shù)多。。也就是基數(shù)大。所以我制作了一張餅狀圖進行觀察。
plt.subplot2grid((1, 2), (0, 0))
plt.title('判斷不同港口的未獲救比例')
colors = ["#9b59b6", "#3498db", "#2ecc71"]
data[data['Survived'] == 0]['Embarked'].value_counts().plot(kind='pie', autopct='%.2f', colors=colors,
explode=(0, 0.1, 0))
plt.subplot2grid((1, 2), (0, 1))
plt.title('判斷不同港口的獲救比例')
data[data['Survived'] == 1]['Embarked'].value_counts().plot(kind='pie', autopct='%1.1f%%', colors=colors,
explode=(0, 0.1, 0))
最終圖表顯示:

??所以此時我對S港口進行格外留意。
現(xiàn)在進行不同港口進出乘客人員總數(shù)統(tǒng)計:
plt.title('不同港口的登陸人數(shù)')
sns.countplot(x='Embarked',data=data[['Embarked']],palette='Set1')
??結(jié)果果然和我們的預(yù)期一樣。S港口的基數(shù)很大。

數(shù)據(jù)預(yù)處理
??通過觀察原始數(shù)據(jù)可以發(fā)現(xiàn)。在Age 這一選項中存在一定量的缺失值。同時 Cabin 這一選項中也存在一定量的缺失值。Age 這一選項毋庸置疑必須要完整的數(shù)據(jù),用腳想一下也知道,小孩子肯定是優(yōu)先被考慮獲救的。所以我們需要年齡這一選項進行評估。而cabin這一選項的話,并不確定,所以我選擇查看一下有Cabin信息和無Cabin信息的獲救比例:
plt.subplot2grid((1,2),(0,0))
plt.title('當(dāng)Cabin有相關(guān)信息時')
data[data['Cabin'].notnull()]['Survived'].value_counts().plot(kind='bar')
plt.subplot2grid((1,2),(0,1))
plt.title('當(dāng)Cabin沒有相關(guān)信息時')
data[data['Cabin'].isnull()]['Survived'].value_counts().plot(kind='bar')
plt.show()
最終顯示結(jié)果如下所示:

??通過這張圖可以看出。若有Cabin這一選項可以發(fā)現(xiàn)獲救的概率會大大增加。所以Cabin應(yīng)該很有必要進行處理一下。但是此處我就舍棄了Name,Ticket,選項。因為我想不出這些有何聯(lián)系。所以暫時先排除這些因素。
??所以此時就可以進行數(shù)據(jù)預(yù)處理,看過我第一篇文章的朋友應(yīng)該知道我接下來要做什么。當(dāng)然是將所有非數(shù)值類型的選項全部轉(zhuǎn)換為數(shù)值類型。這樣我們就需要pandas中的get_dummies()函數(shù)。廢話不多說直接上代碼:
import pandas as pd
from sklearn.ensemble import RandomForestRegressor
from scipy.interpolate import lagrange
from sklearn.preprocessing import Imputer
filename = 'D:/數(shù)據(jù)/RMS/test.csv'
# filename='D:/數(shù)據(jù)/RMS/age.xls'
outputfile = 'D:/數(shù)據(jù)/RMS/trainprocess.csv'
data = pd.read_csv(filename)
age_data = data[['Age', 'Fare', 'Parch', 'SibSp', 'Pclass']]
# 乘客分為已知和未知
age_known = age_data[age_data['Age'].notnull()].as_matrix()
age_unknown = age_data[age_data['Age'].isnull()].as_matrix()
# y為目標(biāo)年齡
y = age_known[:, 0]
# x為特征屬性
x = age_known[:, 1:]
rfr = RandomForestRegressor(n_estimators=1000, n_jobs=-1, random_state=50, max_features="auto")
rfr.fit(x, y)
predict = rfr.predict(age_unknown[:, 1::])
# data.loc[(data['Age'].isnull()), 'Age'] = predict
score = rfr.score(x, y)
??為了證明插值的準(zhǔn)確,可以進行測試其準(zhǔn)確率:

??上述步驟是為了對Age進行補全。
import pandas as pd
import numpy as np
import sklearn.preprocessing as processing
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn import svm
filename = 'D:/數(shù)據(jù)/RMS/train.csv'
outputfile = 'D:/數(shù)據(jù)/RMS/final1.csv'
train_filename = 'D:/數(shù)據(jù)/RMS/trainprocess.csv'
data = pd.read_csv(filename)
data_test = pd.read_csv(train_filename)
data_test = data_test[['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare', 'Embarked', 'Cabin']]
data_test.loc[(data_test['Cabin'].notnull()), 'Cabin'] = 'Yes'
data_test.loc[(data_test['Cabin'].isnull()), 'Cabin'] = 'No'
dummies_Embarked = pd.get_dummies(data_test['Embarked'], prefix='Embarked')
dummies_Sex = pd.get_dummies(data_test['Sex'], prefix='Sex')
dummies_Pclass = pd.get_dummies(data_test['Pclass'], prefix='Pclass')
dummies_Cabin = pd.get_dummies(data_test['Cabin'], prefix='Cabin')
data_test = pd.concat([data_test, dummies_Embarked, dummies_Sex, dummies_Pclass, dummies_Cabin], axis=1)
data_test = data_test.drop(['Embarked', 'Sex', 'Pclass', 'Cabin'], axis=1)
data = data[['Survived', 'Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare', 'Embarked', 'Cabin']]
data.loc[(data['Cabin'].notnull()), 'Cabin'] = 'Yes'
data.loc[(data['Cabin'].isnull()), 'Cabin'] = 'No'
dummies_Embarked = pd.get_dummies(data['Embarked'], prefix='Embarked')
dummies_Sex = pd.get_dummies(data['Sex'], prefix='Sex')
dummies_Pclass = pd.get_dummies(data['Pclass'], prefix='Pclass')
dummies_Cabin = pd.get_dummies(data['Cabin'], prefix='Cabin')
data = pd.concat([data, dummies_Embarked, dummies_Sex, dummies_Pclass, dummies_Cabin], axis=1)
data = data.drop(['Embarked', 'Sex', 'Pclass', 'Cabin'], axis=1)
??通過這一步驟就可以實現(xiàn)把所有的非數(shù)值類型轉(zhuǎn)換為數(shù)值類型。但是觀察Ages這一選項可以發(fā)現(xiàn)Age年齡范圍跳躍太大。熟悉數(shù)據(jù)挖掘預(yù)處理的朋友應(yīng)該都知道,我們在數(shù)據(jù)預(yù)處理時要避免這種情況,還好Sklearn中有這一種處理方法。
scaler = processing.StandardScaler()
age_scale = scaler.fit(data['Age'])
data['Age_scale'] = scaler.fit_transform(data['Age'], age_scale)
fare_scale = scaler.fit(data['Fare'])
data['Fare_scale'] = scaler.fit_transform(data['Fare'], fare_scale)
data = data.drop(['Age', 'Fare'], axis=1)
age_scale = scaler.fit(data_test['Age'])
data_test['Age_scale'] = scaler.fit_transform(data_test['Age'], age_scale)
fare_scale = scaler.fit(data_test['Fare'])
data_test['Fare_scale'] = scaler.fit_transform(data_test['Fare'], fare_scale)
data_test = data_test.drop(['Age', 'Fare'], axis=1)
??這一步驟就可以實現(xiàn)把Age所有的數(shù)據(jù)都縮放至[-1,1]之間。接下來就是模型運用了。在這方面我首先想到的就是隨機森林模型。
同樣的和第一篇博文一樣。訓(xùn)練模型如下所示:
data_information = data.drop(['Survived'], axis=1).values
data_Survived = data['Survived'].values
X_train, X_test, y_train, y_test = train_test_split(data_information, data_Survived, test_size=0.5)
# 邏輯回歸模型測試
lr = LogisticRegression()
lr.fit(X_test, y_test)
# print('LR\'s accuracy rate is:', lr.score(X_train, y_train))
# 隨機森林模型測試
rfr = RandomForestClassifier()
rfr.fit(X_test, y_test)
# print('rfr\'s accuracy rate is:', rfr.score(X_train, y_train))
# svm模型測試
svm_model = svm.SVC()
svm_model.fit(X_test, y_test)
精確度如下所示:

??接下來就采用隨機森林模型進行評估。最終可以得到預(yù)測準(zhǔn)確率如下所示:

??可以看出預(yù)測準(zhǔn)確率高達(dá)85%。
??最終得到結(jié)果如下所示:

??Survived1代表添加Cabin選項,Survived2代表沒有添加,corrent代表真實的數(shù)據(jù)。