[集成学习]基于python的Stacking分类模型的客户购买意愿分类预测

1 导入必要的库

python 复制代码
import pandas as pd
import numpy as np
import missingno as msno
import matplotlib.pyplot as plt
from matplotlib import rcParams
import seaborn as sns
from sklearn.metrics import roc_curve, auc
from sklearn.linear_model import LogisticRegression  
from sklearn.tree import DecisionTreeClassifier  
from sklearn.svm import SVC  
from sklearn.neighbors import KNeighborsClassifier  
from sklearn.ensemble import RandomForestClassifier, AdaBoostClassifier  
from xgboost import XGBClassifier  
from lightgbm import LGBMClassifier  
from sklearn.ensemble import StackingClassifier  
from sklearn.metrics import confusion_matrix   
# 忽略Matplotlib的警告(可选)  
import warnings  
warnings.filterwarnings("ignore") 
# 设置中文显示和负号正常显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

2 导入数据

python 复制代码
# 读取Excel文件
df = pd.read_excel('目标客户体验数据.xlsx')
df

| id | style | a1 | a2 | a3 | a4 | a5 | a6 | a7 | a8 | ... | B9 | B10 | B11 | B12 | B13 | B14 | B15 | B16 | B17 | isorno |
| 0 | 1 | 2 | 753.035399 | 87.653791 | 81.558171 | 85.611593 | 85.629678 | 85.807576 | 82.346453 | 84.769555 | ... | 6 | 14 | 2 | 3 | 19.0 | 11 | 10 | 30 | 5 | 0 |
| 1 | 2 | 3 | 88.922790 | 82.946262 | 85.166081 | 85.189724 | 77.762498 | 83.595579 | 82.152367 | 88.872546 | ... | 6 | 5 | 4 | 4 | 18.0 | 10 | 8 | 0 | 30 | 0 |
| 2 | 3 | 3 | 95.048294 | 93.333131 | 77.660375 | 93.034274 | 88.869998 | 94.169962 | 95.602655 | 95.877373 | ... | 4 | 9 | 5 | 2 | 24.0 | 10 | 17 | 0 | 0 | 0 |
| 3 | 4 | 3 | 71.152328 | 76.785767 | 66.691701 | 81.926125 | 66.654998 | 77.773674 | 77.580247 | 76.989502 | ... | 6 | 10 | 4 | 7 | 27.0 | 10 | 10 | 18 | 25 | 0 |
| 4 | 5 | 3 | 70.573962 | 71.645949 | 70.444554 | 74.029832 | 66.654998 | 66.336092 | 62.093021 | 74.436962 | ... | 6 | 13 | 4 | 2 | 25.0 | 15 | 15 | 0 | 0 | 0 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 1959 | 1960 | 2 | 71.357663 | 75.373690 | 70.444554 | 77.767044 | 68.430276 | 75.026965 | 75.482261 | 70.333970 | ... | 5 | 6 | 3 | 5 | 25.0 | 11 | 20 | 0 | 0 | 0 |
| 1960 | 1961 | 2 | 99.036888 | 99.030172 | 99.032550 | 99.983342 | 99.977498 | 99.991867 | 99.992713 | 99.980365 | ... | 5 | 14 | 7 | 9 | 29.0 | 9 | 9 | 30 | 20 | 0 |
| 1961 | 1962 | 2 | 90.771281 | 91.921055 | 92.671787 | 96.719743 | 94.961899 | 97.245158 | 95.602655 | 95.877373 | ... | 6 | 8 | 4 | 5 | 39.0 | 20 | 17 | 0 | 30 | 0 |
| 1962 | 1963 | 2 | 82.427327 | 88.511489 | 74.052464 | 93.034274 | 76.461711 | 94.704676 | 91.163572 | 95.877373 | ... | 6 | 8 | 4 | 4 | 21.0 | 12 | 7 | 20 | 20 | 0 |

1963 1964 2 77.808692 77.803468 702.996114 77.767044 61.803653 77.773674 73.190189 58.796528 ... 6 7 4 3 25.0 10 12 25 0 0

1964 rows × 28 columns

3 数据预处理

python 复制代码
# 可视化缺失值
msno.matrix(df)
plt.axis('off')
plt.show()
# 将"B7"列中的缺失值替换为整型数值0
df['B7'].fillna(0, inplace=True)
# 检测重复值并处理
print("重复值数量:", df.duplicated().sum())
df.drop_duplicates(inplace=True)

运行结果如图3-1所示:

图3-1 缺失值可视化与重复值检测

4 数据分布

4.1 箱线图
python 复制代码
# 设置颜色风格为精简学术风格
sns.set_style("whitegrid")
# 设置图形大小  
plt.figure(figsize=(15, 40))  
features_to_plot_features = [col for col in df.columns]  
# 对每个特征绘制箱线图子图  
for i, feature in enumerate(features_to_plot_features):  
    plt.subplot(len(features_to_plot_features) // 2 + 1, 4, i + 1)  # 设置子图位置  
    sns.boxplot(df[feature], palette="Set3")  # 使用Set3颜色风格
    plt.title(feature)  
    plt.xlabel('')      
# 显示图形  
plt.tight_layout()  # 调整子图间距  
plt.show()

运行结果如图4-1所示:

图4-1 箱线图

4.2 pair plot
python 复制代码
# 使用seaborn的pairplot绘制数据分布
sns.pairplot(df)

运行结果如图4-2所示:

图4-2 散点图

4.3 hist plot
python 复制代码
# 设置颜色风格为精简学术风格 
#sns.set_style("whitegrid")
# 设置图形大小  
plt.figure(figsize=(15, 40))  
features_to_plot_features = [col for col in df.columns] 
# 对每个特征绘制
for i, feature in enumerate(features_to_plot_features):  
    plt.subplot(len(features_to_plot_features) // 2 + 1, 4, i + 1)  # 设置子图位置  
    #sns.kdeplot(df[feature], palette="Set3")  # 使用Set3颜色风格
    sns.histplot(df[feature], palette="Set3",kde=True)  # 使用Set3颜色风格
    plt.title(feature)  
    plt.xlabel('')          
# 显示图形  
plt.tight_layout()  # 调整子图间距  
plt.show()

运行结果如图4-3所示:

图4-3 直方图

4.4 小提琴图
python 复制代码
# 设置颜色风格为精简学术风格
sns.set_style("whitegrid")
# 设置图形大小  
plt.figure(figsize=(15,45))  
features_to_plot_features = [col for col in df.columns]  
palette=['deep','muted','pastel','muted','pastel','viridis','dark','rocket','crest','mako','flare','magma','viridis','vlag','icefire',
         'deep','muted','pastel','viridis','dark','colorblind','rocket','crest','mako','flare','magma','bright','vlag','icefire']
# 对每个特征绘制箱线图子图  
for i, feature in enumerate(features_to_plot_features):  
    plt.subplot(len(features_to_plot_features) // 2 + 1, 4, i + 1)  # 设置子图位置 
    sns.violinplot(df[feature], palette=palette[i])  
    plt.title(feature)  
    plt.xlabel('')  # 移除x轴标签,因为只有一个变量        
# 显示图形  
plt.tight_layout()  # 调整子图间距  
plt.show()

运行结果如图4-4所示:

图4-4 小提琴图

5 相关性

5.1 heatmap
python 复制代码
# 计算相关性矩阵  
corr_matrix = df.corr()    
# 绘制heatmap
plt.figure(figsize=(25,25))
sns.heatmap(corr_matrix, annot=True, cmap='PuOr', linewidths=.5)  
plt.title('Heatmap of Correlation Matrix')

运行结果如图5-1所示:

图5-1 heatmap

5.2 clustermap
python 复制代码
# 直接使用clustermap对原始数据进行聚类并绘制热图 
sns.clustermap(df, standard_scale=1, cmap='PuBuGn', annot=False, fmt=".2f")  
plt.title('Clustermap of DataFrame')  
plt.show()

运行结果如图5-2所示:

图5-2 clustermap

6 划分数据集

python 复制代码
from sklearn.model_selection import train_test_split
X = df.drop('isorno', axis=1) 
y = df['isorno']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) 

7 Stacking分类模型建立

python 复制代码
# 定义基础层分类器列表  
base_learners = [  
    ('Logistic Regression', LogisticRegression()),  
    ('Decision Tree', DecisionTreeClassifier()),  
    ('SVM', SVC(probability=True)),  
    ('KNN', KNeighborsClassifier(3)),  
    ('Random Forest', RandomForestClassifier()),  
    ('AdaBoost', AdaBoostClassifier()),  
    ('XGBoost', XGBClassifier()),  
    ('LightGBM', LGBMClassifier())  
]  
  
# 使用StackingClassifier构建stacking集成学习模型  
stacking_clf = StackingClassifier(  
    estimators=base_learners,  
    final_estimator=LogisticRegression()  
)  

8 训练模型

python 复制代码
# 训练stacking集成学习模型  
stacking_clf.fit(X_train, y_train) 

模型结构如图8-1所示:

图8-1 Stacking分类模型结构

9 预测

python 复制代码
# 预测  
y_pred_stacking = stacking_clf.predict(X_test) 

10 预测结果

python 复制代码
indices = range(len(y_test))  
  
# 绘制真实值和预测值的折线图  
plt.figure(figsize=(10, 6))  
plt.plot(indices, y_test, color='g', marker='o', markerfacecolor='none', markeredgecolor='black', label='True Values', linestyle='-')  
plt.plot(indices, y_pred_stacking, color='black', marker='*',markerfacecolor='none',markeredgecolor='r',label='Predicted Values', linestyle='--')  
plt.title('True vs Predicted Values')  
plt.xlabel('Index in Test Set')  
plt.ylabel('isorno Value')  
plt.legend()  
plt.grid(True)  
plt.show()

运行结果如图10-1所示:

图10-1 预测结果

11 模型评估

11.1 混淆矩阵
python 复制代码
plt.figure(figsize=(6,6))   
# 假设 num_classes 是类别的数量  
num_classes = len(np.unique(y_train))  
  
# 确保我们可以将分类器数量和一个额外的堆叠模型的混淆矩阵放入布局中  
# 这里我们假设最大可以显示9个基础分类器的混淆矩阵,以及一个堆叠模型的混淆矩阵  
max_classifiers_to_show = 9  
  
# 创建一个3x4的布局来容纳所有子图(9个基础分类器 + 1个堆叠模型)  
fig, axes = plt.subplots(nrows=3, ncols=3, figsize=(18, 12))  # 调整figsize以适应你的需要  
axes = axes.flatten()[:max_classifiers_to_show]  # 只使用前max_classifiers_to_show个子图  
  
# 创建一个颜色映射列表  
#cmaps = sns.color_palette("husl", max_classifiers_to_show)  # 使用seaborn的颜色映射  
cmaps = ['Blues', 'plasma', 'Spectral', 'Purples', 'gist_stern', 'gist_ncar', 'inferno', 'BuGn', 'binary']  
# 遍历分类器  
for ax_idx, (name, clf) in enumerate(base_learners[:max_classifiers_to_show]):  
    # 拟合模型  
    clf.fit(X_train, y_train)  
    # 预测测试集  
    y_pred = clf.predict(X_test)  
    # 计算混淆矩阵  
    cm = confusion_matrix(y_test, y_pred)  
    sns.heatmap(cm, annot=True, fmt='d', cmap=cmaps[ax_idx], ax=axes[ax_idx])  
    axes[ax_idx].set_xlabel('Predicted')  
    axes[ax_idx].set_ylabel('True')  
    axes[ax_idx].set_title(f'Confusion Matrix for {name}')  
  
# 添加堆叠集成学习模型的混淆矩阵  
stacking_cm = confusion_matrix(y_test, y_pred_stacking)  
sns.heatmap(stacking_cm, annot=True, fmt='d', cmap=cmaps[-1], ax=axes[-1])  # 使用最后一个颜色映射  
axes[-1].set_xlabel('Predicted')  
axes[-1].set_ylabel('True')  
axes[-1].set_title('Confusion Matrix for Stacking')  
  
# 显示图形  
plt.tight_layout()  # 确保子图之间不重叠  
plt.show()

运行结果如图11-1所示:

图11-1 混淆矩阵

11.2 ROC曲线
python 复制代码
plt.figure(figsize=(6, 6))  
markers = ['o', '.', '2', '^', '*', '>', '+', '1', 'p', '_', '8']  
linestyles = ['-', '--', ':', '-.', 'solid', 'dashed', '-.', '-.', ':', '-', '--']  
colors = ['b', 'g', 'r', 'c', 'r', 'y', 'k', 'tab:blue', 'tab:orange', 'tab:green', 'tab:red', 'tab:purple', 'tab:brown', 'tab:pink', 'tab:gray', 'tab:olive', 'tab:cyan']  
  
# 绘制基础分类器的ROC曲线  
for i, (name, clf) in enumerate(base_learners):  
    clf.fit(X_train, y_train)  
    y_score = clf.predict_proba(X_test)[:, 1]  
    fpr, tpr, thresholds = roc_curve(y_test, y_score)  
    roc_auc = auc(fpr, tpr)  
    plt.plot(fpr, tpr, color=colors[i % len(colors)], label=f'{name} (AUC = {roc_auc:.2f})', marker=markers[i % len(markers)], linestyle=linestyles[i % len(linestyles)])  
  
# 绘制堆叠分类器的ROC曲线  
stacking_y_score = stacking_clf.predict_proba(X_test)[:, 1]  
stacking_fpr, stacking_tpr, _ = roc_curve(y_test, stacking_y_score)  
stacking_roc_auc = auc(stacking_fpr, stacking_tpr)  
plt.plot(stacking_fpr, stacking_tpr, color='black', label=f'Stacking (AUC = {stacking_roc_auc:.2f})', linestyle='--', marker='s')  
  
plt.plot([0, 1], [0, 1], color='grey', linestyle='--')  
plt.xlim([0.0, 1.0])  
plt.ylim([0.0, 1.05])  
plt.xlabel('False Positive Rate')  
plt.ylabel('True Positive Rate')  
plt.title('Receiver Operating Characteristic')  
plt.legend(loc="lower right")  
plt.show()

运行结果如图11-2所示:

图11-2 ROC曲线对比

12 预测新数据

python 复制代码
# 读取Excel文件
new_data = pd.read_excel('待判定的数据.xlsx')
# 将"B7"列中的缺失值替换为整型数值0
new_data['B7'].fillna(0, inplace=True)
# 检测重复值并处理
print("重复值数量:", new_data.duplicated().sum())
df.drop_duplicates(inplace=True)
if 'isorno' in new_data.columns:  
    new_data = new_data.drop('isorno', axis=1) 
# 预测  
new_pred_stacking = stacking_clf.predict(new_data) 
plt.plot(new_pred_stacking,color='black',marker='*',markerfacecolor='none',markeredgecolor='r',label='Predicted Values', linestyle='--')

新预测结果如图12-1所示:

图12-1 新数据预测结果

相关推荐
CodeCraft Studio32 分钟前
CAD文件处理控件Aspose.CAD教程:使用 Python 将绘图转换为 Photoshop
python·photoshop·cad·aspose·aspose.cad
Python×CATIA工业智造2 小时前
Frida RPC高级应用:动态模拟执行Android so文件实战指南
开发语言·python·pycharm
IT古董3 小时前
【第二章:机器学习与神经网络概述】04.回归算法理论与实践 -(4)模型评价与调整(Model Evaluation & Tuning)
神经网络·机器学习·回归
wenzhangli73 小时前
OneCode 图表组件核心优势解析
数据可视化
onceco3 小时前
领域LLM九讲——第5讲 为什么选择OpenManus而不是QwenAgent(附LLM免费api邀请码)
人工智能·python·深度学习·语言模型·自然语言处理·自动化
狐凄4 小时前
Python实例题:基于 Python 的简单聊天机器人
开发语言·python
悦悦子a啊5 小时前
Python之--基本知识
开发语言·前端·python
笑稀了的野生俊6 小时前
在服务器中下载 HuggingFace 模型:终极指南
linux·服务器·python·bash·gpu算力
Naiva6 小时前
【小技巧】Python+PyCharm IDE 配置解释器出错,环境配置不完整或不兼容。(小智AI、MCP、聚合数据、实时新闻查询、NBA赛事查询)
ide·python·pycharm
路来了7 小时前
Python小工具之PDF合并
开发语言·windows·python