Kaggle比赛——Titanic: Machine Learning from Disaster

0 整体流程

  1. 了解问题 & 获取训练集和测试集
  2. 整理、准备、清洗数据
  3. 分析、识别模式并探索数据
  4. 建模、预测和解决问题
  5. 可视化、报告和呈现问题解决步骤和最终解决方案

数据处理流程:

  • Classifying 分类

    • 对样本进行分类;了解不同类与解决方案目标的含义或相关性
  • Correlating 特征相关性

    • 了解数据集中的哪些特征对解决方案目标有重大贡献;了解特征之间的相关性;关联某些特征可能有助于纠正特征或创建新特征
  • Converting 转换

    • 将所有需要的特征转换成数字形式,便于模型学习
  • Completing 数据补全

    • 将缺失值补全,完整的数据将有助于模型的学习
  • Correcting 矫正错误数据

    • 发现可能存在错误的数据,对错误数据进行校正,或删除那个样本;检测样本或特征中的异常值,若某个特征没有用处或产生反向的作用,也可以丢弃这个特征
  • Creating 创建新的特征

    • 将已有特征进行组合、重造等,创建新的特征
  • Charting 可视化

    • 根据数据的性质和解决方案目标选择正确的可视化图和图表

1 问题定义 & 训练集和测试集

通过泰坦尼克号灾难中包含乘客是否生存的训练样本集,设计一个模型用于预测测试数据集中的乘客是否幸存。

训练集包含信息:

| PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked |

测试集包含信息:

| PassengerId | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked |

VariableDefinitionKey
survivalSurvival0 = No, 1 = Yes
pclassTicket class1 = 1st, 2 = 2nd, 3 = 3rd
sexSex
AgeAge in years
sibsp# of siblings / spouses aboard the Titanic
parch# of parents / children aboard the Titanic
ticketTicket number
farePassenger fare
cabinCabin number
embarkedPort of EmbarkationC = Cherbourg, Q = Queenstown, S = Southampton

2 整理、准备、清洗数据(特征分析)

2.1 导入数据

  • 导包
# 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]

2.2 特征分析

  • 数据集中所包含的特征
print(train_df.columns.values)
#---------------------------------------------------------------
'''
['PassengerId' 'Survived' 'Pclass' 'Name' 'Sex' 'Age' 'SibSp' 'Parch' 'Ticket' 'Fare' 'Cabin' 'Embarked']
'''
  • 特征类别
    • 分类特征
      • 分类:Survived, Sex, and Embarked
      • 序数:Pclass
    • 数值特征
      • 连续:Age, Fare
      • 离散:SibSp, Parch
    • 混合类型
      • Ticket,Cabin 包含字母和数字
train_df.head()
# train_df.tail()
PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS
1211Cumings, Mrs. John Bradley (Florence Briggs Th…female38.010PC 1759971.2833C85C
2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS
  • 可能存在错误的特征

    • 对大数据集来说,很难查找,一般从表中取出一小部分数据集进行检查
    • 如:姓名中可能包含错误和打字错误
  • 存在空值的特征(blank, null or empty)

    • 如:Cabin, Age, Embarked 存在空值
  • 各个特征的数据类型

    • 训练集:7个特征为正数或浮点数, 测试集:6个
    • 5个特征为字符串类型(object)
train_df.info()
print('_'*40)
test_df.info()

#-----------------------OUTPUT-----------------------------
'''
<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
________________________________________
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 418 entries, 0 to 417
Data columns (total 11 columns):
PassengerId    418 non-null int64
Pclass         418 non-null int64
Name           418 non-null object
Sex            418 non-null object
Age            332 non-null float64
SibSp          418 non-null int64
Parch          418 non-null int64
Ticket         418 non-null object
Fare           417 non-null float64
Cabin          91 non-null object
Embarked       418 non-null object
dtypes: float64(2), int64(4), object(5)
memory usage: 36.0+ KB
'''
  • 数值特征分布
    • 「帮助在早期确定训练集的代表性」,从下表可知:
    • 总样本数为891,是泰坦尼克号(2,224)上实际乘客人数的40%
    • Survived是0或1的分类特征
    • 大约38%的样本存活,实际存活率为32%
    • 大多数乘客(> 75%)没有与父母或孩子一起旅行
    • 近30%的乘客有兄弟姐妹或配偶
    • 票价差异很大,有很少的 乘客(<1%)支付高达512美元
    • 年龄在65-80岁之间的老年乘客(<1%)很少
train_df.describe()
PassengerIdSurvivedPclassAgeSibSpParchFare
count891.000000891.000000891.000000714.000000891.000000891.000000891.000000
mean446.0000000.3838382.30864229.6991180.5230080.38159432.204208
std257.3538420.4865920.83607114.5264971.1027430.80605749.693429
min1.0000000.0000001.0000000.4200000.0000000.0000000.000000
25%223.5000000.0000002.00000020.1250000.0000000.0000007.910400
50%446.0000000.0000003.00000028.0000000.0000000.00000014.454200
75%668.5000001.0000003.00000038.0000001.0000000.00000031.000000
max891.0000001.0000003.00000080.0000008.0000006.000000512.329200
  • 分类特征分布
    • 姓名在整个数据集中是唯一的(count = unique = 891)
    • 性别变量为两个值,男性为65%(top=male, freq=577/count=891)
    • Cabin有一些重复的值(几个乘客共用一个小屋)
    • Embarked有三个值。 大多数乘客使用S口(top= S)
    • 船票有很多相同的价格(22%,unique=681)
# 参数include=['O'],表示对Object类型的特征进行统计
train_df.describe(include=['O'])
NameSexTicketCabinEmbarked
count891891891204889
unique89126811473
topPanula, Master. Juha Niilomale1601C23 C25 C27S
freq157774644

2.3 基于特征分析的假设

  • Correlating
    • 每个特征与生存之间的联系
  • Completing
    • 填充Age特征,因为与是否存活关系紧密
    • 填充Embarked特征,因为也与存活或其他重要的特征关系紧密
  • Correcting
    • Ticket特征将会删除,包含高比例的重复项(22%),并且和存活之间可能没有关联
    • Cabin删除,因为含有很多空值
    • PassengerId删除,对是否存活的影响很小
    • Name可能会删除,因为信息不标准,且可能不会直接有助于生存
  • Creating
    • 创造新的特征Family,基于ParchSibSp特征,以得到家庭成员总数
    • Name特征中提取Title作为一个新特征
    • 创建年龄阶层特征Age bands,将数字特征转化为分类特征
    • 可能创建票价范围特征Fare range,用于帮助分析
  • Classifying
    • 女性更容易存活
    • 儿童(Age<?)更容易存活
    • 老人更容易存活

2.4 表格分析特征

用于快速分析特征相关性(目前只能对没有空值的特征进行此操作)

  • Pclass: Pclass=1和存活(分类#3)之间存在显著相关性(> 0.5)。因此决定在模型中包含这个特性
  • Sex: 证实了女性的存活率很高,为74%(分类#1)
  • SibSp and Parch: 这些特征相关性低。最好从这些单独的特征中导出一个或一组特征(创建#1)
train_df[['Pclass', 'Survived']].groupby(['Pclass'], as_index=False).mean().sort_values(by='Survived', ascending=False)
PclassSurvived
010.629630
120.472826
230.242363
train_df[["Sex", "Survived"]].groupby(['Sex'], as_index=False).mean().sort_values(by='Survived', ascending=False)
SexSurvived
0female0.742038
1male0.188908
train_df[["SibSp", "Survived"]].groupby(['SibSp'], as_index=False).mean().sort_values(by='Survived', ascending=False)
SibSpSurvived
110.535885
220.464286
000.345395
330.250000
440.166667
550.000000
680.000000
train_df[["Parch", "Survived"]].groupby(['Parch'], as_index=False).mean().sort_values(by='Survived', ascending=False)
ParchSurvived
330.600000
110.550847
220.500000
000.343658
550.200000
440.000000
660.000000

3 可视化数据

3.1 特征相关性

直方图可用于分析Age这样的连续数值变量,可以使用自动定义的区间或等距离范围来指示样本的分布。其中条带或范围将有助于识别有用的模式

g = sns.FacetGrid(train_df, col='Survived')
g.map(plt.hist, 'Age', bins=20)

在这里插入图片描述

  • Observations
    • 婴儿(年龄≤4岁)存活率高
    • 年龄最大的乘客(年龄= 80岁)幸存下来
    • 大量15-25岁的人没有存活下来
    • 大多数乘客年龄在15-35岁之间
  • Decisions
    • 在模型训练中,应该考虑年龄特征(假设分类#2)
    • 填充年龄特征中的空值 (completing #1)
    • 为年龄分组 (creating #3)

3.2 关联数字和序数特征

使用一个图来组合多个特征来识别相关性

# 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();

在这里插入图片描述

  • Observations
    • Pclass=3的乘客很多,但是大部分没有幸存下来。确认分类假设#2
    • Pclass=2Pclass=3的婴儿乘客大多幸存下来。进一步确定了分类假设#2
    • Pclass=1的大多数乘客幸存下来。确认分类假设#3
    • 乘客的年龄分布不同
  • Decisions
    • 考虑使用Pclass特征进行模型训练

3.3 关联分类特征

将分类特征与我们的解决方案目标相关联

# 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()

在这里插入图片描述

  • Observations
    • 女性乘客的存活率比男性高得多。确认分类(#1)
    • Embarked=C的男性存活率较高外。这可能是PclassEmbarked之间的相关性,反过来是PclassSurvived,不一定是EmbarkedSurvived之间的直接相关
    • 当C和Q口登船的男性中,Pclass=3Pclass=2存活率更高。完成(#2) ???
    • 对于Pclass=3和男性乘客来说,登机港的存活率各不相同。关联(#1) ???

3.4 关联分类和数字特征

将分类特征和数值特征相关联。我们可以考虑将Embarked(分类特征)、Sex(分类特征)、Fare(连续数字特征)与Survived(分类特征)相关联。

# grid = sns.FacetGrid(train_df, col='Embarked', hue='Survived', palette={0: 'k', 1: 'w'})
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()

在这里插入图片描述

  • Observations.

    • 票价越高存活率越高。证实了创建票价范围的假设(#4)
    • Embarked与存活率相关。确认#1的关联性和完成#2
  • Decisions.

    • 考虑对票价分组

4 数据整理

目前已经收集了一些解决方案的假设和决策。接下来执行决策和假设,以纠正、创建和完成目标

4.1 补全特征值

有以下三种方法用于特征值补全:

  1. 一种简单的方法是在均值和标准差之间生成随机数
  2. 使用其他特征来猜测缺失值
  3. 结合方法1和2。因此,不要根据中位数来猜测年龄值,而是根据不同的类别和性别组合,使用均值和标准差之间的随机数

方法1和3将在我们的模型中引入随机噪声。多次执行的结果可能不同。因此更偏向方法2。

4.1.1 补全Age特征 & 分组
# 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 x Gender的组合
guess_ages = np.zeros((2,3))
guess_ages

# ------------------OUTPUT--------------------
array([[0., 0., 0.],
       [0., 0., 0.]])
  • 根据Sex(0 or 1)和Pclass(1, 2, 3)两个特征来猜测Age
    • 使用搜索结果中符合条件的中位数
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()
  • 对年龄分组
train_df['AgeBand'] = pd.cut(train_df['Age'], 5)
train_df[['AgeBand', 'Survived']].groupby(['AgeBand'], as_index=False).mean().sort_values(by='AgeBand', ascending=True)
AgeBandSurvived
0(-0.08, 16.0]0.550000
1(16.0, 32.0]0.337374
2(32.0, 48.0]0.412037
3(48.0, 64.0]0.434783
4(64.0, 80.0]0.090909
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()
SurvivedPclassSexAgeSibSpParchFareEmbarkedTitleAgeBand
00301107.2500S1(16.0, 32.0]
111121071.2833C3(32.0, 48.0]
21311007.9250S2(16.0, 32.0]
311121053.1000S3(32.0, 48.0]
40302008.0500S1(32.0, 48.0]
  • 删除AgeBand特征
train_df = train_df.drop(['AgeBand'], axis=1)
combine = [train_df, test_df]
train_df.head()
4.1.2 补全Embarked特征

Embarked特征中丢失了两个值,将样本中出现最多的值填进去

  • 统计出现最多的值
freq_port = train_df.Embarked.dropna().mode()[0]
freq_port

# ---------------OUTPUT------------------
'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)
EmbarkedSurvived
0C0.553571
1Q0.389610
2S0.339009
4.1.3 补全Fare特征

使用中位数进行补全

test_df['Fare'].fillna(test_df['Fare'].dropna().median(), inplace=True)
test_df.head()
PassengerIdPclassSexAgeFareEmbarkedTitleIsAloneAge*Class
08923027.82922116
18933127.00000306
28942039.68752116
38953018.66250113
489631112.28750303

4.2 创建新特征

4.2.1 创建title特征

先分析是否可以将Name特征来提取titles并测试titlesSurvival之间的相关性,然后再删除NamePassengerId特征。

提取Name中的第一个词:

for dataset in combine:
    dataset['Title'] = dataset.Name.str.extract(' ([A-Za-z]+)\.', expand=False)

pd.crosstab(train_df['Title'], train_df['Sex'])
Sexfemalemale
Title
Capt01
Col02
Countess10
Don01
Dr16
Jonkheer01
Lady10
Major02
Master040
Miss1820
Mlle20
Mme10
Mr0517
Mrs1250
Ms10
Rev06
Sir01
  • Observations.

    • 大多数title与年龄分组想对应
    • 一些title大多数存活下来(Mme, Lady, Sir),一些没存活(Don, Rev, Jokheer)
  • Decision.

    • 决定保留新特征title用于模型训练

title特征进行合并:

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()
TitleSurvived
0Master0.575000
1Miss0.702703
2Mr0.156673
3Mrs0.793651
4Rare0.347826

title分类特征转换为序数特征:

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()
PassengerIdSurvivedPclassNameSexAgeSibSpParchFareEmbarkedTitle
0103Braund, Mr. Owen Harrismale22.0107.2500S1
1211Cumings, Mrs. John Bradley (Florence Briggs Th…female38.01071.2833C3
2313Heikkinen, Miss. Lainafemale26.0007.9250S2
3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01053.1000S3
4503Allen, Mr. William Henrymale35.0008.0500S1

现在可以删除NamePassengerId特征了:

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

# -------------OUTPUT--------------
'''
((891, 9), (418, 9))
'''
4.2.2 创建FamilySize特征

Parch(父母+孩子),SibSp(兄妹+配偶)

train_df = train_df.drop(['AgeBand'], axis=1)
combine = [train_df, test_df]
train_df.head()
FamilySizeSurvived
340.724138
230.578431
120.552795
670.333333
010.303538
450.200000
560.136364
780.000000
8110.000000
4.2.3 创建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()
IsAloneSurvived
000.505650
110.303538
4.2.4 创建组合特征Age*Class

PclassAge特征进行组合

for dataset in combine:
    dataset['Age*Class'] = dataset.Age * dataset.Pclass

train_df.loc[:, ['Age*Class', 'Age', 'Pclass']].head(10)
4.2.5 创建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)
FareBandSurvived
0(-0.001, 7.91]0.197309
1(7.91, 14.454]0.303571
2(14.454, 31.0]0.454955
3(31.0, 512.329]0.581081
  • 将分组范围转换为数字类型
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)
SurvivedPclassSexAgeFareEmbarkedTitleIsAloneAge*Class
0030100103
1111231302
2131110213
3111230302
4030210116
5030112113
6010330113
7030020400
8131110303
9121021300

4.3 特征转换

将所有非数字特征转换为数字特征。这是大多数模型算法所要求的,这样做也将有助于完成目标。

4.3.1 转换Sex特征

Sex特征转换为Gender新特征,其中female=1, male=0

for dataset in combine:
    dataset['Sex'] = dataset['Sex'].map( {'female': 1, 'male': 0} ).astype(int)

train_df.head(
4.3.2 转换Embarked特征

Embarked中的S, C, Q特征值转换为数字特征

for dataset in combine:
    dataset['Embarked'] = dataset['Embarked'].map( {'S': 0, 'C': 1, 'Q': 2} ).astype(int)

train_df.head()
SurvivedPclassSexAgeFareEmbarkedTitleIsAloneAge*Class
003017.25000103
1111271.28331302
213117.92500213
3111253.10000302
403028.05000116

4.4 删除特征

删除没用(或用处不大)的特征以减少数据量,加快分析速度

4.4.1 删除Cabin和Ticket特征
  • 根据前面的分析,决定删除CabinTicket特征
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]

"After", train_df.shape, test_df.shape, combine[0].shape, combine[1].shape

# ----------------------OUTPUT--------------------------
'''
Before (891, 12) (418, 11) (891, 12) (418, 11)
('After', (891, 10), (418, 9), (891, 10), (418, 9))
'''
4.4.2 删除Parch、 SibSp和FamilySize特征

由于4.1.3节中创建了IsAlone特征,比这三个特征更具有代表意义,因此把这三个特征删除。(FamilySize是否可以保留?)

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()

5 模型预测 & 分析 & 检验

5.1 模型预测

  • 现在,准备训练一个模型并预测所需的解决方案。有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

#-------------------OUTPUT--------------------
'''
((891, 8), (891,), (418, 8))
'''
5.1.1 Logistic Regression

逻辑回归是工作流早期运行的有用模型。逻辑回归通过使用逻辑函数(即累积逻辑分布)估计概率来测量分类因变量(特征)和一个或多个自变量(特征)之间的关系。

# 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
5.1.2 KNN or k-Nearest Neighbors

在模式识别中,k-最近邻算法(简称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
5.1.3 Support Vector Machines

使用支持向量机建模,支持向量机是监督学习模型,具有分析用于分类和回归分析的数据的相关学习算法。给定一组训练样本,每个样本标记为属于两个类别中的一个或另一个,SVM训练算法建立一个模型,将新的测试样本分配给一个类别或另一个类别,使其成为非概率二进制线性分类器。

# Support Vector Machines

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
5.1.4 Naive Bayes classifier

在机器学习中,朴素贝叶斯分类器是一个简单的概率分类器家族,基于贝叶斯定理,特征之间具有强(朴素)独立性假设。朴素贝叶斯分类器具有很高的可伸缩性,在学习问题中需要多个变量(特征)呈线性的参数。参考维基百科。

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
5.1.5 Decision Tree

该模型使用决策树作为预测模型,将特征(树枝)映射到关于目标值(树叶)的结论。目标变量可以取一组有限值的树模型称为分类树;在这些树结构中,树叶代表类标签,树枝代表导致这些类标签的特征的结合。目标变量可以取连续值(通常是实数)的决策树称为回归树。

# 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
5.1.6 Random Forrest

下一个模型随机森林是最受欢迎的模型之一。随机森林或随机决策森林是一种用于分类、回归和其他任务的集成学习方法,它通过在训练时构建大量决策树(n _ assessors = 100)并输出作为单个树的类别(分类)或平均预测(回归)模式的类别来操作。

# 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
5.1.7 Perceptron

感知器是一种用于二进制分类器监督学习的算法(可以决定由数字向量表示的输入是否属于某个特定类别的函数)。它是一种线性分类器,即基于将一组权重与特征向量相结合的线性预测函数进行预测的分类算法。该算法允许在线学习,因为它一次处理一个训练集中的元素。

# 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
5.1.8 Linear SVC
# 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
5.1.9 Stochastic Gradient Descent
# 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

5.2 分析

可以使用Logistic回归来验证我们对功能创建和完成目标的假设和决策。 这可以通过计算决策函数中的特征的系数来完成。

正系数增加了响应的对数几率(从而增加了概率),负系数降低了响应的对数几率(从而降低了概率)。

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)
FeatureCorrelation
1Sex2.201527
5Title0.398234
2Age0.287163
4Embarked0.261762
6IsAlone0.129140
3Fare-0.085150
7Age*Class-0.311200
0Pclass-0.749007

5.3 模型评估

现在可以对所有模型的评估进行排序,以选择最适合我们问题的模型。虽然决策树和随机森林得分相同,但我们选择使用随机森林,因为它们纠正了决策树过度拟合其训练集的习惯。

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)
ModelScore
3Random Forest86.76
8Decision Tree86.76
1KNN84.74
0Support Vector Machines83.84
2Logistic Regression80.36
7Linear SVC79.12
6Stochastic Gradient Decent78.56
5Perceptron78.00
4Naive Bayes72.28

6 提交结果

submission = pd.DataFrame({
        "PassengerId": test_df["PassengerId"],
        "Survived": Y_pred
    })
# submission.to_csv('../output/submission.csv', index=False)
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值