Kaggle項目泰坦尼克號生存預測
f="">機器學習演算法:把人類決策思考的過程抽象成一個模型,用數學的方法給模型找到最優化的解,用代碼把最優化的解決方案變成機器可以執行的代碼。所以演算法就是人對於特定事情的理解被轉化為機器的可以理解執行的模型和代碼。需要海量數據不斷優化決策。
所以機器學習演算法和海量數據是相輔相成。兩者的結合是機器學習的本質
機器學習的基本步驟
1.提出問題
一切機器學習目標都是解決生活和實際中的問題,明確的問題為後面的機器學習提供了目標。
2.理解數據
採集數據 根據研究問題,採用相關數據
3.導入數據
查看數據集的信息,從整體上了解數據
4.數據清洗
從數據集中提取需要的數據
5.構建模型
需要用訓練數據來構建模型,用第三步數據特徵放入機器學習演算法中構建模型,所以機器學習最核心的部分就是機器學習演算法
6.模型評估
有了模型後,需要對模型進行評估。通過測試數據評估模型的準確性
7.方案實施
例子:預測泰坦尼克號中存活率
1. 提出問題
什麼樣的人在泰坦尼克號中更容易存活?
2. 理解數據
2.1 數據採集
從Kaggle泰坦尼克號項目頁面下載數據:https://www.kaggle.com/c/titanic
3. 導入數據
#訓練數據集合train = pd.read_csv(train.csv)#測試數據集合test = pd.read_csv(test.csv)print(訓練數據集合,train.shape,測試數據集合,test.shape)full = train.append(test,ignore_index=True)print(合併後的數據集合,full.shape)
查看數據集合信息
full.head()describe只能查看數據類型的描述統計信息,對於其他類型的數據不顯示,比如字元串類型姓名(name),客艙號(Cabin)這很好理解,因為描述統計指標是計算數值,所以需要該列的數據類型是數據#獲取數據集合的描述性統計信息full.describe()full.info()我們發現數據總共有1309行。其中數據類型列:年齡(Age)、船艙號(Cabin)裡面有缺失數據:1)年齡(Age)裡面數據總數是1046條,缺失了1309-1046=263,缺失率263/1309=20%2)船票價格(Fare)裡面數據總數是1308條,缺失了1條數據字元串列:1)登船港口(Embarked)裡面數據總數是1307,只缺失了2條數據,缺失比較少2)船艙號(Cabin)裡面數據總數是295,缺失了1309-295=1014,缺失率=1014/1309=77.5%,缺失比較大這為我們下一步數據清洗指明了方向,只有知道哪些數據缺失數據,我們才能有針對性的處理。
4. 數據清洗(Data Preparation )
4.1 數據預處理
預設值處理
在前面,理解數據階段,我們發現數據總共有1309行。
其中數據類型列:年齡(Age)、船票(Fare)裡面有缺失數據。
字元串列:登船港口(Embarked)、船艙號(Cabin)裡面有缺失數據。
這為我們下一步數據清洗指明了方向,只有知道哪些數據缺失數據,我們才能有針對性的處理。
很多機器學習演算法為了訓練模型,要求所傳入的特徵中不能有空值。
對於數據類型,處理缺失值最簡單的方法就是用平均數來填充缺失值。
數據類型列
年齡(Age)、船票(Fare)欄位處理,使用平均值進行填充
print(處理前)full.info()#對於年齡和船票用平均值來填充full[Age] = full[Age].fillna(full[Age].mean())full[Fare] = full[Fare].fillna(full[Fare].mean())print(處理後)full.info()
字元串列
登船港口(Embarked)處理,先觀察登船港口(Embarked)數據full[Embarked].head()
出發地點:S=英國南安普頓Southampton
途徑地點1:C=法國 瑟堡市Cherbourg
途徑地點2:Q=愛爾蘭 昆士敦Queenstown
只有兩個缺失值,我們將缺失值填充為最頻繁出現的值:
S=英國南安普頓Southampton
print(數據處理前)full.info()full[Embarked] = full[Embarked].fillna(S)print(數據處理後)full.info()
船艙號(Cabin)處理,用占絕大多數的Unkown即『U』來填充
full[Cabin].head()print(數據處理前)full.info()full[Cabin] = full[Cabin].fillna(U)print(數據處理後)full.info()
最終所有空值都處理完畢!!
4.2 特徵工程-特徵提取
在機器學習中,經常使用一堆原始數據和機器學習演算法,例如邏輯回歸演算法或者線性回歸演算法,得到機器學習模型。用機器模型預測。
如何使用各種機器學習的各種演算法?如何使用原始數據達到最優的預測結果??
特徵工程,最大限度的從原始數據中提取體征,以供機器學習演算法和模型使用。數據和特徵決定機器學習的上限,模型和演算法只是逼近機器學習上限。
特徵工程包括特徵提取和特徵選擇與特徵降維
特徵提取,提取出數據的特徵,分為三種數據提取:
(1)數據類型 可也用數據衡量的,之間可以使用
(2)時間序列 在一段時間內定期搜集的序列,單獨轉化為年月日
(3)分類數據 對事物進行描述的信息,無法進行量化。例如:性別,顏色。
用數值代替分類數據,對於兩種類別的數據可以用數字進行提取,大於兩種類別的 可以用one-hot編碼
例如登陸港口,有三個港口,通過one-hot編碼為每一種類別生成一個新的特徵(虛擬變數或者啞變數)
4.2.1數據分類
查看數據類型,分為3種數據類型。並對類別數據處理:用數值代替類別,並進行One-hot編碼.
1.數值類型:
乘客編號(PassengerId),年齡(Age),船票價格(Fare),同代直系親屬人數(SibSp),不同代直系親屬人數(Parch)
2.時間序列:無
3.分類數據:
1)有直接類別的
乘客性別(Sex):男性male,女性female
登船港口(Embarked):出發地點S=英國南安普頓Southampton,途徑地點1:C=法國 瑟堡市Cherbourg,出發地點2:Q=愛爾蘭 昆士敦Queenstown
客艙等級(Pclass):1=1等艙,2=2等艙,3=3等艙
2)字元串類型:可能從這裡面提取出特徵來,也歸到分類數據中
乘客姓名(Name)
客艙號(Cabin)
船票編號(Ticket)
4.2.1.3分類數據
1)有直接類別
乘客性別(Sex):男性male,女性female
full[Sex].head()sex_Mapdict= {male:1, female:0}#map函數:對Series每個數據應用自定義的函數計算full[Sex]= full[Sex].map(sex_Mapdict)full[Sex].head()
登船港口(Embarked):出發地點S=英國南安普頓Southampton,途徑地點1:C=法國 瑟堡市Cherbourg,出發地點2:Q=愛爾蘭 昆士敦Queenstown
#查看該類數據內容full[Embarked].head()#存放提取後的特徵embarkedDf = pd.DataFrame()使用get_dummies進行one-hot編碼,產生虛擬變數(dummy variables),列名前綴是EmbarkedembarkedDf = pd.get_dummies(full[Embarked],prefix=Embarked)embarkedDf#添加one-hot編碼產生的虛擬變數(dummy variables)到泰坦尼克號數據集fullfull = pd.concat([full,embarkedDf],axis=1)因為已經使用登船港口(Embarked)進行了one-hot編碼產生了它的虛擬變數(dummy variables)所以這裡把登船港口(Embarked)刪掉full.drop(Embarked,axis=1,inplace=True)full.head()
客艙等級(Pclass):1=1等艙,2=2等艙,3=3等艙
客艙等級(Pclass):1=1等艙,2=2等艙,3=3等艙#存放提取後的特徵pclassDf = pd.DataFrame()#使用get_dummies進行one-hot編碼,列名前綴是PclasspclassDf = pd.get_dummies(full[Pclass],prefix=Pclass)pclassDf.head()#添加one-hot編碼產生的虛擬變數(dummy variables)到泰坦尼克號數據集fullfull = pd.concat([full,pclassDf],axis=1)#刪掉客艙等級(Pclass)這一列full.drop(Pclass,axis=1,inplace=True)full.head()
2)字元串類型:可能從這裡面提取出特徵來,也歸到分類數據中
乘客姓名(Name)
從姓名中提取頭銜
full[ Name ].head()
查看姓名這一列長啥樣
注意到在乘客名字(Name)中,有一個非常顯著的特點:
乘客頭銜每個名字當中都包含了具體的稱謂或者說是頭銜,將這部分信息提取出來後可以作為非常有用一個新變數,可以幫助我們進行預測。
例如:
Braund, Mr. Owen Harris
Heikkinen, Miss. Laina
Oliva y Ocana, Dona. Fermina
Peter, Master. Michael J
#練習從字元串中提取頭銜,例如Mr#split用於字元串分割,返回一個列表#我們看到姓名中Braund, Mr. Owen Harris,逗號前面的是「名」,逗號後面是『頭銜. 姓』name1=Braund, Mr. Owen Harrissplit用於字元串按分隔符分割,返回一個列表。這裡按逗號分隔字元串也就是字元串Braund, Mr. Owen Harris被按分隔符,拆分成兩部分[Braund,Mr. Owen Harris]你可以把返回的列表列印出來瞧瞧,這裡獲取到列表中元素序號為1的元素,也就是獲取到頭銜所在的那部分,即Mr. Owen Harris這部分#Mr. Owen Harrisstr1=name1.split( , )[1] 繼續對字元串Mr. Owen Harris按分隔符.拆分,得到這樣一個列表[Mr, Owen Harris]這裡獲取到列表中元素序號為0的元素,也就是獲取到頭銜所在的那部分Mr#Mr.str2=str1.split( . )[0]#strip() 方法用於移除字元串頭尾指定的字元(默認為空格)str3=str2.strip()
定義函數:從姓名中獲取頭銜def getTitle(name): str1=name.split( , )[1] #Mr. Owen Harris str2=str1.split( . )[0]#Mr #strip() 方法用於移除字元串頭尾指定的字元(默認為空格) str3=str2.strip() return str3
#存放提取後的特徵titleDf = pd.DataFrame()#map函數:對Series每個數據應用自定義的函數計算titleDf[Title] = full[Name].apply(getTitle)titleDf.head()
定義以下幾種頭銜類別:Officer政府官員Royalty王室(皇室)Mr已婚男士Mrs已婚婦女Miss年輕未婚女子Master有技能的人/教師#姓名中頭銜字元串與定義頭銜類別的映射關係title_mapDict = { "Capt": "Officer", "Col": "Officer", "Major": "Officer", "Jonkheer": "Royalty", "Don": "Royalty", "Sir" : "Royalty", "Dr": "Officer", "Rev": "Officer", "the Countess":"Royalty", "Dona": "Royalty", "Mme": "Mrs", "Mlle": "Miss", "Ms": "Mrs", "Mr" : "Mr", "Mrs" : "Mrs", "Miss" : "Miss", "Master" : "Master", "Lady" : "Royalty" }#map函數:對Series每個數據應用自定義的函數計算titleDf[Title] = titleDf[Title].map(title_mapDict)titleDf.head()
titleDf = pd.get_dummies(titleDf[Title])titleDf.head()#添加one-hot編碼產生的虛擬變數(dummy variables)到泰坦尼克號數據集fullfull = pd.concat([full,titleDf],axis=1)#刪掉姓名這一列full.drop(Name,axis=1,inplace=True)full.head()
客艙號(Cabin)
從客艙號中提取客艙類別
客艙號的首字母是客艙的類別#查看客艙號的內容full[Cabin].head()
#存放客艙號信息cabinDf = pd.DataFrame()full[Cabin] = full[Cabin].apply( lambda x : x[0] )##使用get_dummies進行one-hot編碼,列名前綴是CabincabinDf = pd.get_dummies( full[Cabin] , prefix = Cabin )cabinDf.head()
#添加one-hot編碼產生的虛擬變數(dummy variables)到泰坦尼克號數據集fullfull = pd.concat([full,cabinDf],axis=1)#刪掉客艙號這一列full.drop(Cabin,axis=1,inplace=True)full.head()
建立家庭人數和家庭類別
#存放家庭信息familyDf = pd.DataFrame()家庭人數=同代直系親屬數(Parch)+不同代直系親屬數(SibSp)+乘客自己(因為乘客自己也是家庭成員的一個,所以這裡加1)familyDf[ FamilySize ] = full[ Parch ] + full[ SibSp ] + 1家庭類別:小家庭Family_Single:家庭人數=1中等家庭Family_Small: 2<=家庭人數<=4大家庭Family_Large: 家庭人數>=5#if 條件為真的時候返回if前面內容,否則返回0familyDf[ Family_Single ] = familyDf[ FamilySize ].map( lambda s : 1 if s == 1 else 0 )familyDf[ Family_Small ] = familyDf[ FamilySize ].map( lambda s : 1 if 2 <= s <= 4 else 0 )familyDf[ Family_Large ] = familyDf[ FamilySize ].map( lambda s : 1 if 5 <= s else 0 )familyDf.head()
full = pd.concat([full,familyDf],axis=1)full.head()
4.3 特徵選擇
相關係數法:計算各個特徵的相關係數
#相關性矩陣corrDf = full.corr() corrDf
查看各個特徵與生成情況(Survived)的相關係數,ascending=False表示按降序排列corrDf[Survived].sort_values(ascending =False)
根據各個特徵與生成情況(Survived)的相關係數大小,我們選擇了這幾個特徵作為模型的輸入:
頭銜(前面所在的數據集titleDf)、客艙等級(pclassDf)、家庭大小(familyDf)、船票價格(Fare)、船艙號(cabinDf)、登船港口(embarkedDf)、性別(Sex)
#特徵選擇full_X = pd.concat( [titleDf,#頭銜 pclassDf,#客艙等級 familyDf,#家庭大小 #full[Fare],#船票價格 cabinDf,#船艙號 embarkedDf,#登船港口 full[Sex]#性別 ] , axis=1 )full_X.head()
5.構建模型
用訓練數據和某個機器學習演算法得到機器學習模型,用測試數據評估模型
5.1 建立訓練數據集和測試數據集
KAGGLE中的訓練數據集合為原始數據集(source)即train.csv,測試數據集合由於沒有結果這一列,因此叫做預測數據集(pred)即test.csv。 因此要構建3個數據集合:1.訓練數據train,為原始數據集的80% 2.測試數據test,為原始數據集的20% 3.預測數據pred,為KAGGLE提供的預測數據集.
print(訓練數據集合,train.shape,測試數據集合,test.shape)
訓練數據集合 (891, 12) 測試數據集合 (418, 11)
#原始數據有891行source_Row = 891#原始數據集:特徵source_X = full_X.loc[0:source_Row-1,:]#原始數據集:標籤source_y = full.loc[0:source_Row-1,Survived]#預測數據集:特徵pred_X = full_X.loc[source_Row:,:]from sklearn.cross_validation import train_test_split#建立模型用的訓練數據集和測試數據集train_X,test_X,train_y,test_y = train_test_split(source_X,source_y,train_size=.8)#輸出數據集大小print(原始數據集特徵,source_X.shape,訓練數據集特徵,train_X.shape,測試數據集特徵,test_X.shape)print(原始數據集標籤,source_y.shape,訓練數據集標籤,train_y.shape,測試數據集標籤,test_y.shape)
原始數據集特徵 (891, 26) 訓練數據集特徵 (712, 26) 測試數據集特徵 (179, 26)
原始數據集標籤 (891,) 訓練數據集標籤 (712,) 測試數據集標籤 (179,)5.2訓練模型
#導入演算法from sklearn.linear_model import LogisticRegression#創建模型,邏輯回歸model = LogisticRegression()#訓練模型model.fit(train_X,train_y)
6 模型評估
# 分類問題,score得到的是模型的正確率model.score(test_X,test_y)
7.方案實施(Deployment)
#使用機器學習模型,對預測數據集中的生存情況進行預測pred_Y = model.predict(pred_X)
生成的預測值是浮點數(0.0,1.0)但是Kaggle提交的結果是整數(0,1)所以要對數據類型進行轉換pred_Y = pred_Y.astype(int)#乘客idpassenger_id = full.loc[source_Row:,PassengerId]#數據框:乘客id,預測生存情況的值predDf = pd.DataFrame({PassengerId:passenger_id,Survived:pred_Y})predDf.shapepredDf.head()#把預測數據導出CSV格式predDf.to_csv(tatanic.csv,index = False)
推薦閱讀:
※IMDB Movie :Python數據分析報告
※泰坦尼克生存概率預測
※數據分析師必須知道的九個問題
※不識廬山真面目,只緣身在此山中
※成為領導的秘密
TAG:數據分析 |