Titanic:Machine Learning from Disaster 人工智能,大數據分析常用入門kaggle項目

索引

0.瞭解Kaggle:

1.觀察大局:

2.獲得數據:

3.從數據探索和可視化中獲得洞見:

4.機器學習算法的數據準備:

5.選擇和訓練模型:

6.微調模型:

 

0.瞭解Kaggle:

Kaggle成立於2010年,是一個進行數據發掘和預測競賽的在線平臺。從公司的角度來講,可以提供一些數據,進而提出一個實際需要解決的問題;從參賽者的角度來講,他們將組隊參與項目,針對其中一個問題提出解決方案,最終由公司選出的最佳方案可以獲得5K-10K美金的獎金。

除此之外,Kaggle官方每年還會舉辦一次大規模的競賽,獎金高達一百萬美金,吸引了廣大的數據科學愛好者參與其中。從某種角度來講,可以把它理解爲一個衆包平臺,類似國內的豬八戒。但是不同於傳統的低層次勞動力需求,Kaggle一直致力於解決業界難題,因此也創造了一種全新的勞動力市場——不再以學歷和工作經驗作爲唯一的人才評判標準,而是着眼於個人技能,爲頂尖人才和公司之間搭建了一座橋樑。

輸入https://www.kaggle.com/即可進入Kaggle主頁,網站有這麼幾個版塊:

競賽competitions

數據datasets

代碼kernels

討論區 Discussion

在線課程學習learn

Kaggle競賽分類:

Kaggle上的競賽有各種分類,例如獎金極高競爭激烈的的 “Featured”,相對平民化的 “Research”等等。但整體的項目模式是一樣的,就是通過出題方給予的訓練集建立模型,再利用測試集算出結果用來評比。同時,每個進行中的競賽項目都會顯示剩餘時間、參與的隊伍數量以及獎金金額,並且會實時更新選手排位。在截止日期之前,所有隊伍都可以自由加入競賽,或者對已經提交的方案進行完善,因此排名也會不斷變動,不到最後一刻誰都不知道花落誰家。

推薦比賽Featured:瞄準商業問題帶有獎金的公開競賽。如果有幸贏得比賽,不但可以獲得獎金,模型也可能會被競賽贊助商應用到商業實踐中呢。

人才徵募Recruitment:贊助企業尋求數據科學家、算法設計人才的渠道。只允許個人參賽,不接受團隊報名。
研究型Research競賽通常是機器學習前沿技術或者公益性質的題目。競賽獎勵可能是現金,也有一部分以會議邀請、發表論文的形式獎勵。

遊樂場Playground:題目以有趣爲主,比如貓狗照片分類的問題。現在這個分類下的題目不算多,但是熱度很高。

入門比賽Getting Started:給萌新們一個試水的機會,沒有獎金,但有非常多的前輩經驗可供學習。很久以前Kaggle這個欄目名稱是101的時候,比賽題目還很多,但是現在只保留經典的入門競賽:手寫數字識別、沉船事故倖存估計、臉部識別。

課業比賽In Class:是學校教授機器學習的老師留作業的地方,這裏的競賽有些會向public開放參賽,也有些僅僅是學校內部教學使用。

 

比賽流程

Kaggle競賽的排名機制

在比賽結束之前,參賽者每天最多可以提交5次測試集的預測結果。每一次提交結果都會獲得最新的臨時排名成績,直至比賽結束獲得最終排名。在比賽過程中,Kaggle將參賽者每次提交的結果取出25%-33%,並依照準確率進行臨時排名。在比賽結束時,參賽者可以指定幾個已經提交的結果,Kaggle從中去除之前用於臨時排名的部分,用剩餘數據的準確率綜合得到最終排名。所以,比賽過程中用於最終排名的那部分數據,參賽者是始終得不到關於準確率的反饋的。這樣一定程度避免參賽模型的過擬合,保證評選出兼顧準確率和泛化能力的模型。

數據Datasets版塊

每一個競賽題目都有一個數據入口,描述數據相關的信息,與主頁上的Datasets選擇一個數據其實指向同一個地方。在這裏可以下載到提交結果的示範、測試集、訓練集。Kaggle的數據以CSV格式最常見,提交的結果也要求是CSV格式。

代碼Kernels板塊

這是Kaggle最棒的功能!在這裏可看到其他參賽者自願公開的模型代碼,是學習和交流的最佳所在!取名爲kernels意味支持線上調試和運行代碼,目前支持Python、R。對那些暫時缺少硬件資源的參賽者,相當於Kaggle提供了一個“雲計算”平臺,可以作爲一個備選的計算資源。其中Python語言中絕大部分是使用Jupyter Notebook完成的。

 

1.觀察大局:

Kaggle是一個數據分析建模的應用競賽平臺,有點類似KDD-CUP(國際知識發現和數據挖掘競賽),企業或者研究者可以將問題背景、數據、期望指標等發佈到Kaggle上,以競賽的形式向廣大的數據科學家徵集解決方案。

故事背景

泰坦尼克號的沉沒是歷史上最臭名昭著的海難之一。

 

1912年4月15日,在她的處女航中,泰坦尼克號與冰山相撞後沉沒,2224名乘客和船員中有1502人遇難。

 

這一聳人聽聞的悲劇震驚了國際社會,併爲船隻帶來了更好的安全監管。

 

造成這樣的損失的原因之一是沒有足夠的救生艇給乘客和船員。

 

儘管在沉船事故中倖存下來的運氣有一些因素,但一些羣體比其他羣體更有可能存活下來,比如婦女、兒童和上層社會。

 

在這個挑戰中,要求完成對可能存活下來的人的分析。

 

特別地,要求應用機器學習的工具來預測哪些乘客在這場悲劇中倖存了下來。

 

Titanic生存預測是Kaggle上參賽人數最多的競賽之一。它要求參賽選手通過訓練數據集分析出什麼類型的人更可能倖存,並預測出測試數據集中的所有乘客是否生還。

常用數據集

學習機器學習最好使用真實數據進行實驗, 而不僅僅是人工數據

集。 我們有成千上萬覆蓋了各個領域的開放數據集可以選擇。 以下是

一些可以獲得數據的地方:

·流行的開放數據存儲庫:

·UC Irvine Machine Learning

Repository(http://archive.ics.uci.edu/ml/)

·Kaggle datasets(https://www.kaggle.com/datasets)

·Amazon’s AWS datasets(http://aws.amazon.com/fr/datasets/)

·元門戶站點(它們會列出開放的數據存儲庫) :

·http://dataportals.org/

·http://opendatamonitor.eu/

·http://quandl.com/

·其他一些列出許多流行的開放數據存儲庫的頁面:

·Wikipedia’s list of Machine Learning

datasets(https://goo.gl/SJHN2k)

·Quora.com question(http://goo.gl/zDR78y)

·Datasets subreddithttps://www.reddit.com/r/datasets

2.獲得數據:

Titanic生存預測中提供了兩組數據:train.csv 和test.csv,分別是訓練集和測試集。本實驗爲練手項目,所以數據就直接給了,不過有缺失的數據,需要我們來處理一下。

打開kaggle對應項目的數據欄

下載數據

Train.csv

Test.csv

gender_submission.csv

導入numpy,pandas,matplotlib,seaborn包

注:Seaborn是基於matplotlib的圖形可視化python包。它提供了一種高度交互式界面,便於用戶能夠做出各種有吸引力的統計圖表

從當前目錄導入train.csv和test.csv,並顯示兩個數據文件的相關信息

 

瞭解數據特徵含義:

Index(['PassengerId', 'Survived', 'Pclass', 'Name', 'Sex', 'Age', 'SibSp', 'Parch', 'Ticket', 'Fare', 'Cabin', 'Embarked'], dtype='object')

 

PassengerId:乘客編號,唯一;   

Survived:是否獲救 0未獲救 1獲救;   

Pclass:客艙等級;

Name:乘客姓名;   

Sex:性別;   

Age:年齡;

SibSp:在船上的兄弟姐妹或者配偶數量;   

Parch:在船上的父母或兒女數量;   

Ticket:船票編號;   

Fare:船票價格;   

Cabin:客艙號;   

Embarked:登船港口

其中PassengerId爲預測唯一序號,Survived爲預測目標值。

 

瞭解數據基本情況:

可以發現,訓練數據集一共891個樣本,其中Age、Cabin、Embarked屬性有缺失值。我們需要對缺失值進行處理,Age字段缺失值可以用預測年齡來代替,Cabin字段由於Cabin項缺失太多,只能將有無Cain作爲特徵值進行建模,Embarked字段由於數據僅有兩個樣本缺值,可以選擇隨機填充該屬性特徵例值,或者刪除這兩個樣本。

 

查看各特徵值有無異常

Survived屬性包含0、1兩種值無異常,其中549死亡,342存活;Pclass包含1、2、3三種值無異常;Name屬性包含891個值,無重複無異常;Sex包含male 577位,female 314位;SibSp 包含0、1、2、3、4、5、8幾種值,其中屬性爲n的人數,應該爲n+1的倍數,即若某人有8個SIbSp則至少有9個人互爲SibSp,該數據出現的原因是因爲訓練數據只包含部分船上的人員,因此該特徵暫未發現異常;Parch特徵類似,暫未發現異常;Ticket字段包含681個不同值,該值爲每個票據的基本特徵,與生存與否關係不大;特徵Fare爲船票價格,未發現異常,可能與Pclass屬性有關,也可以劃分區間作爲預測是否存活的特徵;特徵Cabin存在缺失值可單獨處理,另外我們發現客艙編號以A、B、C、D、E開頭,可能與船艙位置有關;特徵Embarked包含三個值,船上乘客來源於三個地方。

 

通過matplotlib的餅圖模塊看到了存活比例,大概1/3多一些


3.從數據探索和可視化中獲得洞見:

(1)性別與生存的關係:

通過表格查看女性存活233/314,男性存活109/577

通過Matplotlib的條形統計圖bar查看

女性的存活比例遠大於男性,符合婦女先走的特點

(2)船艙等級與生存的關係

船艙等級與生存的關係,圖示:

表格計數:

對比兩種語句的不同表現形式,上面分組參考了兩個屬性,下面的只參考了一個屬性,上面的展示的更好

看來船艙等級越高,生存率越高,下面將性別,船艙等級和存活情況放一起比較

如下圖所示:

表格計數:

從上圖和表中明顯可以看到,雖然泰坦尼克號逃生總體符合婦女優先,但是對各個等級船艙還是有區別的,而且一等艙中的男子憑藉自身的社會地位強行混入了救生艇。如白星航運公司主席伊斯梅(他否決了配備48艘救生艇的想法,認爲少點也沒關係)則拋下他的乘客、他的船員、他的船,在最後一刻跳進可摺疊式救生艇C(共有39名乘客)。

(3)年齡與存活的關係

下面的圖使用了matplot的sns模塊,表現力更強

船艙等級和年齡與存活的關係:

船艙等級越高,男性年齡越大,看來社會地位和經濟實力的提升需要男性的長時間奮鬥,但是在存活的人當中,特別是頭等艙年輕的人更容易存活,看來是要保存年輕的生產力,還要爲祖國好好的做貢獻。年長的人就準備犧牲自我了。

性別和年齡與存活的關係:

存活的人當中,女性比男性更年長不知道是不是女性平均壽命比男性長的緣故。

(4)稱呼與存活關係

在數據的Name項中包含了對該乘客的稱呼,如Mr、Miss、Mrs等,這些信息包含了乘客的年齡、性別、也有可能包含社會地位,如Dr、Lady、Major、Master等稱呼。

這一項不方便用圖表展示,但是在特徵工程中,我們會將其加入到特徵中。

(5)登船港口與存活關係

泰坦尼克號從英國的南安普頓港出發,途徑法國瑟堡和愛爾蘭昆士敦,一部分在瑟堡或昆士敦下船的人逃過了一劫。

(6)船上親友人數與存活關係

從圖中可以看到,孤身一人存活率很低,但是如果親友太多,難以估計周全,也很危險

(7)其他因素

剩餘因素還有船票價格、船艙號和船票號,這三個因素都可能會影響乘客在船中的位置從而影響逃生順序,但是因爲這三個因素與生存之間看不出明顯規律,所以在後期模型融合時,將這些因素交給模型來決定其重要性。

(8)總結

通過分析,我們發現當時的歷史背景下,所屬階層、經濟水平處於高位的人更容易獲救,並且由於當時的急救策略,女人、孩子以及有家庭成員存在的人更容易獲救。並且能夠發現,當時上傳的三個港口經濟發展情況。

 

通過,集中模型,我們對乘客生存進行預測,發現對於預測結果並不是特別滿意,想要獲得一個理想對模型,需要對數據進行進一步的特徵化,同時可以利用voting對不同模型進行融合,調整參數,增加預測準確率

 

其實我有個想法,在救生艇容量一定的情況下婦女和小孩的體重比較輕,能救出更多的生命,可能是一個原因。

 

4.機器學習算法的數據準備:

首先將traintest合併一起進行特徵工程處理:

特徵工程即從各項參數中提取出可能影響到最終結果的特徵,作爲模型的預測依據。特徵工程一般應先從含有缺失值即NaN的項開始。

(1)Embarked(登船口)

先填充缺失值,對缺失的Embarked以衆數來填補

再將Embarked的三個上船港口分爲3列,每一列均只包含01兩個值

(2)Sex (性別)

無缺失值,直接分列

(3)Name(名字)

名字當中包含了一些稱謂,可能包含一些社會地位信息,需要提取出一些特徵

從名字中提取出稱呼:

將各式稱呼統一:

對名字長短進行分類

 

名字的長度

對“名”進行處理

對“姓”進行處理

(4)Fare(票價)

填充NaN,按一二三等艙各自的均價來填充。

泰坦尼克號中有家庭團體票(分析Ticket號可以得到),所以需要將團體票分到每個人。

票價分級

分列(這一項分列與不分列均可)

(5)Pclass(船艙等級)

Pclass項本身已經不需要處理,爲了更好地利用這一項,我們假設一二三等艙各自內部的票價也與逃生方式相關,從而分出高價一等艙、低價一等艙……這樣的分類。

(6)Parch and SibSp(親屬:父母子女+兄弟姐妹)

這兩組數據都能顯著影響到Survived,但是影響方式不完全相同,所以將這兩項合併成FamilySize組的同時保留這兩項。

(7)Age(年齡)

因爲Age項缺失較多,所以不能直接將其填充爲衆數或者平均數。常見有兩種填充法,一是根據Title項中的MrMasterMiss等稱呼的平均年齡填充,或者綜合幾項(SexTitlePclass)的Age均值。二是利用其他組特徵量,採用機器學習算法來預測Age,本例採用的是第二種方法。

Age完整的項作爲訓練集、將Age缺失的項作爲測試集。

 

建立融合模型

使用梯度提升和線性迴歸來填充age

填充Age

檢查異常值的情況

(8)Ticket:

Ticket中的字母與數字分開,分爲Ticket_LetterTicket_Number兩項。

(9)Cabin:

Cabin項缺失太多,只能將有無Cain作爲特徵值進行建模

(10)將Age和Fare正則化:

(11)棄掉無用列:

(12)整理數據

將訓練集與測試集分離

 

將輸入屬性和輸出屬性分離

 

準備開始訓練模型

 

 

5.選擇和訓練模型:

(1)用幾個模型篩選出較爲重要的特徵:

# 篩選重要特徵

def get_top_n_features(titanic_train_data_X, titanic_train_data_Y, top_n_features):

    # 隨機森林randomforest

    rf_est = RandomForestClassifier(random_state=42)

    rf_param_grid = {'n_estimators': [500], 'min_samples_split': [2, 3], 'max_depth': [20]}

    rf_grid = model_selection.GridSearchCV(rf_est, rf_param_grid, n_jobs=25, cv=10, verbose=1)

    rf_grid.fit(titanic_train_data_X,titanic_train_data_Y)

    print('Top N Features Best RF Params:' + str(rf_grid.best_params_))

    print('Top N Features Best RF Score:' + str(rf_grid.best_score_))

    print('Top N Features RF Train Error:' + str(rf_grid.score(titanic_train_data_X, titanic_train_data_Y)))

    feature_imp_sorted_rf = pd.DataFrame({'feature': list(titanic_train_data_X),

                            'importance': rf_grid.best_estimator_.feature_importances_}).sort_values('importance', ascending=False)

    features_top_n_rf = feature_imp_sorted_rf.head(top_n_features)['feature']

    print('Sample 25 Features from RF Classifier')

    print(str(features_top_n_rf[:25]))

 

    # AdaBoost算法

    ada_est = ensemble.AdaBoostClassifier(random_state=42)

    ada_param_grid = {'n_estimators': [500], 'learning_rate': [0.5, 0.6]}

    ada_grid = model_selection.GridSearchCV(ada_est, ada_param_grid, n_jobs=25, cv=10, verbose=1)

    ada_grid.fit(titanic_train_data_X, titanic_train_data_Y)

    print('Top N Features Best Ada Params:' + str(ada_grid.best_params_))

    print('Top N Features Best Ada Score:' + str(ada_grid.best_score_))

    print('Top N Features Ada Train Error:' + str(ada_grid.score(titanic_train_data_X, titanic_train_data_Y)))

    feature_imp_sorted_ada = pd.DataFrame({'feature': list(titanic_train_data_X),

                            'importance': ada_grid.best_estimator_.feature_importances_}).sort_values('importance', ascending=False)

    features_top_n_ada = feature_imp_sorted_ada.head(top_n_features)['feature']

    print('Sample 25 Feature from Ada Classifier:')

    print(str(features_top_n_ada[:25]))

 

    # 極限樹ExtraTree

    et_est = ensemble.ExtraTreesClassifier(random_state=42)

    et_param_grid = {'n_estimators': [500], 'min_samples_split': [3, 4], 'max_depth': [15]}

    et_grid = model_selection.GridSearchCV(et_est, et_param_grid, n_jobs=25, cv=10, verbose=1)

    et_grid.fit(titanic_train_data_X, titanic_train_data_Y)

    print('Top N Features Best ET Params:' + str(et_grid.best_params_))

    print('Top N Features Best ET Score:' + str(et_grid.best_score_))

    print('Top N Features ET Train Error:' + str(et_grid.score(titanic_train_data_X, titanic_train_data_Y)))

    feature_imp_sorted_et = pd.DataFrame({'feature': list(titanic_train_data_X),

                            'importance': et_grid.best_estimator_.feature_importances_}).sort_values('importance', ascending=False)

    features_top_n_et = feature_imp_sorted_et.head(top_n_features)['feature']

    print('Sample 25 Features from ET Classifier:')

    print(str(features_top_n_et[:25]))

 

    # 融合以上三個模型

    features_top_n = pd.concat([features_top_n_rf, features_top_n_ada, features_top_n_et],ignore_index=True).drop_duplicates()

 

    return features_top_n

 

(2)根據篩選出的特徵值挑選訓練集和測試集:

利用特徵值重要性排名來去除無用列

(3)利用votingClassifer建立最終預測模型:

#14.建立模型

rf_est = ensemble.RandomForestClassifier(n_estimators = 750, criterion = 'gini', max_features = 'sqrt',

                                            max_depth = 3, min_samples_split = 4, min_samples_leaf = 2,

                                            n_jobs = 50, random_state = 42, verbose = 1)

gbm_est = ensemble.GradientBoostingClassifier(n_estimators=900, learning_rate=0.0008, loss='exponential',

                                                min_samples_split=3, min_samples_leaf=2, max_features='sqrt',

                                                max_depth=3, random_state=42, verbose=1)

et_est = ensemble.ExtraTreesClassifier(n_estimators=750, max_features='sqrt', max_depth=35, n_jobs=50,

                                        criterion='entropy', random_state=42, verbose=1)

 

voting_est = ensemble.VotingClassifier(estimators = [('rf', rf_est),('gbm', gbm_est),('et', et_est)],

                                    voting = 'soft', weights = [3,5,2],

                                    n_jobs = 50)

voting_est.fit(titanic_train_data_X,titanic_train_data_Y)

print('VotingClassifier Score:' + str(voting_est.score(titanic_train_data_X,titanic_train_data_Y)))

print('VotingClassifier Estimators:' + str(voting_est.estimators_))

 

如果不用VotingClassifier的也可以自己根據這幾個模型的測試準確率給幾個模型的結果自定義權重,將最終的加權平均值作爲預測結果。

(4)預測及生成提交文件

#預測

titanic_test_data_X['Survived'] = voting_est.predict(titanic_test_data_X)

 

submission = pd.DataFrame({'PassengerId':test_data_org.loc[:,'PassengerId'],

                            'Survived':titanic_test_data_X.loc[:,'Survived']})

submission.to_csv('result.csv',index=False,sep=',')

輸出文件已經生成,提交到kaggle查看排名

查看排名的步驟

看到了自己的排名是843/13751(當然,這是後面模型微調後提交的最好成績)

0.79在一萬三千人中排兩千名,0.808在一萬三千人中排八百名,看來這個分段大家咬的很緊呀。

看了看排最前面的人準確率居然是百分百,感覺就是把測試集答案給交上去了,正常情況也就是80%+的準確率,正規比賽應該不會出現這種情況。

看到了kaggle提供的在線notebook,還是挺不錯的,爲大家學習大數據競賽提供了良好的條件。

6.微調模型:

準備通過調整不同基礎模型的權重來尋找最佳權重:

(1)修改voting權重爲5 2 2 輸出result1.csv並提交kaggle

提交到kaggle查看排名

得分提高了0.014,但是名次提高了1396名,真的是不可思議,提高一分幹掉千人

修改voting權重爲2 2 5 輸出result2.csv並提交kaggle

名次沒什麼變化,得分還是原來的樣子。

修改voting權重爲0 4 4  輸出result3.csv並提交kaggle

沒有變化,提升困難

修改voting權重爲4 0 4  輸出result3.csv並提交kaggle

(因爲我發現隨機森林和極限樹比較給力,於是就多給一些權重,剛好我學號尾數也是404)

名次又上升了190名到了654名,百尺竿頭更進一步,great!感覺非常棒,那麼模型微調就到此結束了。

我的得分提升過程:

還有一個問題就是kaggle提交預測結果.csv需要上外網

 

如果沒有上外網:

上了外網後:

然後:

等到處理完成

點擊提交

到這裏,我的第一次kaggle練手項目就完成了,學到了很多東西,再回顧一下一般的流程就是

其中特徵工程的部分內容感覺還需要以後的學習再接再厲,大數據競賽還是不容易的,如果能多人組隊分工的話也挺好的,希望大家再以後的kaggle競賽中越戰越勇。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章