逻辑回归
分类算法 - 逻辑回归
Section titled “分类算法 - 逻辑回归”逻辑回归简介
Section titled “逻辑回归简介”尽管名称中带有“回归”,但逻辑回归(Logistic Regression)是一种用于监督学习的基本分类算法。它主要用于预测输入属于特定类别或类别的概率。虽然它可以扩展到多类问题,但其最常见的应用是二元分类,其中目标变量只有两个可能的输出(例如,是/否,真/假,0/1)。
可以想象预测客户是否会点击广告(是/否),或者肿瘤是恶性还是良性(M/B)。逻辑回归对“正”类(通常表示为 1)发生的概率进行建模。
与预测连续值的线性回归不同,逻辑回归使用一个特定的转换函数——逻辑函数(或 Sigmoid 函数)——将任何实数值输入(通常是特征的线性组合)映射到 0 到 1 之间的概率值。
在数学上,它将概率 P(Y=1 | X) 建模为输入特征 X 的函数。
Sigmoid 函数
Section titled “Sigmoid 函数”逻辑回归的核心是 Sigmoid 函数:
σ(z) = 1 / (1 + e^(-z))
其中 z 是输入特征和权重的线性组合(类似于线性回归):z = θ₀ + θ₁x₁ + θ₂x₂ + ... + θ<0xE2><0x82><0x99>x<0xE2><0x82><0x99>(或向量表示法中的 z = Xθ)。
Sigmoid 函数将输出 z(范围从 -∞ 到 +∞)压缩到 (0, 1) 范围内。此输出可以解释为正类的估计概率。
为了进行类别预测,我们通常设定一个阈值(通常是 0.5)。如果预测概率 σ(z) 大于或等于阈值,我们将该实例分类为正类(1);否则,将其分类为负类(0)。
损失函数与优化
Section titled “损失函数与优化”为了训练模型(即,找到最优权重 θ),逻辑回归使用一个称为对数损失(Log Loss)(或二元交叉熵,Binary Cross-Entropy)的损失函数。该函数衡量预测概率与训练数据中实际类别标签(0 或 1)的匹配程度。
训练期间的目标是最小化此对数损失函数。这通常使用优化算法实现,如梯度下降(Gradient Descent)或更高级的方法(例如,L-BFGS,在库实现中常用),这些方法会迭代地调整权重 θ 以减少损失。
逻辑回归的类型
Section titled “逻辑回归的类型”根据目标类别的数量:
二元逻辑回归
Section titled “二元逻辑回归”最常见的类型,其中目标变量只有两个可能的输出(例如,0 或 1,垃圾邮件/非垃圾邮件,恶性/良性)。
多项逻辑回归
Section titled “多项逻辑回归”当目标变量有三个或更多无序(名义)的可能输出时使用,这意味着类别之间没有固有的排序(例如,将新闻文章分类为“体育”、“政治”、“科技”)。它对每个类别的概率进行建模。
序数逻辑回归
Section titled “序数逻辑回归”当目标变量有三个或更多有序(序数)的可能输出时使用,这意味着类别之间存在有意义的排序(例如,客户满意度评分,如“差”、“好”、“优秀”)。它考虑了排序关系。
Scikit-learn 的 LogisticRegression 类可以直接处理二元和多项情况。
逻辑回归的关键假设
Section titled “逻辑回归的关键假设”虽然逻辑回归相对稳健,但它依赖于某些假设以获得最佳性能:
- 二元结果: 对于二元逻辑回归,因变量必须是二元的。
- 观测独立性: 观测之间应该是相互独立的。
- 无严重多重共线性: 自变量之间不应高度相关。高度的多重共线性会增加方差,并使系数解释不可靠。
- 自变量与对数几率的线性关系: 假设自变量与结果的对数几率之间存在线性关系。违反此假设有时可以通过转换变量或添加交互项来解决。
- 大样本量: 逻辑回归通常需要足够大的样本量才能获得稳定可靠的系数估计。
特征缩放: 虽然不是严格的假设,但如果对特征进行缩放(例如,使用 StandardScaler 或 MinMaxScaler),性能(特别是训练期间的收敛速度)通常会显著提高。
使用 Scikit-learn 在 Python 中实现
Section titled “使用 Scikit-learn 在 Python 中实现”让我们使用 Scikit-learn 实现二元和多项逻辑回归。
1. 二元逻辑回归示例(Iris 数据集)
Section titled “1. 二元逻辑回归示例(Iris 数据集)”我们将使用 Iris 数据集,但将其修改为二元任务:分类花是“setosa”(类别 0)还是“非 setosa”(类别 1,合并了“versicolor”和“virginica”)。我们只使用前两个特征(花萼长度和宽度),以便于可视化(尽管原始教程的绘图已被移除)。
import numpy as npimport pandas as pdfrom sklearn.datasets import load_irisfrom sklearn.model_selection import train_test_splitfrom sklearn.preprocessing import StandardScalerfrom sklearn.linear_model import LogisticRegressionfrom sklearn.metrics import accuracy_score, classification_report, confusion_matrix
# --- Load and Prepare Data ---iris = load_iris()# Use only first two features for this exampleX = iris.data[:, :2]# Create binary target: 0 = setosa, 1 = not setosay = (iris.target != 0).astype(int)
feature_names = iris.feature_names[:2]target_names = ['setosa', 'not setosa']
# --- Split Data ---X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42, stratify=y)
# --- Scale Features ---scaler = StandardScaler()X_train_scaled = scaler.fit_transform(X_train)X_test_scaled = scaler.transform(X_test)
# --- Train Logistic Regression Model ---# C is the inverse of regularization strength; smaller values specify stronger regularization.model_binary = LogisticRegression(C=1.0, random_state=42, solver='liblinear')model_binary.fit(X_train_scaled, y_train)
# --- Make Predictions ---y_pred_binary = model_binary.predict(X_test_scaled)proba_binary = model_binary.predict_proba(X_test_scaled) # Get probabilities
# --- Evaluate Model ---print("-- Binary Logistic Regression (Iris: Setosa vs. Not Setosa) ---")accuracy_binary = accuracy_score(y_test, y_pred_binary)print(f"Accuracy: {accuracy_binary:.4f}")
print("\nConfusion Matrix:")print(confusion_matrix(y_test, y_pred_binary))
print("\nClassification Report:")print(classification_report(y_test, y_pred_binary, target_names=target_names))
# print("\nPredicted Probabilities (first 5):\n", proba_binary[:5])# Description: Shows the probability estimates for each class (setosa, not setosa) for the first 5 test samples.解释:此代码训练了一个二元逻辑回归模型。它加载 Iris 数据,将目标变量转换为二元形式,分割数据集,缩放特征,训练模型,预测类别和概率,并使用标准指标进行评估。输出显示了高准确率,表明模型能够根据花萼尺寸有效区分 setosa 和其他两个物种。
2. 多项逻辑回归示例(Digits 数据集)
Section titled “2. 多项逻辑回归示例(Digits 数据集)”现在,让我们使用 Digits 数据集,它有 10 个类别(数字 0-9),这使其成为一个多项分类问题。
import numpy as npfrom sklearn.datasets import load_digitsfrom sklearn.model_selection import train_test_splitfrom sklearn.preprocessing import StandardScalerfrom sklearn.linear_model import LogisticRegressionfrom sklearn.metrics import accuracy_score, classification_report, confusion_matrix
# --- Load Data ---digits = load_digits()X = digits.datay = digits.target
# --- Split Data ---# Using a larger test size as in the original exampleX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.4, random_state=1, stratify=y)
# --- Scale Features ---scaler = StandardScaler()X_train_scaled = scaler.fit_transform(X_train)X_test_scaled = scaler.transform(X_test)
# --- Train Multinomial Logistic Regression Model ---# Scikit-learn's LogisticRegression handles multinomial automatically# when multi_class='auto' or 'multinomial' (with appropriate solvers like 'lbfgs')# Using a solver suitable for multinomial like 'lbfgs'model_multi = LogisticRegression(multi_class='multinomial', solver='lbfgs', max_iter=5000, random_state=42)model_multi.fit(X_train_scaled, y_train)
# --- Make Predictions ---y_pred_multi = model_multi.predict(X_test_scaled)
# --- Evaluate Model ---print("\n--- Multinomial Logistic Regression (Digits Dataset) ---")accuracy_multi = accuracy_score(y_test, y_pred_multi)print(f"Accuracy: {accuracy_multi:.4f}")
# Confusion matrix is larger for multi-classprint("\nConfusion Matrix:")cm_multi = confusion_matrix(y_test, y_pred_multi)# print(cm_multi) # Can be large, maybe just print shape or specific partsprint(f"(Confusion Matrix Shape: {cm_multi.shape})")
print("\nClassification Report:")# Get target names as strings for the reporttarget_names_digits = [str(i) for i in digits.target_names]print(classification_report(y_test, y_pred_multi, target_names=target_names_digits))解释:此代码解决了一个多类问题。它加载 Digits 数据集,分割数据,缩放特征,并训练一个配置为多项分类(multi_class='multinomial',solver='lbfgs')的 LogisticRegression 模型。评估结果显示高准确率,并在分类报告中提供了每个类别的指标(precision, recall, f1-score),展示了模型识别手写数字的有效性。
逻辑回归是一种通用且易于解释的分类算法,可作为出色的基线模型,并且通常在线性可分或接近线性可分的数据上表现良好。其输出的概率在许多应用中也很有价值。
进一步阅读:https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression