最近埋頭苦讀,啃機器學習的算法和編程,真是非(xiang)常(dang)歡(lan)樂(sou)呢~ 於是開始自我膨脹躍躍欲試。
嗯,那就從Kaggle的playground開始吧,找了個經典而又浪漫的愛情故事—泰坦尼克,應該能引起我的興趣好好挖掘吧~
"You jump! I jump! ",『Jack and Rose』的故事想必大家都很熟悉。愛情故事很動人,但是泰坦尼克號在與冰山相撞后沉沒后,2224名乘客中有1502人死亡。盡管幸存者有一些運氣因素,但是是否獲救其實並非隨機,而是基於一些背景有rank先后的,比如女人,孩子和上流社會。在這個挑戰中,我們需要根據乘客的個人信息和存活情況,運用機器學習工具來預測哪些乘客在悲劇中幸存下來。這是一個典型的二分類問題。
Titanic: Machine Learning from Disaster
1. 首先從整體觀察數據情況
- 可用
.info()
,.describe()
查看數據的基本信息和統計特征
#-*- coding: utf-8 -*-
import numpy as np
import pandas as pd
from pandas import DataFrame,Series
data_train = pd.read_csv("train.csv") #讀取訓練數據
data_train.columns #展示數據數據的表頭
data_train.info()
data_train.describe()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
PassengerId 891 non-null int64
Survived 891 non-null int64
Pclass 891 non-null int64
Name 891 non-null object
Sex 891 non-null object
Age 714 non-null float64
SibSp 891 non-null int64
Parch 891 non-null int64
Ticket 891 non-null object
Fare 891 non-null float64
Cabin 204 non-null object
Embarked 889 non-null object
dtypes: float64(2), int64(5), object(5)
memory usage: 83.6+ KB
PassengerId | Survived | Pclass | Age | SibSp | Parch | Fare | |
---|---|---|---|---|---|---|---|
count | 891.000000 | 891.000000 | 891.000000 | 714.000000 | 891.000000 | 891.000000 | 891.000000 |
mean | 446.000000 | 0.383838 | 2.308642 | 29.699118 | 0.523008 | 0.381594 | 32.204208 |
std | 257.353842 | 0.486592 | 0.836071 | 14.526497 | 1.102743 | 0.806057 | 49.693429 |
min | 1.000000 | 0.000000 | 1.000000 | 0.420000 | 0.000000 | 0.000000 | 0.000000 |
25% | 223.500000 | 0.000000 | 2.000000 | 20.125000 | 0.000000 | 0.000000 | 7.910400 |
50% | 446.000000 | 0.000000 | 3.000000 | 28.000000 | 0.000000 | 0.000000 | 14.454200 |
75% | 668.500000 | 1.000000 | 3.000000 | 38.000000 | 1.000000 | 0.000000 | 31.000000 |
max | 891.000000 | 1.000000 | 3.000000 | 80.000000 | 8.000000 | 6.000000 | 512.329200 |
我們可以看到數據中大概有以下這些字段
PassengerId => 乘客ID
Pclass => 乘客艙級(1/2/3等艙位)
Name => 乘客姓名
Sex => 性別
Age => 年齡
SibSp => 堂兄弟/妹個數
Parch => 父母與小孩個數
Ticket => 船票信息
Fare => 票價
Cabin => 艙位編號
Embarked => 登船港口(3個港口)
Survived => 幸存情況(1為幸存)
其中,我們可以觀察到
- 乘客艙級,性別,登船港口,幸存情況,堂兄妹個數、父母與小孩個數是離散屬性
- 年齡,票價為連續值屬性
- 乘客ID, 乘客姓名,船票信息,艙位編號等屬性具有唯一值
- 年齡、艙位編號 有缺失值
2. 數據可視化,分析屬性特征
可做數據分析的圖標類型有:
- 線型圖
- 柱形圖
- 直方圖
- 散點圖
- 密度圖
- 箱型圖
其中:
- 離散屬性,可用柱狀圖觀察屬性每種類別的分布情況
- 年齡,票價為連續值屬性,可用散點、線性或者密度圖來描述分布情況
- 堂兄妹個數、父母與小孩個數, 可試驗
- 乘客ID, 乘客姓名,船票信息,艙位編號等信息,可找源數據觀察數據特征,價值有待挖掘
首先分析幾個離散屬性本身的特征情況
#coding:utf-8
import matplotlib.pyplot as plt
plt.rc('figure',figsize=(8,6))
plt.rcParams['font.sans-serif']=['SimHei'] #用來正常顯示中文標簽
plt.rcParams['axes.unicode_minus']=False #用來正常顯示負號
fig = plt.figure()
fig.set(alpha=0.2) # 設定圖表顏色alpha參數
fig.add_subplot(2,2,1)
data_train.Survived.value_counts().plot(kind="bar")
plt.ylabel(u"人數")
plt.title(u"獲救情況(1為獲救)")
fig.add_subplot(2,2,2)
data_train.Pclass.value_counts().plot(kind="bar")
plt.ylabel(u"人數")
plt.title(u"艙級情況")
fig.add_subplot(2,2,3)
data_train.Sex.value_counts().plot(kind="bar")
plt.ylabel(u"人數")
plt.title(u"性別情況")
fig.add_subplot(2,2,4)
data_train.Embarked.value_counts().plot(kind="bar")
plt.ylabel(u"人數")
plt.title(u"登船港口情況")
Text(0.5,1,'登船港口情況')
由上圖可以得到以下信息:
- 三個艙位人數: 3級 > 1級 > 2級 ,3級的人數基本是其他兩個艙級總和。
- 獲救人數大概只有30%
- 乘客中男性比例大於女性
- 三個登船港口人數:S > C > G ,其中S 登船港口人數最多
分析離散屬性與最終目標值的關系
1.不同乘客等級的獲救情況
- 如圖可以看出乘客等級的獲救概率為: 1 > 2 > 3
Survived0=data_train.Pclass[data_train.Survived==0]
Survived1=data_train.Pclass[data_train.Survived==1]
df=DataFrame({u'不獲救':Survived0.value_counts(),u'獲救':Survived1.value_counts()})
df.plot(kind='bar',stacked=True)
plt.xlabel(u"乘客等級")
plt.ylabel(u"人數")
plt.title(u"各乘客等級的獲救情況")
plt.show()
2.不同性別的獲救情況
- 如圖可以看到女性的獲救概率比男性的獲救概率要高
Survived0=data_train.Sex[data_train.Survived==0]
Survived1=data_train.Sex[data_train.Survived==1]
df=DataFrame({u'不獲救':Survived0.value_counts(),u'獲救':Survived1.value_counts()})
df.plot(kind='bar',stacked=True)
plt.xlabel(u"性別")
plt.ylabel(u"人數")
plt.title(u"不同性別的獲救情況")
plt.show()
3.不同登船港口的情況
- 可以看出港口的獲救情況:C>S>Q
Survived0=data_train.Embarked [data_train.Survived==0]
Survived1=data_train.Embarked [data_train.Survived==1]
df=DataFrame({u'不獲救':Survived0.value_counts(),u'獲救':Survived1.value_counts()})
df.plot(kind='bar',stacked=True)
plt.xlabel(u"登船港口")
plt.ylabel(u"人數")
plt.title(u"不同登船港口的獲救情況")
plt.show()
分析兩個連續值 年齡和票價 本身屬性的特征
- 一般用直方圖、密度圖 (兩者反應的信息是相似的)
- 如圖可以看出:乘客年齡的分布主要是集中在20-40歲之間,同時,票價集中在0-50之間,由部分土豪消費較高
import pandas as pda
from pandas import DataFrame,Series
# fig,axes=plt.subplots(1,1)
fig=plt.figure()
fig.add_subplot(2,1,1)
# data_train.Age.plot(kind='kde')
data_train.Age.hist()
plt.title(u"年齡分布情況")
fig.add_subplot(2,1,2)
# data_train.Fare.plot(kind='kde')
data_train.Fare.hist()
plt.title(u"票價分布情況")
Text(0.5,1,'票價分布情況')
兩個連續值與最終獲救情況的關系
- 可根據最終分類將數值分為幾組,比較直方圖或者密度圖的差異
- 可用散點圖、箱型圖
Survived0=data_train.Age[data_train.Survived==0]
Survived1=data_train.Age[data_train.Survived==1]
df=DataFrame({u'不獲救':Survived0,u'獲救':Survived1})
df.plot(kind='kde')
plt.xlabel(u"年齡")
plt.ylabel(u"核密度")
plt.title(u"不同獲救情況的年齡分布密度圖")
plt.show()
Survived0=data_train.Fare[data_train.Survived==0]
Survived1=data_train.Fare[data_train.Survived==1]
df=DataFrame({u'不獲救':Survived0,u'獲救':Survived1})
df.plot(kind='kde',xlim=[-50,400])
plt.xlabel(u"票價")
plt.ylabel(u"核密度")
plt.title(u"不同獲救情況的票價分布密度圖")
plt.show()
接下來可以分析組合多個屬性,得到有價值的信息
首先看看有重要影響的因素——艙級,分別與年齡、票價、港口的關系
Pclass1=data_train.Age[data_train.Pclass==1]
Pclass2=data_train.Age[data_train.Pclass==2]
Pclass3=data_train.Age[data_train.Pclass==3]
df=DataFrame({u'艙級1':Pclass1,u'艙級2':Pclass2,u'艙級3':Pclass3})
df.plot(kind='kde')
plt.xlabel(u"年齡")
plt.ylabel(u"核密度")
plt.title(u"不同艙級的年齡分布密度圖")
plt.show()
Pclass1=data_train.Fare[data_train.Pclass==1]
Pclass2=data_train.Fare[data_train.Pclass==2]
Pclass3=data_train.Fare[data_train.Pclass==3]
df=DataFrame({u'艙級1':Pclass1,u'艙級2':Pclass2,u'艙級3':Pclass3})
df.plot(kind='kde',xlim=[-50,400])
plt.xlabel(u"票價")
plt.ylabel(u"核密度")
plt.title(u"不同艙級的票價分布密度圖")
plt.show()
Pclass1=data_train.Embarked [data_train.Pclass==1]
Pclass2=data_train.Embarked [data_train.Pclass==2]
Pclass3=data_train.Embarked [data_train.Pclass==3]
df=DataFrame({u'艙級1':Pclass1.value_counts(),u'艙級2':Pclass2.value_counts(),u'艙級3':Pclass3.value_counts()})
df.plot(kind='bar',stacked=True)
plt.xlabel(u"港口")
plt.ylabel(u"核密度")
plt.title(u"不同艙級的港口占比圖")
plt.show()
Embarked_C =data_train.Fare[data_train.Embarked =='C']
Embarked_Q =data_train.Fare[data_train.Embarked =='Q']
Embarked_S =data_train.Fare[data_train.Embarked =='S']
df=DataFrame({u'港口C':Embarked_C,u'港口Q':Embarked_Q,u'港口S':Embarked_S})
df.plot(kind='kde',xlim=[-50,400])
plt.xlabel(u"票價")
plt.ylabel(u"核密度")
plt.title(u"不同港口的票價分布圖")
plt.show()
data_train.groupby(['SibSp','Survived']).count()
PassengerId | Pclass | Name | Sex | Age | Parch | Ticket | Fare | Cabin | Embarked | ||
---|---|---|---|---|---|---|---|---|---|---|---|
SibSp | Survived | ||||||||||
0 | 0 | 398 | 398 | 398 | 398 | 296 | 398 | 398 | 398 | 49 | 398 |
1 | 210 | 210 | 210 | 210 | 175 | 210 | 210 | 210 | 77 | 208 | |
1 | 0 | 97 | 97 | 97 | 97 | 86 | 97 | 97 | 97 | 17 | 97 |
1 | 112 | 112 | 112 | 112 | 97 | 112 | 112 | 112 | 52 | 112 | |
2 | 0 | 15 | 15 | 15 | 15 | 14 | 15 | 15 | 15 | 1 | 15 |
1 | 13 | 13 | 13 | 13 | 11 | 13 | 13 | 13 | 5 | 13 | |
3 | 0 | 12 | 12 | 12 | 12 | 8 | 12 | 12 | 12 | 1 | 12 |
1 | 4 | 4 | 4 | 4 | 4 | 4 | 4 | 4 | 2 | 4 | |
4 | 0 | 15 | 15 | 15 | 15 | 15 | 15 | 15 | 15 | 0 | 15 |
1 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 0 | 3 | |
5 | 0 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 0 | 5 |
8 | 0 | 7 | 7 | 7 | 7 | 0 | 7 | 7 | 7 | 0 | 7 |
Survived0=data_train.SibSp[data_train.Survived==0].value_counts() # 通過布爾索引
Survived1=data_train.SibSp[data_train.Survived==1].value_counts()
Survived1=Series(Survived1,index=Survived0.index)
Survived1=Survived1.fillna(0)
num=Survived0+Survived1
Survived_rate=Survived1/num
Survived_rate=Survived_rate.sort_index()
plt.figure()
Survived_rate.plot()
plt.xlabel(u"兄弟/妹個數")
plt.ylabel(u"存活率(%)")
plt.title(u"兄弟/妹個數對幸存率的影響")
plt.show()
data_train.groupby(['SibSp','Survived']).count()
PassengerId | Pclass | Name | Sex | Age | Parch | Ticket | Fare | Cabin | Embarked | ||
---|---|---|---|---|---|---|---|---|---|---|---|
SibSp | Survived | ||||||||||
0 | 0 | 398 | 398 | 398 | 398 | 296 | 398 | 398 | 398 | 49 | 398 |
1 | 210 | 210 | 210 | 210 | 175 | 210 | 210 | 210 | 77 | 208 | |
1 | 0 | 97 | 97 | 97 | 97 | 86 | 97 | 97 | 97 | 17 | 97 |
1 | 112 | 112 | 112 | 112 | 97 | 112 | 112 | 112 | 52 | 112 | |
2 | 0 | 15 | 15 | 15 | 15 | 14 | 15 | 15 | 15 | 1 | 15 |
1 | 13 | 13 | 13 | 13 | 11 | 13 | 13 | 13 | 5 | 13 | |
3 | 0 | 12 | 12 | 12 | 12 | 8 | 12 | 12 | 12 | 1 | 12 |
1 | 4 | 4 | 4 | 4 | 4 | 4 | 4 | 4 | 2 | 4 | |
4 | 0 | 15 | 15 | 15 | 15 | 15 | 15 | 15 | 15 | 0 | 15 |
1 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 0 | 3 | |
5 | 0 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 5 | 0 | 5 |
8 | 0 | 7 | 7 | 7 | 7 | 0 | 7 | 7 | 7 | 0 | 7 |
Survived0=data_train.Parch[data_train.Survived==0].value_counts()
Survived1=data_train.Parch[data_train.Survived==1].value_counts()
Survived1=Series(Survived1,index=Survived0.index)
Survived1=Survived1.fillna(0)
num=Survived0+Survived1
Survived_rate=Survived1/num
Survived_rate=Survived_rate.sort_index()
plt.figure()
Survived_rate.plot()
plt.xlabel(u"父母/小孩個數")
plt.ylabel(u"幸存率(%)")
plt.title(u"父母/小孩對幸存率的影響")
plt.show()
Survived_noCabin=data_train.Survived[data_train.Cabin.isnull()]
Survived_haveCabin=data_train.Survived[data_train.Cabin.notnull()]
df=DataFrame({'無':Survived_noCabin.value_counts(),'有':Survived_haveCabin.value_counts()}).transpose()
df.plot(kind='bar', stacked=True)
plt.title(u"按Cabin有無看獲救情況")
plt.xlabel(u"Cabin有無")
plt.ylabel(u"人數")
plt.show()
3.缺失值處理
通常遇到缺值的情況,我們會有幾種常見的處理方式
- 如果缺值的樣比例極高,直接舍棄,因為作為特征可能反倒帶入noise,影響結果
- 如果缺值的樣本適中,而該屬性是離散值(比如說類目屬性),那就把NaN作為一個新類別,加到類別特征中
- 如果缺值的樣本適中,而該屬性為連續值,有時候我們會考慮給定一個step(比如這里的age,我們可以考慮每隔2/3歲為一個步長),然后把它離散化,之后把NaN作為一個type加到屬性類目中。
- 有些情況下,缺失的值個數並不是特別多,那我們也可以試着根據已有的值,使用模型擬合一下數據,補充上。
在第1步的源數據分析中,我們知道Age 和Cabin 有缺失值
其中 :
- Cabin 字段缺失太多,暫時按Cabin有無數據,將這個屬性處理成Yes和No兩種類
- Age 字段 通過模型擬合,補充數據
# Cabin 的缺失值填充函數
def set_Cabin_type(df):
# df.Cabin[df.Cabin.notnull()]='YES'
# df.Cabin[df.Cabin.isnull()]='NO'
df.loc[(df.Cabin.notnull()),'Cabin']='YES'
df.loc[(df.Cabin.isnull()),'Cabin']='NO'
return df
data_train=set_Cabin_type(data_train)
# 使用 RandomForestClassifier 填補缺失的年齡屬性
from sklearn.ensemble import RandomForestRegressor
def set_missing_ages(df):
# 把已有的數值型特征取出來丟進Random Forest Regressor中,因為邏輯回歸算法輸入都需要數值型特征
age_df = df[['Age','Fare', 'Parch', 'SibSp', 'Pclass']]
age_known=age_df.loc[age_df.Age.notnull()].values # 要用sklearn的模型,輸入參數要把Series和DataFrame 轉成nparray
age_unknown=age_df.loc[age_df.Age.isnull()].values
#將有值的年齡樣本 訓練數據,然后用訓練好的模型用於 預測 缺失的年齡樣本的值
#訓練數據的特征集合
X=age_known[:,1:]
#訓練數據的目標
y=age_known[:,0]
#構建隨機森林回歸模型器
rfr = RandomForestRegressor(random_state=0, n_estimators=2000, n_jobs=-1)
# 擬合數據,訓練模型
rfr.fit(X,y)
# 用訓練好的模型 預測 有缺失值的年齡屬性
predictedAges=rfr.predict(age_unknown[:,1:])
# 得到的預測結果,去填補缺失數據
df.loc[df.Age.isnull(),'Age']=predictedAges
return df,rfr
data_train,rfr=set_missing_ages(data_train)
4.類目型特征因子化
因為邏輯回歸建模時,需要輸入的特征都是數值型特征,我們通常會先對類目型的特征進行轉化
- 當類目型特征值 與數值大小有關聯關系時,比如大小S,M,L,可以映射為數值型,比如分別映射為 1,2,3。
- 當類目型特征值 僅僅表示類別,沒有大小關系,則需要使用 因子化/one-hot編碼,使用pandas的.get_dummies函數。
類目型特征有:Cabin、Embarked、Sex、Pclass
dummies_Cabin = pd.get_dummies(data_train.Cabin,prefix='Cabin') #ptefix 是前綴,因子花之后的字段名為 前綴_類名
dummies_Embarked = pd.get_dummies(data_train['Embarked'], prefix= 'Embarked')
dummies_Sex = pd.get_dummies(data_train['Sex'], prefix= 'Sex')
dummies_Pclass = pd.get_dummies(data_train['Pclass'], prefix= 'Pclass')
df = pd.concat([data_train, dummies_Cabin, dummies_Embarked, dummies_Sex, dummies_Pclass], axis=1) #將啞編碼的內容拼接到data_train后
df.drop(['Pclass', 'Name', 'Sex', 'Ticket', 'Cabin', 'Embarked'], axis=1, inplace=True) # 把編碼前的字段刪除
5.標准化和歸一化
對於量綱差異太大的數值型特征,我們需要將其標准化或歸一化到一個范圍,不然會對建模產生很大的影響(比如邏輯回歸和梯度下降)
- 其中有 preprocessing 中的MinMaxScaler類、MinMaxScaler類、Normalizer類等
需要做 scaleing的 特征有: Age、Fare
# 這里用StandardScaler類對
from sklearn.preprocessing import StandardScaler
# 創建一個定標器
scaler=StandardScaler()
# 擬合數據
#---fit和transform為兩個動作,可用fit_transform 合並完成
#df['Age_Scale']=scaler.fit_transform(df.Age.values.reshape(-1,1)) # 若為單個特征,需要reshape為(-1,1)
#--但是由於test和train 需要用同一個fit出來的參數,所以需要記錄fit參數,用於test數據的標准化,因此分開計算
Age_Scale_parame=scaler.fit(df.Age.values.reshape(-1,1))
#df['Age_Scale']=scaler.transform(df.Age.values.reshape(-1,1))
df['Age_Scale']=scaler.fit_transform(df.Age.values.reshape(-1,1),Age_Scale_parame)
Fare_Scale_parame=scaler.fit(df.Fare.values.reshape(-1,1))
df['Fare_Scale']=scaler.fit_transform(df.Age.values.reshape(-1,1),Fare_Scale_parame)
df.drop(['Age', 'Fare'], axis=1, inplace=True)
到這里,我們的數據預處理就結束了。
6.訓練模型
接下來,我們用邏輯回歸算法將訓練數據進行訓練模型
from sklearn.linear_model import LogisticRegression
df_train=df.filter(regex='Survived|Age_.*|SibSp|Parch|Fare_.*|Cabin_.*|Embarked_.*|Sex_.*|Pclass_.*').values #用正則表達式把需要的字段過濾出來
# 訓練特征
df_train_feature=df_train[:,1:]
#訓練目標
df_train_label=df_train[:,0]
#構建邏輯回歸分類器
clf=LogisticRegression(C=1.0, penalty='l1', tol=1e-6)
#擬合數據
clf.fit(df_train_feature,df_train_label)
clf
LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
intercept_scaling=1, max_iter=100, multi_class='ovr', n_jobs=1,
penalty='l1', random_state=None, solver='liblinear', tol=1e-06,
verbose=0, warm_start=False)
7.測試模型
我們對測試數據 做訓練數據相同的數據預處理,包括:
- 缺失值填充:Age,Cabin,Fare
- 類目特征因子化: Pclass、Sex、Cabin、Embarked
- 歸一化 : Age、Fare
data_test = pd.read_csv("test.csv")
# 缺失值填充
data_test.loc[data_test.Fare.isnull(),'Fare']=0
data_test= set_Cabin_type(data_test)
age_data = data_test[['Age','Fare', 'Parch', 'SibSp', 'Pclass']]
age_test=age_data[age_data.Age.isnull()].values
# age的缺失值填充也用前訓練數據 的age值fit計算的模型,所以可以直接預測
predictedAges = rfr.predict(age_test[:,1:])
data_test.loc[data_test.Age.isnull(),'Age'] = predictedAges
# 類目特征因子化
dummies_Cabin = pd.get_dummies(data_test.Cabin, prefix= 'Cabin')
dummies_Sex = pd.get_dummies(data_test.Sex, prefix= 'Sex')
dummies_Pclass = pd.get_dummies(data_test.Pclass, prefix= 'Pclass')
dummies_Embarked = pd.get_dummies(data_test.Embarked, prefix= 'Embarked')
#歸一化也用訓練數據fit出來的參數進行轉化
data_test['Age_scaled'] = scaler.fit_transform(data_test['Age'].values.reshape(-1, 1), Age_Scale_parame)
data_test['Fare_scaled'] = scaler.fit_transform(data_test['Fare'].values.reshape(-1, 1), Fare_Scale_parame)
# 拼接處理后數據以及刪除處理前數據
df_test = pd.concat([data_test, dummies_Cabin, dummies_Embarked, dummies_Sex, dummies_Pclass], axis=1)
df_test.drop(['Pclass', 'Name', 'Sex', 'Ticket', 'Cabin', 'Embarked','Age','Fare'], axis=1, inplace=True)
將測試數據 用訓練數據訓練出來的模型 進行預測
df_test=df_test.values
# df_test = df_test.filter(regex='Age_.*|SibSp|Parch|Fare_.*|Cabin_.*|Embarked_.*|Sex_.*|Pclass_.*') #可用正則表達式取刪選數據
predict_result=clf.predict(df_test[:,1:])
result = pd.DataFrame({'PassengerId':data_test['PassengerId'].values, 'Survived':predict_result.astype(np.int32)})
result.to_csv("logistic_regression_predictions.csv", index=False)
pd.read_csv("logistic_regression_predictions.csv")
PassengerId | Survived | |
---|---|---|
0 | 892 | 1 |
1 | 893 | 0 |
2 | 894 | 1 |
3 | 895 | 0 |
4 | 896 | 0 |
5 | 897 | 0 |
6 | 898 | 1 |
7 | 899 | 0 |
8 | 900 | 0 |
9 | 901 | 0 |
10 | 902 | 0 |
11 | 903 | 0 |
12 | 904 | 0 |
13 | 905 | 0 |
14 | 906 | 0 |
15 | 907 | 0 |
16 | 908 | 1 |
17 | 909 | 0 |
18 | 910 | 0 |
19 | 911 | 0 |
20 | 912 | 0 |
21 | 913 | 0 |
22 | 914 | 0 |
23 | 915 | 0 |
24 | 916 | 1 |
25 | 917 | 0 |
26 | 918 | 0 |
27 | 919 | 0 |
28 | 920 | 0 |
29 | 921 | 0 |
... | ... | ... |
388 | 1280 | 1 |
389 | 1281 | 0 |
390 | 1282 | 0 |
391 | 1283 | 0 |
392 | 1284 | 0 |
393 | 1285 | 0 |
394 | 1286 | 0 |
395 | 1287 | 0 |
396 | 1288 | 1 |
397 | 1289 | 0 |
398 | 1290 | 0 |
399 | 1291 | 1 |
400 | 1292 | 1 |
401 | 1293 | 0 |
402 | 1294 | 0 |
403 | 1295 | 0 |
404 | 1296 | 0 |
405 | 1297 | 0 |
406 | 1298 | 0 |
407 | 1299 | 1 |
408 | 1300 | 1 |
409 | 1301 | 0 |
410 | 1302 | 1 |
411 | 1303 | 1 |
412 | 1304 | 0 |
413 | 1305 | 0 |
414 | 1306 | 0 |
415 | 1307 | 0 |
416 | 1308 | 0 |
417 | 1309 | 0 |
418 rows × 2 columns
把預測結果提交到Kaggle官網,得到准確率為:0.76555。
沒錯,效果還不夠理想,因為簡單分析過后出的一個baseline系統,前面數據探索出來的結論還沒用上呢,真正的挖掘工作現在才剛剛開始呢~~~
接下來將對模型狀態進行分析,並做一系列的優化工作。
未完待續...
本文參考了來自寒小陽的github:Kaggle_Titanic,有興趣的小伙伴可以看看。