Scikit-learn 机器学习:经典算法与流水线
Scikit-learn 机器学习:经典算法与流水线
简介
Scikit-learn(简称 sklearn)是 Python 最流行的机器学习库,它封装了大量经典算法和模型评估工具,并提供了统一、简洁的 API 接口。无论是分类、回归还是聚类,只需几行代码即可完成从数据预处理到模型部署的全流程。本教程将以初学者视角,带你掌握核心算法的使用,并学会利用 Pipeline 构建高效的机器学习工作流。
确保你已安装 scikit-learn 以及常用依赖库:
pip install scikit-learn pandas numpy matplotlib
一、机器学习核心流程与 API 设计
Scikit-learn 中所有模型都遵循相同的设计模式:
- 导入对应的评估器(Estimator)类
- 实例化并设置超参数
- 调用
.fit()在训练集上学习 - 调用
.predict()或.transform()对新数据进行预测或转换
from sklearn.linear_model import LogisticRegression
model = LogisticRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
二、数据预处理与模型评估基础
真实数据往往包含缺失值、类别特征等,必须经过预处理才能喂给模型。Scikit-learn 提供了 SimpleImputer、StandardScaler、OneHotEncoder 等转换器,可与 train_test_split、cross_val_score 等评估方法无缝配合。
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.impute import SimpleImputer
# 分割数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 数值预处理:填补缺失值 + 标准化
imputer = SimpleImputer(strategy='mean')
scaler = StandardScaler()
X_train_imputed = imputer.fit_transform(X_train)
X_train_scaled = scaler.fit_transform(X_train_imputed)
注意:预处理器的 .fit() 必须只在训练集上执行,.transform() 再应用到测试集,避免数据泄露。
三、经典监督学习算法
3.1 分类算法
逻辑回归
虽然名字带有“回归”,但它是应用最广泛的二分类模型之一,通过 Sigmoid 函数输出概率。
from sklearn.linear_model import LogisticRegression
clf = LogisticRegression(penalty='l2', C=1.0)
clf.fit(X_train_scaled, y_train)
print('准确率:', clf.score(X_test_scaled, y_test))
决策树与随机森林
决策树易于解释,随机森林通过集成多棵树减少过拟合,性能更稳健。
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
dt = DecisionTreeClassifier(max_depth=3)
rf = RandomForestClassifier(n_estimators=100, max_depth=5)
rf.fit(X_train_scaled, y_train)
支持向量机(SVM)
SVM 通过寻找最大间隔超平面进行分类,核技巧使其能处理非线性问题。
from sklearn.svm import SVC
svm = SVC(kernel='rbf', C=1.0, gamma='scale')
svm.fit(X_train_scaled, y_train)
3.2 回归算法
线性回归
最为基础的回归模型,直接拟合特征与目标的线性关系。
from sklearn.linear_model import LinearRegression
reg = LinearRegression()
reg.fit(X_train_scaled, y_train)
y_pred = reg.predict(X_test_scaled)
随机森林回归
继承随机森林的抗过拟合能力,适用于复杂非线性回归任务。
from sklearn.ensemble import RandomForestRegressor
rf_reg = RandomForestRegressor(n_estimators=100, max_depth=5)
rf_reg.fit(X_train_scaled, y_train)
四、无监督学习:聚类
K-Means 是最经典的聚类算法,需要提前指定聚类数 k,通过迭代优化簇内的平方误差。
from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters=3, random_state=42)
kmeans.fit(X_scaled)
labels = kmeans.labels_
centers = kmeans.cluster_centers_
选择合适的 k 可使用肘部法则:
inertia = []
for k in range(1, 8):
model = KMeans(n_clusters=k, random_state=42)
model.fit(X_scaled)
inertia.append(model.inertia_)
# 绘制 inertia 随 k 的变化曲线,寻找“拐点”
五、模型流水线:Pipeline
在实际项目中,数据预处理和模型训练往往包含多个步骤。使用 Pipeline 可以将这些步骤封装为一个整体,避免代码重复并防止数据泄露。
5.1 构建流水线
Pipeline 由一系列 (名称, 转换器/评估器) 元组组成,最后一步通常为模型。
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder
# 假设有数值列和类别列
numeric_features = ['age', 'income']
categorical_features = ['gender', 'occupation']
numeric_transformer = Pipeline(steps=[
('imputer', SimpleImputer(strategy='median')),
('scaler', StandardScaler())
])
categorical_transformer = Pipeline(steps=[
('imputer', SimpleImputer(strategy='constant', fill_value='missing')),
('onehot', OneHotEncoder(handle_unknown='ignore'))
])
preprocessor = ColumnTransformer(
transformers=[
('num', numeric_transformer, numeric_features),
('cat', categorical_transformer, categorical_features)
])
# 组合预处理与最终模型
clf = Pipeline(steps=[
('preprocessor', preprocessor),
('classifier', RandomForestClassifier())
])
5.2 训练与评估
Pipeline 的使用和单个模型完全一样,支持 .fit()、.predict()、.score()。
clf.fit(X_train, y_train)
print('测试集准确率:', clf.score(X_test, y_test))
5.3 流水线中的交叉验证与网格搜索
Pipeline 还可以与 GridSearchCV 结合,实现一站式超参数调节。
from sklearn.model_selection import GridSearchCV
param_grid = {
'classifier__n_estimators': [50, 100, 200],
'classifier__max_depth': [None, 5, 10]
}
grid = GridSearchCV(clf, param_grid, cv=5)
grid.fit(X_train, y_train)
print('最佳参数:', grid.best_params_)
注意:参数名需加上 步骤名称__参数 的前缀。
六、完整示例:从原始数据到最终预测
下面用一个简化的泰坦尼克号数据集演示完整流程。
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.impute import SimpleImputer
# 加载数据(示例)
df = pd.read_csv('titanic.csv')
X = df.drop('Survived', axis=1)
y = df['Survived']
# 定义特征列类型
num_cols = ['Age', 'Fare']
cat_cols = ['Sex', 'Embarked', 'Pclass']
# 预处理管道
num_pipe = Pipeline([('imputer', SimpleImputer(strategy='median')),
('scaler', StandardScaler())])
cat_pipe = Pipeline([('imputer', SimpleImputer(strategy='most_frequent')),
('onehot', OneHotEncoder(handle_unknown='ignore'))])
preprocessor = ColumnTransformer([('num', num_pipe, num_cols),
('cat', cat_pipe, cat_cols)])
# 完整 pipeline
pipeline = Pipeline([('prep', preprocessor),
('clf', RandomForestClassifier(random_state=42))])
# 拆分数据
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 训练并评估
pipeline.fit(X_train, y_train)
print(f'准确率: {pipeline.score(X_test, y_test):.3f}')
输出预测结果:
predictions = pipeline.predict(X_test)
七、总结与最佳实践
- 统一 API:所有模型遵循
fit/predict(或transform)接口,方便切换和对比。 - 防止数据泄露:务必在
ColumnTransformer或Pipeline内完成预处理,并对训练集执行.fit()。 - 从小模型开始:先用简单模型(如逻辑回归)建立基线,再尝试复杂模型(随机森林、SVM)。
- 超参数调优:利用
GridSearchCV或RandomizedSearchCV自动搜索最佳参数。 - 持久化模型:使用
joblib保存训练好的 pipeline:import joblib joblib.dump(pipeline, 'model.pkl') # 加载 pipeline = joblib.load('model.pkl')
掌握了这些经典算法和流水线技巧,你已具备解决大部分结构化数据机器学习任务的能力。随着经验增长,可以进一步探索特征工程、集成方法、模型解释等高级话题。