目标
使用泰坦尼克号乘客数据(名字,年龄,票价等)预测谁将存活或者死去。
数据
在数据中有三份文件:(1) train.csv, (2) test.csv, and (3) gender_submission.csv.
(1) train.csv
train.csv 包含机上乘客子集的详细信息(确切地说是891名乘客------每个乘客在表中都有不同的一行。
第二列中的值("幸存")可用于确定每个乘客是否幸存:
- 如果是"1",乘客就活了下来。
- 如果是"0",则乘客死亡。
例如,train.csv 中列出的第一位乘客是 Owen Harris Braund 先生。他在泰坦尼克号上去世时22岁。
(2) test.csv
使用您在 train.csv 中训练的模型,预测船上其他418名乘客(在 test.csv 中)是否幸存。
(3) gender_submission.csv
提供了gender_submition.csv文件作为示例,该文件显示了您应该如何构建预测。据预测,所有女性乘客幸存,所有男性乘客死亡。你关于生存的假设可能会有所不同,这将导致不同的提交文件。但是,就像这个文件一样,您提交的文件应该有:
- PassengerId";列,其中包含test.csv中每个乘客的ID。
- 幸存的";列(您将创建!),其中"1"表示您认为乘客幸存的行,"0"表示您预测乘客死亡的行。
过程
代码
- 导入所需要的库和训练集:
ini
import pandas as pd
train_data = pd.read_csv('data/titanic/train.csv')
train_data.head()
输出:
PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S |
1 | 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
2 | 3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | S |
3 | 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S |
4 | 5 | 0 | 3 | Allen, Mr. William Henry | male | 35.0 | 0 | 0 | 373450 | 8.0500 | NaN | S |
- 导入测试集:
ini
train_data = pd.read_csv('data/titanic/train.csv')
train_data.head()
输出:
PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S |
1 | 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
2 | 3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | S |
3 | 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S |
4 | 5 | 0 | 3 | Allen, Mr. William Henry | male | 35.0 | 0 | 0 | 373450 | 8.0500 | NaN | S |
- 男性存活率:
scss
men = train_data.loc[train_data.Sex == 'male']["Survived"]
rate_men = sum(men)/len(men)
print("% of men who survived:", rate_men)
输出:
% of men who survived: 0.18890814558058924
- 在有兄弟姐妹的男性中,男性的存活率:
scss
men_sibsb_survived = train_data.loc[(train_data['Sex'] == 'male') & (train_data['SibSp'] == 1), 'Survived']
men = train_data.loc[(train_data.Sex == 'male') & (train_data['SibSp'] == 1)]["Survived"]
men_sibsb = sum(men_sibsb_survived)/len(men)
print("有兄弟姐妹的男性中,男性存活率", men_sibsb)
输出:
有兄弟姐妹的男性中,男性存活率: 0.3106796116504854
- 在有父母和孩子的男性中,男性存活率:
scss
men_parch_survived = train_data.loc[(train_data['Sex'] == 'male') & (train_data['Parch'] == 1), 'Survived']
men = train_data.loc[(train_data.Sex == 'male') & (train_data['Parch'] == 1)]["Survived"]
men_parch = sum(men_sibsb_survived)/len(men)
print("有父母孩子的男性中,男性存活率:", men_parch)
输出:
有父母孩子的男性中,男性存活率: 0.5517241379310345
- 女性存活率:
scss
women = train_data.loc[train_data.Sex == 'female']["Survived"]
rate_women = sum(women)/len(women)
print("% of women who survived:", rate_women)
输出:
% of women who survived: 0.7420382165605095
- 使用随机森林模型对结果进行预测,选用的特征是船票等级,性别,是否有配偶在船上,是否有父母在船上。
ini
from sklearn.ensemble import RandomForestClassifier
y = train_data["Survived"]
features = ["Pclass", "Sex", "SibSp", "Parch"]
X = pd.get_dummies(train_data[features])
X_test = pd.get_dummies(test_data[features])
model = RandomForestClassifier(n_estimators=100, max_depth=5, random_state=1)
model.fit(X, y)
predictions = model.predict(X_test)
output = pd.DataFrame({'PassengerId': test_data.PassengerId, 'Survived': predictions})
output.to_csv('submission.csv', index=False)
print("Your submission was successfully saved!")
- 准确率计算:
ini
from sklearn.metrics import accuracy_score
true_data = pd.read_csv('data/titanic/gender_submission.csv')
y_true = true_data.Survived
y_pred = predictions
# 计算准确率
accuracy = accuracy_score(y_true, y_pred)
print(f'Accuracy: {accuracy}')
输出:
Accuracy: 0.9712918660287081
模型
随机森林模型
随机森林模型在分类和回归任务上都有优秀的表现。但是如果要理解随机森林模型的具体原理,这对初学者来说颇具难度,这里面设计到了大量的数学运算,具体步骤参考最后的引文资料,本文尽量以最简单的概念来让你对其有一定的了解。
假设你要判断一些戴着面具的孩子的性别,你可以对他们提出问题,根据他们的回答进行判断,你能提出问题只包括是否喜欢运动,是否喜欢电脑游戏,是否喜欢粉色,是否喜欢甜食等等。
为了使你需要提问的次数最少,判断更准确,那么你需要准备好合适的问题和问题的次序。
在正式的测试前,允许你先刷一会的题。这就对应了模型中训练的过程。
首先,你找来100个人,其中有50个男生和50个女生站在一起,你对他们喊道:喜欢甜食的站在左边,不喜欢的人站在右边。
这时候70个人站在了左边,30个站在了右边。但是别高兴太早,你又发现70个中男生占一半,女生占一半,另外30个也是一样。
那么看来,对于在吃甜食这一事件上,性别不同不会有什么特殊偏好,所以在分辨男女这件事上,是否喜欢甜食,不是一个好问题。
所以你让男女生又站了回来,换把问题换成了是否喜欢打电脑游戏。
这时候60个人站在了左边,40个站在了右边,但是60个人之中有40个是男生,20个是女生,那么40个中30个是女生,10个是男生。
很明显,在左边里面,男生的比例明显增加,在右边里面,女生比例明显增加。
所以在是否喜欢玩电脑游戏这个问题,有效区分这个人是男生和女生,所以这是一个好问题。
当然,你希望准确率可以更高一些,那么你可以对左边右边继续问问题,左右边可以是相同的问题,也可以是不同问题。
知道最后不断划分,你就可以通过一系列问题判断出这个人大概率是男生还是女生,这时候这系列问题被称为树。
但是不要忘了,这是随机森林模型,一棵树怎么可以称之为森林呢。但是你可以重复上述步骤,从人群中选择不同样本集合,选择不同问题训练出不同的树。
不同树可能对同一个样本给出不同答案,这时候我们应该相信哪棵树的答案?
投票,哪个答案给出的多,那我们就信哪个答案。
那再实际的随机森林模型中,对于问题的选择,通常采用信息增益、增益率或者基尼指数对所选参量进行判断,在选择一个参量后,群体分支几个部分,每个部分中某一类数量占比特别高,其它类别总占比小,我们就称这个参量的信息增益大,可以看看上面我给你举的例子,不同问题代表不同参量,好的参量最后造成了左右队列中男女比例明显的变化。
同时,为了防止过拟合,还需要对模型进行剪支处理。这些概念具体请看我后面给你的参考文献。
以上,就是我对随机森林模型粗浅的了解,欢迎各位的指正。