Loliko_LinawZ

导航

 

先做入门笔记吧,从每个kaggler入门必学的泰塔尼克号幸存者开始。

先看问题,我们要思考什么类型的人得救的概率较大。这里会给出train.cvs文件让我们直接做处理和建模,然后需要对test.cvs数据集里的人幸存率做一个大概的猜测。

 

 

先对整个流程宏观处理:

  • 到kaggle上下载幸存者数据集,思考问题,做出假设。
  • 针对数据集做图形化处理。这里主要是处理数据信息,其中包括部分缺失的数据。
  • 对数据清洗,做预处理。
  • 拟合建模,验证猜测。

 

关于一些数据属性:

  • PassengerId => 乘客ID
  • Pclass => 乘客等级(1/2/3等舱位)
  • Name => 乘客姓名
  • Sex => 性别
  • Age => 年龄
  • SibSp => 堂兄弟/妹个数
  • Parch => 父母与小孩个数
  • Ticket => 船票信息
  • Fare => 票价
  • Cabin => 客舱
  • Embarked => 登船港口

数据可以直接到kaggle上下载,首先对数据进行可视化处理,我们可以使用info函数来查看数据信息。

import pandas as pd
import numpy as np
data_train=pd.read_csv("E:/Titanic/train.csv")
print(data_train.info())#查看数据缺失情况
print(data_train.describe())#查看数据基本统计信息

 

 

 

 这是info函数采集到的信息:我们可以看到有891名乘客,但是age(年龄)和cabin(客舱)都有明显的数据缺失,其中年龄数据缺失了177个数据,客舱缺失687个数据。

 

 

 

这是describe函数采集到的信息,在这里我们可以看到891人里最后的幸存率是38.3%,幸存者平均年龄在29岁左右。接下来可以使用matplotlib函数开始对数据做可视化处理。

 

 

 

import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from pylab import *

plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
data_train = pd.read_csv("E:/titanic/train.csv")
# 查看各乘客等级的获救情况
survived_0 = data_train.Pclass[data_train.Survived == 0].value_counts()
survived_1 = data_train.Pclass[data_train.Survived == 1].value_counts()
df = pd.DataFrame({'获救': survived_1, '未获救': survived_0})
df.plot(kind='bar', stacked=True)
plt.title('各船舱乘客获救情况')
plt.xlabel('船舱等级')
plt.ylabel('人数')

# 查看性别的获救情况
survived_0 = data_train.Sex[data_train.Survived == 0].value_counts()
survived_1 = data_train.Sex[data_train.Survived == 1].value_counts()
df2 = pd.DataFrame({'获救': survived_1, '未获救': survived_0})
df2.plot(kind='bar', stacked=True)
plt.title('男女乘客获救情况')
plt.xlabel('性别')
plt.ylabel('人数')

#查看各船舱级别下的男女获救情况
fig=figure()
plt.subplot(141)
data_train.Survived[data_train.Sex=='female'][data_train.Pclass==3].value_counts().sort_index().plot(kind='bar',color='pink')
plt.xticks(arange(2),['未获救','获救'])
plt.yticks(arange(0,301,50))
plt.legend(['低等舱/女生'],loc='best')
plt.subplot(142)
data_train.Survived[data_train.Sex=='female'][data_train.Pclass!=3].value_counts().sort_index().plot(kind='bar',color='hotpink')
plt.xticks(arange(2),['未获救','获救'])
plt.yticks(arange(0,301,50))
plt.legend(['高等舱/女生'],loc='best')
plt.subplot(143)
data_train.Survived[data_train.Sex=='male'][data_train.Pclass==3].value_counts().sort_index().plot(kind='bar',color='lightsteelblue')
plt.xticks(arange(2),['未获救','获救'])
plt.yticks(arange(0,301,50))
plt.legend(['低等舱/男生'],loc='best')
plt.subplot(144)
data_train.Survived[data_train.Sex=='male'][data_train.Pclass!=3].value_counts().sort_index().plot(kind='bar',color='cornflowerblue')
plt.xticks(arange(2),['未获救','获救'])
plt.yticks(arange(0,301,50))
plt.legend(['高等舱/男生'],loc='best')
fig.tight_layout()
plt.show()

 

 

 从这里可以看出来,获救几率和船舱等级成正比,船舱等级越高获救几率越大。

 

 

 从这里可以看出,女性的获救几率明显大于男性。

 

 

 

 

 对其他情况统一进行数据处理:

import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from pylab import *
fig=figure()
fig.set(alpha=0.2)
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
data_train=pd.read_csv("E:/titanic/train.csv")
 
plt.subplot(341)
data_train.Survived.value_counts().plot(kind='bar')
plt.title("获救情况(1为获救)")
plt.ylabel("人数")
 
plt.subplot(342)
data_train.Pclass.value_counts().plot(kind='bar')
plt.title("乘客等级分布")
plt.ylabel("人数")
 
plt.subplot(344)
y=data_train.Age
x=data_train.Survived
plt.scatter(x,y)
plt.title("按年龄看获救分布(1)为获救")
plt.ylabel("年龄")
 
plt.subplot(312)
y=data_train.Age.value_counts()
y.sort_index().plot(kind='bar')
plt.xlabel("年龄")
plt.ylabel("人数")
plt.title("各年龄的乘客人数")
 
plt.subplot(313)
data_train.Age[data_train.Pclass==1].plot(kind='kde')#密度图
data_train.Age[data_train.Pclass==2].plot(kind='kde')
data_train.Age[data_train.Pclass==3].plot(kind='kde')
plt.xlabel("年龄")
plt.ylabel("密度")
plt.title("各等级的乘客年龄分布")
plt.legend(('头等舱','二等舱','三等舱'),loc='best')
 
plt.subplot(343)
data_train.Embarked.value_counts().plot(kind='bar')
plt.title("各登船口岸上船人数")
plt.ylabel("人数")  
#subplots_adjust(wspace=0.5,hspace=1)#也可以调节各图形之间的间距
fig.tight_layout()#自动调整各图形之间的间距
plt.show()

 

 

到此我们可以针对图标结论做出猜测:

  • 女性比男性更容易获救。
  • 社会地位高的人更容易获救。
  • 获救几率与年龄有关。

 

 通过第一步的info函数查看数据的缺失情况,发现Age(年龄)缺失的数据较少,所以采用插值法来处理。用到的插值方法是随机森林。而Cabin(船舱号)则缺失了约3/4,而船舱号码暂时看不出来对获救有什么影响,所以我选择了对其进行数值化,有船舱号的值记为为1,没有船舱号的记为0。同样,为了方便后面的建模,我需要对非数值的属性Sex(性别),Embarked(登舱口),Name(名字),Ticket(票号)进行同样的数值化处理。这里用到了pandas库中的dummies函数。

from sklearn.ensemble import RandomForestRegressor
import numpy as np
import pandas as pd
from sklearn import preprocessing
data_train=pd.read_csv("E:/titanic/train.csv")
# 使用 RandomForestClassifier 填补缺失的年龄属性
def set_missing_ages(df):
    age_df=df[['Age','Fare','Parch','SibSp','Pclass']]
    known_age=age_df[age_df.Age.notnull()].as_matrix()
    unknown_age=age_df[age_df.Age.isnull()].as_matrix()
    y=known_age[:,0]#第一列所有元素
    x=known_age[:,1:]#分割出矩阵第二列以后的所有元素
    rfr=RandomForestRegressor(random_state=0,n_estimators=2000,n_jobs=-1)
    rfr.fit(x,y)
    predictedAges=rfr.predict(unknown_age[:,1:])
    df.loc[(df.Age.isnull()),'Age']=predictedAges#loc通过行标签来索引数据
    return df
 
def set_Cabin_type(df):
    df.loc[ (df.Cabin.notnull()), 'Cabin' ] = "Yes"
    df.loc[ (df.Cabin.isnull()), 'Cabin' ] = "No"
    return df
data_train = set_missing_ages(data_train)
data_train = set_Cabin_type(data_train)
data_train.to_csv('processed_data1.csv')#新文件夹没有空值
dummies_Cabin=pd.get_dummies(data_train['Cabin'],prefix='Cabin')
dummies_Embarked=pd.get_dummies(data_train['Embarked'],prefix='Embarked')
dummies_Sex = pd.get_dummies(data_train['Sex'], prefix= 'Sex')
dummies_Pclass = pd.get_dummies(data_train['Pclass'], prefix= 'Pclass')
df = pd.concat([data_train, dummies_Cabin, dummies_Embarked, dummies_Sex, dummies_Pclass], axis=1)#增加列属性,concat默认是增加行,axis=1为增加列
df.drop(['Pclass', 'Name', 'Sex', 'Ticket', 'Cabin', 'Embarked'], axis=1, inplace=True)#drop为删除原来的列,axis=1为删除列
df.to_csv('processed_data2.csv')#新文件夹的数据都为数值型,对原数据进行了特征因子化

处理后的数据都为数值型,但一些值的变化范围太大,如Fare,Age等,需要对其进行规范化处理,我采用的是零—均值规范化。

#将Age和Fare两个属性进行零——均值标准化。
scale_age=(df['Age']-df['Age'].mean())/df['Age'].std()
scale_fare=(df['Fare']-df['Fare'].mean())/df['Fare'].std()
df.copy()
df['Age']=scale_age
df['Fare']=scale_fare
df.to_csv('processed_data3.csv')

输出文件:

 

 

构建逻辑回归模型并进行预测:

from sklearn import linear_model
import numpy as np
from sklearn.ensemble import RandomForestRegressor
import pandas as pd
from sklearn import preprocessing
from datapreprocessing import set_Cabin_type
df=pd.read_csv("E:/titanic/processed_data3.csv")
 
train_df = df.filter(regex='Survived|Age_.*|SibSp|Parch|Fare_.*|Cabin_.*|Embarked_.*|Sex_.*|Pclass_.*')
train_np = train_df.as_matrix()
# y即Survival结果
y = train_np[:, 0]
 
# X即特征属性值
X = train_np[:, 1:]
 
# fit到LogisticRegression之中
clf = linear_model.LogisticRegression(C=1.0, penalty='l1', tol=1e-6)
clf.fit(X, y)
 
 
####对测试数据同样进行数据预处理
data_test = pd.read_csv("E:/titanic/data/test.csv")
data_train=pd.read_csv("E:/titanic/data/train.csv")
#构建同一个随机森林
age_df=data_train[['Age','Fare','Parch','SibSp','Pclass']]
known_age=age_df[age_df.Age.notnull()].as_matrix()
unknown_age=age_df[age_df.Age.isnull()].as_matrix()
y=known_age[:,0]#第一列所有元素
x=known_age[:,1:]#分割出矩阵第二列以后的所有元素
rfr=RandomForestRegressor(random_state=0,n_estimators=2000,n_jobs=-1)
rfr.fit(x,y)
data_test.loc[ (data_test.Fare.isnull()), 'Fare' ] = 0
tmp_df = data_test[['Age','Fare', 'Parch', 'SibSp', 'Pclass']]
null_age = tmp_df[data_test.Age.isnull()].as_matrix()
X = null_age[:, 1:]
predictedAges = rfr.predict(X)
data_test.loc[ (data_test.Age.isnull()), 'Age' ] = predictedAges
data_test = set_Cabin_type(data_test)
dummies_Cabin = pd.get_dummies(data_test['Cabin'], prefix= 'Cabin')
dummies_Embarked = pd.get_dummies(data_test['Embarked'], prefix= 'Embarked')
dummies_Sex = pd.get_dummies(data_test['Sex'], prefix= 'Sex')
dummies_Pclass = pd.get_dummies(data_test['Pclass'], prefix= 'Pclass')
df_test = pd.concat([data_test, dummies_Cabin, dummies_Embarked, dummies_Sex, dummies_Pclass], axis=1)
df_test.drop(['Pclass', 'Name', 'Sex', 'Ticket', 'Cabin', 'Embarked'], axis=1, inplace=True)
data_test.to_csv('processed_test_data1.csv')#新文件夹没有空值
 
#将Age和Fare两个属性进行零——均值标准化。
scale_age=(df['Age']-df['Age'].mean())/df['Age'].std()
scale_fare=(df['Fare']-df['Fare'].mean())/df['Fare'].std()
df.copy()
df['Age']=scale_age
df['Fare']=scale_fare
df.to_csv('processed_test_data2.csv')
 
#用逻辑回归模型做预测
test = df_test.filter(regex='Age_.*|SibSp|Parch|Fare_.*|Cabin_.*|Embarked_.*|Sex_.*|Pclass_.*')
predictions = clf.predict(test)
result = pd.DataFrame({'PassengerId':data_test['PassengerId'].as_matrix(), 'Survived':predictions.astype(np.int32)})
result.to_csv("logistic_regression_predictions.csv", index=False)

 

 

预测部分结果如下:

 

 这个结果评分在kaggle上是0.76076

 

参考自:

https://blog.csdn.net/han_xiaoyang/article/details/49797143

https://blog.csdn.net/weixin_42036641/article/details/80294896

https://www.cnblogs.com/cutd/p/5713520.html

 

posted on 2020-11-09 17:20  数码暴龙猪  阅读(155)  评论(0编辑  收藏  举报