機器學(xué)習(xí)工程師納米學(xué)位
機器學(xué)習(xí)基礎(chǔ)
項目 0: 預(yù)測泰坦尼克號乘客生還率
1912年竖螃,泰坦尼克號在第一次航行中就與冰山相撞沉沒捧灰,導(dǎo)致了大部分乘客和船員身亡吨娜。在這個入門項目中树肃,我們將探索部分泰坦尼克號旅客名單丐吓,來確定哪些特征可以最好地預(yù)測一個人是否會生還甸赃。為了完成這個項目柿汛,你將需要實現(xiàn)幾個基于條件的預(yù)測并回答下面的問題。我們將根據(jù)代碼的完成度和對問題的解答來對你提交的項目的進行評估埠对。
提示:這樣的文字將會指導(dǎo)你如何使用 iPython Notebook 來完成項目络断。
點擊這里查看本文件的英文版本。
了解數(shù)據(jù)
當(dāng)我們開始處理泰坦尼克號乘客數(shù)據(jù)時项玛,會先導(dǎo)入我們需要的功能模塊以及將數(shù)據(jù)加載到 pandas
DataFrame貌笨。運行下面區(qū)域中的代碼加載數(shù)據(jù),并使用 .head()
函數(shù)顯示前幾項乘客數(shù)據(jù)襟沮。
提示:你可以通過單擊代碼區(qū)域躁绸,然后使用鍵盤快捷鍵 Shift+Enter 或 Shift+ Return 來運行代碼〕枷或者在選擇代碼后使用播放(run cell)按鈕執(zhí)行代碼净刮。像這樣的 MarkDown 文本可以通過雙擊編輯,并使用這些相同的快捷鍵保存硅则。Markdown 允許你編寫易讀的純文本并且可以轉(zhuǎn)換為 HTML淹父。
# 檢查你的Python版本
from sys import version_info
if version_info.major != 2 and version_info.minor != 7:
raise Exception('請使用Python 2.7來完成此項目')
import numpy as np
import pandas as pd
# 數(shù)據(jù)可視化代碼
from titanic_visualizations import survival_stats
from IPython.display import display
%matplotlib inline
# 加載數(shù)據(jù)集
in_file = 'titanic_data.csv'
full_data = pd.read_csv(in_file)
# 顯示數(shù)據(jù)列表中的前幾項乘客數(shù)據(jù)
display(full_data.head())
PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S |
1 | 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
2 | 3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | S |
3 | 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S |
4 | 5 | 0 | 3 | Allen, Mr. William Henry | male | 35.0 | 0 | 0 | 373450 | 8.0500 | NaN | S |
從泰坦尼克號的數(shù)據(jù)樣本中,我們可以看到船上每位旅客的特征
- Survived:是否存活(0代表否怎虫,1代表是)
- Pclass:社會階級(1代表上層階級暑认,2代表中層階級,3代表底層階級)
- Name:船上乘客的名字
- Sex:船上乘客的性別
-
Age:船上乘客的年齡(可能存在
NaN
) - SibSp:乘客在船上的兄弟姐妹和配偶的數(shù)量
- Parch:乘客在船上的父母以及小孩的數(shù)量
- Ticket:乘客船票的編號
- Fare:乘客為船票支付的費用
-
Cabin:乘客所在船艙的編號(可能存在
NaN
) - Embarked:乘客上船的港口(C 代表從 Cherbourg 登船大审,Q 代表從 Queenstown 登船蘸际,S 代表從 Southampton 登船)
因為我們感興趣的是每個乘客或船員是否在事故中活了下來⊥椒觯可以將 Survived 這一特征從這個數(shù)據(jù)集移除粮彤,并且用一個單獨的變量 outcomes
來存儲。它也做為我們要預(yù)測的目標(biāo)。
運行該代碼导坟,從數(shù)據(jù)集中移除 Survived 這個特征屿良,并將它存儲在變量 outcomes
中。
# 從數(shù)據(jù)集中移除 'Survived' 這個特征惫周,并將它存儲在一個新的變量中尘惧。
outcomes = full_data['Survived']
data = full_data.drop('Survived', axis = 1)
# 顯示已移除 'Survived' 特征的數(shù)據(jù)集
display(data.head())
PassengerId | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 3 | Braund, Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S |
1 | 2 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
2 | 3 | 3 | Heikkinen, Miss. Laina | female | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | S |
3 | 4 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S |
4 | 5 | 3 | Allen, Mr. William Henry | male | 35.0 | 0 | 0 | 373450 | 8.0500 | NaN | S |
這個例子展示了如何將泰坦尼克號的 Survived 數(shù)據(jù)從 DataFrame 移除。注意到 data
(乘客數(shù)據(jù))和 outcomes
(是否存活)現(xiàn)在已經(jīng)匹配好递递。這意味著對于任何乘客的 data.loc[i]
都有對應(yīng)的存活的結(jié)果 outcome[i]
喷橙。
計算準(zhǔn)確率
為了驗證我們預(yù)測的結(jié)果,我們需要一個標(biāo)準(zhǔn)來給我們的預(yù)測打分登舞。因為我們最感興趣的是我們預(yù)測的準(zhǔn)確率重慢,既正確預(yù)測乘客存活的比例。運行下面的代碼來創(chuàng)建我們的 accuracy_score
函數(shù)以對前五名乘客的預(yù)測來做測試逊躁。
思考題:在前五個乘客中似踱,如果我們預(yù)測他們?nèi)慷即婊睿阌X得我們預(yù)測的準(zhǔn)確率是多少稽煤?
In [5]:
def accuracy_score(truth, pred):
""" 返回 pred 相對于 truth 的準(zhǔn)確率 """
# 確保預(yù)測的數(shù)量與結(jié)果的數(shù)量一致
if len(truth) == len(pred):
# 計算預(yù)測準(zhǔn)確率(百分比)
return "Predictions have an accuracy of {:.2f}%.".format((truth == pred).mean()*100)
else:
return "Number of predictions does not match number of outcomes!"
# 測試 'accuracy_score' 函數(shù)
predictions = pd.Series(np.ones(5, dtype = int)) #五個預(yù)測全部為1核芽,既存活
print accuracy_score(outcomes[:5], predictions)
Predictions have an accuracy of 60.00%.
提示:如果你保存 iPython Notebook,代碼運行的輸出也將被保存酵熙。但是轧简,一旦你重新打開項目,你的工作區(qū)將會被重置匾二。請確保每次都從上次離開的地方運行代碼來重新生成變量和函數(shù)哮独。
最簡單的預(yù)測
如果我們要預(yù)測泰坦尼克號上的乘客是否存活,但是我們又對他們一無所知察藐,那么最好的預(yù)測就是船上的人無一幸免皮璧。這是因為,我們可以假定當(dāng)船沉沒的時候大多數(shù)乘客都遇難了分飞。下面的 predictions_0
函數(shù)就預(yù)測船上的乘客全部遇難悴务。
def predictions_0(data):
""" 不考慮任何特征,預(yù)測所有人都無法生還 """
predictions = []
for _, passenger in data.iterrows():
# 預(yù)測 'passenger' 的生還率
predictions.append(0)
# 返回預(yù)測結(jié)果
return pd.Series(predictions)
# 進行預(yù)測
predictions = predictions_0(data)
問題1:對比真實的泰坦尼克號的數(shù)據(jù)譬猫,如果我們做一個所有乘客都沒有存活的預(yù)測讯檐,這個預(yù)測的準(zhǔn)確率能達到多少?
回答: 61.62%
提示:運行下面的代碼來查看預(yù)測的準(zhǔn)確率染服。
print accuracy_score(outcomes, predictions)
Predictions have an accuracy of 61.62%.
考慮一個特征進行預(yù)測
我們可以使用 survival_stats
函數(shù)來看看 Sex 這一特征對乘客的存活率有多大影響别洪。這個函數(shù)定義在名為 titanic_visualizations.py
的 Python 腳本文件中,我們的項目提供了這個文件柳刮。傳遞給函數(shù)的前兩個參數(shù)分別是泰坦尼克號的乘客數(shù)據(jù)和乘客的 生還結(jié)果挖垛。第三個參數(shù)表明我們會依據(jù)哪個特征來繪制圖形痒钝。
運行下面的代碼繪制出依據(jù)乘客性別計算存活率的柱形圖。
survival_stats(data, outcomes, 'Sex')
觀察泰坦尼克號上乘客存活的數(shù)據(jù)統(tǒng)計晕换,我們可以發(fā)現(xiàn)大部分男性乘客在船沉沒的時候都遇難了午乓。相反的站宗,大部分女性乘客都在事故中生還闸准。讓我們以此改進先前的預(yù)測:如果乘客是男性,那么我們就預(yù)測他們遇難梢灭;如果乘客是女性夷家,那么我們預(yù)測他們在事故中活了下來。
將下面的代碼補充完整敏释,讓函數(shù)可以進行正確預(yù)測库快。
提示:您可以用訪問 dictionary(字典)的方法來訪問船上乘客的每個特征對應(yīng)的值。例如钥顽, passenger['Sex']
返回乘客的性別义屏。
def predictions_1(data):
""" 只考慮一個特征,如果是女性則生還 """
predictions = []
for _, passenger in data.iterrows():
# TODO 1
# 移除下方的 'pass' 聲明
# 輸入你自己的預(yù)測條件
if passenger['Sex'] == 'male':
predictions.append(0)
else:
predictions.append(1)
# 返回預(yù)測結(jié)果
return pd.Series(predictions)
# 進行預(yù)測
predictions = predictions_1(data)
問題2:當(dāng)我們預(yù)測船上女性乘客全部存活蜂大,而剩下的人全部遇難闽铐,那么我們預(yù)測的準(zhǔn)確率會達到多少?
回答: 78.68%
提示:你需要在下面添加一個代碼區(qū)域奶浦,實現(xiàn)代碼并運行來計算準(zhǔn)確率兄墅。
print accuracy_score(outcomes, predictions)
Predictions have an accuracy of 78.68%.
考慮兩個特征進行預(yù)測
僅僅使用乘客性別(Sex)這一特征,我們預(yù)測的準(zhǔn)確性就有了明顯的提高“牟妫現(xiàn)在再看一下使用額外的特征能否更進一步提升我們的預(yù)測準(zhǔn)確度隙咸。例如,綜合考慮所有在泰坦尼克號上的男性乘客:我們是否找到這些乘客中的一個子集成洗,他們的存活概率較高五督。讓我們再次使用 survival_stats
函數(shù)來看看每位男性乘客的年齡(Age)。這一次瓶殃,我們將使用第四個參數(shù)來限定柱形圖中只有男性乘客概荷。
運行下面這段代碼,把男性基于年齡的生存結(jié)果繪制出來碌燕。
survival_stats(data, outcomes, 'Age', ["Sex == 'male'"])
仔細觀察泰坦尼克號存活的數(shù)據(jù)統(tǒng)計误证,在船沉沒的時候,大部分小于10歲的男孩都活著修壕,而大多數(shù)10歲以上的男性都隨著船的沉沒而遇難愈捅。讓我們繼續(xù)在先前預(yù)測的基礎(chǔ)上構(gòu)建:如果乘客是女性,那么我們就預(yù)測她們?nèi)看婊畲瑞蝗绻丝褪悄行圆⑶倚∮?0歲蓝谨,我們也會預(yù)測他們?nèi)看婊睿凰衅渌覀兙皖A(yù)測他們都沒有幸存。
將下面缺失的代碼補充完整譬巫,讓我們的函數(shù)可以實現(xiàn)預(yù)測咖楣。
提示: 您可以用之前 predictions_1
的代碼作為開始來修改代碼,實現(xiàn)新的預(yù)測函數(shù)芦昔。
def predictions_2(data):
""" 考慮兩個特征:
- 如果是女性則生還
- 如果是男性并且小于10歲則生還 """
predictions = []
for _, passenger in data.iterrows():
# TODO 2
# 移除下方的 'pass' 聲明
# 輸入你自己的預(yù)測條件
if passenger['Sex'] == 'female':
predictions.append(1)
elif passenger['Age'] < 10:
predictions.append(1)
else:
predictions.append(0)
## 用這段代碼準(zhǔn)確率下降了诱贿,(原因是數(shù)據(jù)中有字段值缺失)
# if passenger['Sex'] == 'male':
# if passenger['Age'] >= 10:
# predictions.append(0)
# else:
# predictions.append(1)
# else:
# predictions.append(1)
# 返回預(yù)測結(jié)果
return pd.Series(predictions)
# 進行預(yù)測
predictions = predictions_2(data)
問題3:當(dāng)預(yù)測所有女性以及小于10歲的男性都存活的時候,預(yù)測的準(zhǔn)確率會達到多少咕缎?
回答: 79.35%
提示:你需要在下面添加一個代碼區(qū)域珠十,實現(xiàn)代碼并運行來計算準(zhǔn)確率。
print accuracy_score(outcomes, predictions)
Predictions have an accuracy of 79.35%.
你自己的預(yù)測模型
添加年齡(Age)特征與性別(Sex)的結(jié)合比單獨使用性別(Sex)也提高了不少準(zhǔn)確度∑竞溃現(xiàn)在該你來做預(yù)測了:找到一系列的特征和條件來對數(shù)據(jù)進行劃分焙蹭,使得預(yù)測結(jié)果提高到80%以上。這可能需要多個特性和多個層次的條件語句才會成功嫂伞。你可以在不同的條件下多次使用相同的特征孔厉。Pclass,Sex帖努,Age撰豺,SibSp和 Parch 是建議嘗試使用的特征。
使用 survival_stats
函數(shù)來觀測泰坦尼克號上乘客存活的數(shù)據(jù)統(tǒng)計然磷。
提示: 要使用多個過濾條件郑趁,把每一個條件放在一個列表里作為最后一個參數(shù)傳遞進去。例如: ["Sex == 'male'", "Age < 18"]
survival_stats(data, outcomes, "Pclass")
survival_stats(data, outcomes, "Pclass",["Sex == 'female'"] )
survival_stats(data, outcomes, 'Parch', ["Pclass == 3","Sex == 'female'",])
survival_stats(data, outcomes, "SibSp",["Pclass == 3","Sex == 'female'","Parch > 0"] )
survival_stats(data, outcomes, "SibSp",["Pclass == 3","Sex == 'female'","Parch > 0","Parch > 0"] )
survival_stats(data, outcomes, "Parch",["Pclass == 1","Sex == 'male'","Age >= 10"] )
當(dāng)查看和研究了圖形化的泰坦尼克號上乘客的數(shù)據(jù)統(tǒng)計后姿搜,請補全下面這段代碼中缺失的部分寡润,使得函數(shù)可以返回你的預(yù)測。
在到達最終的預(yù)測模型前請確保記錄你嘗試過的各種特征和條件舅柜。
提示: 您可以用之前 predictions_2
的代碼作為開始來修改代碼梭纹,實現(xiàn)新的預(yù)測函數(shù)。
def predictions_3(data):
""" 考慮多個特征致份,準(zhǔn)確率至少達到80% """
predictions = []
for _, passenger in data.iterrows():
# TODO 3
# 移除下方的 'pass' 聲明
# 輸入你自己的預(yù)測條件
if passenger['Sex'] == 'female':
if passenger['Pclass'] == 3 and passenger['Parch'] > 0 and passenger['SibSp'] > 0:
predictions.append(0)
else:
predictions.append(1)
elif passenger['Age'] < 10:
predictions.append(1)
else:
predictions.append(0)
# 返回預(yù)測結(jié)果
return pd.Series(predictions)
# 進行預(yù)測
predictions = predictions_3(data)
問題4:請描述你實現(xiàn)80%準(zhǔn)確度的預(yù)測模型所經(jīng)歷的步驟变抽。您觀察過哪些特征?某些特性是否比其他特征更有幫助氮块?你用了什么條件來預(yù)測生還結(jié)果绍载?你最終的預(yù)測的準(zhǔn)確率是多少?
回答:通過前面的Sex和Age特征分析大致了解了分析過程和影響結(jié)果滔蝉,后來單獨觀察過特征有Pclass击儡、Parch、SibSp蝠引,發(fā)現(xiàn)Pclass==3時死亡比例相對很高阳谍,又由于之前在決策樹根分支下將female全部假設(shè)存活蛀柴,所以想按照Pclass特征將female中的死亡的區(qū)分出來,發(fā)現(xiàn)Pclass==3時female死亡和存活的比例相同矫夯,然后再想能否在該條件下通過其他特征進行區(qū)分鸽疾,試了Age發(fā)現(xiàn)很難區(qū)分,然后分別試了Parch和SibSp,發(fā)現(xiàn)Parch>0或SibSp>0時训貌,female死亡率均>50%,由此制肮,可以將female在Pclass==3條件下,Parch>0或SibSp>0的全部假設(shè)為死亡旺订,這樣會提供死亡的預(yù)測準(zhǔn)確性弄企。通過實驗發(fā)現(xiàn)超燃,Parch>0或SibSp>0時均提高準(zhǔn)確率到81.03%区拳,若兩者同時滿足測準(zhǔn)確率又進一步提高,所以最終采用了Parch>0且SibSp>0來將女性低階層的假設(shè)為死亡意乓,準(zhǔn)確率達到81.14%
提示:你需要在下面添加一個代碼區(qū)域樱调,實現(xiàn)代碼并運行來計算準(zhǔn)確率。
print accuracy_score(outcomes, predictions)
Predictions have an accuracy of 81.14%.
結(jié)論
經(jīng)過了數(shù)次對數(shù)據(jù)的探索和分類届良,你創(chuàng)建了一個預(yù)測泰坦尼克號乘客存活率的有用的算法笆凌。在這個項目中你手動地實現(xiàn)了一個簡單的機器學(xué)習(xí)模型——決策樹(decision tree)。決策樹每次按照一個特征把數(shù)據(jù)分割成越來越小的群組(被稱為 nodes)士葫。每次數(shù)據(jù)的一個子集被分出來乞而,如果分割后新子集之間的相似度比分割前更高(包含近似的標(biāo)簽),我們的預(yù)測也就更加準(zhǔn)確慢显。電腦來幫助我們做這件事會比手動做更徹底爪模,更精確。這個鏈接提供了另一個使用決策樹做機器學(xué)習(xí)入門的例子荚藻。
決策樹是許多監(jiān)督學(xué)習(xí)算法中的一種屋灌。在監(jiān)督學(xué)習(xí)中,我們關(guān)心的是使用數(shù)據(jù)的特征并根據(jù)數(shù)據(jù)的結(jié)果標(biāo)簽進行預(yù)測或建模应狱。也就是說共郭,每一組數(shù)據(jù)都有一個真正的結(jié)果值,不論是像泰坦尼克號生存數(shù)據(jù)集一樣的標(biāo)簽疾呻,或者是連續(xù)的房價預(yù)測除嘹。
問題5:想象一個真實世界中應(yīng)用監(jiān)督學(xué)習(xí)的場景,你期望預(yù)測的結(jié)果是什么岸蜗?舉出兩個在這個場景中能夠幫助你進行預(yù)測的數(shù)據(jù)集中的特征尉咕。
回答: 天氣預(yù)報的預(yù)測,預(yù)測明天是否晴天還是非晴天散吵,特征數(shù)據(jù)有:今天是否天晴龙考、風(fēng)力蟆肆、濕度、氣壓等
注意: 當(dāng)你寫完了所有5個問題晦款,3個TODO炎功。你就可以把你的 iPython Notebook 導(dǎo)出成 HTML 文件。你可以在菜單欄缓溅,這樣導(dǎo)出File -> Download as -> HTML (.html) 把這個 HTML 和這個 iPython notebook 一起做為你的作業(yè)提交蛇损。
翻譯:毛禮建 | 校譯:黃強 | 審譯:曹晨巍