多元 Logistic 回归的推导与 Python 实现

您所在的位置:网站首页 多变量逻辑回归模型的应用 多元 Logistic 回归的推导与 Python 实现

多元 Logistic 回归的推导与 Python 实现

2024-07-12 06:30:45| 来源: 网络整理| 查看: 265

多元 Logistic 回归的推导与 Python 实现¶

多元 Logistic 回归的目标函数推导,并用 Python 实现 OvO、OvR 和直接构造多元 Logistic 模型的方法。

数学推导¶

记 \(x=\left[\begin{array}{l} 1 \\\ x \end{array}\right]\),即下文的推导中,\(x\) 的含义是在原始特征的上方添加元素“ \(1\) ”。

对数几率模型是线性模型¶

由上述关于 \(x\) 的定义,在多元 Logistic 回归下,有

\[ \log \frac{P(Y=k \mid X=x)}{P(Y=K \mid X=x)}=\beta_k^{\top} x,\quad k=1,2, \cdots, K-1 \]

上式中,\(x\) 和 \(\beta_k\) 均是 \(n+1\) 维列向量。

待求解的 Logistic 模型¶

多元 Logistic 回归的模型参数为

\[ \theta=\lbrace\beta_1, \beta_2, \ldots, \beta_{k-1}\rbrace \]

当\(k=1,2, \cdots, K-1\)时,

\[ \begin{aligned} P\left(y_i=k \mid x\right)&=\frac{P\left(y_i=k \mid x\right)}{1}\\\ &=\frac{P\left(y_i=k \mid x\right)}{P\left(y_i=K \mid x\right)+\sum\limits_{l=1}^{K-1} P\left(y_i=l \mid x\right)}\\\ &=\frac{\frac{P\left(y_i=k \mid x\right)}{P\left(y_i=K \mid x\right)}} {\frac{P\left(y_i=K \mid x\right)}{P\left(y_i=K \mid x\right)}+\frac{\sum\limits_{l=1}^{K-1} P\left(y_i=l \mid x\right)}{P\left(y_i=K \mid x\right)}}\\\ &=\frac{e^{\beta_{k} ^{\top} x}}{1+\sum\limits_{l=1}^{K-1} e^{\beta_{l} ^{\top} x}} \end{aligned} \]

当\(k=K\)时,

\[ \begin{aligned} P\left(y_i=K \mid x\right)=\frac{1}{1+\sum_{l=1}^{K-1} e^{\beta_l ^{\top} x}} \end{aligned} \] 似然函数¶ \[ L(\theta)=\prod_{i=1}^n \prod_{k=1}^K P\left(y_i=k \mid x ; \theta\right)^{I\left(y_i=k\right)} \]

这里的\(I\left(y_i=k\right)\)作为示性函数放在指数部分,方便识别样本的观测值,也方便后续求导,因此是一个十分巧妙的办法。

目标函数(损失函数)¶

寻找最优参数\(\theta\),使得似然函数最大,即对数似然函数的相反数最小。

\[ \begin{aligned} l(\theta)=&-\log L(\theta) \\\ =&-\sum_{i=1}^n \sum_{k=1}^K I\left(y_i=k\right) \log P\left(y_{i}=k \mid x_{i; \theta}\right) \\\ =&-\sum_{i=1} ^n \left(\sum_{k=1}^{K-1} I\left(y_{i}=k\right)\left(\beta_k ^{\top} x_i-\log \left(1+\sum_{l=1}^{K-1} e^{\beta_l ^{\top} x_i}\right)\right)\right.\\\ &\left.+I\left(y_i=K\right)\left(-\log \left(1+\sum_{l=1}^{K-1} e^{\beta_l ^{\top} x_i}\right)\right)\right) \\\ =&-\sum_{i=1} ^n \left(\sum_{k=1}^{K-1} I\left(y_i=k\right) \beta_k ^{\top} x_i-\log \left(1+\sum_{l=1}^{K-1} e^{\beta_l ^{\top} x_i}\right) \sum_{k=1}^K I\left(y_i=k\right)\right) \\\ =& \sum_{i=1} ^n \left[-\sum_{k=1}^{K-1} I\left(y_i=k\right) \beta_k ^{\top} x_i+\log \left(1+\sum_{l=1}^{K-1} e^{\beta_l ^{\top} x_i}\right)\right] \end{aligned} \] 求梯度下降法的迭代公式¶

先将损失函数对\(\theta\)求导,对于\(k=1,2, \cdots, K-1\),有

\[ \begin{aligned} \frac{\partial l(\theta)}{\partial \beta_k} &=\sum_{i=1} ^n \left[-I\left(y_i=k\right) x_i+\frac{e^{\beta_k ^{\top} x_i} x_i}{1+\sum\limits_{l=1}^{K-1} e^{\beta_l ^{\top} x_i}}\right] \\\ &=\sum_{i=1} ^n \left(P\left(y_i=k \mid x\right)-I\left(y_i=k\right)\right) x_i \end{aligned} \]

因此,梯度下降法的迭代公式为

\[ \beta_{k}^{'}=\beta_k-\sum_{i=1}^n\left(P\left(y_i=k \mid x\right)-I\left(y_i=k\right)\right) x_i \] Python 实现多元逻辑回归¶ 导入相关包¶ Python# 导入数据处理相关的包 import pandas as pd import numpy as np from scipy import stats # 导入逻辑回归的包 from sklearn.linear_model import LogisticRegression as LR from sklearn.preprocessing import LabelEncoder from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score # 导入绘制循环进度条的包 from tqdm import tqdm # 忽略警告 import warnings warnings.filterwarnings("ignore") 导入数据¶ Python# 导入数据 data = pd.read_csv("letter_recognition.csv") # 划分特征和标签 X = data.iloc[:, 1:] y = data.iloc[:, :1] # 为字母进行编码 y = LabelEncoder().fit_transform(y.values.ravel()) # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.4, shuffle=False) # 提取唯一的标签 labels = np.unique(y_train) One vs. One 算法¶ Python# OvO count = 0 # 将预测值初始化为 0 y_pred = np.zeros((len(y_test), 1)) pbar = tqdm(range(len(labels))) for i in pbar: for j in range(i + 1, len(labels)): # 输出进度条 pbar.set_description("正在构建第{}_{}分类器".format(labels[i] + 1, labels[j] + 1)) count += 1 # 只使用属于第 i 类和第 j 类的样本训练模型 y_train_ = np.where( np.logical_or(y_train == labels[i], y_train == labels[j]), y_train, np.NAN ) X_train_ = X_train.iloc[~np.isnan(y_train_)] # 二元逻辑回归 globals()["LR_{}_{}".format(labels[i], labels[j])] = LR().fit( X_train_, y_train_[~np.isnan(y_train_)] ) # 测试集预测 globals()["y_pred_{}_{}".format(labels[i], labels[j])] = globals()[ "LR_{}_{}".format(labels[i], labels[j]) ].predict(X_test) # 合并预测结果 y_pred = np.append( y_pred, globals()["y_pred_{}_{}".format(labels[i], labels[j])].reshape(-1, 1), axis=1, ) print("一共构建了{}个分类器".format(count)) # 删除第一列的初始零值 y_pred = np.delete(y_pred, 0, axis=1) # 以所有分类器的分类结果的众数作为最终的预测结果 y_pred = np.squeeze(stats.mode(y_pred, axis=1)[0]) error_rate_OvO = 1 - accuracy_score(y_test, y_pred) # 查看预测结果 pd.DataFrame( np.append(y_pred.reshape(-1, 1), y_test.reshape(-1, 1), axis=1), columns=["预测值", "真实值"], dtype=int, )

One vs. Rest 算法¶ Python# OvR count = 0 # 将预测值初始化为 0 y_pred = np.zeros((len(y_test), 1)) pbar = tqdm(range(len(labels))) for i in pbar: # 输出进度条 pbar.set_description("正在构建第{}分类器".format(labels[i] + 1)) count += 1 # 只使用属于第 i 类和第 j 类的样本训练模型 y_train_ = np.where(y_train == labels[i], y_train, -1) # 二元逻辑回归 globals()["LR_{}".format(labels[i])] = LR().fit(X_train, y_train_) # 测试集预测 globals()["y_pred_{}".format(labels[i])] = globals()[ "LR_{}".format(labels[i]) ].predict_proba(X_test)[:, 1] # 合并预测结果 y_pred = np.append( y_pred, globals()["y_pred_{}".format(labels[i])].reshape(-1, 1), axis=1 ) print("一共构建了{}个分类器".format(count)) # 删除第一列的初始零值 y_pred = np.delete(y_pred, 0, axis=1) # 以所有分类器的分类概率的最大值对应的值作为最终的预测结果 y_pred = np.argmax(y_pred, axis=1) error_rate_OvR = 1 - accuracy_score(y_test, y_pred) # 查看预测结果 pd.DataFrame( np.append(y_pred.reshape(-1, 1), y_test.reshape(-1, 1), axis=1), columns=["预测值", "真实值"], dtype=int, )

直接构造多元逻辑回归模型¶ Python# 直接构造多元逻辑回归模型 # 多元逻辑回归 LR_multiclass = LR(multi_class="multinomial").fit(X_train, y_train) # 测试集预测 y_pred_multiclass = LR_multiclass.predict(X_test) error_rate_multiclass = 1 - accuracy_score(y_test, y_pred_multiclass) # 查看预测结果 pd.DataFrame( np.append(y_pred_multiclass.reshape(-1, 1), y_test.reshape(-1, 1), axis=1), columns=["预测值", "真实值"], dtype=int, )

比较三种方法的误差率¶ Python# 输出各方法的误差率 for method in ["OvO", "OvR", "multiclass"]: print(method + "的分类误差率{:.2%}".format(globals()["error_rate_" + method]), sep="")

比较三种方法的运行速度¶

OvO 需要构造\(\frac{K\times (K-1)}{2}\)个二元分类器,因此耗时较长(本例耗时 16 秒),但结果也更准确。

OvR 需要构造\(K\)个二元分类器,因此耗时较短(本例耗时 3 秒),但结果不如 OvO 准确。

评论


【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭