机器学习中的 Logistic Regression
Logistic Regression 简介
Logistic regression 是一种监督学习分类算法,用于预测目标变量的概率。目标或因变量的性质是二元的,这意味着只有两个可能类别。
简单来说,因变量本质上是二进制的,数据编码为 1(代表成功/是)或 0(代表失败/否)。
从数学上讲,logistic regression 模型预测 P(Y=1) 作为 X 的函数。它是最简单的 ML 算法之一,可用于各种分类问题,如垃圾邮件检测、糖尿病预测、癌症检测等。
Logistic Regression 的类型
通常,logistic regression 指具有二元目标变量的 binary logistic regression,但它还可以预测两种更多类别的目标变量。根据这些类别的数量,Logistic regression 可分为以下类型 −
Binary 或 Binomial
在这种分类中,因变量只有两种可能类型,即 1 和 0。例如,这些变量可能代表成功或失败、是或否、胜或负等。
Multinomial
在这种分类中,因变量可以有 3 个或更多无序类型,或者没有定量意义的类型。例如,这些变量可能代表“类型 A”、“类型 B”或“类型 C”。
Ordinal
在这种分类中,因变量可以有 3 个或更多有序类型,或者具有定量意义的类型。例如,这些变量可能代表“差”、“好”、“很好”、“优秀”,每个类别可以有分数如 0、1、2、3。
Logistic Regression 的假设
在深入实现 logistic regression 之前,我们必须了解以下关于它的假设 −
在 binary logistic regression 的情况下,目标变量必须始终是二元的,并且期望结果由因子水平 1 表示。
模型中不应存在多重共线性,这意味着自变量必须相互独立。
我们必须在模型中包含有意义的变量。
我们应该为 logistic regression 选择较大的样本量。
二元 Logistic 回归模型
Logistic 回归的最简单形式是二元或二项式 Logistic 回归,其中目标或因变量只能有 2 种可能类型,即 1 或 0。它允许我们建模多个预测变量与二元/二项式目标变量之间的关系。在 Logistic 回归的情况下,线性函数基本上用作另一个函数的输入,如以下关系所示 −
$$h_{\theta}{(x)}=g(\theta^{T}x) 0h_{\theta}1$$这里,$g$ 是 Logistic 或 sigmoid 函数,可以表示如下 −
$$g(z)= \frac{1}{1+e^{-z}} =\theta ^{T}$$Sigmoid 曲线可以通过以下图表表示。我们可以看到 y 轴的值位于 0 和 1 之间,并在 0.5 处穿过轴。
类别可以分为正类或负类。如果输出位于 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 中实现二元 Logistic 回归模型
现在我们将在 Python 中实现上述二项式 Logistic 回归的概念。为此,我们使用名为 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();
接下来,我们将定义 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');

多项逻辑斯蒂回归模型
逻辑回归的另一种有用形式是多项逻辑斯蒂回归,其中目标或因变量可以有 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
接下来,我们需要加载 digit 数据集 −
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)
现在创建 logistic regression 的对象,如下所示 −
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%。