Sololearn 自学机器学习(8)构建逻辑回归模型
Scikit-learn 是什么
既然我们已经建立了逻辑回归(Logistic Regression)的基础,让我们深入一些代码来构建一个模型。
为此,我们将介绍一个名为 scikit-learn 的 Python 模块。Scikit-learn,通常缩写为 sklearn ,是我们的科学工具包。
所有基本的机器学习算法都已经在 sklearn 中实现。我们将看到,只需几行代码,我们就可以构建几种不同的强大模型。
请注意,scikit-learn 正在不断更新。如果您的计算机上安装的模块版本略有不同,一切仍将正常工作,但您可能会看到与本文中略有不同的值。
Scikit-learn 是 Python 中文档最详尽的模块之一。您可以在 scikit-learn.org 上找到大量的代码示例。
使用 Pandas 准备数据
在我们使用 sklearn 构建模型之前,我们需要使用 Pandas 准备数据。让我们回到完整的数据集并回顾一下 Pandas 命令。
这是一个包含所有列的 Pandas DataFrame 数据:
Survived | Pclass | Sex | Age | SibSp | Parch | Fare | |
---|---|---|---|---|---|---|---|
0 | 0 | 3 | male | 22.0 | 1 | 0 | 7.2500 |
1 | 1 | 1 | female | 38.0 | 1 | 0 | 71.2833 |
2 | 1 | 3 | female | 26.0 | 0 | 0 | 7.9250 |
3 | 1 | 1 | female | 35.0 | 1 | 0 | 53.1000 |
4 | 0 | 3 | male | 35.0 | 0 | 0 | 8.0500 |
注:SibSp 是 Sibling / Spouses;Parch 是 Parents / Children
首先,我们需要使所有列变成数值型。回顾一下如何为性别创建布尔列。
df['male'] = df['Sex'] == 'male' |
现在,让我们将所有特征(features)创建一个名为 X
的 numpy 数组。我们首先选择我们感兴趣的所有列,然后使用 values
方法将其转换为 numpy
数组。
X = df[['Pclass', 'male', 'Age', 'SibSp', 'Parch', 'Fare']].values |
现在让我们取目标(targets, Survived 列)并将其存储在变量 y
中。
y = df['Survived'].values |
通常,我们习惯将特征的2D数组称为X,将目标值的1D数组称为y。
使用 Sklearn 构建逻辑回归模型
首先,我们需要从 skikit-learn 包中导入逻辑回归模型
from sklearn.linear_model import LogisticRegression |
所有 sklearn 中的模型都被构建成了 Python 类,因此我们需要实例化这个类
model = LogisticRegression() |
现在,我们可以使用之前准备的数据来训练模型。使用 fit
函数来构建模型,他接受两个参数:X(特征,是一个 2D numpy 数组),y(目标,是一个 1D numpy 数组)。
一切从简,我们使用 Fare 和 Age 作为特征来构建模型,首先我们定义特征和目标数组:
由于我们提供的数据有空值,所以需要对其进行预处理(Preprocessing),这里我们将年龄的空值填补为年龄的平均值,代码如下:
df['Age'].fillna(df['Age'].mean(), inplace=True) |
X = df[['Fare', 'Age']].values |
别忘了加上 values
属性来获取 numpy array!
现在,使用 fit
来构建模型
model.fit(X, y) |
拟合模型(Fitting the model)意味着使用数据选择最佳拟合线(a line of best fit)。我们可以使用 coef_
和 intercept_
属性来查看系数(coefficients)。
print(model.coef_, model.intercept_) |
得到的返回值为:
[[ 0.01619443 -0.01738676]] [-0.45768136] |
这个数据意味着我们的线性方程为:
所以我们可以再次调用 matplotlib 进行画图,你可以看到它在分割黄色和紫色点方面做得还不错(但不是很好)。通过仅使用2个特征,我们有点自限,所以在接下来的部分中,我们将使用所有特征。
# 获取系数和截距 |
记住不同 sklearn 模型的导入语句可能有点困难。如果记不住,只需查看 scikit-learn 文档。
构建逻辑回归模型完整源码
今天的完整源码:
import numpy as np |
使用我们构建的模型进行预测
在先前的部分中,我们只使用了两个特征,这实际上对我们的模型造成了一些限制,因此让我们使用所有特征重新构建模型。在这里,我们需要用到 male 字段,同时也要填补 Age 字段的缺省值:
df['male'] = df['Sex'] == 'male' |
现在,我们可以用 predict(X)
函数进行预测。数据集中的第一位乘客是:
PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | 0 | 3 | “Braund, Mr. Owen Harris” | male | 22 | 1 | 0 | A/5 21171 | 7.25 | S |
其中我们要用到的数据为:
[3, True, 22, 1, 0, 7.25] |
Survived | Pclass | male | Age | SibSp | Parch | Fare |
---|---|---|---|---|---|---|
0 | 3 | True | 22 | 1 | 0 | 7.25 |
这意味着该乘客位于 Pclass 3,男性,年龄22岁,有 1 名兄弟/配偶,0 名父母/子女,支付 7.25 美元。让我们看看模型对于这位乘客的预测结果。请注意,即使有一个数据点,predict 方法也需要一个二维的 numpy 数组并返回一个一维的 numpy 数组。
print(model.predict([[3, True, 22.0, 1, 0, 7.25]])) |
执行结果为 [0]
。意味着模型预测的这位乘客并没有生还。
让我们看看模型对前5行数据的预测结果,并将其与目标数组进行比较。我们使用 X[:5]
获取前5行数据,使用 y[:5]
获取目标的前5个值。
print(model.predict(X[:5])) |
我们看到它全部预测正确!
事实上,训练模型我们需要将训练集与测试集分开,这就是为什么我们同时上传了 训练集 和 测试集
predict
方法返回一个包含 1 和 0 的数组,其中 1 表示模型预测乘客生还,0 表示模型预测乘客没有生还。
使用模型进行预测的完整代码
import numpy as np |
评估模型的性能
通过计算模型正确预测的数据点数量,我们可以了解模型的表现好坏。这被称为准确率分数。
让我们创建一个包含预测的y值的数组。
y_pred = model.predict(X) |
然后创建一个布尔值数组 y == y_pred
,表示我们的模型是否正确预测了每个乘客。要获取其中为真的数量,我们可以使用 numpy 的 sum 方法。
print((y == y_pred).sum()) |
返回值为:711,这说明在 891 个数据点中,模型对其中的 711 个数据点进行了正确的预测。
为了得到百分比,我们将其除以总乘客数。我们使用 shape
属性获取总乘客数 y.shape[0]
。计算准确性的分数如下:
print((y == y_pred).sum() / y.shape[0]) |
因此,模型的准确性为 79%。换句话说,模型在 79% 的数据点上做出了正确的预测。
这是一个足够常见的计算,sklearn 已经为我们实现了它。因此,我们可以使用 score
方法得到相同的结果。score
方法使用模型对 X 进行预测,计算匹配 y 的百分比。
print(model.score(X, y)) |
通过这种替代方法计算准确性,我们得到相同的值,79%。
评估模型性能的完整代码
import pandas as pd |
练习
鉴于以下代码和输出,模型的准确性是多少?
print(model.predict(X)) |
输出:[1 0 0 0 1]
[1 1 0 0 0]
- 60%
- 20%
- 80%
- 40%