Skip to content

监督学习:回归与分类 ​

核心:用「已知答案」的数据,反推出从特征到答案的映射。

监督学习占工业落地的 80%。这篇给出四类主力算法的心智模型、适用场景与最小代码。

一张表选算法 ​

算法类型核心思想何时首选弱点
线性回归回归找一条直线/超平面拟合需要可解释性、基线只能表达线性关系
逻辑回归分类线性打分 + sigmoid 压到 0–1二分类基线、需要概率边界是线性的
决策树两者一系列 if-else 切分空间需要规则可解释极易过拟合
KNN两者看最近的 K 个邻居投票小数据、无训练成本预测慢、怕维度高
SVM两者找最大间隔的分界面中小数据、高维稀疏大数据慢、调核麻烦

默认起手式:先 逻辑回归 / 线性回归 做基线,再上树模型。

一、回归:预测一个连续数 ​

线性回归 ​

$$\hat y = w_1x_1 + w_2x_2 + \dots + b$$

python
from sklearn.linear_model import Ridge
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import make_pipeline
from sklearn.metrics import mean_absolute_error, r2_score

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

model = make_pipeline(StandardScaler(), Ridge(alpha=1.0))
model.fit(X_train, y_train)

pred = model.predict(X_test)
print(f"MAE={mean_absolute_error(y_test, pred):.3f}  R²={r2_score(y_test, pred):.3f}")
变体加的正则效果
LinearRegression无容易过拟合
Ridge (L2)$\lambda\sum w^2$权重变小,默认选它
Lasso (L1)$\lambda\sum\lvert w\rvert$部分权重变 0,可做特征选择
ElasticNetL1 + L2介于两者之间

为什么用 pipeline

make_pipeline(StandardScaler(), model) 保证缩放只在训练集上 fit,预测时用同一套参数。手写 scaler.fit(X) 在合并数据上做,就是典型的数据泄漏。

回归任务的三个坑 ​

坑表现处理
目标偏态少数极大值主导损失对 y 取 log(预测后 exp 回来)
异常值MAE 正常但 RMSE 爆炸检查并处理异常,或改用 MAE/Huber
只看 R²R²=0.95 但业务不可用一定要看 MAE 的实际量级是否可接受

二、分类:预测一个类别 ​

逻辑回归(名字叫回归,其实是分类) ​

$$p = \sigma(w^\top x + b) = \frac{1}{1+e^{-(w^\top x+b)}}$$

输出是概率,用 0.5(或业务最优阈值)判类。

python
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report, roc_auc_score

clf = make_pipeline(StandardScaler(), LogisticRegression(max_iter=1000, class_weight="balanced"))
clf.fit(X_train, y_train)

proba = clf.predict_proba(X_test)[:, 1]
print(classification_report(y_test, proba > 0.5, digits=3))
print(f"AUC={roc_auc_score(y_test, proba):.3f}")

class_weight="balanced" 处理类别不平衡 —— 比上采样稳定得多。

为什么它至今仍是首选基线:训练快、输出概率、系数直接可解释(「该特征每增加 1 单位,对数几率增加 w」)。

决策树 ​

python
from sklearn.tree import DecisionTreeClassifier, export_text

tree = DecisionTreeClassifier(max_depth=4, min_samples_leaf=20, random_state=42)
tree.fit(X_train, y_train)
print(export_text(tree, feature_names=list(X.columns), max_depth=3))

它真正的价值是可解释性:能把规则打印出来给业务方看。但几乎不要在最终模型里用单棵树 —— 换成随机森林/GBDT,见 集成学习。

控制过拟合的三个旋钮:

参数作用建议
max_depth树的最大深度3–10,从 4 起调
min_samples_leaf叶子最少样本数20–100
min_samples_split分裂最少样本数常与上一个配合

KNN ​

python
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler

knn = make_pipeline(StandardScaler(), KNeighborsClassifier(n_neighbors=5, weights="distance"))
knn.fit(X_train, y_train)

必须标准化,否则距离被量纲大的特征主导。适合小数据、低维、无训练时间要求(比如推荐召回)。

SVM ​

python
from sklearn.svm import SVC
svm = make_pipeline(StandardScaler(), SVC(kernel="rbf", C=1.0, gamma="scale", probability=True))

在中小规模、高维稀疏(文本 TF-IDF)场景依然很强。数据超 10 万行就换树模型。

三、特征工程:收益最大的一步 ​

类型手法说明
缺失中位数/众数/「未知」类别见 L1 清洗
数值缩放StandardScaler / MinMax线性模型、KNN、SVM、神经网络必须;树模型不需要
类别编码One-Hot(低基数);目标编码(高基数)目标编码必须用 CV 内均值,否则泄漏
偏态log1p / Box-Cox房价、收入这类长尾特征
派生特征比率、差值、时间间隔、聚合统计收益往往最大
分箱等频分箱 + One-Hot捕捉非线性、抗异常
特征选择方差过滤、互信息、L1、树的重要性降维、降过拟合

派生特征的例子(比调参有用得多):

python
df["price_per_sqm"] = df["price"] / df["area"]
df["days_since_signup"] = (df["order_date"] - df["signup_date"]).dt.days
df["avg_30d"] = df.groupby("user_id")["amount"].transform(
    lambda s: s.rolling("30D").mean())

四、训练循环:不要一次上大模型 ​

推荐的自上而下顺序:

轮次做什么目的
0常数基线(预测众数/均值)建立下限,防止后面自欺
1逻辑/线性回归建立可解释基线
2随机森林看非线性是否带来收益
3LightGBM / XGBoost通常到这里就接近上限
4特征工程迭代真正的分数来源
5融合 / 调参边际收益递减,注意过拟合验证集

通过标准 ​

下一步 ​

→ 模型评估:先学会判断模型好坏,再谈提升

AI 学习路线 · 从入门到专家