Python基础系列课程
欢迎关注微信公众号
Scikit-learn(简称 sklearn)是 Python 中最流行、最广泛使用的机器学习库之一,建立在 NumPy、SciPy 和 Matplotlib 之上。
统一的 API 设计,所有模型都遵循 fit → predict 范式
涵盖分类、回归、聚类、降维等数十种经典算法
数据预处理、模型选择、评估指标一应俱全
官方文档丰富,社区活跃,学习曲线平缓
# 安装 sklearn
pip install scikit-learn
# 基本导入
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
将数据集划分为训练集和测试集,是机器学习流程的第一步。
from sklearn.model_selection import train_test_split
from sklearn import datasets
# 加载内置数据集
iris = datasets.load_iris()
X, y = iris.data, iris.target
# 划分数据集:测试集占 20%,设置随机种子保证可复现
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
print(f"训练集大小: {len(X_train)}, 测试集大小: {len(X_test)}")
# 输出: 训练集大小: 120, 测试集大小: 30
不同特征的量纲差异会影响模型性能,需要进行标准化处理。
将特征转换为均值为0、标准差为1的标准正态分布:
z = (x - μ) / σ
适用于数据近似正态分布的情况。
将特征缩放到 [0, 1] 范围:
x_scaled = (x - min) / (max - min)
适用于需要固定边界的情况。
from sklearn.preprocessing import StandardScaler, MinMaxScaler
# 标准化处理
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test) # 测试集用同样的参数转换
# 归一化处理
normalizer = MinMaxScaler()
X_train_norm = normalizer.fit_transform(X_train)
| 算法 | 类名 | 核心思想 | 适用场景 |
|---|---|---|---|
| K近邻 | KNeighborsClassifier | 物以类聚,找最近的K个邻居投票 | 小数据集,非线性边界 |
| 决策树 | DecisionTreeClassifier | 基于特征条件递归划分数据 | 需要可解释性 |
| 朴素贝叶斯 | GaussianNB | 基于贝叶斯定理,假设特征独立 | 文本分类、高维数据 |
| 逻辑回归 | LogisticRegression | 用Sigmoid函数拟合概率 | 二分类、概率输出 |
| SVM | SVC | 寻找最优超平面最大化间隔 | 高维数据、复杂边界 |
| 随机森林 | RandomForestClassifier | 多棵决策树集成投票 | 通用场景,抗过拟合 |
| 梯度提升 | GradientBoostingClassifier | 串行训练弱分类器,逐步修正 | 追求高精度 |
| AdaBoost | AdaBoostClassifier | 加权组合弱分类器 | 提升简单模型性能 |
"近朱者赤,近墨者黑" —— 一个样本的类别由其最相似的 K 个邻居的类别投票决定。
n_neighbors
:K 值,邻居个数(默认5)
weights
:权重,'uniform' 等权 / 'distance' 按距离加权
metric
:距离度量,'minkowski'、'euclidean'、'manhattan'
from sklearn.neighbors import KNeighborsClassifier
# 创建 KNN 分类器
knn = KNeighborsClassifier(n_neighbors=5, weights='uniform')
# 训练模型
knn.fit(X_train_scaled, y_train)
# 预测
y_pred = knn.predict(X_test_scaled)
# 预测概率
proba = knn.predict_proba(X_test_scaled[:3])
print(proba)
通过一系列if-else判断条件,像一棵树一样层层分叉,最终将样本分到某个叶子节点(类别)。
criterion
:划分标准,'gini'(基尼系数)或 'entropy'(信息熵)
max_depth
:树的最大深度,防止过拟合
min_samples_split
:节点再划分所需最小样本数
min_samples_leaf
:叶子节点最小样本数
from sklearn.tree import DecisionTreeClassifier
# 创建决策树
dt = DecisionTreeClassifier(
criterion='gini',
max_depth=5,
min_samples_split=10,
random_state=42
)
# 训练
dt.fit(X_train, y_train)
# 查看特征重要性
print("特征重要性:", dt.feature_importances_)
在特征空间中寻找一个超平面,使得两类样本之间的间隔(Margin)最大化。间隔越大,模型泛化能力越强。
SVM 的精髓在于核技巧,将低维不可分的数据映射到高维空间:
linear
:线性核,适合线性可分数据
rbf
:径向基函数,适合非线性数据(最常用)
poly
:多项式核
from sklearn.svm import SVC
# 线性 SVM
linear_svm = SVC(kernel='linear', C=1.0)
# RBF 核 SVM(适合复杂边界)
rbf_svm = SVC(kernel='rbf', C=1.0, gamma='scale')
rbf_svm.fit(X_train_scaled, y_train)
y_pred = rbf_svm.predict(X_test_scaled)
虽然叫"回归",但是分类算法。用 Sigmoid 函数将线性输出映射到 (0,1) 概率。
from sklearn.linear_model import LogisticRegression
lr = LogisticRegression(
max_iter=1000,
C=1.0,
solver='lbfgs'
)
lr.fit(X_train_scaled, y_train)
# 输出概率
proba = lr.predict_proba(X_test_scaled)
基于贝叶斯定理,假设特征之间相互独立。简单高效,适合文本分类。
from sklearn.naive_bayes import GaussianNB
nb = GaussianNB()
nb.fit(X_train, y_train)
# 先验概率
print(nb.class_prior_)
Bagging 策略:多棵决策树并行训练,随机选特征、随机采样,最后投票。
from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier(
n_estimators=100, # 树的数量
max_depth=10,
random_state=42
)
rf.fit(X_train, y_train)
# 特征重要性排序
importances = rf.feature_importances_
Boosting 策略:串行训练,每棵树修正前一棵的错误,逐步提升精度。
from sklearn.ensemble import GradientBoostingClassifier
gb = GradientBoostingClassifier(
n_estimators=100,
learning_rate=0.1,
max_depth=3
)
gb.fit(X_train, y_train)
核心区别: RandomForest 是"并行民主投票",GradientBoosting 是"串行纠错精进"。
预测连续值(如房价、温度、销售额),而非离散类别。
拟合一条直线(或超平面),使预测值与真实值的误差平方和最小。
from sklearn.linear_model import LinearRegression
from sklearn.datasets import fetch_california_housing
# 加载加州房价数据集
housing = fetch_california_housing()
X, y = housing.data, housing.target
# 划分并标准化
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
scaler = StandardScaler()
X_train_s = scaler.fit_transform(X_train)
X_test_s = scaler.transform(X_test)
# 训练线性回归模型
model = LinearRegression()
model.fit(X_train_s, y_train)
# 预测
y_pred = model.predict(X_test_s)
# 查看系数和截距
print(f"系数: {model.coef_}")
print(f"截距: {model.intercept_}")
from sklearn.metrics import accuracy_score, classification_report, mean_squared_error, r2_score
# 分类评估
print(accuracy_score(y_test, y_pred))
print(classification_report(y_test, y_pred))
# 回归评估
print(f"MSE: {mean_squared_error(y_test, y_pred)}")
print(f"R²: {r2_score(y_test, y_pred)}")
将数据分成 K 份,轮流用 K-1 份训练、1 份验证,避免偶然性,更可靠地评估模型。
from sklearn.model_selection import cross_val_score, GridSearchCV
# 5折交叉验证
scores = cross_val_score(rf, X, y, cv=5)
print(f"5折交叉验证得分: {scores}")
print(f"平均得分: {scores.mean():.4f}")
# 网格搜索:自动寻找最优超参数
param_grid = {
'n_estimators': [50, 100, 200],
'max_depth': [3, 5, 10, None]
}
grid_search = GridSearchCV(
RandomForestClassifier(random_state=42),
param_grid,
cv=5,
scoring='accuracy',
n_jobs=-1 # 使用所有CPU核心
)
grid_search.fit(X_train, y_train)
print(f"最优参数: {grid_search.best_params_}")
# 第1步:导入库
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
# 第2步:加载数据
X, y = load_iris(return_X_y=True)
# 第3步:划分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 第4步:特征预处理
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
# 第5步:创建并训练模型
model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X_train, y_train)
# 第6步:预测与评估
y_pred = model.predict(X_test)
print(f"准确率: {accuracy_score(y_test, y_pred):.4f}")
📌 核心范式:导入 → 数据 → 划分 → 预处理 → fit → predict → 评估
fit 学习参数(如均值/方差),transform 应用转换。训练集用 fit_transform,测试集只用 transform。
绝不能先对整个数据集做标准化再划分!测试集信息会通过统计量泄露到训练过程。
决策树 max_depth 太大 → 过拟合;太小 → 欠拟合。交叉验证是判断的金标准。
线性核快但表达能力弱;RBF 核强大但需要调 gamma。数据量大时优先考虑线性核。
下一章:再谈编程 —— 时间复杂度分析