機器學習入門實戰---預測泰坦尼克號上的生存者並熟悉機器學習的基礎知識

背景知識:

泰坦尼克號1912年4月從英國南安普頓出發,途徑法國,愛爾蘭在美國大西洋碰觸冰山沉沒,一部分人倖免於難,一部分人沒有生存,這個案例中就是要經過機器學習的算法來預測一下test.csv中418人的生存情況。案例詳細內容能夠訪問網站:https://www.kaggle.com/c/titanic。經過這個案例你能夠大體掌握一個機器學習的基本步驟,本文最後附上案例的源碼。算法

1、提出問題

首先咱們從kaggle上下載了泰坦尼克號案例的train.csv和test.csv兩個數據,這裏我爲你們已經下好,你們能夠在百度網盤裏下載,地址:連接:https://pan.baidu.com/s/1RV-U... 密碼:zlkj。app

2、理解數據

首先導入數據,能夠看到訓練數據集train.csv中有891行,12列數據,而測試數據集中有418行,11列數據;缺乏的這一列數據正是咱們要預測的生存情況數據。機器學習

import numpy as np
import pandas as pd
#導入訓練集
train = pd.read_csv('train.csv')
#導入測試集
test = pd.read_csv('test.csv')
#查看測試數據集合訓練數據集的形狀
# print("訓練數據集:",train.shape)
# print("測試數據集:",test.shape)
full = train.append(test,ignore_index=True)
# print("合併後的數據集:",full.shape)
# print(full.head(10))

經過實驗結果咱們能夠知道,每一名乘客都對應着一個12維數據,其含義是:函數

1.Age:乘客年齡      
   2.Cabin:乘客船艙座位號
   3.Embarked:乘客登船的港口,有三個可選值:S:南安普頓,C:法國瑟堡 Q:愛爾蘭昆士敦
   4.Fare:船票費用
   5.Name:乘客姓名
   6.parch:乘客的父母與子女數量
   7.PassengerId:乘客ID
   8.Pclass:乘客所在的船艙等級,1;一等,2;二等;3:三等
   9.sex:乘客性別
   10.SibSp:乘客的兄弟姐妹以及配偶數量
   11.Survived:乘客是否存活標誌;1:活着的  0:死亡
   12.Ticket:票的編號

總數據有1309行,Age、Cabin、Embarked、Fare這四列數據中有缺失的狀況,接下來的第三步就是要清洗數據,填補缺失值。學習

3、清洗數據

首先處理一下缺失的數據,若是缺失的數據是數字類型的,能夠用平均數代替,若是是字符串類型的,能夠用出現最多的數(衆數)來替代。測試

# 填充年齡缺失值
full.Age = full.Age.fillna(full.Age.mean())
# 填充船票價格缺失值
full.Fare = full.Fare.fillna(full.Fare.mean())
# #填充登船的港口,由於最多的爲s,故將全部的缺失值填充爲S
full.Embarked = full.Embarked.fillna('S')
# 因爲船票號這一欄缺失值過多,故將其填充爲U
full.Cabin = full.Cabin.fillna('U')

在作好這一步以後,數據還須要對一些列的字符串數據類型進行編碼,好比Sex性別的分類數據,須要進行one-hot編碼,方便機器學習識別。這裏須要對性別、港口和姓名、船艙等級這些分類數據,進行從新編碼。應用map函數能夠對一列數據作同一個操做:網站

sexDict = {'male':1,'female':0}
sex = full.Sex.map(sexDict)
print(sex.head())

登船的港口有三個,分別是英國南安普頓、法國瑟堡、愛爾蘭昆士敦,分別用首字母S、C、Q表示。編碼

embarked = pd.DataFrame()
embarked = pd.get_dummies(full.Embarked,prefix="Embarked")
print(embarked.head())
#對船艙等級採起一樣的方法
pclass = pd.DataFrame()
pclass = pd.get_dummies(full.Pclass,prefix="Pclass")
print(pclass.head())

接下來咱們看一下名字這一列的數據字符串格式:名,頭銜,姓,咱們須要從名字裏面獲取頭銜來斷定是否對生存狀況的影響。經過定義一個函數:
第一步獲取name1剔除名字中逗號前面的名,
第二步剔除名字中冒號後面的姓,
第三步用strip函數剔除字符串頭尾指定的字符(默認爲空格)而後返回中間的頭銜。
第四步應用函數,用一個表格型數據Df存放提取後的頭銜,
第五步講姓名中的頭銜字符串與定義頭銜類別的映射關係,再把頭銜進行one-hot編碼,code

定義一個函數獲取每個姓名列中的頭銜

def title1(name):
    name1 = name.split(',')[1]
    name2 = name1.split('.')[0]
    #使用strip函數提出姓名列的頭尾,得到頭銜
    name3 = name2.strip()
    return name3
titleDf = pd.DataFrame()
titleDf['Title'] = full.Name.map(title1)
titleDict = {
    'Capt':'officer',
    'Col':'officer',
    'Major':'officer',
    'Dr':'officer',
    'Rev':'officer',
    'Jonkheer':'Royalty',
    'Don':'Royalty',
    'Sir':'Royalty',
    'the Countess':'Royalty',
    'Dona':'Royalty',
    'Lady':'Royalty',
    'Mlle':'Miss',
    'Miss':'Miss',
    'Mr':'Mr',
    'Mme':'Mrs',
    'Ms':'Mrs',
    'Mrs':'Mrs',
    'Master':'Master'
}
titleDf['Title'] = titleDf['Title'].map(titleDict)
titleDf = pd.get_dummies(titleDf['Title'])
print(titleDf.head())

接着從座位號提取坐席類別,用seat存放客艙號的信息坐席類別就是座位號的首字母,好比C85,類別映射爲首字母C,用U表明不知道的數據。使用lambda匿名函數提取Cabin中的首字母:ip

seat = pd.DataFrame()
seat['seat'] = full['Cabin']
seat.seat = seat.seat.map(lambda  a:a[0])
#使用one-hot編碼
seat = pd.get_dummies(seat.seat,prefix="Cabin")
#print(seat.head())

對船上每個乘客的家庭成員數量進行一個統計。分別將原始數據中的SibSp列和Parch中的數據相加,再加上被統計者自身。

#對船上每個乘客的家庭成員數量進行一個統計
family = pd.DataFrame()
family['family'] = full.SibSp + full.Parch + 1
#print(family.head())

最後就是將原始數據複製一份,刪除咱們剛剛對其中從新編碼的列(Cabin、Name、Sex、Pclass、Embarked、Parch、SibSp;還有票的編號Ticket這一列沒有關係的數據。
最後合併的列包括了剛剛處理產生的新列名好比:da、family、seat、titleDf、pclass、embarked、sex。咱們發現新的數據da有1309行,27列。

最後就是將原始數據複製一份,

刪除咱們剛剛對其中從新編碼的列(Cabin、Name、Sex、Pclass、Embarked、Parch、SibSp; 還有票的編號Ticket這一列沒有關係的數據.最後合併的列包括了剛剛處理產生的新列名好比:da、family、seat、titleDf、pclass、embarked、sex.咱們發現新的數據da有1309行,27列

da = train.append(test,ignore_index=True)
#採起一樣的方式填充缺失值
da.Age = da.Age.fillna(da.Age.mean())
da.Fare = da.Fare.fillna(da.Fare.mean())
da.Embarked = da.Embarked.fillna('S')
da.Cabin = da.Cabin.fillna('U')
#提出不須要的列
da = da.drop(['Name','Pclass','Cabin','Parch','Embarked','SibSp','Ticket','Sex'],axis=1)
#合併修改後的列
da = pd.concat([titleDf,seat,family,pclass,embarked,da,sex],axis=1)
#print(da.shape)
#print(da.head())

4、模型創建與評估

第一步:用數據框corr()獲得相關係數矩陣,

第二步:講相關係數矩陣的生存狀況的列提取出來,分別按照降序排列和升序排列

#使用數據框corr獲取相關係數矩陣,將相關係數提取出來,按照升序和降序排列
corrDf = da.corr()
#print(corrDf['Survived'].sort_values(ascending=False))
#print(corrDf['Survived'].sort_values(ascending=True))

咱們發現相關係數大於0的列中:頭銜、客艙等級、船票價格、船艙號都與生存情況呈現正線性關係在相關係數小於0的列中:頭銜、性別、客艙等級、客艙號與生存狀況呈現負線性相關。這些特徵其實與咱們在數據清洗過程當中處理的列很是相關,這裏咱們直接採用上一步最後造成的新數據da

第三步:咱們在原始訓練數據中有891行,選取特徵和標籤,而後對這個數據進行拆分訓練集和測試集,

#將原始數據集拆分爲訓練集合評估集
sourceRow = 891
source_X  = da.loc[0:sourceRow-1,:]
source_X = source_X.drop(['Survived'],axis  =1)
source_y  =da.loc[0:sourceRow-1,'Survived']

#拆分訓練集和測試集
train_X,test_X,train_y,test_y = train_test_split(source_X,source_y,train_size=0.8)

#輸出數據集大小
# print('原始數據集特徵:',source_X.shape)
# print('訓練集特徵:',train_X.shape)
# print('測試集特徵:',test_X.shape)
# print('原始數據集標籤:',source_y.shape)
# print('訓練數據集標籤:',train_y.shape)
# print('測試數據集標籤:',test_y.shape)

第四步是導入算法,訓練模型:

導入訓練數據的特徵train_X712條,包括性別,頭銜等,導入標籤train_y712條生存情況,獲得正確率0.87:

#使用邏輯迴歸模型
model = LogisticRegression()
#使用數據,訓練模型
model.fit(train_X,train_y)
# print(model.fit(train_X,train_y))
# print(model.score(test_X,test_y))

第五步:方案實施

用機器學習模型,對預測數據集中的生存狀況進行預測,這裏用乘客的ID,數據框Df保存預測狀況的值。

#方案實施,對預測數據集中的數據進行預測
predict_X = da.loc[sourceRow:,:]
predict_X = da.drop(['Survived'],axis=1)
pred_Y = model.predict(predict_X)
pred_Y = pred_Y.astype(int)  
#乘客ID
passenger_id = da.loc[sourceRow,'PassengerId']
predDf = pd.DataFrame({'PassengerId':passenger_id,'Survived':pred_Y})
print(predDf.shape)
print(predDf)

最後附上源碼:連接:https://pan.baidu.com/s/1cb60... 密碼:y12u。有興趣的能夠在閱讀本文點贊,歡迎評論哦!

相關文章
相關標籤/搜索