当前位置:   article > 正文

Python入门之机器学习(非常详细)篇幅拉满,一般人看不完!_python机器学习

python机器学习

一、什么是机器学习

什么是机器学习?机器学习其实就是想让计算机像人一样思考而研发出的计算机理论,目前常用的机器学习有以下几种算法:

  • 监督学习 supervised learning;
  • 非监督学习 unsupervised learning;
  • 半监督学习 semi-supervised learning;
  • 强化学习 reinforcement learning;

监督学习是不断向计算机提供数据(特征),并告诉计算机对应的值(标签),最后通过大量的数据,让计算机自己学会判断和识别。例如Google Photo,你在APP中输入狗,这时就会弹出与狗相关的图片,这背后使用的算法就是监督学习。通过告诉计算机狗长什么样(特征),最后教会计算机认识狗(标签)。再比如今日头条,你使用APP的时间越长,给你推送的内容就越是你平时感兴趣的内容。通过对用户平时日常使用数据(特征)的分析,找到用户的兴趣爱好(标签),进而更精准的推送内容。

非监督学习与监督学习的区别是,只向计算机提供数据(特征),但并不提供对应的值(标签)。例如需要计算机学会识别猫和狗,这时仅提供猫和狗的图片(特征),但是并不告诉计算机,哪些图片是猫,哪些图片是狗,让计算机自己去总结归纳出两者的特征规律。

半监督学习是综合了监督学习和非监督学习两者的特点,利用少量有标签的样本,和大量没有标签的样本对计算机进行训练。

强化学习是将计算机放入一个陌生的环境中,让它自己去学习,其中包含了4个关键要素,分别是环境(environment)、状态(state)、行动(action)和奖励(reward)。例如要设计一款自动投篮机器,首先让机器自己去选择投篮的角度、力度等动作进行尝试,告诉机器如果投篮命中便能获得奖励,之后机器会根据练习所产生的数据,不断修改自身的动作策略,经过数次迭代之后,学习并完成投篮任务。战胜李世石的AlphaGo,所使用的就是强化学习。强化学习与监督学习和非监督学习最大的不同是,不需要使用海量的数据去“喂养”机器,而是通过不断地尝试去获取数据。

使用Python进行机器学习时,都会用到一个非常强大的第三方包,那就是scikit-learn。

Sklearn包含了四类算法,分别是回归(regression)、分类(classification)、聚类(clustering)和降维(dimensionality reduction)。其中回归和分类是监督式学习,下面使用Python对简单线性回归和逻辑回归分类进行简要介绍。

二、简单线性回归

线性回归(linear regression)是利用称为线性回归方程的最小二乘函数对一个或多个自变量和因变量之间关系进行建模的一种回归分析。这种函数是一个或多个称为回归系数的模型参数的线性组合。只有一个自变量的情况称为简单回归,大于一个自变量情况的叫做多元回归。

简单线性回归方程其实就像我们初中学习的二元一次方程:y=a+bx

其中a称作截距,b称作回归系数,x为自变量,y为因变量。

简单线性回归分析通常包含以下步骤:

  • 提出问题
  • 理解数据
  • 数据清洗
  • 构建模型
  • 评估模型

1.提出问题

假设现在提出一个问题,通过收集学生学习时间和分数,得出学习时间与分数之间的相关关系,其中特征为学习时间,标签为分数。

2.理解数据

采集所需的数据,并导入Python。

import pandas as pd
examDict = { '学习时间':[0.50,0.75,1.00,1.25,1.50,1.75,1.75,2.00,2.25,
            2.50,2.75,3.00,3.25,3.50,4.00,4.25,4.50,4.75,5.00,5.50],
    '分数':[10,  22,  13,  43,  20,  22,  33,  50,  62,  
              48,  55,  75,  62,  73,  81,  76,  64,  82,  90,  93]}
examDf = pd.DataFrame(examDict)
print(examDf.head())
学习时间  分数
0  0.50  10
1  0.75  22
2  1.00  13
3  1.25  43
4  1.50  20
#提取特征和标签
#特征features
exam_X=examDf.loc[:,'学习时间']
#标签labes
exam_y=examDf.loc[:,'分数']

#绘制散点图
import matplotlib.pyplot as plt
plt.scatter(exam_X,exam_y,color='b',label='exam data')
#添加图标标签
plt.xlabel('Hours') #X轴命名
plt.ylabel('Score') #Y轴命名

print(plt.show())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

img

通过观察上面的散点图,我们可以对相关性做出初步的分析。相关性通常有3种情况,正线性相关、负线性相关和非线性相关。当线性回归方程中的回归系数b大于0,即直线朝上时,为正线性相关,回归系数b小于0,即直线朝下时,为负线性相关。我们还可以通过计算相关系数r,对相关性大小进行判断。相关系数公式如下:

img

#计算相关系数r
rDf = examDf.corr()
print('相关系数矩阵:\n',rDf)
print('相关系数r=',rDf.iloc[0,1])
相关系数矩阵:
           学习时间        分数
学习时间  1.000000  0.923985
分数    0.923985  1.000000
相关系数r= 0.9239852119728443
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

3.数据清洗

本案例中数据较为简单,主要是为了介绍简单线性回归的操作过程,具体的步骤可查看,Python入门之Numpy与Pandas中的数据清洗一节。

4.构建模型

利用交叉验证函数中的train_test_split()进行建模分析。交叉验证是指:

交叉验证(Cross Validation)也称作循环估计(Rotation Estimation),是一种统计学上将数据样本切割成较小子集的实用方法。在给定的建模样本中,拿出大部分样本进行建模型,留小部分样本用刚建立的模型进行预测。交叉验证的基本思想是把在某种意义下将原始数据(dataset)进行分组,一部分做为训练集(train set),另一部分做为验证集(validation set or test set),首先用训练集对分类器进行训练,再利用验证集来测试训练得到的模型(model),以此来做为评价分类器的性能指标。

①创建模型

利用sklearn中train_test_split方法进行数据分割,将数据随机分成训练数据和测试数据,占比为8:2。

from sklearn.model_selection import train_test_split
#建立训练数据和测试数据
X_train,X_test,y_train,y_test = train_test_split(exam_X,exam_y,train_size=0.8) #train_size指训练数据占比
#输出数据大小
print('原始数据特征:',exam_X.shape,
      '训练数据特征:',X_train.shape,
      '测试数据特征:',X_test.shape)

print('原始数据标签:',exam_y.shape,
      '训练数据标签:',y_train.shape,
      '测试数据标签:',y_test.shape)
原始数据特征: (20,) 训练数据特征: (16,) 测试数据特征: (4,)
原始数据标签: (20,) 训练数据标签: (16,) 测试数据标签: (4,)
#绘制散点图
import matplotlib.pyplot as plt

#散点图
plt.scatter(X_train, y_train, color="blue", label="train data")
plt.scatter(X_test, y_test, color="red", label="test data")

#添加图标标签
plt.legend(loc=4) #设置图签的位置
plt.xlabel("Hours")
plt.ylabel("Score")
#显示图像
plt.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

img

②训练模型

#第1步:导入线性回归第三方包
from sklearn.linear_model import LinearRegression
#第2步:创建线性回归模型
model = LinearRegression()
#将训练数据特征和测试数据特征转换成二维数组
'''
reshape是重新定义行数和列数。如果行的参数是-1,就会根据所给的列数,
自动按照原始数组的大小形成一个新的数组,例如reshape(-1,1)就是改变
成1列的数组,这个数组的长度是根据原始数组的大小来自动形成的。
例如原始数组总共是2行*3列=6个数,那么这里就会形成6行*1列的数组。
'''
X_train = X_train.values.reshape(-1,1) 
X_test = X_test.values.reshape(-1,1)
#第3步:训练模型
model.fit(X_train,y_train)
LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None, normalize=False)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

③计算最佳拟合线

最佳拟合线:y= + x,截距intercept:a,回归系数:b

回归分析求最佳拟合线的常用方法为最小二乘法,通过最小二乘法,可以使得误差平方和最小,进而求出a和b的值。 这个数学问题过于复杂,如果想知道证明的原理可自行搜索学习。误差平方和的计算公式为:

img

#截距
a = model.intercept_
b = model.coef_
print('最佳拟合线:y=%f+%fx'%(a,b))
最佳拟合线:y=10.251797+15.840256x
#绘制训练数据散点图
plt.scatter(X_train, y_train, color='blue', label="train data")

#训练数据的预测值
y_train_pred = model.predict(X_train)
#绘制最佳拟合线
plt.plot(X_train, y_train_pred, color='black', linewidth=3, label="best line")

#添加图标标签
plt.legend(loc=4)
plt.xlabel("Hours")
plt.ylabel("Score")
#显示图像
plt.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

img

5.模型评估

要想评估模型的精确度,可以使用决定系数R平方进行判断,R平方越大,表明回归模型越精确。使用测试数据进行模型评估,利用score方法,对第一个参数X_test用拟合曲线自动计算出y预测值。决定系数R平方计算公式如下:

img

#线性回归的scroe方法得到的是决定系数
#评估模型:决定系数
r2 = model.score(X_test , y_test)
print(r2)
0.8823686336975715
  • 1
  • 2
  • 3
  • 4
  • 5

把训练数据集(图中蓝色的点),和测试数据集(图中红色的点)放到一张图上来进行比较,并在图上标注出决定系数R平方。

#第1步:绘制训练数据散点图
plt.scatter(X_train, y_train, color='blue', label="train data")

#第2步:用训练数据绘制最佳拟合线
#最佳拟合线训练数据的预测值
y_train_pred = model.predict(X_train)
#绘制最佳拟合线:标签用的是训练数据的预测值y_train_pred
plt.plot(X_train, y_train_pred, color='black', linewidth=3, label="best line")

#第3步:绘制测试数据的散点图
plt.scatter(X_test, y_test, color='red', label="test data")
#添加图标标签
plt.legend(loc=4)
plt.xlabel("Hours")
plt.ylabel("Score")

plt.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

img

三、逻辑回归

逻辑回归(Logistic Regression)主要用来解决二分类问题,表示某件事情发生的可能性。什么是二分类呢,说简单点就是答案只有Yes和No两种可能。逻辑回归和线性回归一样,在机器算法中都属于监督学习,但是逻辑回归在Sklearn的4类算法中属于分类算法。

逻辑回归的公式如下:

img

逻辑函数图像如下:

img

可以看到,逻辑回归函数是一个s形的曲线,取值在[0,1]之间,在远离0的地方函数的值会很快接近0或者1。通常可以选择0.5作为阈值,划定一个决策面,当y>=0.5时,确定标签为1,当y<0.5时,确定标签为0。例如之前所举的今日头条的例子,就可以通过逻辑回归去找到关于用户喜好程度的决策面,通过下图可以帮助理解决策面的含义。

img

利用Python进行逻辑回归分析的方法与简单线性回归分析的步骤一致,同样是包括提出问题、理解问题、数据清洗、构建模型、模型评估5步。

1.提出问题

假设现在提出一个问题,通过收集学生学习时间和通过考试情况,得出学习时间与通过考试之间的相关关系,其中特征为学习时间,标签为通过考试。

2.理解数据

采集所需的数据,并导入Python。

import pandas as pd
#采集数据
exam2Dict = { '学习时间':[0.50,0.75,1.00,1.25,1.50,1.75,1.75,2.00,2.25,2.50,
            2.75,3.00,3.25,3.50,4.00,4.25,4.50,4.75,5.00,5.50],
    '通过考试':[0,0,0,0,0,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1]}
examDf = pd.DataFrame(exam2Dict)
print(examDf)
学习时间  通过考试
0   0.50     0
1   0.75     0
2   1.00     0
3   1.25     0
4   1.50     0
5   1.75     0
6   1.75     1
7   2.00     0
8   2.25     1
9   2.50     0
10  2.75     1
11  3.00     0
12  3.25     1
13  3.50     0
14  4.00     1
15  4.25     1
16  4.50     1
17  4.75     1
18  5.00     1
19  5.50     1
#特征features
exam2_X = examDf.loc[:,'学习时间']
exam2_y = examDf.loc[:,'通过考试']

#绘制散点图
import matplotlib.pyplot as plt
plt.scatter(exam2_X,exam2_y,color='b',label='exam data')
#添加图标标签
plt.xlabel('Hours') #X轴命名
plt.ylabel('Pass') #Y轴命名

print(plt.show())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

img

3.数据清洗

本案例中数据较为简单,主要是为了介绍逻辑回归的操作过程,此步暂时省略。

4.创建模型

与线性回归创建模型一样,同样利用sklearn中train_test_split方法进行数据分割,将数据随机分成训练数据和测试数据,占比为8:2。

①创建模型

from sklearn.model_selection import train_test_split
#建立训练数据和测试数据
X_train,X_test,y_train,y_test = train_test_split(exam2_X,exam2_y,train_size=0.8) #train_size指训练数据占比
#输出数据大小
print('原始数据特征:',exam2_X.shape,
      '训练数据特征:',X_train.shape,
      '测试数据特征:',X_test.shape)

print('原始数据标签:',exam2_y.shape,
      '训练数据标签:',y_train.shape,
      '测试数据标签:',y_test.shape)
原始数据特征: (20,) 训练数据特征: (16,) 测试数据特征: (4,)
原始数据标签: (20,) 训练数据标签: (16,) 测试数据标签: (4,)
#绘制散点图
import matplotlib.pyplot as plt

#散点图
plt.scatter(X_train, y_train, color="blue", label="train data")
plt.scatter(X_test, y_test, color="red", label="test data")

#添加图标标签
plt.legend(loc=4) #设置图签的位置
plt.xlabel("Hours")
plt.ylabel("Pass")
#显示图像
plt.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

img

②训练模型

#第1步:导入逻辑回归
from sklearn.linear_model import LogisticRegression
#第2步:创建模型:逻辑回归
model = LogisticRegression()

X_train = X_train.values.reshape(-1,1) 
X_test = X_test.values.reshape(-1,1)
#第3步:训练模型
model.fit(X_train,y_train)

LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
                   intercept_scaling=1, l1_ratio=None, max_iter=100,
                   multi_class='warn', n_jobs=None, penalty='l2',
                   random_state=None, solver='warn', tol=0.0001, verbose=0,
                   warm_start=False)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

5.模型评估

与线性回归不同,线性回归是使用决定系数R平方进行判断,而逻辑回归则是利用准确率进行判断。利用score方法,通过输入测试数据,利用刚才的逻辑回归模型,计算出预测结果。

#评估模型:决定系数
accuracy = model.score(X_test , y_test)
print(accuracy)
0.75
#获取概率值:使用predict_proba方法获取通过考试的概率
#第1个值是标签为0(不通过考试)的概率值,第2个值是标签为1(通过考试)的概率值
print(model.predict_proba([[3]])) #计算学习时间3小时通过考试的概率
[[0.38237083 0.61762917]]
#预测数据:使用模型的predict方法可以进行预测。
pred=model.predict([[3]]) #学习时间3小时通过的概率为61.76%,概率大于0.5,因此预测该学生通过考试,模型应返回结果标签1。
print(pred)
[1]
#计算逻辑回归函数
import numpy as np
#第1步:计算回归方程的z值
#回归方程:z= + x
#截距
a=model.intercept_
#回归系数
b=model.coef_
print('回归方程为:z=%f+%fx'%(a,b))

#第2步:假设学习时间3小时,进一步计算出通过考试概率
x=3
z=a+b*x
y_pred=1/(1+np.exp(-z))
print('预测的概率值:',y_pred)
回归方程为:z=-1.093589+0.524362x
预测的概率值: [[0.61762917]]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

小结

通过对回归(regression)和分类(classification)算法的介绍,对两类算法进行简单比较,可发现3点区别。

  • 输出数据类型不同:回归为连续数据,分类为离散数据。
  • 目的不同:回归目标为找到最优拟合线,分类目标为找到决策面
  • 评价方法不同:回归评价方法为决定系数R平方,分类评价方法为准确率。

四、案例:泰坦尼克号生存预测

结合之前介绍的线性回归算法和逻辑回归算法,对经典的泰坦尼克号生存率数据分析案例进行实操。首先,在Kaggle数据平台下载泰坦尼克号案例的分析数据。之后同样按照提出问题、理解数据、数据清洗、构建模型、模型评估的步骤进行分析。

1.提出问题

什么人在泰坦尼克号中更容易存活?

2.理解数据

#导入数据
import numpy as np
import pandas as pd

#训练数据集
trainDf = pd.read_csv(r'C:\Users\gyl21\Desktop\数据分析(高级)(Python)\第4关:机器学习(入门)\3.泰坦尼克号\train.csv')
#测试数据集
testDf = pd.read_csv(r'C:\Users\gyl21\Desktop\数据分析(高级)(Python)\第4关:机器学习(入门)\3.泰坦尼克号\test.csv')

print('训练数据集:',trainDf.shape,'测试数据集:',testDf.shape)
训练数据集: (891, 12) 测试数据集: (418, 11)
#合并数据集,方便同时对两个数据集进行清洗
fullDf = trainDf.append(testDf,ignore_index = True)
print('合并后的数据集:',fullDf.shape)
#读取列标签名称
column_headers = list(fullDf.columns.values)
print('列标签名称:',column_headers)
print(fullDf.head())
合并后的数据集: (1309, 12)
列标签名称: ['Age', 'Cabin', 'Embarked', 'Fare', 'Name', 'Parch', 'PassengerId', 'Pclass', 'Sex', 'SibSp', 'Survived', 'Ticket']
    Age Cabin Embarked     Fare  \
0  22.0   NaN        S   7.2500   
1  38.0   C85        C  71.2833   
2  26.0   NaN        S   7.9250   
3  35.0  C123        S  53.1000   
4  35.0   NaN        S   8.0500

                                                Name  Parch  PassengerId  \
0                            Braund, Mr. Owen Harris      0            1   
1  Cumings, Mrs. John Bradley (Florence Briggs Th...      0            2   
2                             Heikkinen, Miss. Laina      0            3   
3       Futrelle, Mrs. Jacques Heath (Lily May Peel)      0            4   
4                           Allen, Mr. William Henry      0            5

   Pclass     Sex  SibSp  Survived            Ticket  
0       3    male      1       0.0         A/5 21171  
1       1  female      1       1.0          PC 17599  
2       3  female      0       1.0  STON/O2. 3101282  
3       1  female      1       1.0            113803  
4       3    male      0       0.0            373450
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

观察输出的数据可以发现,将train和test合并之后的数据为一个1309行、12列的数组,包含的11个列标签,分别是Age、Cabin、Embarked、Fare、Name、Parch、PassengerId、Sex、SibSp、Survived、Ticket,为了方便记忆和使用,可创建一个字典方便查询。

columnDisc = {'Age':'年龄','Cabin':'客舱号','Embarked':'登船港口(S-英国,C-法国,Q-爱尔兰)','Fare':'船票价格','Name':'姓名',
              'Parch':'不同代直系亲属数(在船上的父母及子女数)','PassengerId':'乘客编号','Pclass':'客舱等级','Sex':'性别',
              'SibSp':'同代直系亲属数(在船上的兄弟姐妹及配偶数)','Survived':'生存情况','Ticket':'船票编号'}
print(columnDisc)
{'Age': '年龄', 'Cabin': '客舱号', 'Embarked': '登船港口(S-英国,C-法国,Q-爱尔兰)', 'Fare': '船票价格', 'Name': '姓名', 'Parch': '不同代直系亲属数(在船上的父母及子女数)', 'PassengerId': '乘客编号', 'Pclass': '客舱等级', 'Sex': '性别', 'SibSp': '同代直系亲属数(在船上的兄弟姐妹及配偶数)', 'Survived': '生存情况', 'Ticket': '船票编号'}
#获取数据类型列的描述统计信息
print(fullDf.describe())
Age         Fare        Parch  PassengerId       Pclass  \
count  1046.000000  1308.000000  1309.000000  1309.000000  1309.000000   
mean     29.881138    33.295479     0.385027   655.000000     2.294882   
std      14.413493    51.758668     0.865560   378.020061     0.837836   
min       0.170000     0.000000     0.000000     1.000000     1.000000   
25%      21.000000     7.895800     0.000000   328.000000     2.000000   
50%      28.000000    14.454200     0.000000   655.000000     3.000000   
75%      39.000000    31.275000     0.000000   982.000000     3.000000   
max      80.000000   512.329200     9.000000  1309.000000     3.000000

             SibSp    Survived  
count  1309.000000  891.000000  
mean      0.498854    0.383838  
std       1.041658    0.486592  
min       0.000000    0.000000  
25%       0.000000    0.000000  
50%       0.000000    0.000000  
75%       1.000000    1.000000  
max       8.000000    1.000000
#查看每一列的数据类型和数据总数
print(fullDf.info())
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1309 entries, 0 to 1308
Data columns (total 12 columns):
Age            1046 non-null float64
Cabin          295 non-null object
Embarked       1307 non-null object
Fare           1308 non-null float64
Name           1309 non-null object
Parch          1309 non-null int64
PassengerId    1309 non-null int64
Pclass         1309 non-null int64
Sex            1309 non-null object
SibSp          1309 non-null int64
Survived       891 non-null float64
Ticket         1309 non-null object
dtypes: float64(3), int64(4), object(5)
memory usage: 122.8+ KB
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

3.数据清洗

通过info()查看每一列的数据类型和数据总数,可以发现数据总行数为1309行,其中Age、Cabin、Embarked、Fare、Survived5列有缺失数据,其中Age、Cabin、Embarked、Fare需对缺失数据进行补充,而Survived是需要进行预测的数据。

(1)数据预处理

缺失值处理

#数据类型缺失值处理

#年龄(Age)列通过平均年龄进行填充
fullDf['Age']=fullDf['Age'].fillna(fullDf['Age'].mean())
#船票价格(Fare)列通过平均价格进行填充
fullDf['Fare']=fullDf['Fare'].fillna(fullDf['Fare'].mean())
'''
登船港口(Embarked)列通过查看其中列中的数量最多者进行补充。
通过value_counts()查询出Embarked列中的不同值数量,发现最多的值为S。
利用S进行补充。
'''
print(fullDf.loc[:,'Embarked'].value_counts())
fullDf['Embarked']=fullDf['Embarked'].fillna('S')
S    914
C    270
Q    123
Name: Embarked, dtype: int64
#船舱号(Cabin):因缺失数据较多,船舱号(Cabin)缺失值填充为U,表示未知(Unknow)
fullDf['Cabin']=fullDf['Cabin'].fillna('U')

print(fullDf.info())
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1309 entries, 0 to 1308
Data columns (total 12 columns):
Age            1309 non-null float64
Cabin          1309 non-null object
Embarked       1309 non-null object
Fare           1309 non-null float64
Name           1309 non-null object
Parch          1309 non-null int64
PassengerId    1309 non-null int64
Pclass         1309 non-null int64
Sex            1309 non-null object
SibSp          1309 non-null int64
Survived       891 non-null float64
Ticket         1309 non-null object
dtypes: float64(3), int64(4), object(5)
memory usage: 122.8+ KB
None
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

(2)特征提取

①数据分类

查看数据类型,通常数据类型可分为数值数据、分类数据、时间序列3类。其中数值数据可直接使用,时间序列可转化为年月日,分类数据需用数值进行代替,并进行One-hot编码,One-Hot编码,又称为一位有效编码,主要是采用N位状态寄存器来对N个状态进行编码,N的大小通常要大于2时,才会用到。例如Embarked中包含了S、C、Q3种类型,这时需要针对不同的类型新建一列表格,这一列的表格就好像是一个容器,每一个容器中只装入这一种类型的信息,并用1和0表示,1表示有,零表示没有。如下图所示,其中Embarked_Q、Embarked_S、Embarked_C就是新创建的容器,也称为虚拟变量。

img

在本案例中,可将分类数据进一步分类,分为有直接类别的数据和字符串类型数据。

有直接类别的数据: 乘客性别(Sex):男性male,女性female 登船港口(Embarked):出发地点:S=英国南安普顿Southampton;途径地点1:C=法国 瑟堡市Cherbourg;出发地点2:Q=爱尔兰 昆士敦Queenstown * 客舱等级(Pclass):1=1等舱,2=2等舱,3=3等舱

字符串类型数据:

  • 乘客姓名(Name)
  • 客舱号(Cabin)
  • 家庭类别(Parch、SipSb)

分类数据:有直接类别的数据

性别(Sex)

#查看性别数据列
print(fullDf['Sex'].head())
0      male
1    female
2    female
3    female
4      male
Name: Sex, dtype: object
#将性别的值映射为数值,男性(male)对应数值1,女型(female)对应数值0
sex_mapDict = {'male':1,'female':0}

#map函数:对指定序列做映射,将male和female分别映射为1和0
fullDf['Sex']=fullDf['Sex'].map(sex_mapDict)
print(fullDf['Sex'].head())
0    1
1    0
2    0
3    0
4    1
Name: Sex, dtype: int64
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

登船港口(Embarked)

#查看该类数据内容
print(fullDf['Embarked'].head())
0    S
1    C
2    S
3    S
4    S
Name: Embarked, dtype: object
#存放提取后的特征
embarkedDf = pd.DataFrame()

#使用get_dummies进行one-hot编码,产生虚拟变量(dummy variables),列名前缀是Embarked
embarkedDf = pd.get_dummies(fullDf['Embarked'],prefix='Embarked')
print(embarkedDf.head())
Embarked_C  Embarked_Q  Embarked_S
0           0           0           1
1           1           0           0
2           0           0           1
3           0           0           1
4           0           0           1
#添加one-hot编码产生的虚拟变量(dummy variables)到泰坦尼克号数据集full
fullDf = pd.concat([fullDf,embarkedDf],axis=1)

'''
因为已经使用登船港口(Embarked)进行了one-hot编码产生了它的虚拟变量(dummy variables)
所以这里把登船港口(Embarked)删掉
'''
#使用drop删除列
fullDf.drop('Embarked',axis=1,inplace=True)
print(fullDf.head())
Age Cabin     Fare                                               Name  \
0  22.0     U   7.2500                            Braund, Mr. Owen Harris   
1  38.0   C85  71.2833  Cumings, Mrs. John Bradley (Florence Briggs Th...   
2  26.0     U   7.9250                             Heikkinen, Miss. Laina   
3  35.0  C123  53.1000       Futrelle, Mrs. Jacques Heath (Lily May Peel)   
4  35.0     U   8.0500                           Allen, Mr. William Henry

   Parch  PassengerId  Pclass  Sex  SibSp  Survived            Ticket  \
0      0            1       3    1      1       0.0         A/5 21171   
1      0            2       1    0      1       1.0          PC 17599   
2      0            3       3    0      0       1.0  STON/O2. 3101282   
3      0            4       1    0      1       1.0            113803   
4      0            5       3    1      0       0.0            373450

   Embarked_C  Embarked_Q  Embarked_S  
0           0           0           1  
1           1           0           0  
2           0           0           1  
3           0           0           1  
4           0           0           1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

客舱等级(Pclass)

'''
客舱等级(Pclass):
1=1等舱,2=2等舱,3=3等舱
'''
#存放提取后的特征
pclassDf = pd.DataFrame()

#使用get_dummies进行one-hot编码,列名前缀是Pclass
pclassDf = pd.get_dummies( fullDf['Pclass'] , prefix='Pclass' )
print(pclassDf.head())
Pclass_1  Pclass_2  Pclass_3
0         0         0         1
1         1         0         0
2         0         0         1
3         1         0         0
4         0         0         1
#添加one-hot编码,将产生的类别加入泰坦尼克号数据集fullDf
fullDf = pd.concat([fullDf,pclassDf],axis=1)

#删掉客舱等级(Pclass)这一列
fullDf.drop('Pclass',axis=1,inplace=True)
print(fullDf.head())
Age Cabin     Fare                                               Name  \
0  22.0     U   7.2500                            Braund, Mr. Owen Harris   
1  38.0   C85  71.2833  Cumings, Mrs. John Bradley (Florence Briggs Th...   
2  26.0     U   7.9250                             Heikkinen, Miss. Laina   
3  35.0  C123  53.1000       Futrelle, Mrs. Jacques Heath (Lily May Peel)   
4  35.0     U   8.0500                           Allen, Mr. William Henry

   Parch  PassengerId  Sex  SibSp  Survived            Ticket  Embarked_C  \
0      0            1    1      1       0.0         A/5 21171           0   
1      0            2    0      1       1.0          PC 17599           1   
2      0            3    0      0       1.0  STON/O2. 3101282           0   
3      0            4    0      1       1.0            113803           0   
4      0            5    1      0       0.0            373450           0

   Embarked_Q  Embarked_S  Pclass_1  Pclass_2  Pclass_3  
0           0           1         0         0         1  
1           0           0         1         0         0  
2           0           1         0         0         1  
3           0           1         1         0         0  
4           0           1         0         0         1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

分类数据:字符串类型数据

姓名(Name)

通过观察数据,可以发现名字一列中,包含有Mr、Mrs、Miss、Master的称呼。在国外,这些称谓都有特定的用法,不是一概而论的,所以需要将这些称呼进行分类。

#定义函数,从姓名中获取头衔。数据中Name一列的格式为:名+ ',' + 称为 + '.' + 姓
def getTitle(name):
    str1 = name.split(',')[1]
    str2 = str1.split('.')[0]
    #strip()方法用于移除字符串头尾指定的字符
    str3 = str2.strip()
    return str3
#存放提取后的特征
titleDf = pd.DataFrame()
titleDf['Title'] = fullDf['Name'].map(getTitle)
print(titleDf.head())
Title
0    Mr
1   Mrs
2  Miss
3   Mrs
4    Mr
#姓名中头衔字符串与定义头衔类别的映射关系
title_mapDict = {
                    "Capt":         "Officer",
                    "Col":          "Officer",
                    "Major":        "Officer",
                    "Jonkheer":     "Royalty",
                    "Don":          "Royalty",
                    "Sir" :         "Royalty",
                    "Dr":           "Officer",
                    "Rev":          "Officer",
                    "the Countess": "Royalty",
                    "Dona":         "Royalty",
                    "Mme":          "Mrs",
                    "Mlle":         "Miss",
                    "Ms":           "Mrs",
                    "Mr" :          "Mr",
                    "Mrs" :         "Mrs",
                    "Miss" :        "Miss",
                    "Master" :      "Master",
                    "Lady" :        "Royalty"
                }
#map函数:对指定序列做映射
titleDf['Title'] = titleDf['Title'].map(title_mapDict)
#使用get_dummies进行one-hot编码,产生虚拟变量(dummy variables),列名前缀是Embarked
titleDf = pd.get_dummies(titleDf['Title'])
print(titleDf.head())
Master  Miss  Mr  Mrs  Officer  Royalty
0       0     0   1    0        0        0
1       0     0   0    1        0        0
2       0     1   0    0        0        0
3       0     0   0    1        0        0
4       0     0   1    0        0        0
#添加one-hot编码,将产生的类别加入泰坦尼克号数据集fullDf
fullDf = pd.concat([fullDf,titleDf],axis=1)

#删掉姓名(Name)这一列
fullDf.drop('Name',axis=1,inplace=True)
print(fullDf.head())
Age Cabin     Fare  Parch  PassengerId  Sex  SibSp  Survived  \
0  22.0     U   7.2500      0            1    1      1       0.0   
1  38.0   C85  71.2833      0            2    0      1       1.0   
2  26.0     U   7.9250      0            3    0      0       1.0   
3  35.0  C123  53.1000      0            4    0      1       1.0   
4  35.0     U   8.0500      0            5    1      0       0.0

             Ticket  Embarked_C  ...  Embarked_S  Pclass_1  Pclass_2  \
0         A/5 21171           0  ...           1         0         0   
1          PC 17599           1  ...           0         1         0   
2  STON/O2. 3101282           0  ...           1         0         0   
3            113803           0  ...           1         1         0   
4            373450           0  ...           1         0         0

   Pclass_3  Master  Miss  Mr  Mrs  Officer  Royalty  
0         1       0     0   1    0        0        0  
1         0       0     0   0    1        0        0  
2         1       0     1   0    0        0        0  
3         0       0     0   0    1        0        0  
4         1       0     0   1    0        0        0

[5 rows x 21 columns]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77

客舱(Cabin)

#查看客舱号的内容
print(fullDf['Cabin'].head())
0       U
1     C85
2       U
3    C123
4       U
Name: Cabin, dtype: object
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

观察客舱号,可以发现有A、B、C、D…U等类型,同样可以进行分类。

#存放客舱号信息
cabinDf = pd.DataFrame()

#利用lambda匿名函数,提取Cabin列中的第一个字母。lambda的格式为 参数1,参数2:函数体或者表达式。例如sum = lambda a,b: a + b

fullDf[ 'Cabin' ] = fullDf[ 'Cabin' ].map( lambda c : c[0] )

##使用get_dummies进行one-hot编码,列名前缀是Cabin
cabinDf = pd.get_dummies( fullDf['Cabin'] , prefix = 'Cabin' )
print(cabinDf.head())
Cabin_A  Cabin_B  Cabin_C  Cabin_D  Cabin_E  Cabin_F  Cabin_G  Cabin_T  \
0        0        0        0        0        0        0        0        0   
1        0        0        1        0        0        0        0        0   
2        0        0        0        0        0        0        0        0   
3        0        0        1        0        0        0        0        0   
4        0        0        0        0        0        0        0        0

   Cabin_U  
0        1  
1        0  
2        1  
3        0  
4        1
#添加one-hot编码,将产生的类别加入泰坦尼克号数据集fullDf
fullDf = pd.concat([fullDf,cabinDf],axis=1)

#删掉客舱号(Cabin)这一列
fullDf.drop('Cabin',axis=1,inplace=True)
print(fullDf.head())
Age     Fare  Parch  PassengerId  Sex  SibSp  Survived            Ticket  \
0  22.0   7.2500      0            1    1      1       0.0         A/5 21171   
1  38.0  71.2833      0            2    0      1       1.0          PC 17599   
2  26.0   7.9250      0            3    0      0       1.0  STON/O2. 3101282   
3  35.0  53.1000      0            4    0      1       1.0            113803   
4  35.0   8.0500      0            5    1      0       0.0            373450

   Embarked_C  Embarked_Q  ...  Royalty  Cabin_A  Cabin_B  Cabin_C  Cabin_D  \
0           0           0  ...        0        0        0        0        0   
1           1           0  ...        0        0        0        1        0   
2           0           0  ...        0        0        0        0        0   
3           0           0  ...        0        0        0        1        0   
4           0           0  ...        0        0        0        0        0

   Cabin_E  Cabin_F  Cabin_G  Cabin_T  Cabin_U  
0        0        0        0        0        1  
1        0        0        0        0        0  
2        0        0        0        0        1  
3        0        0        0        0        0  
4        0        0        0        0        1

[5 rows x 29 columns]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

家庭类别(Parch、SipSb)

在Parch和SibSp两列中,分别表示同代直系亲属数和不同代直系亲属数,可以将这两列的数量进行合并,得到家庭成员数据,并根据数量划分家庭类别。

#存放家庭信息
familyDf = pd.DataFrame()
familyDf['FamilySize'] = fullDf[ 'Parch' ] + fullDf[ 'SibSp' ] + 1#家庭人数=同代直系亲属数(Parch)+不同代直系亲属数(SibSp)+乘客自己

'''
家庭类别:
小家庭Family_Single:家庭人数=1
中等家庭Family_Small: 2<=家庭人数<=4
大家庭Family_Large: 家庭人数>=5
'''
#if 条件为真的时候返回if前面内容,否则返回0
familyDf[ 'Family_Single'] = familyDf[ 'FamilySize' ].map( lambda s : 1 if s == 1 else 0 )
familyDf[ 'Family_Small' ] = familyDf[ 'FamilySize' ].map( lambda s : 1 if 2 <= s <= 4 else 0 )
familyDf[ 'Family_Large' ] = familyDf[ 'FamilySize' ].map( lambda s : 1 if 5 <= s else 0 )
print(familyDf.head())
FamilySize  Family_Single  Family_Small  Family_Large
0           2              0             1             0
1           2              0             1             0
2           1              1             0             0
3           2              0             1             0
4           1              1             0             0
#添加one-hot编码,将产生的类别加入泰坦尼克号数据集fullDf
fullDf = pd.concat([fullDf,familyDf],axis=1)
print(fullDf.head())
Age     Fare  Parch  PassengerId  Sex  SibSp  Survived            Ticket  \
0  22.0   7.2500      0            1    1      1       0.0         A/5 21171   
1  38.0  71.2833      0            2    0      1       1.0          PC 17599   
2  26.0   7.9250      0            3    0      0       1.0  STON/O2. 3101282   
3  35.0  53.1000      0            4    0      1       1.0            113803   
4  35.0   8.0500      0            5    1      0       0.0            373450

   Embarked_C  Embarked_Q  ...  Cabin_D  Cabin_E  Cabin_F  Cabin_G  Cabin_T  \
0           0           0  ...        0        0        0        0        0   
1           1           0  ...        0        0        0        0        0   
2           0           0  ...        0        0        0        0        0   
3           0           0  ...        0        0        0        0        0   
4           0           0  ...        0        0        0        0        0

   Cabin_U  FamilySize  Family_Single  Family_Small  Family_Large  
0        1           2              0             1             0  
1        0           2              0             1             0  
2        1           1              1             0             0  
3        0           2              0             1             0  
4        1           1              1             0             0

[5 rows x 33 columns]
#查看目前的数据结构
print(fullDf.shape)
(1309, 33)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

(3)特征选择

数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已。因此,如何去选择已经提取出来的特征,将影响到最终的评价结果。下面使用相关系数法,计算各个特征的相关系数,根据计算结果进行特征选择。

#相关型矩阵
corrDf = fullDf.corr()
print(corrDf)
Age      Fare     Parch  PassengerId       Sex     SibSp  \
Age            1.000000  0.171521 -0.130872     0.025731  0.057397 -0.190747   
Fare           0.171521  1.000000  0.221522     0.031416 -0.185484  0.160224   
Parch         -0.130872  0.221522  1.000000     0.008942 -0.213125  0.373587   
PassengerId    0.025731  0.031416  0.008942     1.000000  0.013406 -0.055224   
Sex            0.057397 -0.185484 -0.213125     0.013406  1.000000 -0.109609   
SibSp         -0.190747  0.160224  0.373587    -0.055224 -0.109609  1.000000   
Survived      -0.070323  0.257307  0.081629    -0.005007 -0.543351 -0.035322   
Embarked_C     0.076179  0.286241 -0.008635     0.048101 -0.066564 -0.048396   
Embarked_Q    -0.012718 -0.130054 -0.100943     0.011585 -0.088651 -0.048678   
Embarked_S    -0.059153 -0.169894  0.071881    -0.049836  0.115193  0.073709   
Pclass_1       0.362587  0.599956 -0.013033     0.026495 -0.107371 -0.034256   
Pclass_2      -0.014193 -0.121372 -0.010057     0.022714 -0.028862 -0.052419   
Pclass_3      -0.302093 -0.419616  0.019521    -0.041544  0.116562  0.072610   
Master        -0.363923  0.011596  0.253482     0.002254  0.164375  0.329171   
Miss          -0.254146  0.092051  0.066473    -0.050027 -0.672819  0.077564   
Mr             0.165476 -0.192192 -0.304780     0.014116  0.870678 -0.243104   
Mrs            0.198091  0.139235  0.213491     0.033299 -0.571176  0.061643   
Officer        0.162818  0.028696 -0.032631     0.002231  0.087288 -0.013813   
Royalty        0.059466  0.026214 -0.030197     0.004400 -0.020408 -0.010787   
Cabin_A        0.125177  0.020094 -0.030707    -0.002831  0.047561 -0.039808   
Cabin_B        0.113458  0.393743  0.073051     0.015895 -0.094453 -0.011569   
Cabin_C        0.167993  0.401370  0.009601     0.006092 -0.077473  0.048616   
Cabin_D        0.132886  0.072737 -0.027385     0.000549 -0.057396 -0.015727   
Cabin_E        0.106600  0.073949  0.001084    -0.008136 -0.040340 -0.027180   
Cabin_F       -0.072644 -0.037567  0.020481     0.000306 -0.006655 -0.008619   
Cabin_G       -0.085977 -0.022857  0.058325    -0.045949 -0.083285  0.006015   
Cabin_T        0.032461  0.001179 -0.012304    -0.023049  0.020558 -0.013247   
Cabin_U       -0.271918 -0.507197 -0.036806     0.000208  0.137396  0.009064   
FamilySize    -0.196996  0.226465  0.792296    -0.031437 -0.188583  0.861952   
Family_Single  0.116675 -0.274826 -0.549022     0.028546  0.284537 -0.591077   
Family_Small  -0.038189  0.197281  0.248532     0.002975 -0.255196  0.253590   
Family_Large  -0.161210  0.170853  0.624627    -0.063415 -0.077748  0.699681

               Survived  Embarked_C  Embarked_Q  Embarked_S  ...   Cabin_D  \
Age           -0.070323    0.076179   -0.012718   -0.059153  ...  0.132886   
Fare           0.257307    0.286241   -0.130054   -0.169894  ...  0.072737   
Parch          0.081629   -0.008635   -0.100943    0.071881  ... -0.027385   
PassengerId   -0.005007    0.048101    0.011585   -0.049836  ...  0.000549   
Sex           -0.543351   -0.066564   -0.088651    0.115193  ... -0.057396   
SibSp         -0.035322   -0.048396   -0.048678    0.073709  ... -0.015727   
Survived       1.000000    0.168240    0.003650   -0.149683  ...  0.150716   
Embarked_C     0.168240    1.000000   -0.164166   -0.778262  ...  0.107782   
Embarked_Q     0.003650   -0.164166    1.000000   -0.491656  ... -0.061459   
Embarked_S    -0.149683   -0.778262   -0.491656    1.000000  ... -0.056023   
Pclass_1       0.285904    0.325722   -0.166101   -0.181800  ...  0.275698   
Pclass_2       0.093349   -0.134675   -0.121973    0.196532  ... -0.037929   
Pclass_3      -0.322308   -0.171430    0.243706   -0.003805  ... -0.207455   
Master         0.085221   -0.014172   -0.009091    0.018297  ... -0.042192   
Miss           0.332795   -0.014351    0.198804   -0.113886  ... -0.012516   
Mr            -0.549199   -0.065538   -0.080224    0.108924  ... -0.030261   
Mrs            0.344935    0.098379   -0.100374   -0.022950  ...  0.080393   
Officer       -0.031316    0.003678   -0.003212   -0.001202  ...  0.006055   
Royalty        0.033391    0.077213   -0.021853   -0.054250  ... -0.012950   
Cabin_A        0.022287    0.094914   -0.042105   -0.056984  ... -0.024952   
Cabin_B        0.175095    0.161595   -0.073613   -0.095790  ... -0.043624   
Cabin_C        0.114652    0.158043   -0.059151   -0.101861  ... -0.053083   
Cabin_D        0.150716    0.107782   -0.061459   -0.056023  ...  1.000000   
Cabin_E        0.145321    0.027566   -0.042877    0.002960  ... -0.034317   
Cabin_F        0.057935   -0.020010   -0.020282    0.030575  ... -0.024369   
Cabin_G        0.016040   -0.031566   -0.019941    0.040560  ... -0.011817   
Cabin_T       -0.026456   -0.014095   -0.008904    0.018111  ... -0.005277   
Cabin_U       -0.316912   -0.258257    0.142369    0.137351  ... -0.353822   
FamilySize     0.016639   -0.036553   -0.087190    0.087771  ... -0.025313   
Family_Single -0.203367   -0.107874    0.127214    0.014246  ... -0.074310   
Family_Small   0.279855    0.159594   -0.122491   -0.062909  ...  0.102432   
Family_Large  -0.125147   -0.092825   -0.018423    0.093671  ... -0.049336

                Cabin_E   Cabin_F   Cabin_G   Cabin_T   Cabin_U  FamilySize  \
Age            0.106600 -0.072644 -0.085977  0.032461 -0.271918   -0.196996   
Fare           0.073949 -0.037567 -0.022857  0.001179 -0.507197    0.226465   
Parch          0.001084  0.020481  0.058325 -0.012304 -0.036806    0.792296   
PassengerId   -0.008136  0.000306 -0.045949 -0.023049  0.000208   -0.031437   
Sex           -0.040340 -0.006655 -0.083285  0.020558  0.137396   -0.188583   
SibSp         -0.027180 -0.008619  0.006015 -0.013247  0.009064    0.861952   
Survived       0.145321  0.057935  0.016040 -0.026456 -0.316912    0.016639   
Embarked_C     0.027566 -0.020010 -0.031566 -0.014095 -0.258257   -0.036553   
Embarked_Q    -0.042877 -0.020282 -0.019941 -0.008904  0.142369   -0.087190   
Embarked_S     0.002960  0.030575  0.040560  0.018111  0.137351    0.087771   
Pclass_1       0.242963 -0.073083 -0.035441  0.048310 -0.776987   -0.029656   
Pclass_2      -0.050210  0.127371 -0.032081 -0.014325  0.176485   -0.039976   
Pclass_3      -0.169063 -0.041178  0.056964 -0.030057  0.527614    0.058430   
Master         0.001860  0.058311 -0.013690 -0.006113  0.041178    0.355061   
Miss           0.008700 -0.003088  0.061881 -0.013832 -0.004364    0.087350   
Mr            -0.032953 -0.026403 -0.072514  0.023611  0.131807   -0.326487   
Mrs            0.045538  0.013376  0.042547 -0.011742 -0.162253    0.157233   
Officer       -0.024048 -0.017076 -0.008281 -0.003698 -0.067030   -0.026921   
Royalty       -0.012202 -0.008665 -0.004202 -0.001876 -0.071672   -0.023600   
Cabin_A       -0.023510 -0.016695 -0.008096 -0.003615 -0.242399   -0.042967   
Cabin_B       -0.041103 -0.029188 -0.014154 -0.006320 -0.423794    0.032318   
Cabin_C       -0.050016 -0.035516 -0.017224 -0.007691 -0.515684    0.037226   
Cabin_D       -0.034317 -0.024369 -0.011817 -0.005277 -0.353822   -0.025313   
Cabin_E        1.000000 -0.022961 -0.011135 -0.004972 -0.333381   -0.017285   
Cabin_F       -0.022961  1.000000 -0.007907 -0.003531 -0.236733    0.005525   
Cabin_G       -0.011135 -0.007907  1.000000 -0.001712 -0.114803    0.035835   
Cabin_T       -0.004972 -0.003531 -0.001712  1.000000 -0.051263   -0.015438   
Cabin_U       -0.333381 -0.236733 -0.114803 -0.051263  1.000000   -0.014155   
FamilySize    -0.017285  0.005525  0.035835 -0.015438 -0.014155    1.000000   
Family_Single -0.042535  0.004055 -0.076397  0.022411  0.175812   -0.688864   
Family_Small   0.068007  0.012756  0.087471 -0.019574 -0.211367    0.302640   
Family_Large  -0.046485 -0.033009 -0.016008 -0.007148  0.056438    0.801623

               Family_Single  Family_Small  Family_Large  
Age                 0.116675     -0.038189     -0.161210  
Fare               -0.274826      0.197281      0.170853  
Parch              -0.549022      0.248532      0.624627  
PassengerId         0.028546      0.002975     -0.063415  
Sex                 0.284537     -0.255196     -0.077748  
SibSp              -0.591077      0.253590      0.699681  
Survived           -0.203367      0.279855     -0.125147  
Embarked_C         -0.107874      0.159594     -0.092825  
Embarked_Q          0.127214     -0.122491     -0.018423  
Embarked_S          0.014246     -0.062909      0.093671  
Pclass_1           -0.126551      0.165965     -0.067523  
Pclass_2           -0.035075      0.097270     -0.118495  
Pclass_3            0.138250     -0.223338      0.155560  
Master             -0.265355      0.120166      0.301809  
Miss               -0.023890     -0.018085      0.083422  
Mr                  0.386262     -0.300872     -0.194207  
Mrs                -0.354649      0.361247      0.012893  
Officer             0.013303      0.003966     -0.034572  
Royalty             0.008761     -0.000073     -0.017542  
Cabin_A             0.045227     -0.029546     -0.033799  
Cabin_B            -0.087912      0.084268      0.013470  
Cabin_C            -0.137498      0.141925      0.001362  
Cabin_D            -0.074310      0.102432     -0.049336  
Cabin_E            -0.042535      0.068007     -0.046485  
Cabin_F             0.004055      0.012756     -0.033009  
Cabin_G            -0.076397      0.087471     -0.016008  
Cabin_T             0.022411     -0.019574     -0.007148  
Cabin_U             0.175812     -0.211367      0.056438  
FamilySize         -0.688864      0.302640      0.801623  
Family_Single       1.000000     -0.873398     -0.318944  
Family_Small       -0.873398      1.000000     -0.183007  
Family_Large       -0.318944     -0.183007      1.000000

[32 rows x 32 columns]
#查看各个特征与生存情况(Survived)的相关系数
corrDf['Survived'].sort_values(ascending=False) #ascending=False表示降序排列
Survived         1.000000
Mrs              0.344935
Miss             0.332795
Pclass_1         0.285904
Family_Small     0.279855
Fare             0.257307
Cabin_B          0.175095
Embarked_C       0.168240
Cabin_D          0.150716
Cabin_E          0.145321
Cabin_C          0.114652
Pclass_2         0.093349
Master           0.085221
Parch            0.081629
Cabin_F          0.057935
Royalty          0.033391
Cabin_A          0.022287
FamilySize       0.016639
Cabin_G          0.016040
Embarked_Q       0.003650
PassengerId     -0.005007
Cabin_T         -0.026456
Officer         -0.031316
SibSp           -0.035322
Age             -0.070323
Family_Large    -0.125147
Embarked_S      -0.149683
Family_Single   -0.203367
Cabin_U         -0.316912
Pclass_3        -0.322308
Sex             -0.543351
Mr              -0.549199
Name: Survived, dtype: float64
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175

通过观察不同特征与生成情况(Survived)的相关系数大小可以发现,头衔(Mrs、Miss)、客舱等级(Pclass_1)、家庭大小(Family_Small)、船票价格(Fare)、船舱号(Cabin_B)和登船港口(Embarked_C)有较强的正线性相关性;登船港口(Embarked_S)、家庭大小(Family_Single、Family_Large)、船舱号(Cabin_U)、客舱等级(Pclass_3)、头衔(Mr)、性别(Sex)有较强的负线性相关性,因此选择选择头衔(titleDf)、客舱等级(pclassDf)、家庭大小(familyDf)、船票价格(Fare)、船舱号(cabinDf)、登船港口(embarkedDf)、性别(Sex)这几个特征。

#特征选择
full_X = pd.concat( [titleDf,#头衔
                     pclassDf,#客舱等级
                     familyDf,#家庭大小
                     fullDf['Fare'],#船票价格
                     cabinDf,#船舱号
                     embarkedDf,#登船港口
                     fullDf['Sex']#性别
                    ] , axis=1 )
print(full_X.head())
print(full_X.shape)
print(fullDf.shape)
Master  Miss  Mr  Mrs  Officer  Royalty  Pclass_1  Pclass_2  Pclass_3  \
0       0     0   1    0        0        0         0         0         1   
1       0     0   0    1        0        0         1         0         0   
2       0     1   0    0        0        0         0         0         1   
3       0     0   0    1        0        0         1         0         0   
4       0     0   1    0        0        0         0         0         1

   FamilySize  ...  Cabin_D  Cabin_E  Cabin_F  Cabin_G  Cabin_T  Cabin_U  \
0           2  ...        0        0        0        0        0        1   
1           2  ...        0        0        0        0        0        0   
2           1  ...        0        0        0        0        0        1   
3           2  ...        0        0        0        0        0        0   
4           1  ...        0        0        0        0        0        1

   Embarked_C  Embarked_Q  Embarked_S  Sex  
0           0           0           1    1  
1           1           0           0    0  
2           0           0           1    0  
3           0           0           1    0  
4           0           0           1    1

[5 rows x 27 columns]
(1309, 27)
(1309, 33)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

4.构建模型

(1)创建模型

将项目所给的数据有train.csv数据和test.csv数据。因为坦尼克号测试数据集是我们最后要提交给Kaggle的结果,里面没有生存情况的值,所以不能用于评估模型。于是我们将train.csv数据设置为原始数据,test.csv数据设置为预测数据,利用原始数据(train.csv)创建模型。按照之前已经介绍过的sklearn中train_test_split方法进行数据分割,将数据随机分成训练数据和测试数据,占比为8:2。

num = fullDf['Survived'].isna().sum()
print(num)
418
#训练数据集有891行
sourceRow = 891
#原始数据集:特征
source_X = full_X.loc[0:sourceRow-1,:]#从特征集合full_X中提取原始数据集前891行数据时,需减去1,因为行号是从0开始
#原始数据集:标签
source_y = fullDf.loc[0:sourceRow-1,'Survived']

#预测数据集:特征
pred_X = full_X.loc[sourceRow:,:]#前891行是测试数据集,891行之后的是预测数据集
#原始数据集有多少行
print('原始数据集有多少行:',source_X.shape[0])
#预测数据集大小
print('预测数据集有多少行:',pred_X.shape[0])
原始数据集有多少行: 891
预测数据集有多少行: 418
from sklearn.model_selection import train_test_split 

#建立模型用的训练数据集和测试数据集
train_X, test_X, train_y, test_y = train_test_split(source_X ,
                                                    source_y,
                                                    train_size=.8)

#输出数据集大小
print ('原始数据集特征:',source_X.shape, 
       '训练数据集特征:',train_X.shape ,
       '测试数据集特征:',test_X.shape)

print ('原始数据集标签:',source_y.shape, 
       '训练数据集标签:',train_y.shape ,
       '测试数据集标签:',test_y.shape)
原始数据集特征: (891, 27) 训练数据集特征: (712, 27) 测试数据集特征: (179, 27)
原始数据集标签: (891,) 训练数据集标签: (712,) 测试数据集标签: (179,)
#原始数据查看
source_y.head()
0    0.0
1    1.0
2    1.0
3    1.0
4    0.0
Name: Survived, dtype: float64
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

(2)训练模型

因为最终得出的Survived数据为非连续性数据,使用逻辑回归算法进行训练。

#第1步:导入逻辑回归
from sklearn.linear_model import LogisticRegression
#第2步:创建模型:逻辑回归
model = LogisticRegression()
#第3步:训练模型
model.fit(train_X , train_y)

LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
                   intercept_scaling=1, l1_ratio=None, max_iter=100,
                   multi_class='warn', n_jobs=None, penalty='l2',
                   random_state=None, solver='warn', tol=0.0001, verbose=0,
                   warm_start=False)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

5.模型评估

# 分类问题,score得到的是模型的正确率
model.score(test_X , test_y )
0.7877094972067039
  • 1
  • 2
  • 3

6.实施方案

使用预测数据集进行预测,并保存到csv文件中,之后上传到Kaggle查看排名。

#使用机器学习模型,对预测数据集中的生存情况进行预测
pred_y = model.predict(pred_X)
#生成的预测值是浮点数,但是Kaggle要求提交的结果是整型,所以要对数据类型进行转换
pred_y = pred_y.astype(int)
#乘客id
passenger_id = fullDf.loc[sourceRow:,'PassengerId']
#数据框:乘客id,预测生存情况的值
predDf = pd.DataFrame( 
    { 'PassengerId': passenger_id , 
      'Survived': pred_y } )
print(predDf.shape)
print(predDf.head())
#保存结果
predDf.to_csv('titanic_pred.csv',index = False)
(418, 2)
     PassengerId  Survived
891          892         0
892          893         1
893          894         0
894          895         0
895          896         1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

上传预测数据

img

点击头像中的My Profie,便可以查看当前的排名。

img

五、总结

1.常用的机器学习有监督学习 (supervised learning)、非监督学习( unsupervised learning)、半监督学习 (semi-supervised learning)、强化学习 (reinforcement learning)

2.介绍了简单线性回归逻辑回归两种方法,按照提出问题、理解数据、数据清洗、构建模型、模型评估的步骤进行分析。

3.通过实践泰坦尼克号生存预测案例,进一步了解了数据预处理、特征提取、特征选择内容**。**

以上就是今天的全部内容分享,觉得有用的话欢迎点赞收藏哦!

Python经验分享

学好 Python 不论是用于就业还是做副业赚钱都不错,而且学好Python还能契合未来发展趋势——人工智能、机器学习、深度学习等。
小编是一名Python开发工程师,自己整理了一套最新的Python系统学习教程,包括从基础的python脚本到web开发、爬虫、数据分析、数据可视化、机器学习等。如果你也喜欢编程,想通过学习Python转行、做副业或者提升工作效率,这份【最新全套Python学习资料】 一定对你有用!

小编为对Python感兴趣的小伙伴准备了以下籽料 !

对于0基础小白入门:

如果你是零基础小白,想快速入门Python是可以考虑培训的!

  • 学习时间相对较短,学习内容更全面更集中
  • 可以找到适合自己的学习方案

包括:Python激活码+安装包、Python web开发,Python爬虫,Python数据分析,人工智能、机器学习、Python量化交易等学习教程。带你从零基础系统性的学好Python!

一、Python所有方向的学习路线

Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
在这里插入图片描述

二、学习软件

工欲善其事必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。

三、入门学习视频

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。

四、实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

五、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。


最新全套【Python入门到进阶资料 & 实战源码 &安装工具】(安全链接,放心点击)

我已经上传至CSDN官方,如果需要可以扫描下方官方二维码免费获取【保证100%免费】

*今天的分享就到这里,喜欢且对你有所帮助的话,记得点赞关注哦~下回见 !

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/147336
推荐阅读
相关标签
  

闽ICP备14008679号