关键词:分类算法、Sigmoid、概率、线性决策边界
一、为什么会有逻辑回归?
我们先从直觉说起。
假如你想用程序判断:
这封邮件是不是垃圾邮件?
这个用户会不会流失?
这笔交易有没有欺诈风险?
这些问题都有一个共同点:
👉结果只有两类:是 / 否
你可能第一反应是:
用线性回归行不行?
答案是:不太行。
因为线性回归的输出是:
y=wTx+b
它的范围是负无穷到正无穷,
而我们想要的是一个0~1 之间的概率值。
于是,逻辑回归就登场了。
二、逻辑回归的核心思想
逻辑回归的思路非常简单,只有两步:
1️⃣ 先用线性回归算一个“分数”
2️⃣ 再用一个函数把这个分数“压扁”到 0~1
这个函数就是——Sigmoid 函数。
三、Sigmoid:把一切变成概率
Sigmoid 函数的公式是:
σ(z)=1+e−z1
它的图像长这样(想象一下):
1 ──────────────╮ │ 0.5 │ │ 0 ──────────────╯特点很关键:
输入越大,输出越接近 1
输入越小,输出越接近 0
中间是平滑的 S 形曲线
四、逻辑回归的完整公式
设:
z=w1x1+w2x2+⋯+wnxn+b
那么逻辑回归模型就是:
这里的含义是:
在给定特征 x 的情况下,样本属于“正类”的概率
例如:
y^=0.92→ 92% 可能是垃圾邮件
y^=0.03→ 几乎不是垃圾邮件
五、怎么分类?
逻辑回归本身输出的是概率,
分类规则通常是人为设定的:
如果 ŷ ≥ 0.5 → 类别 1 如果 ŷ < 0.5 → 类别 0对应回 z:
wᵀx + b ≥ 0 → 类别 1 wᵀx + b < 0 → 类别 0👉 这说明:逻辑回归的决策边界是线性的
(这是面试和考试高频点)
六、逻辑回归是怎么学习的?
逻辑回归不用“最小二乘法”,
而是用极大似然估计 或交叉熵损失:
直观理解就是:
预测对了 → 惩罚很小
预测错了 → 惩罚很大
错得离谱 → 惩罚爆炸式增长
然后通过梯度下降不断调整参数。
七、逻辑回归有什么优点?
✅输出概率,可解释性强
✅训练速度快,计算简单
✅不容易过拟合(参数少)
✅工业界非常常用
很多真实系统中:
信用评分
广告点击率预估
风控系统
底层都有逻辑回归的身影。
八、逻辑回归的局限性
❌ 只能处理线性可分问题
❌ 对特征工程依赖较大
❌ 多分类需要扩展(Softmax)
但话说回来:
在工业界,“简单可靠”往往比“复杂炫酷”更重要。
九、一句话总结
逻辑回归 = 线性回归 + Sigmoid,用来解决二分类问题,输出概率,用 0.5 作为分类阈值,决策边界是线性的。
十、从零实现一个逻辑回归(NumPy 版)
不调 sklearn,从 0 手写一个逻辑回归,并真正理解它在做什么
关键词:Sigmoid、交叉熵、梯度下降、纯 NumPy
10.1 我们要做什么?
我们要用Python + NumPy 实现:
Sigmoid 函数
损失函数(交叉熵)
梯度下降
预测函数
最终能用它来做二分类任务。
⚠️ 全程不依赖 sklearn 的LogisticRegression。
10.2 逻辑回归的数学回顾(极简版)
逻辑回归的核心公式:
y^=σ(wTx+b)
其中:
σ(z)=1+e−z1
损失函数(交叉熵):
L=−N1∑[ylog(y^)+(1−y)log(1−y^)]
梯度(记住结论即可):
∂w∂L=N1XT(y^−y)
∂b∂L=N1∑(y^−y)
10.3 准备数据(造一点简单数据)
我们用一个线性可分的小数据集:
import numpy as np # 特征 X = np.array([ [1.0, 2.0], [2.0, 1.0], [2.0, 3.0], [3.0, 2.0], ]) # 标签(0 或 1) y = np.array([0, 0, 1, 1])10.4 Step 1:实现 Sigmoid
def sigmoid(z): return 1 / (1 + np.exp(-z))✅ 把任意实数压缩到 (0, 1)
✅ 这就是“概率”的来源
10.5 Step 2:初始化参数
def initialize_parameters(n_features): w = np.zeros(n_features) b = 0.0 return w, b一开始什么都不懂,权重全设为 0。
10.6 Step 3:前向传播(预测概率)
def forward(X, w, b): z = np.dot(X, w) + b y_hat = sigmoid(z) return y_hat这里得到的y_hat就是:
每个样本属于类别 1 的概率
10.7 Step 4:计算损失(交叉熵)
def compute_loss(y, y_hat): m = y.shape[0] loss = -np.mean( y * np.log(y_hat + 1e-8) + (1 - y) * np.log(1 - y_hat + 1e-8) ) return loss✅ 加1e-8是为了防止 log(0)
✅ 损失越小,说明预测越准
10.8 Step 5:反向传播(算梯度)
def backward(X, y, y_hat): m = X.shape[0] dw = (1/m) * np.dot(X.T, (y_hat - y)) db = (1/m) * np.sum(y_hat - y) return dw, db这一步是逻辑回归的灵魂 👑
👉梯度告诉参数该怎么改
10.9 Step 6:梯度下降更新参数
def update_parameters(w, b, dw, db, lr=0.1): w = w - lr * dw b = b - lr * db return w, blr是学习率梯度下降的本质就是:
沿着损失下降最快的方向走一步
10.10 Step 7:训练逻辑回归
def train(X, y, epochs=1000, lr=0.1): w, b = initialize_parameters(X.shape[1]) for i in range(epochs): y_hat = forward(X, w, b) loss = compute_loss(y, y_hat) dw, db = backward(X, y, y_hat) w, b = update_parameters(w, b, dw, db, lr) if i % 200 == 0: print(f"Epoch {i}, Loss: {loss:.4f}") return w, b10.11 Step 8:用训练好的模型做预测
def predict(X, w, b, threshold=0.5): y_hat = forward(X, w, b) return (y_hat >= threshold).astype(int)10.12 跑起来!
w, b = train(X, y) y_pred = predict(X, w, b) print("预测结果:", y_pred) print("真实标签:", y)你会看到:
✅ 损失在不断下降
✅ 预测结果越来越准
10.13 这段代码说明了什么?
逻辑回归并不神秘
本质就是:
线性加权
Sigmoid
交叉熵
梯度下降
所谓“算法工程师”,很多时候就是在写这些循环。
最终总结:逻辑回归 = 线性模型 + Sigmoid + 交叉熵 + 梯度下降