练习赛1:Titanic

kaggle Titanic项目主页:https://www.kaggle.com/c/titanic
Titanic feature engineering

最新参考:https://ahmedbesbes.com/how-to-score-08134-in-titanic-kaggle-challenge.html

0 问题概述

根据给出的乘客特征(年龄、舱室等级、登陆港口等),预测乘客是否幸存,属于典型的分类问题。

数据文件:

  • train.csv 训练集,包含1-891个记录
  • test.csv 测试集,包含892-1309的记录,不包含是否生存的label
  • gender_submission.csv 提交样例,测试集对应的是否生存label

1 训练集、测试集数据对比分析

1.1 特征缺失值情况对比

image.png

存在两个特殊情况,数据缺失补全时应特别注意;
Cabin特征存在大比例的缺失,可以将其忽略;
所有特征在训练集、测试集中的缺失情况基本一致,无需据此删除任何特征。

1.2 特征数据分布情况对比

image.png

通过绘图对所有10个特征在训练集、测试集中的分布情况进行对比,未发现任何明显差异,无需据此删除任何特征。

1 特征工程

参考:https://triangleinequality.wordpress.com/2013/09/08/basic-feature-engineering-with-the-titanic-data/
离散特征:name 、'Cabin'、 'Embarked'、'Pclass'、 'Sex'、'Ticket'
连续特征:age、fare、'SibSp'、Parch'

1.1 离散特征处理

1)name
乘客姓名作为一个整体时这些信息价值不大,此时它的作用和PassengerId相当。
但是,name中包含的Mrs, Miss, Mr and Master.信息很有价值,可以将name切分为first_name, last_name, mid_name三部分。这里只保留mid_name,其余两个暂时不用。

def name_split(data):
    first_name, last_name, mid_name = [], [], []
    for name in data['Name']:
        name = re.split(r'[,.]\s*', name)
        first_name.append(name[0])
        mid_name.append(name[1])
        last_name.append(name[2])
    #data['first_name'] = first_name
    data['mid_name'] = mid_name
    #data['last_name'] = last_name
    print(data['mid_name'].value_counts())  # 输出mid_name中的非重复元素
    return data
>>
Mr              517
Miss            182
Mrs             125
Master           40
Dr                7
Rev               6
Mlle              2
Major             2
Col               2
Lady              1
Capt              1
Ms                1
Mme               1
Sir               1
Jonkheer          1
the Countess      1
Don               1

可以看出,mid_name中共含有十多个非重复元素。查找资料发现,称谓的说明包含了这些称谓的解释。

Dr.= doctor 医生/博士
Rev.= reverend,用于基督教的牧师,如the Rev. Mr.Smith
Dona,是西班牙语对女子的称谓,相当于英语的 Lady
Don,n. <西>(置于男士名字前的尊称)先生,堂
Master,小男孩,相当于汉语的"少爷"。
jonkheer是贵族
Col,Colonel,上校
capt船长; captain (陆军)上尉; (海军) 上校
major, 陆军少校意思有少校人意思
The Countless,女伯爵
Mlle,小姐
Mme是Madame的简写,<法>(用于已婚妇女姓名前的尊称)太太

方法1:利用专业知识对离散的字符特征进行分组

根据常识,称谓中一般包含以下三方面的信息:

  • 【年龄】:Mrs, Miss, Mr and Master等。称谓中的年龄信息基本和age特征同步。
  • 【性别】:基本和sex特征同步;
  • 【社会等级】:尊贵的人/平民。👉尊贵的人:jonkheer、The Countless
  • 【职业】:可分为船员、牧师、军人、医生等。

检查测试集中的称谓是否和训练集中一致:一致√

print(data['mid_name'].value_counts())
>>
Mr              757
Miss            260
Mrs             197
Master           61
Rev               8
Dr                8
Col               4
Ms                2
Major             2
Mlle              2
Mme               1
Don               1
Dona              1
Lady              1
the Countess      1
Sir               1
Jonkheer          1
Capt              1

featureGroupbyList(data, 'mid_name', [['Mme', 'Ms', 'Mrs'],
                                          ['Mlle', 'Miss'],
                                          ['Mr'],
                                          ['Master'],
                                          ['other'],
                                          ['Capt', 'Col', 'Dr', 'Major', 'Rev']],
                       "mid_nameGroup", ['Mrs', 'Miss', 'Mr', 'Master', 'Royalty', 'officer'])

因此,参考Titanic Kaggle Challenge,对'mid_name'进行分组:
1)以基数较多的Mr、Miss、Mrs和Master 为四个独立类别;
2)从剩余基数较少的mid_name中归纳出Royalty、officer两个新类。

归类结果的基数分布、label分布

方法2:利用特征数据-label标签之间的相关程度进行分组

这种方法忽略midname各取值的现实意义,完全根据label列的表现进行分组。

--1)考虑子图1中特征基数影响,将特征分为['Mr']、['Miss', 'Mrs', 'Master']、其他 三类。
用字符标识,onehot处理,训练集正常0.83,测试集降低为0.53588;
用数值标识,试验发现,离散特征标识的数值大小,对SVM模型的预测结果有显著影响!!!
当数值依次为-1、1、0时,训练集0.83,测试集0.636。

--2)忽略子图1中特征基数的影响,按照子图3中存活率比例,将所有特征划分为三类:

    featureGroupbyList(data, 'mid_name', [['Lady', 'Mlle', 'Mme', 'Ms', 'Sir', 'the Countless'],
                                          ['other'],
                                          ['Capt', 'Don', 'Jonkheer', 'Major', 'Mr', 'Rev']],
                       "mid_nameGroup", ['high', 'medium', 'low'])
对Group后的新特征进行可视化,结果与预期基本一致

结果表明:
第二种方法不如第一种方法,应该依靠特征的实际意义进行处理。
另计:👉标识的数值依次为2、1000、0时,训练集0.83,测试集0.79904,竟然刷新了个人最高分,说明这个特征是有益的,且数值标识value有显著影响。

2)Pclass座舱等级
该特征虽然是用123数字表示,它本质是离散特征,应该进行onehot处理。

存活率随着Pclass等级降低而降低
  • 该属性本质是离散特征,改变它的数值标识大小为100、2、0时,测试集得分从0.79904小幅回跌至0.79425;
  • 改变它的数值标识大小为100、10、1时,测试集得分为0.79425;
    提示:后续的Fare特征补全中利用了该特征,因此修改Pclass的value时应该同步修改data['Fare'].fillna(data.Fare[data.Pclass == 3].median(), inplace=True)

3)sex性别
👉性别特征无缺失,属于典型的两种取值的离散特征,0/1数值编码(1个特征)、onehot编码(2个特征)是完全等效的。用数值编码等效于pd.dummpy(drop_first=True)。

data['Sex'] = data['Sex'].map({'male': 1, 'female': 0})
女性乘客总数低,且存活率明显更高

可以看出,登船的男性乘客数量显著多余女性,但是幸存率却显著低于女性,这说明了性别确实存在显著影响。但是,该特征属于典型的两种取值的离散特征,即使用1/100的数值编码,当0-1标准化处理后依然等效于0/1数值编码。

4)ticket票号
👉票号和座舱等级、座位位置(靠窗、过道)等有关,猜想是很有用的特征。
它的value形式如:A/5 21171 ,可大致划分为两部分,
-- 1)提取首字母
-- 2)提取数字的位数。注意:存在四个票后为LINE,不包含任何数字的ticket。

'TicketFirstLetter'首字母特征具有较高的区分度,选择√

将 'TicketFirstLetter'特征进一步Group处理:
featureGroupbyList(data, 'TicketFirstLetter', [[3, 4, 5, 6, 7, 8, 'A', 'W'], [1, 9, 'P'], ['other']],
"TicketFirstLetterGroup", ['verylow', 'high', 'medium'])

TicketFirstLetterGroup特征区分度较高

5)cabin 舱室号码

print(data['Cabin'].unique())
>>
nan 'C85' 'C123' 'E46' 'G6' 'C103' 'D56' 'A6' 'C23 C25 C27' 'B78' 'D33'
 'B30' 'C52' 'B28' 'C83' 'F33' 'F G73' 'E31' 'A5' 'D10 D12' 'D26' 'C110'
 'B58 B60' 'E101' 'F E69' 'D47' 'B86' 'F2' 'C2' 'E33' 'B19' 'A7' 'C49'

提取首字母。只有cabin=T时存活率极低,其他取值并无区分性。
处理:featureGroupbyList(data, 'Cabin', [['T'], ['other']], "CabinGroup", [0, 1])

只有cabin=T时存活率极低,其他取值并无区分性

对于这种缺失值比例极大的特征,需要注意干扰。

6)embarked 登船港口
C = Cherbourg,
Q = Queenstown,
S = Southampton
缺失补全问题:训练集仅有2个缺失记录,测试集无缺失,因此没必要考虑是否用unknown来标记缺失值。由于该三种取值的字符型特征不好寻找相关特征,直接用众数填充。

    data['Embarked'].fillna(data['Embarked'].mode()[0], inplace=True)
等价于:df['Embarked'][df['Embarked'].isnull()]=df.Embarked.dropna().mode().values
    print('embark_fill value:', data['Embarked'].mode())
三种取值的存活率均在50%附近,该特征基本没有区分性

1.2 连续特征处理

1)SibSp 兄弟姐妹、配偶数量 + Parch 父母、儿女数量 = Family_Size
Sibling = brother, sister, stepbrother, stepsister
Spouse = husband, wife (mistresses and fiancés were ignored)
Parent = mother, father
Child = daughter, son, stepdaughter, stepson

Family_Size特征:有区分性,group分段为四部分
    featureGroupbyList(data, 'Family_Size', [[1, 2, 3], [0, 4, 5, 6], [7, 8, 9, 10]],
                             "Family_SizeGroup", ['medium', 'low', 'verylow'])
Family_SizeGroup特征的区分度得到了明显提升,效果与预期一致

3)fare 票价
缺失补全问题:测试集中只有存在唯一一个fare缺失项。基于常识,我们猜想fare票价和Pclass舱室等级具有较强的相关性。
用皮尔逊相关系数查看:确实√,在所有特征列中,fare和Pclass的相关性最高。备注:Fare_Per_Person是基于Fare构造的新特征,需排除在外。

image.png

因此,查询到该fare缺失乘客Pclass = 3,所以用该舱室等级对应的fare平均值进行填充。

def fare_fill(data):
    fare = data.Fare[data.Pclass == 3].mean()
    print('fare fillvalues:', fare)
    data.Fare.replace(np.NaN, fare, inplace=True)
    return data
将连续的Fare细分为60个区间,发现0-51时幸存率明显更低

将Fare划分为:[0,51]、(51,...) 两个区间。结果如下图,FareGroup特征表现出了不错的区分度。

image.png

4)Age
age特征存在缺失值,但由于占比只有1-714/891=0.198,可以对其进行补全后利用。
补全思路:考虑到mid_name称谓中包含部分age信息,可通过前者对人群进行分类后,再按照子类别的age信息进行补全。注意:这里同时对训练集、测试集补全,最大限度利用已知数据信息!!

首先,查看age缺失记录中对应的mid_name种类和缺失数量。

print(data.loc[data.Age.isnull(), 'mid_name'].value_counts())
Mr        176
Miss       50
Mrs        27
Master      8
Ms          1
Dr          1

其次,再看看这几种人群的基数数量(见name特征处理部分)。他们的基数均偏多,基本可以用各自的age均值进行填充。
填充结果:

age fillvalues: {
'Mr': 32.25215146299484, 
'Ms': 28, 
'Mrs': 36.99411764705882, 
'Miss': 21.774238095238097, 
'Master': 5.482641509433963, 
'Dr': 43.57142857142857}

可以看出,五种人群都匹配了较好的缺失填充年龄,和常识基本吻合。只是这个master:4.57 五岁的小宝宝?原来,master并不是硕士称谓,而是对小男孩的称呼。详见:http://blog.udn.com/article/article_print.jsp?uid=z1627384950&f_ART_ID=7592122
再将Age划分为40个连续区间,观察其是否可以进行group处理。

将Age特征细分为40个区间,发现可以将其划分为三段
AgeGroup表现出了较好的区分性

1.3 高阶特征

所谓高阶特征,是指通过特征间的乘除、幂指等运算得到的新特征。这里,暂时不把加减运算得到的新特征归为高阶特征,前面已对这种进行了分析。

高阶特征1:df['Age*Class']=df['Age']*df['Pclass']
理由:This is an interaction term, since age and class are both numbers we can just multiply them.

'Age*Class'高阶特征还真很有区分度

高阶特征2::df['Fare_Per_Person']=df['Fare']/(df['Family_Size']+1)
理由:Here we divide the fare by the number of family members traveling together, I’m not exactly sure what this represents, but it’s easy enough to add in.因为操作不麻烦,就构造了一个新特征,很随性。

'Fare_Per_Person'高阶特征相比Fare,局部区域的区分度得到了增强

总结1:One thing you can do to create new features is linear combinations of features. In a model like linear regression this should be unnecessary, but for a decision tree may find it hard to model such relationships.
【通过线性方法(加减)去构建新的特征,这对于线性回归等模型来说,是没有必要的,但是它对决策树等模型来说就很有意义。】因此,这种构建新特征的方法仍是可取的。

总结2:interaction term交互项至少对线性模型来说,是很有必要的,猜想它对决策树等模型也是有益的。interaction term交互项就是对两个或多个均数值型特征【相乘】,构造出的新特征。交互项=自变项×调节项,即一对存在主从、因果关系的特征相乘。
参考:因果關係的第三者-調節變項(Moderator / Moderation)
文献:Interpreting Interactions in Regression
以线性模型为例:
假设 减肥行为模型model = 截距 + a×减肥知识 + b×性别 + c×(性别×知识)+ 残差error
如果不自行构造(性别×知识)的interaction term交互项特征,仅靠减肥知识、性别两个原有特征,通过线性模型或其他常见模型是不能拟合出来的。

1.4 离散字符特征的连续化处理:

 # 删除label列以及无用的离散特征原列,用于特征选择
x_use_all = x_all.drop(
    ['Survived', 'Cabin', 'Name', 'Parch', 'PassengerId', 'SibSp', 'mid_name',
     'Ticket'], axis=1)
x_use_all = pd.get_dummies(x_use_all,drop_first=True)  # 对选的use_feature进行onehot处理
print('use_feature经onehot处理后的特征共%d个,分别为:' % x_use_all.columns.size, x_use_all.columns)  # 对所有字符特征进行onehot处理

1.5 特征选择

# 选择特征: 嵌入法,用于模型拟合
sfm = SelectFromModel(XGBClassifier(n_estimators=90, learning_rate=0.1, max_depth=6, min_child_weight=8, gamma=0),
                      threshold=0.004, max_features=15)  # 设置特征选择的相关阈值
x_train = sfm.fit_transform(x_train_dummy, y_train)
x_test = sfm.transform(x_test_dummy)
print('-' * 20, '以下为特征选择结果信息:', '-' * 20)
feature_selected = x_train_dummy.columns[sfm.get_support(indices=False)]
# print('最终选取的特征共%d个,分别为:' % feature_selected.size, feature_selected)
features = pd.DataFrame()
features['feature'] = x_use_all.columns
features['importance'] = sfm.estimator_.feature_importances_
features.sort_values(by=['importance'], ascending=True, inplace=True)
features.index = range(features.index.size, 0, -1)
# features.set_index('feature', inplace=True)
print('最终选取的特征共%d个,按importances排序分别为:' % len(feature_selected))
print(features[-len(feature_selected):][::-1])
# features.plot(x='feature', y='importance', kind='barh', figsize=(25, 50))
# plt.show()
print('-' * 50)
image.png
选择了15个特征用于模型拟合

2. 模型-调参-评估

2.1 LR调参

parameters_lr = {'penalty': ['l1'],
              "C": [0.001, 0.01, 1],
              'solver': ['liblinear','saga']
              }

2.2 SVM调参

# SVM模型属于距离计算模型,需要对输入X进行归一化处理
x_train = MinMaxScaler().fit_transform(X=x_train)
x_test = MinMaxScaler().fit_transform(X=x_test)

# gridsearch
parameters_svm = {'C': np.arange(2.5, 7, 0.5),
                  'kernel': ['rbf'],
                  'gamma': np.arange(0.05, 0.7, 0.1),
                  # 'degree': [3, 4],
                  # 'probability': [True, False],
                  # 'class_weight': ['balanced', None]
                  }

调参总结:
1)SVM要计算margin,margin是一种距离计算,因此一定要对数据进行归一化,否则收敛会非常非常慢;
2)如下图,gridsearch时,应该先找到影响最大的参数,这里gamma参数的变化就给score带来了明显的提升。

gamma参数初调
gamma参数再调

经过对gamma参数的两轮调节,知道它的最优取值大概在3~5附近。
3)第二重要参数是C

C参数调参:小幅增大
C参数再调

经过两轮C参数调参,可以看出它的最优取值基本在1~5之间。

4)class_weight参数

5

原以为该问题中存在轻微的survival样本不均衡,设置class_weight=balanced会提升效果,但事实证明相反。

5)其他模型参数
degree : int, optional (default=3) 仅当kernel= ‘poly’多项式核函数时有效;
'decision_function_shape': ['ovo', 'ovr'] 参数对结果基本没有任何影响。

image.png

SVM调参结果:
best_score_: 0.8260381593714927
best_params_: {'C': 2, 'class_weight': None, 'gamma': 5, 'kernel': 'rbf', 'probability': True}
提交后的得分为:0.78468

image.png

除了前述的对模型参数优化以外,还可以:

  • 针对模型特点,对特征数据进行修改;
  • 对调参过程中的超参数(如交叉验证的CV参数)进行优化。

先对超参数CV进行优化:

for cv in [3, 5, 7, 9]:
    print('cv=', cv)
    model = grid(SVC(), parameters_svm, cv)
    test_prediced = model.predict(x_test)
    final_df = pd.DataFrame(data={'PassengerId': range(892, 892 + 418), 'Survived': test_prediced})
    final_df.to_csv(r'test_pred_svm\test_pred__bySVM_gridsearch_noEmBark_cv=%d.csv' % cv, index=False)
    print('-' * 20)
>>
cv= 3
best_score_: 0.8237934904601572
best_params_: {'C': 2, 'class_weight': None, 'gamma': 7, 'kernel': 'rbf', 'probability': True}
--------------------
cv= 5
best_score_: 0.8271604938271605  #得分最高
best_params_: {'C': 5, 'class_weight': None, 'gamma': 5, 'kernel': 'rbf', 'probability': True}
--------------------
cv= 7
best_score_: 0.8249158249158249
best_params_: {'C': 2, 'class_weight': None, 'gamma': 7, 'kernel': 'rbf', 'probability': True}
--------------------
cv= 9
best_score_: 0.8260381593714927
best_params_: {'C': 2, 'class_weight': None, 'gamma': 5, 'kernel': 'rbf', 'probability': True}
--------------------

将CV=5的预测结果提交kaggle,得分小幅提升至:0.78947

image.png

2.3 DT、GBDT调参

#  因为子模型是DT,因此需要进行归一化处理
x_train = MinMaxScaler().fit_transform(X=x_train)
x_test = MinMaxScaler().fit_transform(X=x_test)

parameters_gbdt = {'learning_rate': [0.1],  # np.arange(0.001, 0.1, 0.005),
                   'n_estimators': [65],  # np.arange(25, 100, 5),

                   # 树参数
                   'max_depth': [9],  # np.arange(2, 10, 1),
                   'min_child_weight': [6],  # np.arange(2, 10, 1),  # 剪枝部分,肯定会降低训练集准确率,因此要逐个尝试

                   'gamma': [0.8],  # [i / 10 for i in range(0, 10)],

                   # 'subsample': [i / 100 for i in range(10, 100, 5)],  # [i / 100 for i in range(60, 100, 5)]
                   # 'colsample_bytree': [i / 100 for i in range(10, 100, 5)],  # [i / 100 for i in range(60, 100, 5)]

                   # 'reg_alpha': [0],  # [0, 1e-6, 1e-5, 1e-2, 0.1,1]
                   # 'reg_lambda': [0.05],  # np.arange(0.01, 0.3, 0.02)
                   }

核心思想:
learning rate越小越好,learning rate和n_estimators互相制约
1)先在learning rate=0.1(偏大)时,找出最佳的n_estimators子树数量

image.png

发现n_estimators在30-35附近,此时应该根据训练集样本量、特征数来评估n_estimators取值是否合理?
由于这里样本数仅为900个,特征10个左右,无需那么多n_estimators,因此基本合理。如果n_estimators明显过小,则应该适当增大learning rate,重新测试;反之,减小learning rate。
这里,继续用np.arange(25, 40, 2)尝试:最佳为29

2)再优化tree参数,对结果影响最大的参数应该优先调节
参数:max_depth, min_child_weight, gamma, subsample, colsample_bytree
'max_depth': np.arange(2, 10, 1),
'min_child_weight': np.arange(1, 5, 1),
最佳取值为:'max_depth': 7, 'min_child_weight': 1,此时best_score_: 0.8462401795735129

再调gamma参数:'gamma': [i / 10.0 for i in range(0, 5)]
最优值为:0

再调subsample、colsample_bytree参数:
'subsample': [i / 10.0 for i in range(6, 10)],
'colsample_bytree': [i / 10.0 for i in range(6, 10)],
最优值为:'subsample': 0.8,'colsample_bytree': 0.7,此时0.8540965207631874

再以0.05为步长进行微调:
'subsample': [i / 100.0 for i in range(70, 90, 5)],
'colsample_bytree': [i / 100.0 for i in range(60, 80, 5)],
结果一样

最优值为:'reg_alpha': 1e-05,reg_lambda': 0.15,此时best_score_: 0.8552188552188552,小幅上升。
进一步优化:'reg_alpha':[0, 1e-6, 1e-5, 1e-2, 0.1],'reg_alpha':0,得分未变。

3)最后逐步降低learning rate,同时等比例放大n_estimators
先将earning rate降低1倍为0.05,n_estimators放大1倍为58,best_score_: 0.8406285072951739得分明显降低。

最终,best_score_: 0.8552188552188552

2.4 模型融合

所谓三个臭皮匠赛过诸葛亮,单个模型的结果不尽如人意,应该考虑进行融合处理,通常能够提升性能。

xgboost_pred = pd.read_csv(r"test_pred_DT\test_pred__byGBDT_gridsearch_with_cv=5.csv", engine='python', index_col=[0],
                           skiprows=[0], header=None, names=['xgboost_label'])

xgboost_prob = pd.read_csv(r"test_pred_DT\test_prob__byGBDT_gridsearch_with_cv=5.csv", engine='python', index_col=[0],
                           skiprows=[0], header=None, names=['xgboost_prob'])

svm_pred = pd.read_csv(r"test_pred_svm\test_pred__bySVM_gridsearch_withAgeGroup_cv=6.csv", engine='python',
                       index_col=[0], skiprows=[0], header=None, names=['svm_label'])
svm_prob = pd.read_csv(r"test_pred_svm\test_prob__bySVM_gridsearch_withAgeGroup_cv=6.csv", engine='python',
                       index_col=[0], skiprows=[0], header=None, names=['svm_prob'])

lr_pred = pd.read_csv(r"test_pred_LR\test_pred_byLR_gridsearch_cv=3.csv", engine='python',
                      index_col=[0], skiprows=[0], header=None, names=['lr_label'])
lr_prob = pd.read_csv(r"test_pred_LR\test_prob_byLR_gridsearch_cv=3.csv", engine='python',
                      index_col=[0], skiprows=[0], header=None, names=['lr_prob'])

all_pred = pd.concat([xgboost_pred, svm_pred, xgboost_prob, svm_prob, lr_pred, lr_prob], axis=1)

# all_pred['xgboost_0.5'] = all_pred['xgboost_prob'] - 0.5
# all_pred['svm_0.5'] = all_pred['svm_prob'] - 0.5

all_pred['mean'] = all_pred[['xgboost_prob', 'svm_prob', 'lr_prob']].mean(axis=1)
all_pred['mean'] = all_pred['mean'].apply(lambda x: 1 if x >= 0.5 else 0)

all_pred['Survived'] = all_pred['mean']
print(all_pred[all_pred['xgboost_label'] != all_pred['svm_label']])
all_pred['Survived'].to_csv(r'ensembel.csv', index_label='PassengerId', index=True, header=True)

这里用三个模型预测概率的mean进行判断。三个模型单独得分为:
LR: 0.78947
SVM: 0.79904
XGBoost: 0.79904

融合模型:0.80382


image.png

赛事评价

kaggle排名中有很多准确率达到1的结果,国内外网站上的讨论How do those awesome people improve their score to above 0.9, to an even 1, for the competition “Titanic: Machine Learning from Disaster” in Kaggle?
都认为可能是利用Titanic的公开性,进行了作弊。例如,https://en.wikipedia.org/wiki/Passengers_of_the_RMS_Titanic这个网站就有相关幸存者信息等。

而根据样本数据能够做到的实际最优效果可能是在0.8~0.9之间。为了避免这个问题,消除作弊者的影响,可尽量采用非公开事件的赛题,即不能通过公开渠道获取正确lable的问题。

参考:

  1. 删除了训练集中票价fare=0的样本数据
    理由:票价为零属于一种特殊情况(劳力、苦役等?),通过查看,发现所有的这15个人都是男性、都是独行(没有家人同行)、且只有1/15的比例幸存。因此,作者认为这些数据属于无效的干扰数据。
    疑问补充:测试集中情况呢?发现测试集中有2个票价为零的记录,且他们也都是男性、没有家人同行。
  1. 对各个特征列是否有贡献进行了分析,例如作者认为登船港口特征对模型没有任何贡献,为什么还要保留它。
    👉尝试了一下,保留/删除Embarked特征前后,利用XGB分类模型,模型在训练集上的准确率从93%跌落至87.%,但提交到Kaggle后,在测试集上的表现反而从0.75提升至0.77。很神奇。
  2. 认为dummy这种类似onehot处理,对模型没有提升;
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,122评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,070评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,491评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,636评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,676评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,541评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,292评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,211评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,655评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,846评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,965评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,684评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,295评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,894评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,012评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,126评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,914评论 2 355

推荐阅读更多精彩内容