共计 2378 个字符,预计需要花费 6 分钟才能阅读完成。
从房价预测看泛化能力
假设我们要建立一个预测房价的模型。用历史数据训练后,模型在训练集上误差很低,但实际预测新房子价格时却偏差很大——这就是典型的 泛化能力差。好比学生死记硬背例题却不会举一反三,机器学习模型也需要学会从训练数据中提取通用规律。

过拟合 vs 欠拟合:模型的两难困境
-
过拟合(高方差):模型复杂到连训练数据中的噪声都记住了。表现为训练误差极低但测试误差高,就像用显微镜看数据反而看不清全貌。数学上对应模型权重值过大。
-
欠拟合(高偏差):模型过于简单,连基本规律都没学会。训练和测试误差都较高,好比用老花眼看数据——模糊一片。
# 可视化示例
import matplotlib.pyplot as plt
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
# 生成演示数据
X = np.linspace(0, 10, 20)
y = np.sin(X) + np.random.normal(0, 0.2, 20)
# 不同复杂度模型对比
models = [make_pipeline(PolynomialFeatures(1), LinearRegression()), # 欠拟合
make_pipeline(PolynomialFeatures(3), LinearRegression()), # 适中
make_pipeline(PolynomialFeatures(15), LinearRegression()) # 过拟合
]
plt.figure(figsize=(12, 4))
for i, model in enumerate(models, 1):
model.fit(X[:, None], y)
plt.subplot(1, 3, i)
plt.scatter(X, y, s=20)
plt.plot(X_test, model.predict(X_test[:, None]), c='r')
plt.title(f'Degree {model.steps[0][1].degree}')
正则化实战:Ridge 回归示例
通过 L2 正则化(权重衰减)控制过拟合,让模型权重不会变得过大:
from sklearn.linear_model import Ridge
# 带类型注解的工业级实现
def train_ridge(X: np.ndarray, y: np.ndarray, alpha: float = 1.0) -> Ridge:
"""
:param alpha: 正则化强度,越大表示惩罚越重
:return: 训练好的 Ridge 模型
"""
model = Ridge(alpha=alpha)
model.fit(X, y)
return model
# 对比不同 alpha 值的影响
alphas = [0, 1, 100]
coefs = []
for a in alphas:
ridge = train_ridge(X_train, y_train, alpha=a)
coefs.append(ridge.coef_)
# 绘制权重变化
plt.plot(alphas, coefs)
plt.xscale('log')
plt.xlabel('Alpha (log scale)')
plt.ylabel('Coefficients')
特征工程两大核心技巧
1. One-Hot 编码处理类别特征
直接将字符串类别转为数值会导致模型误判顺序关系:
from sklearn.preprocessing import OneHotEncoder
# 错误示范:直接 LabelEncoder
# encoder = LabelEncoder() # 会生成 0,1,2... 的伪数值关系
# 正确做法
encoder = OneHotEncoder(sparse=False)
housing_type = encoder.fit_transform(df[['house_type']])
2. 特征缩放提升 SVM 性能
不同量纲的特征会导致距离计算失衡:
from sklearn.svm import SVR
from sklearn.preprocessing import StandardScaler
# 注意防止数据泄漏!先拆分再缩放
X_train, X_test = train_test_split(X, test_size=0.2)
scaler = StandardScaler().fit(X_train) # 只用训练集统计量
svm = SVR(kernel='rbf').fit(scaler.transform(X_train), y_train)
# 测试集同样用训练集的 scaler
y_pred = svm.predict(scaler.transform(X_test))
生产环境最佳实践
-
数据划分:小数据按 6:2:2(训练: 验证: 测试),大数据可调整验证集比例
-
早停法实现:监控验证集损失,提前终止训练
from tensorflow.keras.callbacks import EarlyStopping
es = EarlyStopping(
monitor='val_loss',
patience=5, # 允许 5 轮不提升
restore_best_weights=True
)
model.fit(X_train, y_train,
validation_data=(X_val, y_val),
callbacks=[es],
epochs=100)
思考与进阶
当特征维度(如 1000 维)远大于样本量(如 100 个)时:
– 优先选择L1 正则化(Lasso),因为它会产生稀疏解自动做特征选择
– 此时 L2 正则化会使所有特征都保留微小权重,反而降低可解释性
下次可以试试用 Lasso 回归处理高维基因数据,观察权重矩阵的稀疏性变化!
正文完
