1987WEB视界-分享互联网热门产品和行业

您现在的位置是:首页 > 人工智能AI > 正文

人工智能AI

AI算法:逻辑回归原理与实现

1987web2023-08-17人工智能AI106

1、算法思想

线性回归可以对数据进行线性拟合,拟合后的模型可以输出连续的值。由于它没有范围,因此不适合与分类问题。逻辑回归用于离散变量的分类问题,其输出值为属于某一类的概率,主要用于类的判别。

2、算法推导2.1 逻辑回归

对于线性回归的预测函数为:

其中,

图1. sigmoid函数

图2. 逻辑回归示意图

由图1所示:

当 时, ;

当 时, 。

因此,函数的输出值在0-1之间。

对于逻辑回归:

当 时 ,这时应为类别1;

当 时 ,这时应为类别0。

因此,预测输出为在输入与参数条件下预测类别为1的概率。

例如,对于给定的与 所求得的概率为 ,则输出类别1的概率为0.7,相应的类别0的概率为0.3。

2.2 损失函数

对于线性回归模型,我们定义的代价函数是所有模型误差的平方和。理论上来说,我们也可以对逻辑回归模型沿用这个定义,但是问题在于,当我们将下述公式

带入到线性回归的损失函数中会得到图3. 非凸函数,梯度下降法会得到局部最小值。因此,需要重新设计损失函数。

图3. 非凸函数

采用BCE (Binary Cross Entropy)二分类交叉熵损失函数。

其中,

为样本个数。

为类别0的预测值。

因此:

当时,

import numpy as np import seaborn import matplotlib.pyplot as plt x = np.arange(0.1, 1, .01) y = -np.log(x) seaborn.lineplot(x=x, y=y) plt.show()

图4. 类别1损失函数

由图4类别1的损失函数,随着预测值增加loss逐渐减小,预测值为1时,loss=0。

当y=0时,

import numpy as np import seaborn import matplotlib.pyplot as plt x = np.arange(0.1, 1, .01) y = -np.log(1-x) seaborn.lineplot(x=x, y=y) plt.show()

图5. 类别0损失函数

由图5类别0的损失函数,随着预测值减小loss逐渐减小,预测值为时,loss=0。

2.3 求解方法

详细推导如下:

可以使用梯度下降法对参数进行更新

3、算法实现

代码如下:

(1)logistic_regression.py

-*- coding: utf-8 -*- import numpy as np class LogisticRegression(object): def __init__(self, learning_rate=0.1, max_iter=100, seed=None): self.seed = seed self.lr = learning_rate self.max_iter = max_iter def fit(self, x, y): np.random.seed(self.seed) self.w = np.random.normal(loc=0.0, scale=1.0, size=x.shape[1]) self.b = np.random.normal(loc=0.0, scale=1.0) self.x = x self.y = y for i in range(self.max_iter): self._update_step() print(loss: \t{}.format(self.loss())) print(score: \t{}.format(self.score())) print(w: \t{}.format(self.w)) print(b: \t{}.format(self.b)) def _sigmoid(self, z): return 1.0 / (1.0 + np.exp(-z)) def _f(self, x, w, b): z = x.dot(w) + b return self._sigmoid(z) def predict_proba(self, x=None): if x is None: x = self.x y_pred = self._f(x, self.w, self.b) return y_pred def predict(self, x=None): if x is None: x = self.x y_pred_proba = self._f(x, self.w, self.b) y_pred = np.array([0 if y_pred_proba[i] < 0.5 else 1 for i in range(len(y_pred_proba))]) return y_pred def score(self, y_true=None, y_pred=None): if y_true is None or y_pred is None: y_true = self.y y_pred = self.predict() acc = np.mean([1 if y_true[i] == y_pred[i] else 0 for i in range(len(y_true))]) return acc def loss(self, y_true=None, y_pred_proba=None): if y_true is None or y_pred_proba is None: y_true = self.y y_pred_proba = self.predict_proba() return np.mean(-1.0 * (y_true * np.log(y_pred_proba) + (1.0 - y_true) * np.log(1.0 - y_pred_proba))) def _calc_gradient(self): y_pred = self.predict() d_w = (y_pred - self.y).dot(self.x) / len(self.y) d_b = np.mean(y_pred - self.y) return d_w, d_b def _update_step(self): d_w, d_b = self._calc_gradient() self.w = self.w - self.lr * d_w self.b = self.b - self.lr * d_b return self.w, self.b

(2)train_test_lr.py

-*- coding: utf-8 -*- import numpy as np import matplotlib.pyplot as plt import data_helper from logistic_regression import * data generation x, y = data_helper.generate_data(seed=272) x_train, y_train, x_test, y_test = data_helper.train_test_split(x, y) visualize data plt.scatter(x_train[:,0], x_train[:,1], c=y_train, marker=.) plt.show() plt.scatter(x_test[:,0], x_test[:,1], c=y_test, marker=.) plt.show() data normalization x_train = (x_train - np.min(x_train, axis=0)) / (np.max(x_train, axis=0) - np.min(x_train, axis=0)) x_test = (x_test - np.min(x_test, axis=0)) / (np.max(x_test, axis=0) - np.min(x_test, axis=0)) Logistic regression classifier clf = LogisticRegression(learning_rate=0.1, max_iter=500, seed=272) clf.fit(x_train, y_train) plot the result split_boundary_func = lambda x: (-clf.b - clf.w[0] * x) / clf.w[1] xx = np.arange(0.1, 0.6, 0.1) plt.scatter(x_train[:,0], x_train[:,1], c=y_train, marker=.) plt.plot(xx, split_boundary_func(xx), c=red) plt.show() loss on test set y_test_pred = clf.predict(x_test) y_test_pred_proba = clf.predict_proba(x_test) print(clf.score(y_test, y_test_pred)) print(clf.loss(y_test, y_test_pred_proba)) print(y_test_pred_proba)

本文转载自网易,更多内容请点击阅读原文