大神經驗:
1、
應用機器學習,千萬不要一上來就試圖做到完美,先擼一個baseline的model出來,再進行后續的分析步驟,一步步提高,所謂后續步驟可能包括『分析model現在的狀態(欠/過擬合),分析我們使用的feature的作用大小,進行feature selection,以及我們模型下的bad case和產生的原因』等等。
2、
對數據的認識太重要了!
數據中的特殊點/離群點的分析和處理太重要了!
特征工程(feature engineering)太重要了!在很多Kaggle的場景下,甚至比model本身還要重要!
要做模型融合(model ensemble)!
3、
問題或問題的定義。
獲取訓練和測試數據。
Wrangle,准備,清理數據。
分析,識別模式並探索數據。
建模,預測和解決問題。
可視化,報告和呈現問題解決步驟和最終解決方案。
提供或提交結果。
工作流程
分類。我們可能希望對樣本進行分類。我們可能還想了解不同類的含義或相關性與我們的解決方案目標。
相關。可以基於訓練數據集中的可用特征來解決問題。數據集中的哪些功能對我們的解決方案目標有重大貢獻?從統計上講,功能和解決方案目標之間是否存在相關性?隨着特征值的變化,解決方案狀態也會發生變化,反之亦然?這可以針對給定數據集中的數字和分類特征進行測試。我們可能還希望確定除后續目標和工作流程階段的生存之外的特征之間的相關性。關聯某些功能可能有助於創建,完成或更正功能。
轉換。對於建模階段,需要准備數據。根據模型算法的選擇,可能需要將所有特征轉換為數值等效值。例如,將文本分類值轉換為數值。
填補。數據准備可能還需要我們估計要素中的任何缺失值。當沒有缺失值時,模型算法可能最有效。
糾正。我們還可以分析給定的訓練數據集中的錯誤或可能在特征內刪除值,並嘗試糾正這些值或排除包含錯誤的樣本。一種方法是檢測我們的樣本或特征中的任何異常值。如果某項功能無法進行分析,或者可能會嚴重影響結果,我們也可能會完全丟棄該功能。
創建。我們是否可以基於現有功能或一組功能創建新功能,以便新功能遵循關聯,轉換和完整性目標。
圖表。如何根據數據的性質和解決方案目標選擇正確的可視化圖表和圖表。
正式開始
介紹
數據集包含兩部分
- training set (train.csv)
- test set (test.csv)
具體內容
Variable | Definition | Key |
---|---|---|
survival | Survival | 0 = No, 1 = Yes |
pclass | Ticket class | 1 = 1st, 2 = 2nd, 3 = 3rd |
sex | Sex | |
Age | Age in years | |
sibsp | # of siblings / spouses aboard the Titanic | |
parch | # of parents / children aboard the Titanic | |
ticket | Ticket number | |
fare | Passenger fare | |
cabin | Cabin number | |
embarked | Port of Embarkation | C = Cherbourg, Q = Queenstown, S = Southampton |
變量解釋
pclass: A proxy for socio-economic status (SES) 社會地位
1st = Upper
2nd = Middle
3rd = Lower
age: Age is fractional if less than 1. If the age is estimated, is it in the form of xx.5
sibsp: The dataset defines family relations in this way...
Sibling = brother, sister, stepbrother, stepsister 兄弟姐妹,橫向
Spouse = husband, wife (mistresses and fiancés were ignored) 配偶
parch: The dataset defines family relations in this way...
Parent = mother, father 父母
Child = daughter, son, stepdaughter, stepson 兒女
Some children travelled only with a nanny, therefore parch=0 for them.
# data analysis and wrangling import pandas as pd import numpy as np import random as rnd # visualization import seaborn as sns import matplotlib.pyplot as plt %matplotlib inline # machine learning from sklearn.linear_model import LogisticRegression from sklearn.svm import SVC, LinearSVC from sklearn.ensemble import RandomForestClassifier from sklearn.neighbors import KNeighborsClassifier from sklearn.naive_bayes import GaussianNB from sklearn.linear_model import Perceptron from sklearn.linear_model import SGDClassifier from sklearn.tree import DecisionTreeClassifier
導入數據,把訓練集和測試集合並來一起實施操作
train_df = pd.read_csv('../input/train.csv') test_df = pd.read_csv('../input/test.csv') combine = [train_df, test_df]
對數據進行分析,先看看有哪些特征列
print(train_df.columns.values)
out:
['PassengerId' 'Survived' 'Pclass' 'Name' 'Sex' 'Age' 'SibSp' 'Parch'
'Ticket' 'Fare' 'Cabin' 'Embarked']
哪些特征是 categorical,哪些是numerical的?
- 分類: Survived, Sex, and Embarked. 序列: Pclass.
- 連續: Age, Fare. 分離: SibSp, Parch.
整體觀看數據
# preview the data train_df.head()
哪些特征是混合數據類型的?
船票是數字和字母數字數據類型的混合。 船艙是字母和數字混合。
哪些特征是包含錯誤值或錯別字的?
名稱功能可能包含錯誤或拼寫錯誤,因為有多種方法可用於描述名稱,包括標題,圓括號和用於替代或短名稱的引號。
哪些特征包含blank, null or empty values?
- Cabin> Age> Embarked 按訓練數據集的順序包含許多空值。
- Cabin > Age 在測試集上是不完整的
各個特征的數據類型是什么?
如訓練集上2個float,5個int,5個object
train_df.info() print('_'*40) test_df.info()
out:
樣本的特征(數字類)的分布如何?分析一下:
這有助於我們了解早期的數據概貌。
- 實際乘客人數(891)是總樣本泰坦尼克號(2,224)上的40%。
- Survived是一個具有0或1值的分類特征。
- 約38%的樣本存活,代表實際存活率為32%。
- 大多數乘客(> 75%)沒有與父母或孩子一起旅行。
- 近30%的乘客有兄弟姐妹和/或配偶。
- 票價差異很大,很少有乘客(<1%)支付高達512美元。
- 年齡在65-80歲之間的老年乘客(<1%)很少。
train_df.describe() # Review survived rate using `percentiles=[.61, .62]` knowing our problem description mentions 38% survival rate. # Review Parch distribution using `percentiles=[.75, .8]` # SibSp distribution `[.68, .69]` # Age and Fare `[.1, .2, .3, .4, .5, .6, .7, .8, .9, .99]`
分析完數據型的特征,那分類型的特征的分布又是怎樣的?
- Names 在整個數據集中是唯一的(count = unique = 891)
- Sex 變量為兩個可能的值,男性為65%(top=男性,fre= 577 /計數= 891)。
- Cabin 的值在樣本中有幾個副本。 因為有幾名乘客共用一間cabin。
- Embarked 采取三個可能的值。 大多數乘客前往S港口(top= S)
- Ticket 特征具有高比率(22%)的重復值(unique= 681)。
train_df.describe(include=['O']) #參數O代表只列出object類型的列
out:
綜上分析一波:
基於數據分析的假設
我們基於迄今為止所做的數據分析得出以下假設。我們可能會在采取適當行動之前進一步驗證這些假設。
相關:
我們想知道每個特征與生存的相關性。我們希望在項目的早期階段完成這項工作,並將這些快速關聯與項目后期的建模關聯相匹配。
填補:
1.我們可能希望填補Age特征,因為它與生存明確相關。
2.我們可能希望填補Embarked特征,因為它也可能與生存或其他重要功能相關。
修正:
1. Ticket 特征可能會從我們的分析中刪除,因為它包含高比例的重復項(22%),並且Ticket和生存之間可能沒有相關性。
2. Cabin 特征可能會因為高度不完整而丟棄,因為在訓練和測試數據集中包含許多空值。
3. PassengerId 可能會從訓練數據集中刪除,因為它對生存沒有貢獻。
4. Names 特征相對不標准,可能無法直接促成生存,因此可能會丟掉。
創建:
1.我們可能想要創建一個名為Family的基於Parch和SibSp的新特征,以獲得船上家庭成員的總數。
2.我們可能想要創建Name 特征來將Title 提取為新特征。
3.我們可能想為Age列創建新特征。這將連續的數字特征轉換為序數分類特征。
4.如果有助於我們的分析,我們可能還想創建一個Fare 范圍特征。
分類:
我們還可以根據前面提到的問題描述添加我們的假設。
1.女性更有可能幸存下來。
2.兒童(Age<?)更有可能存活下來。
3.上層乘客(Pclass = 1)更有可能幸存下來。
通過pivoting進行分析
為了確認我們的一些觀察和假設,我們可以通過相互pivote特征來快速分析我們的特征相關性。 我們只能在此階段對沒有任何空值的特征執行此操作。 對於分類(Sex),序數(Pclass)或離散(SibSp,Parch)類型的特征,這樣做也是有意義的。
- Pclass 我們觀察到 Pclass = 1 和 Survived(分類#3)之間存在顯着的相關性(> 0.5)。 我們決定在我們的模型中包含此功能。
- Sex 我們在問題定義中確認 Sex=female 的存活率非常高,為74%(分類#1)。
- SibSp和Parch 這些特征對於某些值具有零相關性。 最好從這些單獨的特征中導出一個特征或一組特征(創建#1)。
//as_index參數為false時輸出表格為SQL的風格
train_df[['Pclass', 'Survived']].groupby(['Pclass'], as_index=False).mean().sort_values(by='Survived', ascending=False)
out:
train_df[["Sex", "Survived"]].groupby(['Sex'], as_index=False).mean().sort_values(by='Survived', ascending=False)
train_df[["SibSp", "Survived"]].groupby(['SibSp'], as_index=False).mean().sort_values(by='Survived', ascending=False)
train_df[["Parch", "Survived"]].groupby(['Parch'], as_index=False).mean().sort_values(by='Survived', ascending=False)
到現在為止,進行可視化數據來直觀分析
g = sns.FacetGrid(train_df, col='Survived') g.map(plt.hist, 'Age', bins=20)
關聯數字和序數特征
我們可以使用單個圖組合多個功能來識別相關性。 這可以通過具有數值的數字和分類特征來完成。
觀察
- Pclass = 3有大多數乘客,但大部分都無法生存。 證實我們的分類假設#2。
- Pclass = 2和 Pclass = 3 的嬰兒乘客大部分幸存下來。 進一步證實了我們的分類假設#2。
- Pclass = 1的大多數乘客幸免於難。 證實我們的分類假設#3。
- Pclass在乘客年齡分布方面有所不同。
決定
- 考慮使用Pclass進行模型訓練。
#grid = sns.FacetGrid(train_df, col='Pclass', hue='Survived') grid = sns.FacetGrid(train_df, col='Survived', row='Pclass', size=2.2, aspect=1.6) grid.map(plt.hist, 'Age', alpha=.5, bins=20) grid.add_legend();
關聯分類功能
現在我們可以將分類特征與我們的解決方案目標相關聯。
觀察
- 女性乘客的生存率遠高於男性。 證實分類(#1)。
- 在 Embarked = C 中的例外情況,其中男性的存活率更高。 這可能是 Pclass 和 Embarked 之間的相關性,反過來是 Pclass 和 Survived,不一定是 Embarked 和 Survived 之間的直接相關。
- 對 C 和 Q港口,男性在 Pclass = 3相比在Pclass = 2時的存活率更高。 證實填補(#2)。
- 對於Pclass = 3的男性,不同的登船港口他們的生存率各不相同。 證實相關(#1)。
決定
- 為模型訓練添加 Sex 特征。
- 填補並添加 Embarked 特征來進行模型訓練。
grid = sns.FacetGrid(train_df, col='Embarked') #grid = sns.FacetGrid(train_df, row='Embarked', size=2.2, aspect=1.6) grid.map(sns.pointplot, 'Pclass', 'Survived', 'Sex', palette='deep') grid.add_legend()
關聯分類和數字特征
我們可能還想關聯分類特征(使用非數字值)和數字特征。 我們可以考慮將Embarked(分類非數字),Sex(分類非數字),Ticket(數字連續)與 Survivied(分類數字)相關聯。
觀察
- 高票價乘客的生存率更高。 證實我們創建(#4)Fare 范圍的假設。
- 登船港與生存率相關。 證實相關(#1)和填補(#2)。
決定
- 考慮綁定票價功能。
grid = sns.FacetGrid(train_df, col='Embarked', hue='Survived') #grid = sns.FacetGrid(train_df, row='Embarked', col='Survived', size=2.2, aspect=1.6) grid.map(sns.barplot, 'Sex', 'Fare', alpha=.5, ci=None) grid.add_legend()
Wrangle數據
我們收集了有關數據集和解決方案要求的若干假設和決策。 到目前為止,我們沒有必要更改單個功能或值來實現這些功能。 現在讓我們執行我們的決策和假設,以糾正,創建和填補目標。
通過刪除功能進行更正
這是一個很好的起始目標。 通過刪除功能,我們處理的數據點更少。 加速我們的筆記本電腦並簡化分析。
根據我們的假設和決定,我們希望放棄 Cabin(糾正#2)和 Ticket(糾正#1)特征。
請注意,在適用的情況下,我們同時對訓練和測試數據集執行操作以保持一致。
print("Before", train_df.shape, test_df.shape, combine[0].shape, combine[1].shape) train_df = train_df.drop(['Ticket', 'Cabin'], axis=1) test_df = test_df.drop(['Ticket', 'Cabin'], axis=1) combine = [train_df, test_df] print("After", train_df.shape, test_df.shape, combine[0].shape, combine[1].shape)
out:
Before (891, 12) (418, 11) (891, 12) (418, 11) After (891, 10) (418, 9) (891, 10) (418, 9)
從現有特征提取的新特征
在丟棄 Name 和 PassengerId 特征之前,我們想要分析是否可以設計 Name 特征來提取 titles(稱謂) 並測試 titles (稱謂)和 Survived 之間的相關性,然后再刪除 Name 和 PassengerId 功能。
在下面的代碼中,我們使用正則表達式提取標題功能。 RegEx模式 `(\w+\.)` 匹配名稱特征中以點字符結尾的第一個單詞。 `expand = False` 標志返回一個DataFrame。
觀察
當我們繪制 Title(稱謂),Age和 Survived 時,我們注意到以下觀察結果。
- 大多數titles(稱謂)准確地圍繞年齡組。 例如:Master 稱謂的年齡均值為5年。
- Title 和 Age 列的生存率略有不同。
- 某些 titles稱謂 大多存活下來(Mme,Lady,Sir)或者沒有(Don,Rev,Jonkheer)。
決策
- 我們決定保留新的 Title(稱謂) 特征以進行模型訓練。
for dataset in combine: dataset['Title'] = dataset.Name.str.extract(' ([A-Za-z]+)\.', expand=False) # 參數expand=false 標志返回一個df pd.crosstab(train_df['Title'], train_df['Sex'])
我們可以用更常見的名稱替換許多稱謂或將它們歸類為 ‘Rare’。
for dataset in combine: dataset['Title'] = dataset['Title'].replace(['Lady', 'Countess','Capt', 'Col',\ 'Don', 'Dr', 'Major', 'Rev', 'Sir', 'Jonkheer', 'Dona'], 'Rare') dataset['Title'] = dataset['Title'].replace('Mlle', 'Miss') dataset['Title'] = dataset['Title'].replace('Ms', 'Miss') dataset['Title'] = dataset['Title'].replace('Mme', 'Mrs') train_df[['Title', 'Survived']].groupby(['Title'], as_index=False).mean()
我們可以把分類的稱謂轉換為序列類
title_mapping = {"Mr": 1, "Miss": 2, "Mrs": 3, "Master": 4, "Rare": 5} for dataset in combine: dataset['Title'] = dataset['Title'].map(title_mapping) dataset['Title'] = dataset['Title'].fillna(0) train_df.head()
現在我們可以安全地從訓練和測試數據集中刪除Name 特征。 我們也不需要訓練數據集中的PassengerId功能。
train_df = train_df.drop(['Name', 'PassengerId'], axis=1) test_df = test_df.drop(['Name'], axis=1) combine = [train_df, test_df] train_df.shape, test_df.shape
out:
((891, 9), (418, 9))
轉換分類特征
現在我們可以將包含字符串的特征轉換為數值。 這是大多數模型算法所必需的。 這樣做也有助於我們實現功能完成目標。
讓我們首先將性別特征轉換為名為Gender的新功能,其中女性= 1,男性= 0。
for dataset in combine: dataset['Sex'] = dataset['Sex'].map( {'female': 1, 'male': 0} ).astype(int) train_df.head()
完成數字連續特征
現在我們應該開始估計和填補缺少值或空值的功能。我們將首先針對Age功能執行此操作。
我們可以考慮三種方法來填補數值連續特征。
1. 一種簡單的方法是在均值和標准偏差之間生成隨機數。
2. 更准確地猜測缺失值的方法是使用其他相關特征。在我們的例子中,我們注意到Age,Gender和Pclass之間的相關性。使用 中位數 的值來猜測年齡值,包括 Pclass 和 Gender 特征組合的集合。因此,年齡中位數對於 Pclass = 1且 Gender = 0,對於Pclass = 1且 Gender = 1,依此類推......
3. 結合方法1和2。因此,不是基於中位數來猜測年齡值,而是根據Pclass和Gender組合的集合使用均值和標准差之間的隨機數。
方法1和3將隨機噪聲引入我們的模型。多次執行的結果可能會有所不同。我們更喜歡方法2。
#grid = sns.FacetGrid(train_df, col='Pclass', hue='Gender') grid = sns.FacetGrid(train_df, row='Pclass', col='Sex', size=2.2, aspect=1.6) grid.map(plt.hist, 'Age', alpha=.5, bins=20) grid.add_legend()
讓我們首先准備一個空數組,以包含基於Pclass 和 Gender組合的Age猜測值。
然后我們迭代Sex(0或1)和Pclass(1,2,3)來計算六種組合的Age的猜測值。
guess_ages = np.zeros((2,3))
for dataset in combine: for i in range(0, 2): for j in range(0, 3): guess_df = dataset[(dataset['Sex'] == i) & \ (dataset['Pclass'] == j+1)]['Age'].dropna() # age_mean = guess_df.mean() # age_std = guess_df.std() # age_guess = rnd.uniform(age_mean - age_std, age_mean + age_std) age_guess = guess_df.median() # Convert random age float to nearest .5 age guess_ages[i,j] = int( age_guess/0.5 + 0.5 ) * 0.5 for i in range(0, 2): for j in range(0, 3): dataset.loc[ (dataset.Age.isnull()) & (dataset.Sex == i) & (dataset.Pclass == j+1),\ 'Age'] = guess_ages[i,j] dataset['Age'] = dataset['Age'].astype(int) train_df.head()
讓我們創建 Age bands 並確定與 Survived 的相關性。
train_df['AgeBand'] = pd.cut(train_df['Age'], 5) #把Age列等間隔分成5個區間 train_df[['AgeBand', 'Survived']].groupby(['AgeBand'], as_index=False).mean().sort_values(by='AgeBand', ascending=True)
讓我們使用序列來代替Age上的區間
for dataset in combine: dataset.loc[ dataset['Age'] <= 16, 'Age'] = 0 dataset.loc[(dataset['Age'] > 16) & (dataset['Age'] <= 32), 'Age'] = 1 dataset.loc[(dataset['Age'] > 32) & (dataset['Age'] <= 48), 'Age'] = 2 dataset.loc[(dataset['Age'] > 48) & (dataset['Age'] <= 64), 'Age'] = 3 dataset.loc[ dataset['Age'] > 64, 'Age'] train_df.head()
然后移除 AgeBand 列
train_df = train_df.drop(['AgeBand'], axis=1) combine = [train_df, test_df] train_df.head()
基於現有的特征來創建新的特征
我們可以為 FamilySize 創建一個新特征,它結合了 Parch 和 SibSp 。 這將使我們能夠從數據集中刪除Parch和SibSp。
for dataset in combine: dataset['FamilySize'] = dataset['SibSp'] + dataset['Parch'] + 1 train_df[['FamilySize', 'Survived']].groupby(['FamilySize'], as_index=False).mean().sort_values(by='Survived', ascending=False)
我們可以創建另外一個特征叫做 isAlone
for dataset in combine: dataset['IsAlone'] = 0 dataset.loc[dataset['FamilySize'] == 1, 'IsAlone'] = 1 train_df[['IsAlone', 'Survived']].groupby(['IsAlone'], as_index=False).mean()
讓我們放棄Parch,SibSp和FamilySize特征,轉而使用IsAlone。
train_df = train_df.drop(['Parch', 'SibSp', 'FamilySize'], axis=1) test_df = test_df.drop(['Parch', 'SibSp', 'FamilySize'], axis=1) combine = [train_df, test_df] train_df.head()
我們還可以創建一個結合了Pclass和Age的人工特征。
for dataset in combine: dataset['Age*Class'] = dataset.Age * dataset.Pclass train_df.loc[:, ['Age*Class', 'Age', 'Pclass']].head(10)
填補分類功能
Embarked 特征根據 登船港口獲取S,Q,C值。 我們的訓練數據集有兩個缺失值。 我們只是填寫最常見的事件。
freq_port = train_df.Embarked.dropna().mode()[0] #眾數 freq_port # ‘S' for dataset in combine: dataset['Embarked'] = dataset['Embarked'].fillna(freq_port) train_df[['Embarked', 'Survived']].groupby(['Embarked'], as_index=False).mean().sort_values(by='Survived', ascending=False)
將分類功能轉換為數字
我們現在可以通過創建新的數字型的 Port 特征來轉換 EmbarkedFill 特征。
for dataset in combine: dataset['Embarked'] = dataset['Embarked'].map( {'S': 0, 'C': 1, 'Q': 2} ).astype(int) train_df.head()
快速填補並轉換數字功能
現在,我們可以使用眾數以獲取此特征最常出現的值,為測試數據集中的單個缺失值填補 Fare 特征。 我們在一行代碼中完成此操作。
請注意,我們只替換單個值,我們不會在中間創建新特征或進行任何進一步的相關分析以猜測缺失特征。 填補目標實現了模型算法對非空值進行操作的期望要求。
我們可能還希望將票價四舍五入到兩位小數,因為它代表貨幣。
test_df['Fare'].fillna(test_df['Fare'].dropna().median(), inplace=True) test_df.head()
我們創建 FareBand 並基於他把 Fare 特征轉換成序列數字,然后去掉 FareBand列
train_df['FareBand'] = pd.qcut(train_df['Fare'], 4) train_df[['FareBand', 'Survived']].groupby(['FareBand'], as_index=False).mean().sort_values(by='FareBand', ascending=True) for dataset in combine: dataset.loc[ dataset['Fare'] <= 7.91, 'Fare'] = 0 dataset.loc[(dataset['Fare'] > 7.91) & (dataset['Fare'] <= 14.454), 'Fare'] = 1 dataset.loc[(dataset['Fare'] > 14.454) & (dataset['Fare'] <= 31), 'Fare'] = 2 dataset.loc[ dataset['Fare'] > 31, 'Fare'] = 3 dataset['Fare'] = dataset['Fare'].astype(int) train_df = train_df.drop(['FareBand'], axis=1) combine = [train_df, test_df] train_df.head(10)
至此,特征工程全部完成。接下來進行模型選擇和預測解決問題
模型,預測和解決
現在我們准備訓練模型並預測所需的解決方案。 有60多種預測建模算法可供選擇。 我們必須了解問題的類型和解決方案要求,以縮小到我們可以評估的少數幾個模型。 我們的問題是分類和回歸問題。 我們想要確定輸出(生存與否)與其他變量或特征(性別,年齡,港口......)之間的關系。 我們還開展了一種機器學習,稱為監督學習,因為我們正在使用給定的數據集訓練我們的模型。 有了這兩個標准 - 監督學習加上分類和回歸,我們可以將我們選擇的模型縮小到幾個。 這些包括:
- Logistic Regression
- KNN or k-Nearest Neighbors
- Support Vector Machines
- Naive Bayes classifier
- Decision Tree
- Random Forrest
- Perceptron
- Artificial neural network
- RVM or Relevance Vector Machine
X_train = train_df.drop("Survived", axis=1) Y_train = train_df["Survived"] X_test = test_df.drop("PassengerId", axis=1).copy() X_train.shape, Y_train.shape, X_test.shape
Logistic回歸是在工作流程早期運行的有用模型。 Logistic回歸通過使用邏輯函數(累積邏輯分布)估計概率來測量分類因變量(特征)與一個或多個自變量(特征)之間的關系。
請注意模型基於我們的訓練數據集生成的置信度分數。
# Logistic Regression logreg = LogisticRegression() logreg.fit(X_train, Y_train) Y_pred = logreg.predict(X_test) acc_log = round(logreg.score(X_train, Y_train) * 100, 2) acc_log #得分 80.36
我們可以使用Logistic回歸來驗證我們對特征創建和完成目標的假設和決策。 這可以通過計算決策函數中的特征的系數來完成。
正系數增加響應的對數幾率(從而增加概率),負系數減小響應的對數幾率(從而降低概率)。
- 性別是最高的積極系數,暗示隨着性別值的增加(男性:0到女性:1),存活率= 1的概率增加最多。
- 反過來,隨着Pclass的增加,Survived = 1的概率降低最多。
- 這樣Age * Class是一個很好的人工模型,因為它與Survived具有第二高的負相關。
- 標題是第二高的正相關。
coeff_df = pd.DataFrame(train_df.columns.delete(0)) coeff_df.columns = ['Feature'] coeff_df["Correlation"] = pd.Series(logreg.coef_[0]) coeff_df.sort_values(by='Correlation', ascending=False)
接下來,我們使用支持向量機進行建模,支持向量機是帶有相關學習算法的監督學習模型,用於分析用於分類和回歸分析 給定一組訓練樣本,每個樣本標記為屬於**兩個類別**中的一個或另一個,SVM訓練算法構建一個模型,將新測試樣本分配給一個類別或另一個類別,使其成為非概率二進制 線性分類器。
請注意,該模型生成的置信度得分高於 “邏輯回歸” 模型。
svc = SVC() svc.fit(X_train, Y_train) Y_pred = svc.predict(X_test) acc_svc = round(svc.score(X_train, Y_train) * 100, 2) acc_svc #得分83.84
在模式識別中,k-Nearest Neighbors算法(或簡稱k-NN)是用於分類和回歸的非參數方法。 樣本按其鄰居的多數票進行分類,樣本被分配給其k個最近鄰居中最常見的類(k是正整數,通常很小)。 如果k = 1,則簡單地將對象分配給該單個最近鄰居的類。
KNN置信度得分優於 邏輯回歸,但比SVM差。
knn = KNeighborsClassifier(n_neighbors = 3) knn.fit(X_train, Y_train) Y_pred = knn.predict(X_test) acc_knn = round(knn.score(X_train, Y_train) * 100, 2) acc_knn #得分84.74
# Gaussian Naive Bayes gaussian = GaussianNB() gaussian.fit(X_train, Y_train) Y_pred = gaussian.predict(X_test) acc_gaussian = round(gaussian.score(X_train, Y_train) * 100, 2) acc_gaussian #得分72.28
感知器是用於二元分類器的監督學習的算法(可以決定由數字向量表示的輸入是否屬於某個特定類的函數)。 它是一種線性分類器,即分類算法,其基於將一組權重與特征向量組合的線性預測器函數進行其預測。 該算法允許在線學習,因為它一次一個地處理訓練集中的元素。
# Perceptron perceptron = Perceptron() perceptron.fit(X_train, Y_train) Y_pred = perceptron.predict(X_test) acc_perceptron = round(perceptron.score(X_train, Y_train) * 100, 2) acc_perceptron #得分78.0
# Linear SVC linear_svc = LinearSVC() linear_svc.fit(X_train, Y_train) Y_pred = linear_svc.predict(X_test) acc_linear_svc = round(linear_svc.score(X_train, Y_train) * 100, 2) acc_linear_svc #得分79.12
# Stochastic Gradient Descent sgd = SGDClassifier() sgd.fit(X_train, Y_train) Y_pred = sgd.predict(X_test) acc_sgd = round(sgd.score(X_train, Y_train) * 100, 2) acc_sgd #得分78.23
模型使用決策樹作為預測模型,將特征(樹枝)映射到關於目標值(樹葉)的結論。 目標變量可以采用有限值集的樹模型稱為分類樹; 在這些樹結構中,葉子表示類標簽,分支表示導致這些類標簽的特征的連接。 目標變量可以采用連續值(通常是實數)的決策樹稱為回歸樹。
到目前為止評估的模型中模型置信度得分最高。
# Decision Tree decision_tree = DecisionTreeClassifier() decision_tree.fit(X_train, Y_train) Y_pred = decision_tree.predict(X_test) acc_decision_tree = round(decision_tree.score(X_train, Y_train) * 100, 2) acc_decision_tree #得分86.76
下一個模型隨機森林是最受歡迎的模型之一。 隨機森林或隨機決策森林是用於分類,回歸和其他任務的集成學習方法,其通過在訓練時構建多個決策樹(n_estimators = 100)並輸出作為類的模式的類(分類)來操作。 或者表示各樹的預測(回歸)。
到目前為止評估的模型中模型置信度得分最高。 我們決定使用此模型的輸出(Y_pred)來創建我們的競賽結果提交。
# Random Forest random_forest = RandomForestClassifier(n_estimators=100) random_forest.fit(X_train, Y_train) Y_pred = random_forest.predict(X_test) random_forest.score(X_train, Y_train) acc_random_forest = round(random_forest.score(X_train, Y_train) * 100, 2) acc_random_forest #得分86.76
模型評估
我們現在可以對所有模型進行評估,以便為我們的問題選擇最佳模型。 雖然決策樹和隨機森林得分相同,但我們選擇使用隨機森林來糾正決策樹過度擬合其訓練集的習慣。
models = pd.DataFrame({ 'Model': ['Support Vector Machines', 'KNN', 'Logistic Regression', 'Random Forest', 'Naive Bayes', 'Perceptron', 'Stochastic Gradient Decent', 'Linear SVC', 'Decision Tree'], 'Score': [acc_svc, acc_knn, acc_log, acc_random_forest, acc_gaussian, acc_perceptron, acc_sgd, acc_linear_svc, acc_decision_tree]}) models.sort_values(by='Score', ascending=False)
最后提交方案
submission = pd.DataFrame({ "PassengerId": test_df["PassengerId"], "Survived": Y_pred }) # submission.to_csv('../output/submission.csv', index=False)
來源 kaggle start_kernel