Python学习-泰坦尼克号

泰坦尼克号的名单包括统计到的人员名单,包括人员的ID,是否幸存,仓位(1,2,3以及无座),姓名,性别,年龄等信息,截图如下:

本文将用Python对此样本数据进行一些简单的处理及应用。

首先用Spyder载入了泰坦尼克号的CSV数据文件,并打印了一下列名与样本个体数

train = pd.read_csv('D:/PythonPractice/titanic/train.csv')
print(train.columns.values.tolist()
print(len(train))

['PassengerId', 'Survived', 'Pclass', 'Name', 'Sex', 'Age', 'SibSp', 'Parch', 'Ticket', 'Fare', 'Cabin', 'Embarked']

891

从数据上并不能看出性别年龄等特征与是否幸存的关系。现在利用透视表查看仓位等级、性别与存活率的关系:

class_survived= train.pivot_table(index="Pclass",values="Survived")#仓位等级与存活率
sex_survived=train.pivot_table(index="Sex",values="Survived")#性别与存活率
    Survived
Pclass          
1       0.629630
2       0.472826
3       0.242363
        Survived
Sex             
female  0.742038

male    0.188908

这里发现仓位等级越高存活率越大,并且女性的存活率要远高于男性。

接下来利用绘图工具matplot的柱形图简单统计了一下年龄与存活率的关系:

age=train["Age"]
less5 =train[age<=5]
bigger5 =train[5<age]
less15=train[age<15]
beyond60=train[age>60]

percent5=len(less5[less5["Survived"]==1])/len(less5)
percent15=len(less15[less15["Survived"]==1])/len(less15)
percentB5=len(bigger5[bigger5["Survived"]==1])/len(bigger5)
percentbeyond60=len(beyond60[beyond60["Survived"]==1])/len(beyond60)

x=["<5","<15",">5",">60"]
y=[percent5,percent15,percentB5,percentbeyond60]
plt.bar(x,y)


从图中可以看出,小于五岁的孩子存活率最高,15岁的次之。而大于60岁的存活率最低。

之后来看一下家庭成员数与存活率的关系:

train["FamilySize"]=train["SibSp"]+train["Parch"]#家庭成员数由这两个列组成,新建列FamilySize
size=train[["FamilySize","Survived"]]
size1=size[size["FamilySize"]==1]
size23= size[size["FamilySize"].apply(lambda x: 1<x<4)== True]
size45= size[size["FamilySize"].apply(lambda x: 3<x<6)== True]
size5plus=size[size["FamilySize"]>=5]

survivdPercent1=len(size1[size1["Survived"]==1])/len(size1)#计算各个家庭数目及存活率
survivdPercent23=len(size23[size23["Survived"]==1])/len(size23)
survivdPercent45=len(size45[size45["Survived"]==1])/len(size45)
survivdPercent5plus=len(size5plus[size5plus["Survived"]==1])/len(size5plus)

x=["1","23","45","5 plus"]
y=[survivdPercent1,survivdPercent23,survivdPercent45,survivdPercent5plus]
plt.bar(x,y)

发现家庭成员数与存活率是有关系的。


所以从以上分析得出结论,存活率与年龄,性别,仓位等级有一定联系。接下来,就利用Python库中的随机森林模型对样本进行分析:

1. 要做的事情第一步是处理缺失值,以保证它对结果没有影响:

#train["Age"]=train["Age"].fillna(train["Age"].median())#填充年龄空行
train=train.dropna(subset=["Age"])#删除年龄空行

    可以用年龄的中间值填补空行,或者直接剔除年龄空值。如果样本量非常巨大,那么少量地删除个体对结果的影响是非常小的。

2. 由于Python库处理数值比较方便,所以这里将男女表示为1和0

train.loc[train["Sex"]=="male","Sex"]=1#用0和1代表男女
train.loc[train["Sex"]=="female","Sex"] = 0

3. 声明特性列名

predictors=["Sex","Age","Pclass","FamilySize"]

4. 随机森林分类器

随机森林是由多个决策树组成,决策树是根据各个特性对结果的影响从大到小排列,逐一排查并最终确定最终结果。

例如在这里,对是否存活影响最大的因素为性别,那么建立的决策树的根节点就会判断此人是男人还是女人。之后再根据其他因素最终得出是否幸存。

但是决策树并不是分支越多越好,这样会导致叶子节点的个体个数过少,导致过拟合。所以在建立决策树时,会根据不同情况对决策树进行限制,例如限制节点深度、限制叶子节点的个数、叶子节点的最少样本数等。

在这里,随机森林就是由多个决策树组成。他可以自动给出哪些特性比较重要,并且删除对结果没有影响或者影响极小的特性(对特性加噪并检验对结果影响大小)。

此处声明一个随机森林模型:

alg=RandomForestClassifier(random_state=2,n_estimators=5,min_samples_split=3,min_samples_leaf=1)

-random_state为随机种子,便于以后生成相同的随机数

-n_estimators为决策树个数

-min_samples_split为分割内部节点所需要的最小样本数量

-min_samples_leaf为节点最小叶子数

这里有大神为随机森林参数的详细介绍:点击打开链接


接下来声明交叉验证:

交叉验证会将训练样本分为多份(这里n_fold=5),它将会用1,2,3,4来预测5并用5检验;用1,2,3,5来预测4并用4检验...

交叉验证可以减少数据中缺失值或不准确值对结果的影响。

kf=cross_validation.KFold(train.shape[0],n_folds=5,random_state=1,shuffle= True)
-train.shape[0]为观察样本个数

-n_folds为交叉个数

-shuffle为是否打乱数据

接下来看一下交叉验证的结果如何:

scores=cross_validation.cross_val_score(alg, train[predictors], train["Survived"], cv=kf)#cv:代表不同的cross validation的方法
print(scores.mean()) 
结果为:0.7689254407564267

所以模型的预测成功率只有0.77,对于一个二分类问题并不是一个好的预测成功率。

为了得到一个更好的预测,我将模型的参数重新设置为n_estimators=100,min_samples_split=3,min_samples_leaf=2

结果为:0.8011326701467546


用修改后的模型进行预测,计算准确率

alg.fit(train[predictors],train["Survived"])
test=test.dropna(subset=["Age"])
test["FamilySize"]=test["SibSp"]+test["Parch"]
test.loc[test["Sex"]=="male","Sex"]=1#用0和1代表男女
test.loc[test["Sex"]=="female","Sex"] = 0
test["Predic"]= alg.predict(test[predictors]);
lenth=len(test)
accuracy=len(test[test["Predic"]==test["Survived"]])/len(test)

结果为:0.822289156626506

用混淆矩阵查看预测情况:

mat=confusion_matrix(test["Survived"],test["Predic"])
print(mat)

结果为:

[[175  30]

 [ 29  98]]


0.822的预测效果一般,但是在对原始数据加强分析、加入更多特征、加入更多数据后,模型会有更高的准确率。


参考资料:

网易云课堂唐宇迪老师的

python数据分析与机器学习实战

链接:http://study.163.com/course/courseMain.htm?courseId=1003590004&share=1&shareId=1020608544








猜你喜欢

转载自blog.csdn.net/qq_36056559/article/details/80645128
今日推荐