泰坦尼克号沉船事件是历史上著名的灾难之一。1912年4月15日,这艘号称“永不沉没”的豪华邮轮与冰山相撞后沉没,导致1502名乘客和船员丧生。这场悲剧不仅震惊了全球,也引发了人们对海上安全的广泛关注。
在这个项目中,我们将利用泰坦尼克数据集,详细介绍如何进行数据分析、数据预处理、建立模型、特征选择、以及模型评估与优化。这份教程不仅涵盖了理论知识,还提供了丰富的实战经验,是机器学习入门者不可多得的学习资源。
首先,我们需要导入必要的库,并检查各库的版本和数据文件夹。接下来,我们将加载数据并进行初步检查。
```python
import sys import pandas as pd import matplotlib import numpy as np import scipy as sp import IPython import sklearn import random import time import warnings
warnings.filterwarnings('ignore')
print("Python version: {}". format(sys.version)) print("pandas version: {}". format(pd.version)) print("matplotlib version: {}". format(matplotlib.version)) print("NumPy version: {}". format(np.version)) print("SciPy version: {}". format(sp.version)) print("IPython version: {}". format(IPython.version)) print("scikit-learn version: {}". format(sklearn.version))
dataraw = pd.readcsv('train.csv') dataval = pd.readcsv('test.csv')
print(dataraw.info()) print(dataraw.sample(10)) ```
在数据校正阶段,我们需要检查数据是否有异常值或错误。目前看来,年龄和票价可能存在一些异常值,但这些值是合理的,因此暂时不作处理。
数据集中存在一些缺失值,特别是年龄、客舱和登船位置。对于这些缺失值,我们可以通过估算来填充。具体而言,年龄将用中位数填充,客舱数据将被删除,登船位置将用众数填充。
```python
datacleaner = [dataraw, data_val]
for dataset in data_cleaner: dataset['Age'].fillna(dataset['Age'].median(), inplace=True) dataset['Embarked'].fillna(dataset['Embarked'].mode()[0], inplace=True) dataset['Fare'].fillna(dataset['Fare'].median(), inplace=True)
dropcolumns = ['PassengerId', 'Cabin', 'Ticket'] dataraw.drop(drop_columns, axis=1, inplace=True)
print(dataraw.isnull().sum()) print(dataval.isnull().sum()) ```
在数据创建阶段,我们将通过特征工程创建新的特征。例如,我们可以从名字中提取头衔,从而获得性别和SES(社会经济地位)等信息。
最后,我们将数据格式转换为适合建模的格式。具体而言,我们将分类数据转换为虚拟变量。
```python
label = LabelEncoder() for dataset in datacleaner: dataset['SexCode'] = label.fittransform(dataset['Sex']) dataset['EmbarkedCode'] = label.fittransform(dataset['Embarked']) dataset['TitleCode'] = label.fittransform(dataset['Title']) dataset['AgeBinCode'] = label.fittransform(dataset['AgeBin']) dataset['FareBinCode'] = label.fit_transform(dataset['FareBin'])
Target = ['Survived'] datax = ['Sex', 'Pclass', 'Embarked', 'Title', 'SibSp', 'Parch', 'Age', 'Fare', 'FamilySize', 'IsAlone'] dataxcalc = ['SexCode', 'Pclass', 'EmbarkedCode', 'TitleCode', 'SibSp', 'Parch', 'Age', 'Fare'] dataxy = Target + datax
datadummy = pd.getdummies(dataraw[datax]) dataxdummy = datadummy.columns.tolist() dataxydummy = Target + datax_dummy
print('Dummy X Y: ', dataxydummy) ```
接下来,我们将通过描述性和图形统计来探索数据,以了解各特征与目标变量之间的关系。
```python
for x in datax: if dataraw[x].dtype != 'float64': print('Survival Correlation by:', x) print(dataraw[[x, Target[0]]].groupby(x, asindex=False).mean()) print('-' * 10, 'n')
```
在建模阶段,我们将采用多种分类算法进行训练,并通过交叉验证和评分指标来评估模型性能。
```python
trainx, testx, trainy, testy = modelselection.traintestsplit(dataraw[dataxcalc], dataraw[Target], randomstate=0)
models = [ ('LR', LogisticRegression()), ('LDA', LinearDiscriminantAnalysis()), ('KNN', KNeighborsClassifier()), ('CART', DecisionTreeClassifier()), ('NB', GaussianNB()), ('SVM', SVC()) ]
results = [] names = []
for name, model in models: kfold = modelselection.KFold(nsplits=10, randomstate=0) cvresults = modelselection.crossvalscore(model, trainx, trainy, cv=kfold, scoring='accuracy') results.append(cvresults) names.append(name) msg = "%s: %f (%f)" % (name, cvresults.mean(), cvresults.std()) print(msg) ```
通过交叉验证,我们可以更好地了解模型在未知数据上的表现。我们将使用交叉验证来评估模型性能。
```python
kfold = modelselection.KFold(nsplits=10, randomstate=0) cvresults = modelselection.crossvalscore(bestmodel, trainx, trainy, cv=kfold, scoring='accuracy') print("Cross Validation Accuracy: ", cv_results.mean()) ```
超参数调整是提高模型性能的重要步骤。我们将使用网格搜索和交叉验证来调整模型参数。
```python
param_grid = { 'C': [0.1, 1, 10, 100], 'gamma': [1, 0.1, 0.01, 0.001], 'kernel': ['rbf'] }
grid = GridSearchCV(SVC(), paramgrid, refit=True, verbose=2) grid.fit(trainx, trainy) print(grid.bestparams_) ```
特征选择是提高模型性能的关键步骤。我们将使用递归特征消除(RFE)和交叉验证来选择最佳特征。
```python
selector = RFE(bestmodel, nfeaturestoselect=6, step=1) selector = selector.fit(trainx, trainy) print(selector.support) print(selector.ranking) ```
最后,我们将通过集成学习方法(如硬投票和软投票)来进一步提升模型性能。
```python
ensemble_models = [ ('LR', LogisticRegression()), ('KNN', KNeighborsClassifier()), ('CART', DecisionTreeClassifier()), ('NB', GaussianNB()), ('SVM', SVC()) ]
ensembleresults = [] ensemblenames = []
for name, model in ensemblemodels: kfold = modelselection.KFold(nsplits=10, randomstate=0) cvresults = modelselection.crossvalscore(model, trainx, trainy, cv=kfold, scoring='accuracy') ensembleresults.append(cvresults) ensemblenames.append(name) msg = "%s: %f (%f)" % (name, cvresults.mean(), cv_results.std()) print(msg) ```
通过上述步骤,我们成功构建了一个预测乘客是否生还的模型,并通过交叉验证和超参数调整优化了模型性能。尽管单一数据集上的测试结果可能与实际表现有所不同,但这些方法为我们提供了可靠的方法论指导。
建议有兴趣的读者可以进一步探索数据预处理和特征工程的方法,以提高模型的整体准确率。