泰坦尼克号-高级功能工程教程

翻译自:kaggle
https://www.kaggle.com/heroy12/titanic-advanced-feature-engineering-tutorial

0. 简介

我之所以决定编写此内核,是因为《泰坦尼克号:灾难机器学习》是我在Kaggle上最喜欢的比赛之一。这是一个初学者级内核,专注于探索性数据分析和功能工程。很多人从这场竞赛开始Kaggle,他们迷失在极长的教程内核中。与其他内核相比,这是一个简短的内核。我希望这对初学者来说是一个很好的指南,并以新的功能工程思想启发他们。

泰坦尼克号:从灾难中学习机器是将领域知识应用到特征工程中的一次激烈竞争,因此我进行了研究,并学到很多有关泰坦尼克号的知识。泰坦尼克号数据集下面有许多秘密需要揭示。我试图找出那些在泰坦尼克号沉没时影响乘客生存的秘密因素。我相信还有其他功能尚待发现。

这个内核有3个主要部分:探索性数据分析功能工程模型,并且使用调整后的随机森林分类器可以达到2%(0.83732)的公共排行榜得分。运行整个笔记本需要60秒。如果您有任何想法可以改善此内核,请确保发表评论,或随意进行试验。如果您不了解任何部分,请随时提问。

import numpy as np
import pandas as pd

import matplotlib.pyplot as plt
import seaborn as sns
sns.set(style="darkgrid")

from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import OneHotEncoder, LabelEncoder, StandardScaler
from sklearn.metrics import roc_curve, auc
from sklearn.model_selection import StratifiedKFold

import string
import warnings
warnings.filterwarnings('ignore')

SEED = 42
  • 训练集有891行,测试集有418行
  • 训练集具有12个特征,测试集具有11个特征
  • 训练集中的一项额外特征是生存特征,这是目标变量
def concat_df(train_data, test_data):
    # Returns a concatenated df of training and test set
    return pd.concat([train_data, test_data], sort=True).reset_index(drop=True)

def divide_df(all_data):
    # Returns divided dfs of training and test set
    return all_data.loc[:890], all_data.loc[891:].drop(['Survived'], axis=1)

df_train = pd.read_csv('../input/train.csv')
df_test = pd.read_csv('../input/test.csv')
df_all = concat_df(df_train, df_test)

df_train.name = 'Training Set'
df_test.name = 'Test Set'
df_all.name = 'All Set' 

dfs = [df_train, df_test]

print('Number of Training Examples = {}'.format(df_train.shape[0]))
print('Number of Test Examples = {}\n'.format(df_test.shape[0]))
print('Training X Shape = {}'.format(df_train.shape))
print('Training y Shape = {}\n'.format(df_train['Survived'].shape[0]))
print('Test X Shape = {}'.format(df_test.shape))
print('Test y Shape = {}\n'.format(df_test.shape[0]))
print(df_train.columns)
print(df_test.columns)

1 探索性数据分析

1.1 概述

  • PassengerID是该行唯一性的id,它对target没有任何影响
  • Survived是我们尝试预测的目标变量(0或者1)
    1 = Survived
    0 = Not Survived
  • Pclass(乘客舱)是乘客的社会经济地位,它是一种有序的分类特征,具有3个唯一值(1、2或3):
    1 =上层阶级
    2 =中产阶级
    3 =下层阶级
  • NameSexAge是不言自明的
  • SibSp是乘客的兄弟姐妹和配偶的总数
  • Parch是乘客父母和子女的总数
  • Ticket是乘客的票号
  • Fare是旅客票价
  • Cabin(客舱)是乘客的客舱号
  • Embarked(登船)是登船的港口,它是一种分类特征,具有3个唯一值(C,Q或S):
    C =瑟堡
    Q =皇后镇
    S =南安普敦
print(df_train.info())
df_train.sample(3)
print(df_test.info())
df_test.sample(3)

1.2 Missing Values(缺失值)

从下面可以看出,某些列的值缺失。display_missing函数在训练和测试集中的每列中显示缺失值的计数。

  • 训练集的AgeCabinEmbarked列中缺少值
  • 测试集的AgeCabinFare列中缺少值

在处理缺失值时,可以方便地在级联训练和测试集上进行工作,否则填充的数据可能会过度适合训练或测试集样本。 与总样本相比,AgeEmbarkedFare中的缺失值计数要少,但大约有80%Cabin缺失。 可以使用描述性的统计指标来填充AgeEmbarkedFare中缺少的值,但这不适用于Cabin

def display_missing(df):    
    for col in df.columns.tolist():          
        print('{} column missing values: {}'.format(col, df[col].isnull().sum()))
    print('\n')
    
for df in dfs:
    print('{}'.format(df.name))
    display_missing(df)

1.2.1 Age

Age中的缺失值填充了中位数年龄,但是使用整个数据集的中位数年龄不是一个好选择。 Pclass组的中位年龄是最佳选择,因为它与Age(0.408106)Survived(0.338481)高度相关。 按乘客类别而不是其他特征分组年龄也更合乎逻辑。

df_all_corr = df_all.corr().abs().unstack().sort_values(kind="quicksort", ascending=False).reset_index()
df_all_corr.rename(columns={"level_0": "Feature 1", "level_1": "Feature 2", 0: 'Correlation Coefficient'}, inplace=True)
df_all_corr[df_all_corr['Feature 1'] == 'Age']

为了更准确,在填充缺失的Age值时,将Sex功能用作groupby的第二级。 从下面可以看出,PclassSex组具有不同的Age中值。 当旅客人数增加时,男性和女性的中位年龄也会增加。 但是,女性的中值年龄往往比男性低。 以下年龄中位数用于填充Age特征中的缺失值。

age_by_pclass_sex = df_all.groupby(['Sex', 'Pclass']).median()['Age']

for pclass in range(1, 4):
    for sex in ['female', 'male']:
        print('Median age of Pclass {} {}s: {}'.format(pclass, sex, age_by_pclass_sex[sex][pclass]))
print('Median age of all passengers: {}'.format(df_all['Age'].median()))

# Filling the missing values in Age with the medians of Sex and Pclass groups
df_all['Age'] = df_all.groupby(['Sex', 'Pclass'])['Age'].apply(lambda x: x.fillna(x.median()))

1.2.2 Embarked

Embarked是一种分类特征,整个数据集中只有2个缺失值。 这些乘客都是女性,上层阶级,并且他们的票号相同。 这意味着他们彼此认识并一起从同一港口出发。 上等女性乘客的Embarked值为C(瑟堡),但这并不一定意味着他们从那个港口出发。

df_all[df_all['Embarked'].isnull()]

当我搜寻Stone乔治·纳尔逊夫人(Martha Evelyn)夫人时,我发现她和女仆Amelie IcardS(南安普敦)出发,在本页玛莎·伊芙琳·斯通:《泰坦尼克号幸存者》中。

Mrs Stone boarded the Titanic in Southampton on 10 April 1912 and was travelling in first class with her maid Amelie Icard. She occupied cabin B-28.

Embarked中的缺失值are filled with S with this information.

# Filling the missing values in Embarked with S
df_all['Embarked'] = df_all['Embarked'].fillna('S')

1.2.3 Fare

posted on 2020-08-17 21:46  heroy1  阅读(316)  评论(0)    收藏  举报