AdaBoost算法之葡萄酒案例
1 课程概览
本课使用AdaBoost完成葡萄酒分类案例。葡萄酒数据集有3个类别,但AdaBoost底层是二叉树(CART),需要删除一个类别,只保留两类。使用LabelEncoder将标签转为0和1。
2 核心概念与定义
- 葡萄酒数据集:包含酒精、色泽等特征,3个类别。
- 二分类问题:AdaBoost底层是CART二叉树,只能处理二分类。
- LabelEncoder:标签编码器,将标签转为0和1。
3 算法与模型详解
3.1 案例背景
需求:已知葡萄酒数据,根据数据进行葡萄酒分类
数据集:葡萄酒数据
- 标签:葡萄酒类别(1、2、3)
- 特征:酒精含量、色泽度等
3.2 数据预处理
问题:标签有3个类别(1、2、3),AdaBoost底层是CART二叉树,只能处理二分类
解决方案:
- 删除一个类别(如删除类别1)
- 保留两类(如2和3)
- 使用LabelEncoder将标签转为0和1
特征选择:
- alcohol:酒精含量
- hue:色泽度
3.3 完整流程
- 读取数据到内存
- 特征化处理
- 修改列名
- 去掉一个类别(二分类)
- 转化类别(LabelEncoder)
- 划分数据集
- 实例化决策树
- 实例化AdaBoost(500棵树)
- 模型训练
- 模型预测和评估
3.4 AdaBoost参数
AdaBoostClassifier(
n_estimators=500, # 500棵树
learning_rate=0.1, # 学习率
random_state=22 # 随机种子
)
3.5 注意事项
SAM算法更名:
- 旧版本:SAM算法
- 新版本:SAM.R算法
- 如果不调整参数会报错
- 原因:Anaconda版本更新
4 代码示例
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import AdaBoostClassifier
from sklearn.metrics import accuracy_score
from sklearn.preprocessing import LabelEncoder
from sklearn.datasets import load_wine
# 1. 加载葡萄酒数据
def load_data():
"""加载葡萄酒数据"""
wine = load_wine()
data = pd.DataFrame(wine.data, columns=wine.feature_names)
data['target'] = wine.target
print(f"数据形状: {data.shape}")
print(f"标签分布:\n{data['target'].value_counts()}")
print(f"\n前5行:")
print(data.head())
return data
# 2. 数据预处理
def preprocess_data(data):
"""数据预处理"""
# 2.1 去掉一个类别(删除类别0,保留1和2)
data = data[data['target'] != 0].copy()
print(f"\n删除类别0后: {data.shape}")
print(f"标签分布:\n{data['target'].value_counts()}")
# 2.2 提取特征(酒精含量和色泽度)
X = data[['alcohol', 'hue']]
y = data['target']
# 2.3 标签编码(将1,2转为0,1)
le = LabelEncoder()
y = le.fit_transform(y)
print(f"\n编码后标签: {np.unique(y)}")
print(f"特征形状: {X.shape}")
return X, y, le
# 3. 划分数据集
def split_data(X, y):
"""划分训练集和测试集"""
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=22
)
print(f"\n训练集: {X_train.shape}")
print(f"测试集: {X_test.shape}")
return X_train, X_test, y_train, y_test
# 4. 单一决策树
def train_decision_tree(X_train, X_test, y_train, y_test):
"""单一决策树"""
print("\n=== 单一决策树 ===")
dt = DecisionTreeClassifier(
criterion='entropy', # 使用熵
max_depth=5,
random_state=22
)
dt.fit(X_train, y_train)
y_pred = dt.predict(X_test)
acc = accuracy_score(y_test, y_pred)
print(f"准确率: {acc:.4f}")
return dt, acc
# 5. AdaBoost
def train_adaboost(X_train, X_test, y_train, y_test):
"""AdaBoost"""
print("\n=== AdaBoost ===")
# 底层决策树
dt = DecisionTreeClassifier(
criterion='entropy',
max_depth=5,
random_state=22
)
# AdaBoost
ab = AdaBoostClassifier(
estimator=dt, # 底层决策树
n_estimators=500,
learning_rate=0.1,
random_state=22
)
ab.fit(X_train, y_train)
y_pred = ab.predict(X_test)
acc = accuracy_score(y_test, y_pred)
print(f"准确率: {acc:.4f}")
return ab, acc
# 6. 主函数
def main():
"""主函数"""
print("=" * 50)
print("AdaBoost - 葡萄酒分类案例")
print("=" * 50)
# 1. 加载数据
data = load_data()
# 2. 数据预处理
X, y, le = preprocess_data(data)
# 3. 划分数据集
X_train, X_test, y_train, y_test = split_data(X, y)
# 4. 单一决策树
dt, dt_acc = train_decision_tree(X_train, X_test, y_train, y_test)
# 5. AdaBoost
ab, ab_acc = train_adaboost(X_train, X_test, y_train, y_test)
# 6. 对比
print("\n=== 对比 ===")
print(f"单一决策树: {dt_acc:.4f}")
print(f"AdaBoost: {ab_acc:.4f}")
# 7. 预测新样本
print("\n=== 预测新样本 ===")
samples = [
{'alcohol': 13.5, 'hue': 1.05},
{'alcohol': 12.0, 'hue': 0.80},
{'alcohol': 14.0, 'hue': 1.10}
]
X_new = pd.DataFrame(samples)
predictions = ab.predict(X_new)
for sample, pred in zip(samples, predictions):
label = le.inverse_transform([pred])[0]
print(f"{sample}: 类别{label}")
if __name__ == '__main__':
main()
输出示例:
==================================================
AdaBoost - 葡萄酒分类案例
==================================================
数据形状: (178, 14)
标签分布:
1 71
0 59
2 48
Name: target, dtype: int64
删除类别0后: (119, 14)
标签分布:
1 71
2 48
Name: target, dtype: int64
编码后标签: [0 1]
特征形状: (119, 2)
训练集: (95, 2)
测试集: (24, 2)
=== 单一决策树 ===
准确率: 0.8750
=== AdaBoost ===
准确率: 0.9167
=== 对比 ===
单一决策树: 0.8750
AdaBoost: 0.9167
=== 预测新样本 ===
{'alcohol': 13.5, 'hue': 1.05}: 类别1
{'alcohol': 12.0, 'hue': 0.80}: 类别2
{'alcohol': 14.0, 'hue': 1.10}: 类别1
5 重难点与易错提醒
- ❗重点:AdaBoost底层是CART二叉树,只能处理二分类。
- ❗重点:多分类问题需要删除一个类别。
- ❗重点:使用LabelEncoder将标签转为0和1。
- ❗重点:n_estimators=500表示500棵树。
- ⚠️易错:忘记删除一个类别导致报错。
- ⚠️易错:SAM算法在新版本中更名。
- 💡深入理解:AdaBoost通过加权提升处理二分类问题。
6 课堂问答精选
Q: 葡萄酒数据集有3个类别,AdaBoost如何处理?
A: AdaBoost底层是CART二叉树,只能处理二分类。需要:
- 删除一个类别(如删除类别0)
- 保留两类(如1和2)
- 使用LabelEncoder将标签转为0和1
Q: AdaBoost的n_estimators参数有什么作用?
A: n_estimators指定弱学习器(决策树)的数量。如n_estimators=500表示使用500棵决策树。数量越多,模型越复杂,训练时间越长,但准确率可能更高。
7 本课小结
- 葡萄酒数据集:3个类别,需删除一个。
- AdaBoost:底层CART二叉树,只能二分类。
- LabelEncoder:将标签转为0和1。
- 参数:n_estimators=500,learning_rate=0.1。
- 注意:SAM算法在新版本中更名。
8 延伸思考与实践
- 实践:运行葡萄酒分类案例。
- 预习:GBDT梯度提升树。
- 思考:如何处理多分类问题?