实例化
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
fit_transform()
fit():计算每列的均值和标准差transform():执行标准化 (x - mean) / std
x_train_scaled = scaler.fit_transform(x_train)
x_test_scaled = scaler.transform(x_test)
实例化
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors=5)
模型训练
knn.fit(x_train, y_train) # 生成模型
模型评估
直接比对预测值与真实值
y_pred = knn.predict(x_test)
accuracy = (y_pred == y_test).mean()
计算准确率
score = knn.score(X_test, y_test)
k=1:易受异常点影响k=样本数:退化为多数表决from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler
def knn_iris():
"""
鸢尾花数据集
:return:
"""
# 1. 加载数据集
iris = load_iris()
# 2. 数据集划分
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=42)
# 3. 特征工程 标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train) # fit_transform训练集
x_test = transfer.transform(x_test) # transform测试集
# 4. KNN 算法预估
estimator = KNeighborsClassifier(n_neighbors=3)
estimator.fit(x_train, y_train)
# 5. 模型评估
# 方法一: 直接比对真实值和预测值
y_predict = estimator.predict(x_test)
print("y_predict:\n", y_predict)
print("直接比对真实值和预测值:\n", y_test == y_predict)
# 方法二: 计算准确率
score = estimator.score(x_test, y_test)
print("准确率: \n", score)
return None
if __name__ == '__main__':
knn_iris()
K折交叉验证:将数据分为K份,轮流作为验证集
from sklearn.model_selection import cross_val_score
scores = cross_val_score(knn, X, y, cv=5)
from sklearn.model_selection import GridSearchCV
param_grid = {'n_neighbors': [1,3,5,7,9]}
grid = GridSearchCV(knn, param_grid, cv=5)
grid.fit(X, y)
print(grid.best_params_) # 输出最优参数
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import GridSearchCV
# noinspection DuplicatedCode
def knn_iris_grid_search_cv():
"""
鸢尾花数据集 KNN算法 网格搜索
:return:
"""
# 1. 加载数据集
iris = load_iris()
# 2. 数据集划分
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=22)
# 3. 特征工程 标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train) # fit_transform训练集
x_test = transfer.transform(x_test) # transform测试集
# 4. KNN 算法预估
estimator = KNeighborsClassifier()
# 加入网格搜索与交叉验证
# 参数准备
param_grid = {"n_neighbors": [1, 3, 5, 7, 9, 11]}
estimator = GridSearchCV(estimator, param_grid=param_grid, cv=10)
estimator.fit(x_train, y_train)
# 5. 模型评估
# 方法一: 直接比对真实值和预测值
y_predict = estimator.predict(x_test)
print("y_predict:\n", y_predict)
print("直接比对真实值和预测值:\n", y_test == y_predict)
# 方法二: 计算准确率
score = estimator.score(x_test, y_test)
print("准确率: \n", score)
# 6. 获取最佳参数
print("最佳参数: \n", estimator.best_params_)
print("最佳结果: \n", estimator.best_score_)
print("最佳估计器: \n", estimator.best_estimator_)
print("交叉验证结果: \n", estimator.cv_results_)
return None
if __name__ == '__main__':
knn_iris_grid_search_cv()
朴素贝叶斯(Naive Bayes)是基于贝叶斯定理和特征条件独立假设的分类算法。其核心公式为:
$$
P(Y|X) = \frac{P(X|Y) \cdot P(Y)}{P(X)}
$$
$$
P(X|Y) = \prod_{i=1}^n P(x_i|Y)
$$
这一假设简化了计算,但牺牲了部分准确性。
通过比较后验概率选择最大概率的类别:
$$
\hat{y} = \arg\maxY P(Y) \prod{i=1}^n P(x_i|Y)
$$
由于分母 (P(X)) 对所有类别相同,实际计算中可忽略。
案例:天气预测是否打球
数据集:
| 天气 | 温度 | 湿度 | 风速 | 是否打球 |
|---|---|---|---|---|
| 晴朗 | 炎热 | 高 | 弱 | 否 |
| 晴朗 | 炎热 | 高 | 强 | 否 |
| 多云 | 炎热 | 高 | 弱 | 是 |
| ... | ... | ... | ... | ... |
预测新样本:天气=晴朗,温度=凉爽,湿度=正常,风速=强
计算先验概率:
计算条件概率(拉普拉斯平滑):
后验概率比较:
优点:
缺点:
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import GaussianNB
# 加载数据
iris = load_iris()
X, y = iris.data, iris.target
# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
# 训练模型
model = GaussianNB()
model.fit(X_train, y_train)
# 预测与评估
print("准确率:", model.score(X_test, y_test))
为避免零概率问题,对条件概率进行平滑:
$$ P(x_i|Y) = \frac{\text{count}(x_i,Y) + α}{\text{count}(Y) + α \cdot N} $$
其中 $α=1$为平滑参数,$N$ 为特征可能取值数。
通过上述分析可见,朴素贝叶斯虽假设简单,但在实际应用中常因高效性和鲁棒性表现出色。理解其数学基础与适用场景是合理使用的关键。
决策树是一种基于树状结构的监督学习算法,通过递归划分特征空间实现分类或回归任务。其核心结构包括:
工作原理:
从根节点开始,根据特征取值选择分支,递归划分数据集,直到满足停止条件(如纯度达标或达到最大深度)。
ID3算法(信息增益)
C4.5算法(信息增益率)
解决 $ID3$ 偏向多值特征的问题:,其中 $H_A(D)$为特征 $A$ 的熵,避免选择取值过多的特征。
CART算法(基尼指数)
案例:贷款审批预测
数据集包含特征:年龄、收入、信用评分、是否有房。
步骤:
计算根节点熵:
总样本15个,批准9个,拒绝6个。
选择最优特征:
递归构建子树:
生成树结构:
根节点:信贷情况 ≥ 一般?
├─ 是 → 叶节点:批准(准确率90%)
└─ 否 → 内部节点:有房?
├─ 是 → 叶节点:批准
└─ 否 → 叶节点:拒绝
优点:
缺点:
预剪枝:
后剪枝:
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
def decision_tree_iris():
"""
鸢尾花数据集 决策树算法
:return:
"""
# 1) 加载数据集
iris = load_iris()
# 2) 数据集划分
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=22)
# 3) 特征工程
# 4) 决策树算法预估
estimator = DecisionTreeClassifier(criterion="gini", max_depth=None, random_state=None)
estimator.fit(x_train, y_train)
# 5) 模型评估
# 方法一: 直接比对真实值和预测值
y_predict = estimator.predict(x_test)
print("直接比对真实值和预测值:\n", y_test == y_predict)
# 方法二: 计算准确率
score = estimator.score(x_test, y_test)
print("准确率: \n", score)
return None
if __name__ == '__main__':
decision_tree_iris()
分类任务:
回归任务:
通过特征选择、树结构优化和剪枝策略,决策树在可解释性与性能间取得平衡,是理解复杂数据关系的有力工具。
随机森林(Random Forest)是一种基于集成学习和决策树的算法,通过组合多棵树的预测结果提升模型性能。其核心包含三个关键点:
Bagging(自助采样)
从原始数据集中有放回地随机抽取样本(约63.2%的数据用于训练单棵树),生成多个子数据集。
公式:
$$ \text{Bootstrap采样} = \text{随机选择} \ N \ \text{个样本(允许重复)} $$
随机特征选择
每个节点分裂时,仅从全部特征中随机选择 $m$ 个候选特征(通常 $m = \sqrt{\text{总特征数}}$),避免树间高度相似。
集成策略
案例:鸢尾花分类
数据集包含4个特征(花萼长/宽、花瓣长/宽)和3个类别(Setosa、Versicolour、Virginica)。
步骤:
生成多棵决策树
预测新样本
Python代码实现:
from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
# noinspection DuplicatedCode
def random_forest_iris():
"""
鸢尾花数据集 随机森林算法
:return:
"""
# 1) 加载数据集
iris = load_iris()
# 2) 数据集划分
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=22)
# 3) 特征工程
# 4) 随机森林算法预估
estimator = RandomForestClassifier(n_estimators=10, random_state=22, max_features="sqrt") # n_estimators: 树的数量
# 加入网格搜索与交叉验证
param_grid = {"n_estimators": [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]}
estimator = GridSearchCV(estimator, param_grid=param_grid, cv=10)
estimator.fit(x_train, y_train)
# 5) 模型评估
# 方法一: 直接比对真实值和预测值
y_predict = estimator.predict(x_test)
print("y_predict:\n", y_predict)
print("直接比对真实值和预测值:\n", y_test == y_predict)
# 方法二: 计算准确率
score = estimator.score(x_test, y_test)
print("准确率: \n", score)
# 6. 获取最佳参数
print("最佳参数: \n", estimator.best_params_)
print("最佳结果: \n", estimator.best_score_)
print("最佳估计器: \n", estimator.best_estimator_)
print("交叉验证结果: \n", estimator.cv_results_)
if __name__ == '__main__':
random_forest_iris()
| 特性 | 说明 |
|---|---|
| 抗过拟合 | 通过随机采样和特征选择降低方差,避免单棵树过拟合。 |
| 并行化训练 | 各树独立训练,支持多线程加速(n_jobs参数)。 |
| 特征重要性评估 | 基于特征在分裂时的贡献度(如基尼指数下降)自动排序。 |
| 处理缺失值 | 通过替代分裂机制(Surrogate Splits)自动处理缺失数据。 |
| 参数 | 作用 | 推荐范围 |
|---|---|---|
n_estimators |
树的数量,影响模型稳定性 | 100-500 |
max_depth |
单树最大深度,防止过拟合 | 5-30 |
max_features |
节点分裂时考虑的特征数 | sqrt(分类)、log2 |
min_samples_split |
内部节点分裂所需最小样本数 | 2-20 |
bootstrap |
是否使用自助采样 | True(默认) |
网格搜索示例:
from sklearn.model_selection import GridSearchCV
param_grid = {
'n_estimators': [50, 100, 200],
'max_depth': [5, 10, None],
'max_features': ['sqrt', 'log2']
}
grid_search = GridSearchCV(RandomForestClassifier(), param_grid, cv=5)
grid_search.fit(X_train, y_train)
print("最佳参数:", grid_search.best_params_)
优点:
缺点:
max_depth)。分类任务:
回归任务:
特征工程:
| 特性 | 随机森林 | 梯度提升树(如XGBoost) |
|---|---|---|
| 训练方式 | 并行独立训练多棵树 | 串行训练,每棵树修正前序错误 |
| 偏差-方差权衡 | 主要降低方差 | 同时降低偏差和方差 |
| 参数敏感性 | 相对低(默认参数效果较好) | 高(需精细调参如学习率、树深度) |
| 适用场景 | 快速原型开发、高维数据 | 高精度需求、中小规模数据 |
随机森林通过Bagging和随机特征选择实现高效集成,在多数场景下表现出色。其优势在于抗过拟合和特征可解释性,但需注意计算成本和模型复杂度。对于需要更高精度的任务,可结合梯度提升树进一步优化。
titanic_sample_random_forest.py
| 算法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| KNN | 无需训练,简单直观 | 计算量大,需调参 | 小数据集 |
| 朴素贝叶斯 | 高效,适合文本 | 特征独立性假设 | 文本分类 |
| 决策树 | 可解释性强 | 易过拟合 | 结构化数据分类 |
| 随机森林 | 高准确率,抗过拟合 | 计算成本高 | 大数据集,高维特征 |