监督学习 — 分类算法
逻辑回归 (Logistic Regression)
尽管名字包含"回归",逻辑回归实际上是最经典的二分类算法。它通过 sigmoid 函数将线性组合映射到 [0,1] 区间,输出概率值。模型简单、可解释性强,训练速度极快,适合作为分类问题的基线模型。在特征工程做得好的情况下,逻辑回归往往能取得出乎意料的好效果。
优点:训练快、可解释、不易过拟合、输出概率
缺点:只能学习线性决策边界、复杂关系需手动特征工程
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
model = LogisticRegression(max_iter=1000)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
print(f"Accuracy: {accuracy_score(y_test, y_pred):.4f}")
适用场景:二分类基线、信用评分、广告点击预测、特征效应分析。
决策树 (Decision Tree)
决策树通过递归地将数据按特征值分裂来构建树结构,每个叶节点对应一个预测类别。使用信息增益(ID3)、增益率(C4.5)或基尼不纯度(CART)来选择最优分裂特征。决策树直观易懂,可以直接可视化,但容易过拟合,通常需要剪枝或结合集成方法使用。
优点:可解释性极强、无需标准化、可处理混合类型特征
缺点:容易过拟合、对数据变化敏感、决策边界为轴对齐
from sklearn.tree import DecisionTreeClassifier
model = DecisionTreeClassifier(max_depth=5, min_samples_leaf=10)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
print(f"Accuracy: {accuracy_score(y_test, y_pred):.4f}")
适用场景:需要可解释性的业务决策、特征重要性分析、规则提取。
随机森林 (Random Forest)
随机森林是 Bagging 策略的经典实现:通过训练多棵决策树并取多数投票来进行预测。每棵树使用随机采样的数据子集和特征子集,有效降低方差和过拟合风险。随机森林是实践中最常用的算法之一,开箱即用效果好,对超参数不太敏感,且能提供特征重要性评估。
优点:精度高、不易过拟合、可并行训练、提供特征重要性
缺点:模型较大、推理较慢、可解释性不如单棵决策树
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier(n_estimators=100, max_depth=10, random_state=42)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
print(f"Accuracy: {accuracy_score(y_test, y_pred):.4f}")
print(f"Feature importances: {model.feature_importances_}")
适用场景:通用分类任务、特征选择、缺少领域知识时的首选算法。
支持向量机 (SVM)
SVM 通过寻找最大间隔超平面来分割不同类别的数据点。使用核技巧(如 RBF、多项式核)可以在高维空间中处理非线性可分问题。SVM 在中小规模数据集上表现优异,泛化能力强,但在大数据集上训练较慢,且对特征缩放敏感。
优点:高维空间表现好、泛化能力强、核技巧处理非线性
缺点:大数据训练慢、对缩放敏感、不直接输出概率
from sklearn.svm import SVC
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train_s = scaler.fit_transform(X_train)
X_test_s = scaler.transform(X_test)
model = SVC(kernel='rbf', C=1.0, gamma='scale')
model.fit(X_train_s, y_train)
y_pred = model.predict(X_test_s)
print(f"Accuracy: {accuracy_score(y_test, y_pred):.4f}")
适用场景:文本分类、图像分类、生物信息学、中小规模高维数据。
K-近邻 (KNN)
KNN 是最直观的分类算法:对于待预测样本,找到训练集中距离最近的 K 个邻居,以多数投票决定类别。KNN 属于惰性学习(lazy learning),不需要训练过程,但预测时需遍历所有训练数据,因此在大数据集上效率较低。距离度量的选择和 K 值对结果影响很大。
优点:无需训练、直觉简单、天然支持多分类
缺点:预测慢、维度灾难、对噪声敏感、需特征缩放
from sklearn.neighbors import KNeighborsClassifier
model = KNeighborsClassifier(n_neighbors=5, metric='minkowski')
model.fit(X_train_s, y_train)
y_pred = model.predict(X_test_s)
print(f"Accuracy: {accuracy_score(y_test, y_pred):.4f}")
适用场景:推荐系统原型、小数据集快速验证、异常检测辅助。
朴素贝叶斯 (Naive Bayes)
朴素贝叶斯基于贝叶斯定理,假设特征之间条件独立。尽管这个假设在现实中很少完全成立,但该算法在文本分类(垃圾邮件过滤、情感分析)中表现出色。训练和预测速度极快,在高维稀疏数据上表现良好,适合作为 NLP 任务的基线模型。
优点:极快速、高维稀疏数据表现好、少量数据也有效
缺点:条件独立假设过强、连续特征处理不理想
from sklearn.naive_bayes import MultinomialNB
from sklearn.feature_extraction.text import TfidfVectorizer
vectorizer = TfidfVectorizer(max_features=5000)
X_train_v = vectorizer.fit_transform(X_train_text)
X_test_v = vectorizer.transform(X_test_text)
model = MultinomialNB(alpha=1.0)
model.fit(X_train_v, y_train)
y_pred = model.predict(X_test_v)
print(f"Accuracy: {accuracy_score(y_test, y_pred):.4f}")
适用场景:文本分类、垃圾邮件过滤、情感分析、实时分类系统。
梯度提升 (XGBoost / LightGBM)
梯度提升通过顺序训练弱学习器(通常是决策树),每一轮新模型拟合前一轮的残差,逐步减少预测误差。XGBoost 和 LightGBM 是两种高效实现,在 Kaggle 竞赛和工业界广泛应用。XGBoost 使用二阶泰勒展开优化,LightGBM 使用直方图和 GOSS 采样加速训练。这是表格数据上表现最好的算法类型之一。
优点:精度极高、内置正则化、处理缺失值、特征重要性
缺点:超参数较多、训练较慢、可能过拟合小数据
import xgboost as xgb
model = xgb.XGBClassifier(
n_estimators=200, max_depth=6, learning_rate=0.1,
subsample=0.8, colsample_bytree=0.8, random_state=42
)
model.fit(X_train, y_train, eval_set=[(X_test, y_test)], verbose=False)
y_pred = model.predict(X_test)
print(f"Accuracy: {accuracy_score(y_test, y_pred):.4f}")
# LightGBM alternative
import lightgbm as lgb
model_lgb = lgb.LGBMClassifier(n_estimators=200, learning_rate=0.1)
model_lgb.fit(X_train, y_train)
适用场景:表格数据竞赛、金融风控、推荐系统排序、CTR 预估。
监督学习 — 回归算法
线性回归 (Linear Regression)
线性回归通过最小二乘法拟合特征与目标变量之间的线性关系。它是回归问题的基线模型,简单高效且可解释性强。模型输出每个特征的系数,直观展示特征对目标的影响方向和强度。
优点:训练极快、可解释、数学基础扎实
缺点:只能拟合线性关系、对异常值敏感
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
model = LinearRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
print(f"MSE: {mean_squared_error(y_test, y_pred):.4f}")
print(f"R2: {r2_score(y_test, y_pred):.4f}")
print(f"Coefficients: {model.coef_}")
适用场景:价格预测基线、趋势分析、经济学建模。
Ridge / Lasso 回归
Ridge(L2 正则化)和 Lasso(L1 正则化)在线性回归的基础上增加了正则化项来防止过拟合。Ridge 倾向于缩小所有系数但不会置零,适合特征间存在多重共线性的情况。Lasso 可以将部分系数压缩为零,实现自动特征选择。ElasticNet 结合了两者的优点。
优点:防止过拟合、Lasso 自动特征选择、处理多重共线性
缺点:仍限于线性关系、需调节正则化强度 alpha
from sklearn.linear_model import Ridge, Lasso, ElasticNet
ridge = Ridge(alpha=1.0).fit(X_train, y_train)
lasso = Lasso(alpha=0.1).fit(X_train, y_train)
enet = ElasticNet(alpha=0.1, l1_ratio=0.5).fit(X_train, y_train)
# Lasso 自动特征选择:系数为 0 的特征被剔除
print(f"Lasso non-zero features: {(lasso.coef_ != 0).sum()}")
适用场景:高维数据回归、特征选择、存在共线性的数据集。
决策树回归 (Decision Tree Regression)
决策树回归使用与分类树类似的递归分裂策略,但在叶节点输出连续值(通常为该区域内目标变量的均值)。能够捕捉非线性关系,无需特征缩放,但同样面临过拟合风险。
优点:捕捉非线性、无需缩放、直观
缺点:易过拟合、预测不连续(阶梯状)
from sklearn.tree import DecisionTreeRegressor
model = DecisionTreeRegressor(max_depth=8, min_samples_leaf=20)
model.fit(X_train, y_train)
print(f"R2: {model.score(X_test, y_test):.4f}")
随机森林回归 (Random Forest Regression)
随机森林回归集成多棵决策回归树,取所有树预测值的平均。继承了随机森林抗过拟合的优势,是回归任务中最可靠的选择之一,尤其适合中等规模数据集。
优点:精度高、鲁棒、特征重要性评估
缺点:无法外推(预测值不超出训练范围)、模型大
from sklearn.ensemble import RandomForestRegressor
model = RandomForestRegressor(n_estimators=100, max_depth=12, random_state=42)
model.fit(X_train, y_train)
print(f"R2: {model.score(X_test, y_test):.4f}")
支持向量回归 (SVR)
SVR 将 SVM 的思想扩展到回归问题,通过定义 epsilon 不敏感损失函数,在误差管内不施加惩罚。使用核技巧可以拟合复杂的非线性关系,在中小规模数据上效果好。
优点:核技巧处理非线性、鲁棒、泛化好
缺点:大数据慢、需缩放、超参数调优困难
from sklearn.svm import SVR
model = SVR(kernel='rbf', C=100, epsilon=0.1)
model.fit(X_train_s, y_train)
print(f"R2: {model.score(X_test_s, y_test):.4f}")
无监督学习 — 聚类算法
K-Means
K-Means 是最常用的聚类算法,通过迭代将数据分为 K 个簇,使每个样本到其所属簇中心的距离最小。算法简单高效,适合球形簇结构的数据。需要预先指定 K 值,可通过肘部法则或轮廓系数选择最优 K。
优点:简单高效、可扩展到大数据集
缺点:需预设 K、只能发现球形簇、对初始化和异常值敏感
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
# 肘部法则选 K
inertias = []
for k in range(2, 11):
km = KMeans(n_clusters=k, random_state=42, n_init=10)
km.fit(X_scaled)
inertias.append(km.inertia_)
# 最终模型
model = KMeans(n_clusters=4, random_state=42, n_init=10)
labels = model.fit_predict(X_scaled)
print(f"Silhouette Score: {silhouette_score(X_scaled, labels):.4f}")
DBSCAN
DBSCAN(基于密度的空间聚类)通过定义核心点、边界点和噪声点,自动发现任意形状的簇。无需预设簇数 K,能自动识别噪声点(异常值)。参数 eps(邻域半径)和 min_samples(最小样本数)对结果影响很大。
优点:无需预设 K、发现任意形状簇、自动识别噪声
缺点:对参数敏感、不适合密度差异大的数据
from sklearn.cluster import DBSCAN
model = DBSCAN(eps=0.5, min_samples=5)
labels = model.fit_predict(X_scaled)
n_clusters = len(set(labels)) - (1 if -1 in labels else 0)
n_noise = (labels == -1).sum()
print(f"Clusters: {n_clusters}, Noise points: {n_noise}")
层次聚类 (Hierarchical Clustering)
层次聚类构建簇的树形结构(树状图),可以自底向上(凝聚)或自顶向下(分裂)。通过树状图可以直观选择合适的簇数。不需要预设 K,但计算复杂度为 O(n^3),不适合大规模数据。
优点:无需预设 K、可视化树状图、灵活的距离度量
缺点:计算复杂度高、不可逆(凝聚过程无法撤销)
from sklearn.cluster import AgglomerativeClustering
model = AgglomerativeClustering(n_clusters=4, linkage='ward')
labels = model.fit_predict(X_scaled)
print(f"Silhouette Score: {silhouette_score(X_scaled, labels):.4f}")
降维算法
主成分分析 (PCA)
PCA 通过正交变换将数据投影到方差最大的方向上,从而减少特征维度。保留数据中最重要的信息(解释方差最大的成分),广泛用于数据可视化、噪声过滤和加速后续模型训练。PCA 是线性降维方法,适合数据呈线性结构的情况。
优点:高效、去噪、消除多重共线性
缺点:只能捕捉线性结构、成分可解释性差
from sklearn.decomposition import PCA
import numpy as np
pca = PCA(n_components=0.95) # 保留 95% 方差
X_reduced = pca.fit_transform(X_scaled)
print(f"Original dims: {X_scaled.shape[1]}")
print(f"Reduced dims: {X_reduced.shape[1]}")
print(f"Explained variance: {np.sum(pca.explained_variance_ratio_):.4f}")
t-SNE
t-SNE 是一种非线性降维方法,特别擅长将高维数据可视化到 2D 或 3D 空间中。它通过保持数据点之间的局部相似性结构来创建低维表示。t-SNE 主要用于探索性数据分析和可视化,不适合用于特征工程或降维后接后续模型。
优点:可视化效果优秀、保持局部结构
缺点:计算慢、不确定性(每次运行结果不同)、不适合降维后建模
from sklearn.manifold import TSNE
tsne = TSNE(n_components=2, perplexity=30, random_state=42)
X_2d = tsne.fit_transform(X_scaled)
# 通常接下来用 matplotlib 可视化
# plt.scatter(X_2d[:, 0], X_2d[:, 1], c=labels, cmap='tab10')
模型评估指标
分类指标
准确率 (Accuracy):正确预测数 / 总样本数。Accuracy = (TP + TN) / (TP + TN + FP + FN)
适用于类别平衡的数据集。
精确率 (Precision):预测为正的样本中实际为正的比例。Precision = TP / (TP + FP)
关注"预测正确的成本"时使用,如垃圾邮件过滤。
召回率 (Recall):实际为正的样本中被正确预测的比例。Recall = TP / (TP + FN)
关注"漏检成本"时使用,如疾病诊断。
F1 分数:精确率和召回率的调和平均。F1 = 2 * Precision * Recall / (Precision + Recall)
类别不平衡时比准确率更有意义。
AUC-ROC:ROC 曲线下面积,衡量模型在所有阈值下的分类能力。AUC = 1 表示完美分类,0.5 表示随机猜测
不受分类阈值影响,适合比较不同模型。
from sklearn.metrics import (accuracy_score, precision_score, recall_score,
f1_score, roc_auc_score, classification_report)
print(classification_report(y_test, y_pred))
print(f"AUC-ROC: {roc_auc_score(y_test, y_prob[:, 1]):.4f}")
回归指标
MSE (均方误差):MSE = (1/n) * sum((y_true - y_pred)^2)
对大误差惩罚更重。
RMSE (均方根误差):RMSE = sqrt(MSE)
与目标变量同单位,更易解读。
MAE (平均绝对误差):MAE = (1/n) * sum(|y_true - y_pred|)
对异常值不敏感。
R^2 (决定系数):R^2 = 1 - SS_res / SS_tot
表示模型解释的方差比例。1.0 = 完美拟合,0 = 等同于预测均值。
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
import numpy as np
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
mae = mean_absolute_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print(f"MSE: {mse:.4f} | RMSE: {rmse:.4f} | MAE: {mae:.4f} | R2: {r2:.4f}")
常见问题 (FAQ)
Q: 如何选择分类还是回归算法?
如果目标变量是离散类别(如"是/否"、"猫/狗/鸟"),使用分类算法;如果目标变量是连续数值(如"房价"、"温度"),使用回归算法。有时可以将连续值离散化后使用分类算法,或将类别编码为数值后使用回归算法,但通常不推荐。
Q: 随机森林和 XGBoost 哪个更好?
没有绝对的优劣。随机森林更简单、超参数更少、不易过拟合,适合快速建模;XGBoost/LightGBM 通常精度更高但需要更多调参。实际项目中建议两者都尝试,通过交叉验证比较。在 Kaggle 竞赛中,梯度提升方法通常表现更好。
Q: 什么时候需要做特征缩放(标准化/归一化)?
基于距离的算法(KNN、SVM、K-Means)和梯度下降优化的模型(逻辑回归、神经网络)需要特征缩放。树模型(决策树、随机森林、XGBoost)不需要特征缩放,因为它们基于特征值的排序来分裂节点。
Q: 数据量小时应该选什么算法?
小数据集(<1000 样本)推荐:SVM(泛化好)、朴素贝叶斯(少量数据也有效)、KNN(简单直接)。避免使用深度学习和复杂集成方法,容易过拟合。同时注意使用交叉验证而非简单的训练/测试划分来评估模型。
Q: 如何处理类别不平衡问题?
常用策略包括:1) 过采样少数类(SMOTE);2) 欠采样多数类;3) 调整类别权重(class_weight='balanced');4) 使用 F1/AUC-ROC 而非准确率作为评估指标;5) 使用集成方法如 BalancedRandomForest。选择策略取决于数据量和不平衡程度。