泰坦尼克号

数据挖掘流程:

(一)读取数据:

  • 读取数据,并进行展示
  • 统计数据各项指标
  • 明确数据规模与要完成的任务

(二)特征理解分析

  • 单特征分析,逐个变量分析其对结果的影响
  • 多变量统计分析,综合考虑多种情况影响
  • 统计绘图得出结论

(三)数据清洗与预处理

  • 对缺失值进行填充
  • 特征值标准化/归一化
  • 筛选有价值的特征
  • 分析特征中间的相关性

(四)建立模型

  • 特征数据与标签准备
  • 数据集切分
  • 多种模型算法对比
  • 集成策略等方案改进

挑选兵器:

  • Numpy-科学计算库 主要用来做矩阵运算,什么?你不知道哪里会用到矩阵,那么这样想吧,咱们的数据就是行(样本)和列(特征)组成的,那么数据本身不就是一个矩阵嘛。
  • Pandas-数据分析处理库 很多小伙伴都在说用python处理数据很容易,那么容易在哪呢?其实有了pandas很复杂的操作我们也可以一行代码去解决掉!
  • Matplotlib-可视化库 无论是分析还是建模,光靠好记性可不行,很有必要把结果和过程可视化的展示出来。
  • Seaborn-可视化库 更简单的可视化库封装上Matplot基础之上。
  • Scikit-Learn-机器学习库 非常实用的机器学习算法库,这里面包含了基本你觉得你能用上所有机器学习算法啦。但还远不止如此,还有很多预处理和评估的模块等你来挖掘的!

读取数据

#导入库
import numpy as np 
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
plt.style.use('fivethirtyeight')#使用默认参数
import warnings
warnings.filterwarnings('ignore')#忽略警告
%matplotlib inline#将图内置到浏览器中
#读取数据
train = pd.read_csv("E:Data/train.csv")
test = pd.read_csv("E:Data/test.csv")
train.head()

泰坦尼克号_第1张图片

每一列对应的意义:

  • PassengerId: 乘客ID
  • Survived: 是否生存,0代表遇难,1代表还活着
  • Pclass: 船舱等级:1Upper,2Middle,3Lower
  • Name: 姓名
  • Sex:性别
  • Age: 年龄
  • SibSp: 兄弟姐妹及配偶个数
  • Parch:父母或子女个数
  • Ticket: 乘客的船票号
  • Fare: 乘客的船票价
  • Cabin: 乘客所在的仓位(位置)
  • Embarked:乘客登船口岸

判断是否有缺失值:

#判断是否有缺失值
train.isnull().sum()

泰坦尼克号_第2张图片

年龄,仓位,登船口岸有缺失。

年龄缺失可以使用均值或中值替换,仓位缺失较多,可以考虑删除仓位属性或者将缺失作为一个单独的类,登船口岸只有两个缺失,可以直接删除这两个数据。

对数据属性进行统计

泰坦尼克号_第3张图片

训练集一共有891条数据。

查看获救比例:

#查看获救比例
#1行两列的子图
f,ax=plt.subplots(1,2,figsize=(18,8))
#统计Survived属性
train['Survived'].value_counts().plot.pie(explode=[0,0.1],autopct='%1.1f%%',ax=ax[0],shadow=True)
#ax[0]表示第0个子图,ax[1]表示第一个子图
ax[0].set_title('Survived')
ax[0].set_ylabel('')
sns.countplot('Survived',data=train,ax=ax[1])
ax[1].set_title('Survived')
plt.show()
#查看获救比例
#1行两列的子图
f,ax=plt.subplots(1,2,figsize=(18,8))
#统计Survived属性
train['Survived'].value_counts().plot.pie(explode=[0,0.1],autopct='%1.1f%%',ax=ax[0],shadow=True)
#ax[0]表示第0个子图,ax[1]表示第一个子图
ax[0].set_title('Survived')
ax[0].set_ylabel('')
sns.countplot('Survived',data=train,ax=ax[1])
ax[1].set_title('Survived')
plt.show()

泰坦尼克号_第4张图片

获救比例占38.4%

尝试使用数据集的不同特征来查看对应的生存率,比如:性别,年龄,登船地点等,进行单变量特征分析。

查看性别与存活的关系

泰坦尼克号_第5张图片

女性存活率高达74.2%,而男性存活率只有18.9%,因此性别对存活率有较大影响。

f,ax=plt.subplots(1,2,figsize=(18,8))
#统计Survived属性
train[['Sex','Survived']].groupby(['Sex']).mean().plot.bar(ax=ax[0])
#ax[0]表示第0个子图,ax[1]表示第一个子图
ax[0].set_title('Survived vs Sex')
sns.countplot('Sex',hue ='Survived',data=train,ax=ax[1])
ax[1].set_title('Sex:Survived vs Dead')
plt.show()

泰坦尼克号_第6张图片

Pclass-> 船舱等级与获救情况的关系

pd.crosstab(train.Pclass,train.Survived,margins=True).style.background_gradient(cmap='summer_r')

泰坦尼克号_第7张图片

根据统计,不同等级的船舱获救比例不同,因此获救几率与船舱等级有关。

那这些又和性别有关吗?接下来我们再来看看船舱等级和性别对结果的影响

pd.crosstab([train.Sex,train.Survived],train.Pclass,margins=True).style.background_gradient(cmap='summer_r')

泰坦尼克号_第8张图片

一等舱和二等舱女性几乎都获救,而在三等舱获救几率只有50%。 一等舱男性获救率36.9%,二等舱男性获救率 15.7%,三登船按下获救率13.5%,因此船舱等级不同影响存活率。

Age--> 连续值特征对结果的影响

f,ax=plt.subplots(1,2,figsize=(18,8))
sns.violinplot("Pclass","Age", hue="Survived", data=train,split=True,ax=ax[0])
ax[0].set_title('Pclass and Age vs Survived')
ax[0].set_yticks(range(0,110,10))
sns.violinplot("Sex","Age", hue="Survived", data=train,split=True,ax=ax[1])
ax[1].set_title('Sex and Age vs Survived')
ax[1].set_yticks(range(0,110,10))
plt.show()

泰坦尼克号_第9张图片

结果:1)10岁以下儿童的存活率随passenegers数量增加。

2)生存为20-50岁获救几率更高一些。

3)对男性来说,随着年龄的增长,存活率降低。

缺失值填充

常用方法:
平均值
经验值
回归模型预测
剔除掉

正如我们前面看到的,年龄特征有177个空值。为了替换这些缺失值,我们可以给它们分配数据集的平均年龄。但问题是,有许多不同年龄的人。最好的办法是找到一个合适的年龄段!我们可以检查名字特征。根据这个特征,我们可以看到名字有像先生或夫人这样的称呼这样我们就可以把先生和夫人的平均值分配给各自的组。

统计姓名的前缀

泰坦尼克号_第10张图片

把相同意思不同前缀进行替换

泰坦尼克号_第11张图片

再计算不同称呼的年龄的均值

泰坦尼克号_第12张图片

对年龄缺失值进行填充

#填充年龄缺失值
## 使用每组的均值来进行填充
train.loc[(train.Age.isnull())&(train.Initial=='Mr'),'Age']=33
train.loc[(train.Age.isnull())&(train.Initial=='Mrs'),'Age']=36
train.loc[(train.Age.isnull())&(train.Initial=='Master'),'Age']=5
train.loc[(train.Age.isnull())&(train.Initial=='Miss'),'Age']=22
train.loc[(train.Age.isnull())&(train.Initial=='Other'),'Age']=46

泰坦尼克号_第13张图片

Embarked--> 登船地点

pd.crosstab([train.Embarked,train.Pclass],[train.Sex,train.Survived],margins=True).style.background_gradient(cmap='summer_r')
pd.crosstab([train.Embarked,train.Pclass],[train.Sex,train.Survived],margins=True).style.background_gradient(cmap='summer_r')

泰坦尼克号_第14张图片

登船地点与获救几率的关系

泰坦尼克号_第15张图片

港口中也存在缺失值,在这里我用众数来进行填充了,因为S登船人最多呀

train['Embarked'].fillna('S',inplace=True)

sibsip-->兄弟姐妹的数量

兄弟姐妹的数量与存活的关系

pd.crosstab([train.SibSp],train.Survived).style.background_gradient(cmap='summer_r')

泰坦尼克号_第16张图片

f,ax=plt.subplots(1,2,figsize=(20,8))
#画柱状图
sns.barplot('SibSp','Survived',data=train,ax=ax[0])
ax[0].set_title('SibSp vs Survived')
#画散点图
sns.factorplot('SibSp','Survived',data=train,ax=ax[1])
ax[1].set_title('SibSp vs Survived')
plt.close(2)
plt.show()

泰坦尼克号_第17张图片

根据观察,没有兄弟姐妹和只有一个兄弟姐妹的存活率最高,然后存活率随着兄弟姐妹个数的增多而降低。

Parch-->兄弟姐妹的数量

父母和孩子的数量与存活的关系

f,ax=plt.subplots(1,2,figsize=(20,8))
#画柱状图
sns.barplot('Parch','Survived',data=train,ax=ax[0])
ax[0].set_title('Parch vs Survived')
#画散点图
sns.factorplot('Parch','Survived',data=train,ax=ax[1])
ax[1].set_title('Parch vs Survived')
plt.close(2)
plt.show()

泰坦尼克号_第18张图片

带着父母的乘客有更大的生存机会。然而,它随着数字的增加而减少。

Fare 船票价格的影响

概括地观察所有的特征: 性别:与男性相比,女性的生存机会很高。

Pclass:有,第一类乘客给你更好的生存机会的一个明显趋势。对于pclass3成活率很低。对于女性来说,从pclass1生存的机会几乎是。

年龄:小于5-10岁的儿童存活率高。年龄在15到35岁之间的乘客死亡很多。

港口:上来的仓位也有区别,死亡率也很大!

家庭:有1-2的兄弟姐妹、配偶或父母上1-3显示而不是独自一人或有一个大家庭旅行,你有更大的概率存活。

特征之间的相关性

#特征之间的相关性
sns.heatmap(train.corr(),annot=True,linewidths=0.2)
#data.corr()-->correlation matrix
#annot annotate的缩写 annot默认为False,当annot为True时,在heatmap中每个方格写入数据
fig=plt.gcf()
fig.set_size_inches(10,8)
plt.show()

泰坦尼克号_第19张图片

从特征相关性热度图中可以看出,只有价格与船舱等级存在较强负相关,其他属性直接不存在显著相关性。

特征工程和数据清洗

当我们得到一个具有特征的数据集时,是不是所有的特性都很重要?可能有许多冗余的特征应该被消除,我们还可以通过观察或从其他特征中提取信息来获得或添加新特性。

年龄特征:

正如我前面提到的,年龄是连续的特征,在机器学习模型中存在连续变量的问题。

如果我说通过性别来组织或安排体育运动,我们可以很容易地把他们分成男女分开。

如果我说按他们的年龄分组,你会怎么做?如果有30个人,可能有30个年龄值。

我们需要对连续值进行离散化来分组。

好的,乘客的最大年龄是80岁。所以我们将范围从0-80成5组。所以80/5=16。

#添加一个新的属性,年龄类别
train['Age_band']=0
train.loc[train['Age']<=16,'Age_band']=0
train.loc[(train['Age']>16)&(train['Age']<=32),'Age_band']=1
train.loc[(train['Age']>32)&(train['Age']<=48),'Age_band']=2
train.loc[(train['Age']>48)&(train['Age']<=64),'Age_band']=3
train.loc[train['Age']>64,'Age_band']=4
train

Family_size:家庭总人数

光看兄弟姐妹和老人孩子看不太直接,咱们直接看全家的人数

#新建家庭人数属性
train['Family_Size'] = 0
train['Family_Size'] = train['Parch'] + train['SibSp']
#新建属性标记是否一个人
train['Alone']=0
train.loc[train['Family_Size'] == 0,'Alone'] = 1

船票价格

因为票价也是连续的特性,所以我们需要将它转换为数值。

利用pd.qcut将船票价格分为四个

train['Fare_cat']=0
train.loc[train['Fare']<=7.91,'Fare_cat']=0
train.loc[(train['Fare']>7.91)&(train['Fare']<=14.454),'Fare_cat']=1
train.loc[(train['Fare']>14.454)&(train['Fare']<=31),'Fare_cat']=2
train.loc[(train['Fare']>31)&(train['Fare']<=513),'Fare_cat']=3

#将字符串值转换为数字 因为我们不能把字符串一个机器学习模型部分

#将字符串值转换为数字 因为我们不能把字符串一个机器学习模型
train['Sex'].replace(['male','female'],[0,1],inplace=True)
train['Embarked'].replace(['S','C','Q'],[0,1,2],inplace=True)
train['Initial'].replace(['Mr','Mrs','Miss','Master','Other'],[0,1,2,3,4],inplace=True)

去掉不必要的特征

名称>我们不需要name特性,因为它不能转换成任何分类值

年龄——>我们有age_band特征,所以不需要这个

票号-->这是任意的字符串,不能被归类

票价——>我们有fare_cat特征,所以不需要

船仓号——>这个也不要没啥含义

passengerid -->不能被归类

train.drop(['Name','Age','Ticket','Fare','Cabin','Fare_Range','PassengerId'],axis=1,inplace=True)

删除多于特征后的特征相关热点图

泰坦尼克号_第20张图片

机器学习建模

1)logistic回归

2)支持向量机(线性和径向)

3)随机森林

4)k-近邻

5)朴素贝叶斯

6)决策树

7)神经网络

导入各种模型

#importing all the required ML packages
from sklearn.linear_model import LogisticRegression #logistic regression
from sklearn import svm #support vector Machine
from sklearn.ensemble import RandomForestClassifier #Random Forest
from sklearn.neighbors import KNeighborsClassifier #KNN
from sklearn.naive_bayes import GaussianNB #Naive bayes
from sklearn.tree import DecisionTreeClassifier #Decision Tree
from sklearn.model_selection import train_test_split #training and testing data split
from sklearn import metrics #accuracy measure
from sklearn.metrics import confusion_matrix #for confusion matrix

将数据集拆分成训练集和测试集

train_data,test_data = train_test_split(train,test_size=0.3,random_state=0,stratify=train.Survived)
train_X = train_data[train_data.columns[1:]]
train_Y = train_data[train_data.columns[:1]]
test_X = test_data[test_data.columns[1:]]
test_Y = test_data[test_data.columns[:1]]
X = train[train.columns[1:]]
Y = train['Survived']
#SVM
model = svm.SVC(kernel='rbf',C=1,gamma=0.1)
model.fit(train_X,train_Y)
prediction1 = model.predict(test_X)
print('Accuracy for rbf SVM is ',metrics.accuracy_score(prediction1,test_Y))

model=svm.SVC(kernel='linear',C=0.1,gamma=0.1)
model.fit(train_X,train_Y)
prediction2=model.predict(test_X)
print('Accuracy for linear SVM is',metrics.accuracy_score(prediction2,test_Y))
#逻辑回归
model = LogisticRegression()
model.fit(train_X,train_Y)
prediction3=model.predict(test_X)
print('The accuracy of the Logistic Regression is',metrics.accuracy_score(prediction3,test_Y))

#决策树
model=DecisionTreeClassifier()
model.fit(train_X,train_Y)
prediction4=model.predict(test_X)
print('The accuracy of the Decision Tree is',metrics.accuracy_score(prediction4,test_Y))

#KNN
model=KNeighborsClassifier() 
model.fit(train_X,train_Y)
prediction5=model.predict(test_X)
print('The accuracy of the KNN is',metrics.accuracy_score(prediction5,test_Y))

#贝叶斯
model=GaussianNB()
model.fit(train_X,train_Y)
prediction6=model.predict(test_X)
print('The accuracy of the NaiveBayes is',metrics.accuracy_score(prediction6,test_Y))

#随机森林
model=RandomForestClassifier(n_estimators=100)
model.fit(train_X,train_Y)
prediction7=model.predict(test_X)
print('The accuracy of the Random Forests is',metrics.accuracy_score(prediction7,test_Y))

使用交叉验证

#交叉验证
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import cross_val_predict
kfold = KFold(n_splits=10,random_state=22)#10折交叉验证
xyz=[]
accuracy=[]
std=[]
classifiers=['Linear Svm','Radial Svm','Logistic Regression','KNN','Decision Tree','Naive Bayes','Random Forest']
models=[svm.SVC(kernel='linear'),svm.SVC(kernel='rbf'),LogisticRegression(),KNeighborsClassifier(n_neighbors=9),DecisionTreeClassifier(),GaussianNB(),RandomForestClassifier(n_estimators=100)]
for i in models:
    model = i
    cv_result = cross_val_score(model,X,Y,cv=kfold,scoring="accuracy")
    xyz.append(cv_result.mean())
    std.append(cv_result.std())
    accuracy.append(cv_result)
new_models_dataframe2=pd.DataFrame({'CV Mean':xyz,'Std':std},index=classifiers)       
new_models_dataframe2

泰坦尼克号_第21张图片

超参数选择

from sklearn.model_selection import GridSearchCV
C=[0.05,0.1,0.2,0.3,0.25,0.4,0.5,0.6,0.7,0.8,0.9,1]
gamma=[0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0]
kernel=['rbf','linear']
hyper={'kernel':kernel,'C':C,'gamma':gamma}
gd=GridSearchCV(estimator=svm.SVC(),param_grid=hyper,verbose=True)
gd.fit(X,Y)

集成学习

使用投票的方法集成

from sklearn.ensemble import VotingClassifier
ensemble_lin_rbf=VotingClassifier(estimators=[('KNN',KNeighborsClassifier(n_neighbors=10)),
                                              ('RBF',svm.SVC(probability=True,kernel='rbf',C=0.5,gamma=0.1)),
                                              ('RFor',RandomForestClassifier(n_estimators=500,random_state=0)),
                                              ('LR',LogisticRegression(C=0.05)),
                                              ('DT',DecisionTreeClassifier(random_state=0)),
                                              ('NB',GaussianNB()),
                                              ('svm',svm.SVC(kernel='linear',probability=True))
                                             ], 
                       voting='soft').fit(train_X,train_Y)
print('The accuracy for ensembled model is:',ensemble_lin_rbf.score(test_X,test_Y))
cross=cross_val_score(ensemble_lin_rbf,X,Y, cv = 10,scoring = "accuracy")
print('The cross validated score is',cross.mean())

Bagging:

from sklearn.ensemble import BaggingClassifier
model=BaggingClassifier(base_estimator=KNeighborsClassifier(n_neighbors=3),random_state=0,n_estimators=700)
model.fit(train_X,train_Y)
prediction=model.predict(test_X)
print('The accuracy for bagged KNN is:',metrics.accuracy_score(prediction,test_Y))
result=cross_val_score(model,X,Y,cv=10,scoring='accuracy')
print('The cross validated score for bagged KNN is:',result.mean())

AdaBoost

from sklearn.ensemble import AdaBoostClassifier
ada=AdaBoostClassifier(n_estimators=200,random_state=0,learning_rate=0.1)
result=cross_val_score(ada,X,Y,cv=10,scoring='accuracy')
print('The cross validated score for AdaBoost is:',result.mean())

 

你可能感兴趣的:(机器学习)