分类算法 Logistic 回归


逻辑回归是一种监督学习分类算法,用于预测目标变量的概率。目标或因变量的性质是二分法的,这意味着只有两个可能的类别。

简单来说,因变量本质上是二进制的,其数据编码为 1(代表成功/是)或 0(代表失败/否)。

在数学上,逻辑回归模型将 P(Y=1) 预测为 X 的函数。它是最简单的 ML 算法之一,可用于各种分类问题,例如垃圾邮件检测、糖尿病预测、癌症检测等。

Logistic 回归的类型


通常,逻辑回归是指具有二元目标变量的二元逻辑回归,但它可以预测的目标变量可以多于两类。根据这些类别的数量,逻辑回归可以分为以下类型:

二进制或二项式

在这种分类中,一个因变量将只有两种可能的类型,1 和 0。例如,这些变量可能代表成功或失败,是或否,赢或输等。

多项式

在这种分类中,因变量可以有3种或更多可能的无序类型或没有数量意义的类型。例如,这些变量可以表示“A 型”或“B 型”或“C 型”。

Ordinal

在这种分类中,因变量可以有3种或更多可能的有序类型或具有定量意义的类型。例如,这些变量可能代表“差”或“好”、“非常好”、“优秀”,每个类别的分数可以是 0、1、2、3。

逻辑回归假设


在深入研究逻辑回归的实现之前,我们必须了解以下相同的假设:

  • 在二元逻辑回归的情况下,目标变量必须始终是二元的,并且期望的结果由因子水平 1 表示。

  • 模型中不应存在多重共线性,即自变量必须相互独立。

  • 我们必须在模型中包含有意义的变量。

  • 我们应该选择大样本量进行逻辑回归。

二元逻辑回归模型


最简单的逻辑回归形式是二元或二项式逻辑回归,其中目标或因变量只能有 1 或 0 两种可能的类型。它允许我们对多个预测变量与二元/二项式目标变量之间的关系进行建模。在逻辑回归的情况下,线性函数基本上用作另一个函数的输入,例如?,关系如下:

$$h_{\theta}{(x)}=g(\theta^{T}x)?ℎ??? 0≤h_{\theta}≤1$$

这里,?是逻辑或sigmoid函数,可以如下给出:

$$g(z)= \frac{1}{1+e^{-z}}?ℎ??? ?=\theta ^{T}?$$

To sigmoid 曲线可以在下图的帮助下表示。我们可以看到 y 轴的值介于 0 和 1 之间,并在 0.5 处与轴相交。

Flow

类别可以分为正面或负面。如果输出介于 0 和 1 之间,则输出属于正类概率。对于我们的实现,如果假设函数的输出≥0.5,我们将其解释为正,否则为负。

我们还需要定义一个损失函数来衡量算法使用函数权重的执行情况,用 theta 表示如下:

ℎ=?(??)

$$J(\theta) = \frac{1}{m}.(-y^{T}log(h) - (1 -y)^Tlog(1-h))$$

现在,在定义了损失函数之后,我们的主要目标是最小化损失函数。它可以在拟合权重的帮助下完成,这意味着通过增加或减少权重。借助损失函数对每个权重的导数,我们将能够知道哪些参数应该具有较高的权重,哪些应该具有较小的权重。

下面的梯度下降方程告诉我们,如果我们修改参数,损失会如何变化:

$$\frac{??(?)}{?\theta_{j}}=\frac{1}{m}X^{T}(?(??)−?)$$

用 Python 实现


现在我们将在 Python 中实现上述二项式逻辑回归的概念。为此,我们使用了一个名为“iris”的多元花卉数据集,它有 3 类,每类 50 个实例,但我们将使用前两个特征列。每个类代表一种鸢尾花。

首先,我们需要导入必要的库如下:

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import datasets

接下来,加载 iris 数据集如下:

iris = datasets.load_iris()
X = iris.data[:, :2]
y = (iris.target != 0) * 1

我们可以将我们的训练数据绘制成如下图:

plt.figure(figsize=(6, 6))
plt.scatter(X[y == 0][:, 0], X[y == 0][:, 1], color='g', label='0')
plt.scatter(X[y == 1][:, 0], X[y == 1][:, 1], color='y', label='1')
plt.legend();
Star

接下来,我们将定义 sigmoid 函数、损失函数和梯度下降如下:

class LogisticRegression:
    def __init__(self, lr=0.01, num_iter=100000, fit_intercept=True, verbose=False):
        self.lr = lr
        self.num_iter = num_iter
        self.fit_intercept = fit_intercept
        self.verbose = verbose
    def __add_intercept(self, X):
        intercept = np.ones((X.shape[0], 1))
        return np.concatenate((intercept, X), axis=1)
    def __sigmoid(self, z):
        return 1 / (1 + np.exp(-z))
    def __loss(self, h, y):
        return (-y * np.log(h) - (1 - y) * np.log(1 - h)).mean()
    def fit(self, X, y):
        if self.fit_intercept:
            X = self.__add_intercept(X)

现在,初始化权重如下:

self.theta = np.zeros(X.shape[1])
    for i in range(self.num_iter):
        z = np.dot(X, self.theta)
        h = self.__sigmoid(z)
        gradient = np.dot(X.T, (h - y)) / y.size
        self.theta -= self.lr * gradient
        z = np.dot(X, self.theta)
        h = self.__sigmoid(z)
        loss = self.__loss(h, y)
        if(self.verbose ==True and i % 10000 == 0):
            print(f'loss: {loss} \t')

借助以下脚本,我们可以预测输出概率:

def predict_prob(self, X):
    if self.fit_intercept:
        X = self.__add_intercept(X)
    return self.__sigmoid(np.dot(X, self.theta))
def predict(self, X):
    return self.predict_prob(X).round()

接下来,我们可以评估模型并将其绘制如下:

model = LogisticRegression(lr=0.1, num_iter=300000)
preds = model.predict(X)
(preds == y).mean()

plt.figure(figsize=(10, 6))
plt.scatter(X[y == 0][:, 0], X[y == 0][:, 1], color='g', label='0')
plt.scatter(X[y == 1][:, 0], X[y == 1][:, 1], color='y', label='1')
plt.legend()
x1_min, x1_max = X[:,0].min(), X[:,0].max(),
x2_min, x2_max = X[:,1].min(), X[:,1].max(),
xx1, xx2 = np.meshgrid(np.linspace(x1_min, x1_max), np.linspace(x2_min, x2_max))
grid = np.c_[xx1.ravel(), xx2.ravel()]
probs = model.predict_prob(grid).reshape(xx1.shape)
plt.contour(xx1, xx2, probs, [0.5], linewidths=1, colors='red');
Red Line

多项逻辑回归模型


逻辑回归的另一种有用形式是多项逻辑回归,其中目标或因变量可以具有 3 种或更多可能的无序类型,即没有数量意义的类型。

用 Python 实现


现在我们将在 Python 中实现上述多项逻辑回归的概念。为此,我们使用了来自 sklearn 的名为 digit 的数据集。

首先,我们需要导入必要的库如下:

Import sklearn
from sklearn import datasets
from sklearn import linear_model
from sklearn import metrics
from sklearn.model_selection import train_test_split

接下来,我们需要加载数字数据集:

digits = datasets.load_digits()

现在,定义特征矩阵(X)和响应向量(y)如下:

X = digits.data
y = digits.target

借助下一行代码,我们可以将 X 和 y 拆分为训练集和测试集:

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.4, random_state=1)

现在创建一个逻辑回归对象如下:

digreg = linear_model.LogisticRegression()

现在,我们需要使用如下训练集来训练模型:

digreg.fit(X_train, y_train)

接下来,对测试集进行预测如下:

y_pred = digreg.predict(X_test)

接下来打印模型的精度如下:

print("Accuracy of Logistic Regression model is:",
metrics.accuracy_score(y_test, y_pred)*100)
Accuracy of Logistic Regression model is: 95.6884561891516

从上面的输出我们可以看到我们模型的准确率在 96% 左右。