本文目录导读:

我来详细讲解如何使用Scikit-learn构建分类决策树,包含完整的案例和代码示例。
基础案例:鸢尾花分类
# 导入必要的库
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score, classification_report
import numpy as np
# 1. 加载数据
iris = load_iris()
X = iris.data
y = iris.target
# 2. 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42
)
# 3. 创建决策树分类器
dt_classifier = DecisionTreeClassifier(
max_depth=3, # 限制树的深度,防止过拟合
random_state=42
)
# 4. 训练模型
dt_classifier.fit(X_train, y_train)
# 5. 预测
y_pred = dt_classifier.predict(X_test)
# 6. 评估模型
accuracy = accuracy_score(y_test, y_pred)
print(f"准确率: {accuracy:.4f}")
print("\n分类报告:")
print(classification_report(y_test, y_pred, target_names=iris.target_names))
完整案例:信用卡欺诈检测
# 导入所需库
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.tree import DecisionTreeClassifier
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import confusion_matrix, classification_report, roc_auc_score
import matplotlib.pyplot as plt
from sklearn import tree
# 创建示例数据
np.random.seed(42)
n_samples = 1000
# 生成特征
data = {
'amount': np.random.exponential(100, n_samples),
'time': np.random.uniform(0, 24, n_samples),
'merchant_id': np.random.randint(1, 100, n_samples),
'transaction_type': np.random.randint(0, 3, n_samples),
'location': np.random.randint(0, 5, n_samples)
}
# 生成标签(欺诈/非欺诈)
# 假设欺诈交易具有某些特征
prob_fraud = 0.02 + 0.05 * (data['amount'] > 200) + \
0.03 * (data['time'] < 6) + \
0.02 * (data['transaction_type'] == 2)
fraud = np.random.binomial(1, prob_fraud / prob_fraud.max())
data['is_fraud'] = fraud
df = pd.DataFrame(data)
print("数据集信息:")
print(df.head())
print(f"\n欺诈交易比例: {df['is_fraud'].mean():.2%}")
# 准备特征和目标变量
features = ['amount', 'time', 'merchant_id', 'transaction_type', 'location']
X = df[features]
y = df['is_fraud']
# 数据标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(
X_scaled, y, test_size=0.3, random_state=42, stratify=y
)
# 创建决策树模型(优化参数)
dt_model = DecisionTreeClassifier(
max_depth=5,
min_samples_split=20,
min_samples_leaf=10,
max_features='sqrt',
random_state=42
)
# 训练模型
dt_model.fit(X_train, y_train)
# 预测
y_pred = dt_model.predict(X_test)
y_pred_proba = dt_model.predict_proba(X_test)[:, 1]
# 评估模型
print("\n模型评估结果:")
print(f"准确率: {accuracy_score(y_test, y_pred):.4f}")
print(f"AUC-ROC: {roc_auc_score(y_test, y_pred_proba):.4f}")
print("\n混淆矩阵:")
print(confusion_matrix(y_test, y_pred))
print("\n分类报告:")
print(classification_report(y_test, y_pred))
决策树可视化
# 可视化决策树
def visualize_decision_tree(model, feature_names, class_names, filename='tree.png'):
"""
可视化决策树
"""
plt.figure(figsize=(20, 10))
# 绘制决策树
tree.plot_tree(
model,
feature_names=feature_names,
class_names=class_names,
filled=True,
rounded=True,
fontsize=10
)
plt.title('决策树可视化', fontsize=16)
plt.savefig(filename, dpi=100, bbox_inches='tight')
plt.show()
# 可视化鸢尾花案例的决策树
visualize_decision_tree(
dt_classifier,
iris.feature_names,
iris.target_names,
'iris_decision_tree.png'
)
特征重要性分析
# 特征重要性分析
def analyze_feature_importance(model, feature_names):
"""
分析特征重要性并可视化
"""
importances = model.feature_importances_
indices = np.argsort(importances)[::-1]
# 打印特征重要性
print("特征重要性排序:")
for i in range(len(feature_names)):
print(f"{i+1}. {feature_names[indices[i]]}: {importances[indices[i]]:.4f}")
# 可视化
plt.figure(figsize=(10, 6))
plt.title("特征重要性")
plt.bar(range(len(importances)), importances[indices])
plt.xticks(range(len(importances)), [feature_names[i] for i in indices], rotation=45)
plt.tight_layout()
plt.show()
# 分析信用卡欺诈案例的特征重要性
analyze_feature_importance(dt_model, features)
超参数调优
from sklearn.model_selection import GridSearchCV
# 超参数网格搜索
def optimize_decision_tree(X_train, y_train):
"""
使用网格搜索优化决策树参数
"""
# 定义参数网格
param_grid = {
'max_depth': [3, 5, 7, 10, None],
'min_samples_split': [2, 5, 10, 20],
'min_samples_leaf': [1, 2, 5, 10],
'max_features': [None, 'sqrt', 'log2'],
'criterion': ['gini', 'entropy']
}
# 创建基础模型
dt = DecisionTreeClassifier(random_state=42)
# 网格搜索
grid_search = GridSearchCV(
dt,
param_grid,
cv=5,
scoring='accuracy',
n_jobs=-1,
verbose=1
)
# 执行搜索
grid_search.fit(X_train, y_train)
print("最优参数:")
print(grid_search.best_params_)
print(f"\n最优交叉验证得分: {grid_search.best_score_:.4f}")
return grid_search.best_estimator_
# 优化决策树参数
best_dt = optimize_decision_tree(X_train, y_train)
# 评估优化后的模型
y_pred_best = best_dt.predict(X_test)
print(f"\n优化后的模型准确率: {accuracy_score(y_test, y_pred_best):.4f}")
完整的数据处理流程
# 完整的数据处理和分析流程
class DecisionTreePipeline:
def __init__(self):
self.model = None
self.scaler = StandardScaler()
def preprocess_data(self, X):
"""
数据预处理
"""
# 处理缺失值
X = pd.DataFrame(X).fillna(X.mean())
# 标准化
X_scaled = self.scaler.fit_transform(X)
return X_scaled
def train(self, X_train, y_train, **params):
"""
训练决策树模型
"""
X_processed = self.preprocess_data(X_train)
# 默认参数
default_params = {
'max_depth': 5,
'min_samples_split': 10,
'min_samples_leaf': 5,
'random_state': 42
}
# 合并参数
model_params = {**default_params, **params}
self.model = DecisionTreeClassifier(**model_params)
self.model.fit(X_processed, y_train)
return self.model
def predict(self, X_test):
"""
预测
"""
X_processed = self.scaler.transform(X_test)
return self.model.predict(X_processed)
def predict_proba(self, X_test):
"""
预测概率
"""
X_processed = self.scaler.transform(X_test)
return self.model.predict_proba(X_processed)
def evaluate(self, X_test, y_test):
"""
评估模型
"""
y_pred = self.predict(X_test)
return {
'accuracy': accuracy_score(y_test, y_pred),
'classification_report': classification_report(y_test, y_pred),
'confusion_matrix': confusion_matrix(y_test, y_pred)
}
# 使用Pipeline
pipeline = DecisionTreePipeline()
# 训练模型
pipeline.train(X_train, y_train, max_depth=7)
# 评估模型
results = pipeline.evaluate(X_test, y_test)
print("Pipeline评估结果:")
print(f"准确率: {results['accuracy']:.4f}")
实际应用:客户流失预测
# 客户流失预测案例
def customer_churn_prediction():
"""
客户流失预测案例
"""
# 创建模拟客户数据
np.random.seed(42)
n_customers = 2000
# 客户特征
customer_data = {
'tenure_months': np.random.randint(1, 72, n_customers),
'monthly_charges': np.random.uniform(20, 120, n_customers),
'total_charges': np.random.uniform(100, 8000, n_customers),
'contract_type': np.random.randint(0, 3, n_customers), # 0:月付, 1:年付, 2:两年付
'payment_method': np.random.randint(0, 4, n_customers),
'num_services': np.random.randint(1, 8, n_customers),
'avg_monthly_usage': np.random.uniform(0, 1000, n_customers)
}
# 生成流失标签(基于某些特征)
churn_prob = 0.1 + \
0.2 * (customer_data['contract_type'] == 0) + \
0.1 * (customer_data['tenure_months'] < 12) + \
0.15 * (customer_data['avg_monthly_usage'] < 100)
customer_data['churn'] = np.random.binomial(1, churn_prob / churn_prob.max())
df_customers = pd.DataFrame(customer_data)
# 准备数据
feature_cols = ['tenure_months', 'monthly_charges', 'total_charges',
'contract_type', 'payment_method', 'num_services',
'avg_monthly_usage']
X = df_customers[feature_cols]
y = df_customers['churn']
# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
# 训练决策树模型
churn_model = DecisionTreeClassifier(
max_depth=4,
min_samples_split=50,
min_samples_leaf=20,
class_weight='balanced', # 处理类别不平衡
random_state=42
)
churn_model.fit(X_train, y_train)
# 预测
y_pred = churn_model.predict(X_test)
y_proba = churn_model.predict_proba(X_test)[:, 1]
# 评估
print("客户流失预测模型评估:")
print(f"准确率: {accuracy_score(y_test, y_pred):.4f}")
print(f"AUC-ROC: {roc_auc_score(y_test, y_proba):.4f}")
# 特征重要性
print("\n影响客户流失的最重要因素:")
importances = churn_model.feature_importances_
for i, importance in enumerate(sorted(importances, reverse=True)):
feature_idx = np.where(importances == importance)[0][0]
print(f"{feature_cols[feature_idx]}: {importance:.4f}")
return churn_model, X_train, y_train
# 运行客户流失预测
churn_model, X_train, y_train = customer_churn_prediction()
使用建议
- 参数调优:使用网格搜索找到最优参数
- 防止过拟合:限制树的深度和叶子节点大小
- 特征选择:使用特征重要性选择重要特征
- 类别平衡:对于不平衡数据,使用
class_weight='balanced' - 可视化:可视化决策树来理解模型决策过程
这个案例涵盖了决策树分类器的主要应用场景和优化技术,你可以根据具体需求进行调整。