共计 2136 个字符,预计需要花费 6 分钟才能阅读完成。
核心概念
逻辑回归虽然名字里有 ” 回归 ”,但实际上是一种分类算法。其核心是通过 sigmoid 函数将线性回归的输出映射到 (0,1) 区间:

$$
\sigma(z) = \frac{1}{1+e^{-z}}
$$
其中 $z=w^Tx+b$。在 Anaconda 生态中,scikit-learn 提供了高效的实现,特别适合与 pandas、numpy 等库配合使用。
损失函数采用交叉熵损失:
$$
J(w) = -\frac{1}{m}\sum_{i=1}^m [y^{(i)}\log h(x^{(i)}) + (1-y^{(i)})\log(1-h(x^{(i)}))]
$$
痛点分析
- 数据尺度差异:当特征量纲差异大时(如年龄和收入),模型收敛困难且特征重要性评估失真
- 类别不平衡:正负样本比例悬殊时,准确率指标会严重失真(如 99% 负样本时全部预测为负也有 99% 准确率)
- 正则化陷阱:L2 正则化与独热编码结合时容易导致某些特征被过度惩罚
技术方案
环境配置
conda create -n logistic_reg python=3.8
conda install -c conda-forge scikit-learn=1.0 pandas matplotlib seaborn
特征缩放对比
from sklearn.preprocessing import StandardScaler, RobustScaler
# StandardScaler 对异常值敏感
scaler_std = StandardScaler()
X_train_std = scaler_std.fit_transform(X_train)
# RobustScaler 使用中位数和四分位数,更适合有异常值的数据
scaler_robust = RobustScaler()
X_train_robust = scaler_robust.fit_transform(X_train)
参数调优模板
from sklearn.model_selection import GridSearchCV
from sklearn.linear_model import LogisticRegression
param_grid = {'C': [0.001, 0.01, 0.1, 1, 10],
'penalty': ['l1', 'l2'],
'solver': ['liblinear']
}
model = LogisticRegression(max_iter=1000)
grid = GridSearchCV(model, param_grid, cv=5, n_jobs=-1) # n_jobs=- 1 使用所有 CPU 核心
grid.fit(X_train_scaled, y_train)
完整代码示例
%%time
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
# 加载数据
data = load_breast_cancer()
X, y = data.data, data.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 特征工程
scaler = RobustScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# 建模
model = LogisticRegression(C=1, penalty='l2', solver='liblinear')
model.fit(X_train_scaled, y_train)
# 特征重要性可视化
coef = pd.Series(model.coef_[0], index=data.feature_names)
plt.figure(figsize=(10,6))
coef.sort_values().plot(kind='barh')
plt.title('Feature Importance')
plt.show()
生产建议
-
增量学习:当数据无法一次性加载时
model = LogisticRegression(warm_start=True) for chunk in pd.read_csv('big_data.csv', chunksize=1000): model.fit(chunk[features], chunk[target]) -
模型持久化:
from joblib import dump # 比 pickle 更安全高效 dump(model, 'model.joblib')
避坑指南
- 独热编码 + 正则化:
- 先进行特征缩放
-
考虑使用分组 Lasso
-
收敛警告 处理步骤:
- 检查特征尺度是否统一
- 增加 max_iter 参数
- 尝试不同的 solver(如 ’saga’)
延伸思考
- 当特征维度远大于样本量时(如文本分类),如何避免过拟合?
- 在实时预测场景下,如何实现模型的热更新?
- 对于多分类问题,OvR 和 multinomial 两种策略该如何选择?
正文完
发表至: 机器学习
五天前
