深度学习入门项目-泰坦尼克号幸存者预估
链接:https://www.kaggle.com/c/titanic
数据:https://www.kaggle.com/c/titanic/data
此数据结果分为幸存和死亡两种,考虑使用有监督分类学习思路,使用随机森林算法
工具:python,sklearn库
数据清洗与转化
网站上提供的数据有12个特征:PassengerId, Survived(是结果,稍后会将其与特征分开), Pclass, Name, Sex, Age, SibSp, Parch, Ticket, Fare, Cabin, Embarked分别是乘客号,是否幸存,票类型,姓名,性别,年龄,非直系亲属人数,直系亲属人数,票号,票价,船舱号,登船地点.显然其中有些数据对结果的影响比较大,有些对结果基本没有影响,有些特征可以合并为新特征,有些特征可以转化,因此首先进行数据清洗和转化:
读取数据:
train = pd.read_csv('data/train.csv', header=0)
test = pd.read_csv('data/test.csv')
首先将训练集中的结果和特征分开,再将结果从训练特征集中删掉
y_train = train['Survived'].ravel()
train = train.drop(['Survived'], axis=1)
检查各数据是否缺失,如果缺失,在处理的时候就补上缺省值
train.isnull().sum()
观察训练数据集,可以发现幸存下来的多为女性,因此,可以假定可以假定女士优先逃生.
由于刚才已经判定女士优先逃生(根据训练集特征)因此,肯定不是随机抽号逃生,比如尾号是3的乘客优先逃生,所以可以将乘客号这一特征排除:
train = train.drop('PassengerId', axis = 1)
第二个特征Pclass,票的类型,不同类型的票在船上的位置不同,肯定会影响逃生速度比如先抵达逃生艇位置等情况,分为数值类型1,2,3,4.可以保留不动
第三个特征姓名,由于逃生本着女士优先原则,因此不会使用名字作为约束条件,所以将其排除
第四个特征性别,毫无疑问影响最大
第五个特征年龄:这个必然有影响
第六个特征非直系亲属数和第七个特征直系亲属数量,合并为新特征家庭人数
第八个特征票票号,没有影响排除
第九个特征票价,暂时保留不确定是否有影响
第十个特征船舱号,暂时保留
第十一个特征登船的港口,无影响删除
train = train.drop(['PassengerId','Name','Ticket','Fare'], axis=1)
for dataset in full_data:
dataset['FamilySize'] = dataset['SibSp'] + dataset['Parch'] + 1
训练集和测试集一起处理数据:
full_data = [train, test]
处理年龄数据,现将缺失值用中位数补充加减标准差补充
for dataset in full_data:
age_avg = dataset['Age'].mean()
age_std = dataset['Age'].std()
age_null_count = dataset['Age'].isnull().sum()
age_null_random_list = np.random.randint(age_avg - age_std, age_avg + age_std, size=age_null_count)
dataset['Age'][np.isnan(dataset['Age'])] = age_null_random_list
dataset['Age'] = dataset['Age'].astype(int)
将年龄按不同年龄段分为0,1,2,3,4
for dataset in full_data:
dataset.loc[dataset['Age'] <= 16, 'Age'] = 0
dataset.loc[(dataset['Age'] > 16) & (dataset['Age'] <= 32), 'Age'] = 1
dataset.loc[(dataset['Age'] > 32) & (dataset['Age'] <= 48), 'Age'] = 2
dataset.loc[(dataset['Age'] > 48) & (dataset['Age'] <= 64), 'Age'] = 3
dataset.loc[dataset['Age'] > 64, 'Age'] = 4
使用sklearn库处理数据
from sklearn.ensemble import RandomForestClassifier
设置参数
rf = RandomForestClassifier(criterion='gini',
n_estimators=1750,
max_depth=7,
min_samples_split=6,
min_samples_leaf=6,
max_features='auto',
oob_score=True,
random_state=0,
n_jobs=-1,
verbose=1)
拟合数据并预测
rf.fit(x_train, y_train)
sub['Survived']=rf.predict(x_test)
查看效果
print(classification_report(y_test, sub1))
随着深度增加准确率降低,深度在2的时候最大,出现了过拟合现象,特征数过多,因此要删除无效特征
删除票价和船舱号
重新拟合数据,随着模型深度的增加,准确率、召回率、f1值都在增加,当到达6时达到最后之后又开始减少,数据拟合良好,深度为6时最大准确率、召回率、f1值为94%
总结:特征过多会产生过拟合,适当减少影响小的特征,模型的表现会好上很多.