关于这个比赛的数据可以在https://www.kaggle.com/c/titanic/data下载
什么是kaggle?
Kaggle成立于2010年,是一个进行数据发掘和预测竞赛的在线平台。从公司的角度来讲,可以提供一些数据,进而提出一个实际需要解决的问题;从参赛者的角度来讲,他们将组队参与项目,针对其中一个问题提出解决方案,最终由公司选出的最佳方案可以获得5K-10K美金的奖金。
除此之外,Kaggle官方每年还会举办一次大规模的竞赛,奖金高达一百万美金,吸引了广大的数据科学爱好者参与其中。从某种角度来讲,大家可以把它理解为一个众包平台,类似国内的猪八戒网。但是不同于传统的低层次劳动力需求,Kaggle一直致力于解决业界难题,因此也创造了一种全新的劳动力市场——不再以学历和工作经验作为唯一的人才评判标准,而是着眼于个人技能,为顶尖人才和公司之间搭建了一座桥梁。
kaggle认可度高吗?
Kaggle作为Data Science业内享有盛名的平台,在业界拥有极高的认可度。所以如果你是想寻找相关行业的工作,那一个漂亮的Kaggle profile将为你的简历增色不少。
一个公司的负责人说过:
“写上参加过Kaggle比赛,我会看简历。
得过一次10%,我会给电话面试。
得过2次或者以上10%,我会给on site面试。
得过一次前10,我们会谈笑风生。”
一. 我们首先要对数据有所了解
![](https://img.haomeiwen.com/i11318644/815c8b923b60abba.png)
训练数据集有891行12列。各列代表的信息:
· PassengerId:一个用以标记每个乘客的数字id
· Survived:标记乘客是否幸存——幸存(1)、死亡(0)。我们将预测这一列。
· Pclass:船舱等级,分为1,2,3等 。
· Name:乘客名字。
· Sex:乘客性别——男male、女female
· Age:乘客年龄。部分。
· SibSp:船上兄弟姐妹和配偶的数量。
· Parch:船上父母和孩子的数量。
· Ticket:乘客的船票号码。
· Fare:乘客为船票付了多少钱。
· Cabin:乘客住在哪个船舱。
· Embarked:乘客从哪个地方登上泰坦尼克号。
titanic = pd.read_csv("train.csv")
#print(titanic.head()) #查看前几行数据,默认为前5行
print(titanic.describe())#查看描述性统计,只能看数值型数据。
print(titanic.info())
![](https://img.haomeiwen.com/i11318644/a4b2dc9ebd9fdaf2.png)
![](https://img.haomeiwen.com/i11318644/ae780aacb5415c2c.png)
可以初步发现,Age这一列只有714,Embarked这一列只有889,说明需要进行缺失值填充;而Cabin这一列总数也就204,缺得太多了,可以考虑删除这一列;Sex、Embarked、Name等属性都是object类型,要将其转化为机器学习能处理的类型。这都是数据预处理的内容,无论哪个案例都需要数据预处理。
二. 数据预处理
填充缺失值,以及将机器学习算法中不能处理的字符值转换成机器学习可以处理的数值
#缺失值填充,Age列缺失的值,按中位数填充
titanic["Age"] = titanic["Age"].fillna(titanic["Age"].median())
#把机器学习不能处理的字符值转换成机器学习可以处理的数值
titanic.loc[titanic["Sex"] == "male", "Sex"] = 0
titanic.loc[titanic["Sex"] == "female", "Sex"] = 1
#通过统计三个登船地点人数最多的填充缺失值
titanic["Embarked"] = titanic["Embarked"].fillna("S")
#字符处理
titanic.loc[titanic["Embarked"] == "S", "Embarked"] = 0
titanic.loc[titanic["Embarked"] == "C", "Embarked"] = 1
titanic.loc[titanic["Embarked"] == "Q", "Embarked"] = 2
三. 通过线性回归来进行预测
#选择我们要用到的特征
predictors = ["Pclass", "Sex", "Age", "SibSp", "Parch", "Fare", "Embarked"]
#将线性回归方法导进来
alg = LinearRegression()
#将m个样本平均分成11份进行交叉验证。
kf = KFold(titanic.shape[0], n_folds=11, random_state=1)
predictions = []
for train, test in kf:
#将predictors作为测试特征
train_predictors = (titanic[predictors].iloc[train, :])
#获取到数据集中交叉分类好的标签,即是否活了下来
train_target = titanic["Survived"].iloc[train]
#将数据放进去做训练
alg.fit(train_predictors, train_target)
#我们现在可以使用测试集来进行预测
test_predictions = alg.predict(titanic[predictors].iloc[test, :])
predictions.append(test_predictions)
#使用线性回归得到的结果是在区间[0,1]上的某个值,需要将该值转换成0或1
predictions = np.concatenate(predictions, axis=0)
predictions[predictions > .5] = 1
predictions[predictions <= .5] = 0
#查看模型准确率
accuracy = sum(predictions == titanic["Survived"]) / len(predictions)
print(accuracy)
得出的准确率为0.7934904601571269。
在这里把样本分成几份这是个学问,我一开始把样本分成5份,发现准确率为0.7878787878787878,后来经过多次测试,发现分成11份应该是最好的,因为分成10份和12份都比分成11份的准确率低。
四. 通过逻辑回归进行预测
#使用逻辑回归算法
alg = LogisticRegression(random_state=1)
#使用逻辑回归做交叉验证
scores = cross_validation.cross_val_score(alg, titanic[predictors], titanic["Survived"], cv=11)
#取scores的平均值
print(scores.mean())
得到的准确率为0.8002744244614163,只比线性回归的准确率高一点点。
五. 使用随机森林
#使用随机森林
#指定随机森林的参数 n_estimators设置决策树的个数 min_samples_split最小的样本个数 min_samples_leaf 最小叶子节点的个数
alg = RandomForestClassifier(random_state=1, n_estimators=20, min_samples_split=4, min_samples_leaf=2)
kf = cross_validation.KFold(titanic.shape[0], n_folds=11, random_state=1)
scores = cross_validation.cross_val_score(alg, titanic[predictors], titanic["Survived"], cv=kf)
print(scores.mean())
得到的准确率为0.8338945005611673,明显比线性回归还有逻辑回归的准确率高。
六. 特征工程
“数据决定了机器学习的上限,而算法只是尽可能逼近这个上限”,这里的数据指的就是经过特征工程得到的数据。特征工程指的是把原始数据转变为模型的训练数据的过程,它的目的就是获取更好的训练数据特征,使得机器学习模型逼近这个上限。吴恩达曾说过:“特征工程不仅操作困难、耗时,而且需要专业领域知识。应用机器学习基本上就是特征工程。”
在做机器学习时,我们不能只使用给出来的特征,我们要在原本特征的基础上挖掘出新的特征,在这里我挖掘出了以下两个新特征。
#提取新的特征
#将船上所有人的亲属朋友关系加起来,新建一个特征,用来表示每个人的亲属关系
titanic["FamilySize"] = titanic["SibSp"] + titanic["Parch"]
#根据名字长度组成一个新特征
titanic["NameLength"] = titanic["Name"].apply(lambda x: len(x))
然后进行特征选择,我们可以通过图形来看哪个特征更重要
#下面进行特征选择
predictors = ["Pclass", "Sex", "Age", "SibSp", "Parch", "Fare", "Embarked", "FamilySize", "NameLength", "Title"]
selector = SelectKBest(f_classif, k=5)
selector.fit(titanic[predictors], titanic["Survived"])
scores = -np.log10(selector.pvalues_)
#画图看各个特征的重要程度
plt.bar(range(len(predictors)), scores)
plt.xticks(range(len(predictors)), predictors, rotation='vertical')
plt.show()
![](https://img.haomeiwen.com/i11318644/b30fe5efbdbfe163.png)
从图中我们可以看出来“Title”最为重要,“Pclass”、 "Sex"、“Fare”和"NameLength"也比较重要。所以我这次选了这五个特征,再用一次随机森林模型。
predictors = ["Pclass","Fare", "NameLength", "Title"]
alg = RandomForestClassifier(random_state=1, n_estimators=20, min_samples_split=4, min_samples_leaf=2)
kf = cross_validation.KFold(titanic.shape[0], n_folds=11, random_state=1)
scores = cross_validation.cross_val_score(alg, titanic[predictors], titanic["Survived"], cv=kf)
print(scores.mean())
得到的准确率为0.8193041526374859
7.集成模型
每个算法都会有自己的优缺点,那么我们可不可以把两个模型集成起来呢?
答案是肯定的。
algorithms = [
[RandomForestClassifier(random_state=1, n_estimators=20, min_samples_split=4, min_samples_leaf=2),
['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare', 'Embarked', 'FamilySize', 'NameLength', 'Title']],
[LogisticRegression(random_state=1),
['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare', 'Embarked', 'FamilySize', 'NameLength', 'Title']]
]
kf = KFold(titanic.shape[0], n_folds=11, random_state=1)
predictions = []
for train, test in kf:
train_target = titanic['Survived'].iloc[train]
full_test_predictions = []
for alg, predictors in algorithms:
alg.fit(titanic[predictors].iloc[train, :], train_target)
test_prediction = alg.predict_proba(titanic[predictors].iloc[test, :].astype(float))[:, 1]
full_test_predictions.append(test_prediction)
test_predictions = (full_test_predictions[0]*2 + full_test_predictions[1]) / 3
test_predictions[test_predictions > .5] = 1
test_predictions[test_predictions <= .5] = 0
predictions.append(test_predictions)
predictions = np.concatenate(predictions, axis=0)
accuracy = sum(predictions == titanic['Survived']) / len(predictions) # 测试准确率
print(accuracy)
最后得到的准确率为0.8316498316498316。
接下来,我们还可以继续从特征工程或者找一些其他的模型继续做下去
网友评论