天天看點

案例-Kaggle泰坦尼克号生存預測分析

資料采集和了解

#設定ast_node_interactivity = "all"使得可以同時輸出多條語句
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
#導入包
import pandas as pd
import numpy as np
#導入資料
train=pd.read_csv(r'E:\python\data\titanic\train.csv')
test=pd.read_csv(r'E:\python\data\titanic\test.csv')
print('訓練集資料規模:{}'.format(train.shape))
print('測試集資料規模:{}'.format(test.shape))

    訓練集資料規模:(, )
    測試集資料規模:(, )
           

訓練資料集比測試資料集的列多一個,即Survived值。由于它是預測的生存值,是以,在測試資料集中沒有。

#檢視訓練集資訊
train.head()
test.head()
           
案例-Kaggle泰坦尼克号生存預測分析

為了友善對訓練資料和測試資料進行清洗,将訓練資料和測試資料進行合并

#通過設定ignore_index=True參數,合并後的資料集會重新生成一個index
full=pd.concat([train,test],ignore_index=True)
full.head()
           
案例-Kaggle泰坦尼克号生存預測分析

針對每一個字段做一個簡單的解釋:

PassengerId: 乘客ID;

Survived: 生存情況,0代表不幸遇難,1代表存活;

Pclass: 倉位等級,1為一等艙,2為二等艙,3為三等艙;

Name: 乘客姓名;

Sex: 性别;

Age: 年齡;

SibSp: 乘客在船上的兄妹姐妹數/配偶數(即同代直系親屬數);

Parch: 乘客在船上的父母數/子女數(即不同代直系親屬數);

Ticket: 船票編号;

Fare: 船票價格;

Cabin: 客艙号;

Embarked: 登船港口(S: Southampton; C: Cherbourg Q: Queenstown)

#檢視資料描述性統計
full.describe()
           
案例-Kaggle泰坦尼克号生存預測分析

因為,describe()函數隻能檢視資料類型的描述統計資訊,無法檢視類似字元類型的資訊。

故需用info()函數進一步檢視每一列的資料資訊。

full.info()

    <class 'pandas.core.frame.DataFrame'>
    RangeIndex:  entries,  to 
    Data columns (total  columns):
    Age             non-null float64
    Cabin           non-null object
    Embarked        non-null object
    Fare            non-null float64
    Name            non-null object
    Parch           non-null int64
    PassengerId     non-null int64
    Pclass          non-null int64
    Sex             non-null object
    SibSp           non-null int64
    Survived        non-null float64
    Ticket          non-null object
    dtypes: float64(), int64(), object()
    memory usage: + KB
           

資料的總行數為1309行,其中,Age一欄中263列有缺失項;Fare一欄中1列有缺失項;Survived一欄隻有891列,剛好對應訓練資料集的行數。除了Age和Fare以外,Cabin/Embarked也有缺失項。

也可以用另一個指令,檢視缺失項資訊

full.isnull().sum()

    Age             
    Cabin          
    Embarked          
    Fare              
    Name              
    Parch             
    PassengerId       
    Pclass            
    Sex               
    SibSp             
    Survived        
    Ticket            
    dtype: int64
           

資料清洗

如果是數值類型,使用平均值或者中位數進行填充

年齡(Age) 最小值為0.17,不存在0值,其資料缺失率為263/1309=20.09%,由于Age的平均數與中位數接近,故選擇平均值作為缺失項的填充值。

full['Age']=full['Age'].fillna(full['Age'].mean())
           

船票價格(Fare)一欄資料缺失項僅為一行,且存在票價為0的記錄,如下:

full.loc[full['Fare']==,:]
           
案例-Kaggle泰坦尼克号生存預測分析

讓我們先看下那些票價不為0的資料,其不同倉位等級的票均價

full.loc[full['Fare']!=,:].groupby('Pclass')['Fare'].mean()

    Pclass
        
        
        
    Name: Fare, dtype: float64
           

我們可以用這三個均值分别填充不同倉位其票價為0的記錄,并用所有記錄的均值填充na

full.loc[(full['Fare']==)&(full['Pclass']==),'Fare']=
full.loc[(full['Fare']==)&(full['Pclass']==),'Fare']=
full.loc[(full['Fare']==)&(full['Pclass']==),'Fare']=
full['Fare']=full['Fare'].fillna(full['Fare'].mean())
full.describe()
           
案例-Kaggle泰坦尼克号生存預測分析

如果是分類資料,使用最常見的類别取代

#檢視Embarked列中各value的數目
full['Embarked'].value_counts()

    S    
    C    
    Q    
    Name: Embarked, dtype: int64
           

可以看到登船港口Embarked最常見的類别是”S”,故,使用其填充缺失項。

full['Embarked']=full['Embarked'].fillna('S')
           

如果是字元串類型,按照實際情況填寫,無法追蹤的資訊,用”Unknow”填充。處理Cabin缺失值 U代表Unknow

full['Cabin']=full['Cabin'].fillna('U')
           
full.describe()
           
案例-Kaggle泰坦尼克号生存預測分析
full.info()


    <class 'pandas.core.frame.DataFrame'>
    RangeIndex:  entries,  to 
    Data columns (total  columns):
    Age             non-null float64
    Cabin           non-null object
    Embarked        non-null object
    Fare            non-null float64
    Name            non-null object
    Parch           non-null int64
    PassengerId     non-null int64
    Pclass          non-null int64
    Sex             non-null object
    SibSp           non-null int64
    Survived        non-null float64
    Ticket          non-null object
    dtypes: float64(), int64(), object()
    memory usage: + KB
           

特征提取

如何知道哪些特征比較重要呢?通常需要與熟悉業務邏輯的人進行溝通,将業務人員說的特征反映到代碼中,并通過實驗和經驗不斷嘗試,産生新的特征。

Sex(性别):

#将性别的值映射為數值
#male對應數值1,female對應數值0
sex_dict={'male':,'female':}
full['Sex']=full['Sex'].map(sex_dict)
full['Sex'].head()

        
        
        
        
        
    Name: Sex, dtype: int64
           

Embarked(登船港口):

使用get_dummies進行one-hot編碼

#使用get_dummies進行one-hot編碼,産生虛拟變量(dummy variables),列名字首(prefix)是Embarked
EmbarkedDf=pd.get_dummies(full['Embarked'],prefix='Embarked')
EmbarkedDf.head()
           
案例-Kaggle泰坦尼克号生存預測分析
# 将EmbarkedDf的特征添加至full資料集
full=pd.concat([full,EmbarkedDf],axis=)#axis=1表示按列插入資料
full.head()
           
案例-Kaggle泰坦尼克号生存預測分析

因為已經使用登船港口(Embarked)進行了one-hot編碼産生了它的虛拟變量(dummy variables),

是以這裡把登船港口(Embarked)删掉

full=full.drop('Embarked',axis=)
full.head()
           
案例-Kaggle泰坦尼克号生存預測分析

Pclass(客艙等級)

方法同上

PclassDf=pd.get_dummies(full['Pclass'],prefix='Pclass')
PclassDf.head()
           
案例-Kaggle泰坦尼克号生存預測分析
full=pd.concat([full,PclassDf],axis=)
full=full.drop('Pclass',axis=)
full.head()
           
案例-Kaggle泰坦尼克号生存預測分析

Name(乘客姓名):

full['Name'].head()

                                  Braund, Mr. Owen Harris
        Cumings, Mrs. John Bradley (Florence Briggs Th...
                                   Heikkinen, Miss. Laina
             Futrelle, Mrs. Jacques Heath (Lily May Peel)
                                 Allen, Mr. William Henry
    Name: Name, dtype: object
           

從上述Name字元串中發現每個名字裡面都包含了頭銜,我們可以擷取到每個乘客的頭銜,它可以幫助我們分析到更多有用的資訊。

def getTitle(name):
    s1=name.split(',')[]
    s2=s1.split('.')[]
    return s2.strip()#移除字元串頭尾空格
full['Title']=full['Name'].map(getTitle)
full['Title'].value_counts()

    Mr              
    Miss            
    Mrs             
    Master           
    Rev               
    Dr                
    Col               
    Ms                
    Major             
    Mlle              
    Capt              
    Don               
    Mme               
    Jonkheer          
    Dona              
    Sir               
    the Countess      
    Lady              
    Name: Title, dtype: int64
           

将上述頭銜對應到下面的幾種類别中:

Officer:政府官員;

Royalty:王室(皇室);

Mr:已婚男士;

Mrs:已婚婦女;

Miss:年輕未婚女子;

Master:有技能的人/教師

title_dict={"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"}
full['Title']=full['Title'].map(title_dict)
full.head()
           
案例-Kaggle泰坦尼克号生存預測分析
full['Title'].value_counts()

    Mr         
    Miss       
    Mrs        
    Master      
    Officer     
    Royalty      
    Name: Title, dtype: int64
           

利用上述頭銜資料框進行One-hot編碼

TitleDf=pd.get_dummies(full['Title'])#One-hot編碼
full=pd.concat([full,TitleDf],axis=)#将特征添加至源資料集
full.head()
           
案例-Kaggle泰坦尼克号生存預測分析
full=full.drop(['Name','Title'],axis=)#删掉不需要的列
full.head()
           
案例-Kaggle泰坦尼克号生存預測分析

Cabin(客艙号):

客場号的類别值是首字母,是以我們提取客艙号的首字母為特征。

full['Cabin']=full['Cabin'].map(lambda x:x[])
full['Cabin'].value_counts()

    U    
    C      
    B      
    D      
    E      
    A      
    F      
    G       
    T       
    Name: Cabin, dtype: int64
           
CabinDf=pd.get_dummies(full['Cabin'],prefix='Cabin')
full=pd.concat([full,CabinDf],axis=)
full=full.drop('Cabin',axis=)
full.head()
           
案例-Kaggle泰坦尼克号生存預測分析

建立家庭人數和家庭類别:

家庭人數=同代直系親屬數(Parch)+不同代直系親屬數(SibSp)+乘客自己(因為乘客自己也是家庭成員的一個,是以這裡加1)

小家庭Family_Single: 家庭人數=1

中等家庭Family_Small: 2<=家庭人數<=4

大家庭Family_Large: 家庭人數>=5

full['familysize']=full['Parch']+full['SibSp']+
full['family_singel']=np.where(full['familysize']==,,)
full['family_small']=np.where((full['familysize']>=)&(full['familysize']<=),,)
full['family_large']=np.where(full['familysize']>=,,)
full.head()
           
案例-Kaggle泰坦尼克号生存預測分析
full.info()

    <class 'pandas.core.frame.DataFrame'>
    RangeIndex:  entries,  to 
    Data columns (total  columns):
    Age               non-null float64
    Fare              non-null float64
    Parch             non-null int64
    PassengerId       non-null int64
    Sex               non-null int64
    SibSp             non-null int64
    Survived          non-null float64
    Ticket            non-null object
    Embarked_C        non-null uint8
    Embarked_Q        non-null uint8
    Embarked_S        non-null uint8
    Pclass_1          non-null uint8
    Pclass_2          non-null uint8
    Pclass_3          non-null uint8
    Master            non-null uint8
    Miss              non-null uint8
    Mr                non-null uint8
    Mrs               non-null uint8
    Officer           non-null uint8
    Royalty           non-null uint8
    Cabin_A           non-null uint8
    Cabin_B           non-null uint8
    Cabin_C           non-null uint8
    Cabin_D           non-null uint8
    Cabin_E           non-null uint8
    Cabin_F           non-null uint8
    Cabin_G           non-null uint8
    Cabin_T           non-null uint8
    Cabin_U           non-null uint8
    familysize        non-null int64
    family_singel     non-null int32
    family_small      non-null int32
    family_large      non-null int32
    dtypes: float64(), int32(), int64(), object(), uint8()
    memory usage: + KB
           
full.loc[:,:]
           
案例-Kaggle泰坦尼克号生存預測分析

特征選擇和特征降維

通過前面的特征選取,得到32個特征,下面使用相關系數法選取特征

#計算相關性矩陣
corr_df=full.corr()
corr_df
           
案例-Kaggle泰坦尼克号生存預測分析
#提取各特征與生存情況(Survived)的相關系數,并降序排列
corr_df['Survived'].sort_values(ascending=False)

Survived         
    Mrs              
    Miss             
    Pclass_1         
    family_small     
    Fare             
    Cabin_B          
    Embarked_C       
    Cabin_D          
    Cabin_E          
    Cabin_C          
    Pclass_2         
    Master           
    Parch            
    Cabin_F          
    Royalty          
    Cabin_A          
    familysize       
    Cabin_G          
    Embarked_Q       
    PassengerId     -
    Cabin_T         -
    Officer         -
    SibSp           -
    Age             -
    family_large    -
    Embarked_S      -
    family_singel   -
    Cabin_U         -
    Pclass_3        -
    Sex             -
    Mr              -
    Name: Survived, dtype: float64
           

根據各特征與生存情況(Survived)的相關系數大小,選取以下特征進行模組化:頭銜(前面所在的資料集TitleDf)、客艙等級(PclassDf)、船票價格(Fare)、船艙号(CabinDf)、登船港口(EmbarkedDf)、性别(Sex)、家庭大小及類别(familysize,family_small,family_large,family_singel)

full_x=pd.concat([TitleDf,PclassDf,CabinDf,EmbarkedDf,full['Fare'],full['Sex'],full['familysize'],full['family_small']
                  ,full['family_large'],full['family_singel']],axis=)
full_x.head()
           
案例-Kaggle泰坦尼克号生存預測分析

構模組化型

建立訓練資料集和測試資料集

根據前面的資料我們知道,train.csv裡包含Survived标簽,是以用來作為模型訓練的資料,并需要将其分為訓練資料集和測試資料集,test.csv無Survived标簽,用來作為預測資料集

#前891行為原始訓練資料,我們将其提取出來
source_x=full_x.loc[:,:]#提取特征
source_y=full.loc[:,'Survived']#提取标簽
#後418行為預測資料
pred_x=full_x.loc[:,:]
source_x.shape
source_y.shape
pred_x.shape

(, )
(,)
(, )
           
#建立模型用的訓練資料集和測試資料集,按照二八原則分為訓練資料和測試資料,其中80%為訓練資料
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=)
print('訓練資料集特征:{0},訓練資料集标簽:{1}'.format(train_x.shape,train_y.shape))
print('測試資料集特征:{0},測試資料集标簽:{1}'.format(test_x.shape,test_y.shape))
           

訓練資料集特征:(712, 27),訓練資料集标簽:(712,) 測試資料集特征:(179, 27),測試資料集标簽:(179,)

#對train_x,test_x進行标準化
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
train_x_std=sc.fit_transform(train_x)
test_x_std=sc.transform(test_x)
           

選擇算法訓練模型

這裡我們選擇邏輯回歸

#第一步:選擇算法,并導入相應算發包
from sklearn.linear_model import LogisticRegression
#第二步:建立模型
model=LogisticRegression()
#第三步:訓練模型
model.fit(train_x_std,train_y)

LogisticRegression(C=, class_weight=None, dual=False, fit_intercept=True,
              intercept_scaling=, max_iter=, multi_class='ovr', n_jobs=,
              penalty='l2', random_state=None, solver='liblinear', tol=,
              verbose=, warm_start=False)
           

評估模型

#得出模型正确率
model.score(test_x_std,test_y)


           

方案實施

#使用訓練得到的模型對pred_x的生存情況進行預測
pred_x_std=sc.fit_transform(pred_x)
pred_y=model.predict(pred_x_std)
pred_y
           

array([0., 1., 0., 0., 1., 0., 1., 0., 1., 0., 0., 0., 1., 0., 1., 1., 0., 0., 1., 1., 0., 1., 1., 0., 1., 0., 1., 0., 0., 0., 0., 0., 1., 1., 0., 0., 1., 1., 0., 0., 0., 0., 0., 1., 1., 0., 0., 0., 1., 1., 0., 0., 1., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 1., 1., 1., 1., 0., 0., 1., 1., 0., 1., 1., 1., 0., 0., 1., 0., 1., 1., 0., 0., 0., 0., 0., 1., 1., 1., 1., 1., 0., 1., 0., 0., 0., 1., 0., 1., 0., 1., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 1., 1., 1., 1., 0., 0., 0., 0., 1., 1., 0., 1., 0., 0., 1., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 1., 0., 0., 0., 0., 1., 0., 0., 0., 1., 0., 0., 1., 0., 0., 1., 1., 0., 1., 1., 1., 1., 0., 0., 1., 0., 0., 1., 1., 0., 0., 0., 0., 0., 1., 1., 0., 1., 1., 0., 1., 1., 0., 1., 0., 1., 0., 0., 0., 0., 0., 1., 0., 1., 0., 1., 1., 0., 1., 1., 1., 1., 1., 0., 0., 1., 0., 1., 0., 0., 0., 0., 1., 0., 0., 1., 0., 1., 0., 1., 0., 1., 0., 1., 1., 0., 1., 0., 0., 0., 1., 0., 0., 0., 0., 1., 0., 1., 1., 1., 1., 1., 0., 1., 0., 1., 0., 1., 1., 1., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 1., 1., 0., 0., 0., 0., 1., 0., 0., 0., 1., 1., 0., 1., 0., 0., 0., 0., 1., 1., 1., 1., 1., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 1., 0., 0., 0., 0., 1., 0., 0., 1., 1., 0., 1., 0., 1., 0., 0., 0., 1., 1., 1., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 1., 0., 0., 0., 1., 0., 0., 1., 0., 0., 0., 0., 0., 1., 0., 0., 0., 1., 1., 1., 0., 1., 0., 1., 1., 0., 0., 0., 1., 1., 1., 0., 0., 1., 0., 1., 1., 0., 1., 0., 0., 1., 1., 0., 0., 1., 0., 0., 1., 1., 1., 0., 0., 0., 0., 0., 1., 1., 0., 1., 0., 0., 0., 0., 0., 1., 1., 0., 0., 1., 0., 1., 0., 0., 1., 0., 1., 0., 1., 1., 0., 0., 1., 1., 1., 1., 1., 0., 1., 0., 0., 1.])

pred_df=pd.DataFrame({'PassengerId':test.PassengerId,'Survived':pred_y})
pred_df.head()
           
案例-Kaggle泰坦尼克号生存預測分析
pred_df.shape

(, )
           
pred_df['Survived']=pred_df['Survived'].astype('int')
pred_df.info()

    <class 'pandas.core.frame.DataFrame'>
    RangeIndex:  entries,  to 
    Data columns (total  columns):
    PassengerId     non-null int64
    Survived        non-null int32
    dtypes: int32(), int64()
    memory usage:  KB
           
#儲存結果
pred_df.to_csv(r'E:\python\data\titanic\predict.csv',index=False)