泰坦尼克号之灾分析
大神经验:
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
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步