当前位置: 首页 > news >正文

改进广告投入与销售额预测分析

文章目录

    • 一、研究问题
    • 二、数据与预处理
    • 三、建模流程
    • 四、主要结果与分析
    • 五、结论
    • 代码附录

基于Python机器学习/利用广告投入预测销售额,尝试使用Pipeline进行优化,并通过statsmodels输出详细的统计量和置信区间。

一、研究问题

在实际商业运营中,企业常常需要根据不同渠道的广告投入(如电视、广播、报纸)来预测产品的销售额。如何利用历史数据,建立一个销售预测模型?本项目旨在探索:“广告投入的不同渠道对销售额的影响有多大?能否通过标准化和线性回归等方法,建立一个带有置信区间的销售预测模型?

二、数据与预处理

  • 数据集包含广告投入(TV、Radio、Newspaper)和对应的销售额(Sales)。
  • 检查数据完整性,无缺失值。
  • 选取TV、Radio、Newspaper三项作为特征,Sales为目标变量。
  • 对特征进行标准化处理,消除量纲影响。

三、建模流程

  1. 数据集划分:将数据集分为训练集和测试集,保证模型评估的客观性。
# 数据划分
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
print("数据准备完成。")
print(f"训练集特征形状: {X_train.shape}")
print(f"测试集特征形状: {X_test.shape}")
  1. 构建Scikit-learn管道:使用Pipeline将标准化(StandardScaler)和线性回归(LinearRegression)整合到一个自动化流程中。这样可以保证数据预处理和建模的一致性,减少数据泄漏风险。
# 构建并拟合 Scikit-learn 管道
# 管道包含标准化和线性回归模型
pipeline = Pipeline([('scaler', StandardScaler()),('regressor', LinearRegression()) 
])
  1. 模型训练与评估:在训练集上拟合模型,在测试集上预测销售额。通过计算均方误差(MSE)和决定系数(R²),量化模型性能。
# 拟合整个管道到训练数据
pipeline.fit(X_train, y_train)
# 使用管道进行预测 (获取点预测)
predictions_sklearn = pipeline.predict(X_test)
# 评估 Scikit-learn 管道模型
mse_sklearn = mean_squared_error(y_test, predictions_sklearn)
r2_sklearn = r2_score(y_test, predictions_sklearn)
print(f'\n--- Scikit-learn Pipeline 评估 ---')
print(f'Mean Squared Error (MSE): {mse_sklearn:.2f}')
print(f'R-squared (R²): {r2_sklearn:.2f}')
  1. 模型参数解释:输出回归系数,分析各广告渠道对销售额的影响。
  2. 结合Statsmodels获取置信区间:用statsmodels对标准化数据进行回归,获得详细统计摘要和每个预测值的95%置信区间。
  3. 结果可视化 :绘制实际销售额、预测值及其置信区间,直观展示模型效果和不确定性。

四、主要结果与分析

  1. 统计摘要(部分)
    在这里插入图片描述
  • R-squared: 0.900,模型能解释90%的销售额方差,拟合效果优秀。

  • Adj. R-squared: 0.898,调整后的R²考虑了特征数量,依然很高,说明模型没有过拟合。

  • F-statistic: 468.7, Prob (F-statistic): 8.51e-78,F检验显著,p值极小,说明至少有一个特征对销售额有显著影响。

  • coef(系数)

    • const(截距):15.3306,表示当所有特征为均值时,预测销售额约为15.33。
    • TV:4.5872,说明TV广告投入每增加一个标准差,销售额平均增加4.59。
    • Radio:1.4898,广播广告投入每增加一个标准差,销售额平均增加1.49。
    • Newspaper:0.0879,报纸广告投入影响很小,且p值为0.537(远大于0.05),说明统计上不显著。
  • std err, t, P>|t|, [0.025, 0.975]
    分别为系数的标准误、t检验统计量、p值和95%置信区间。TV和Radio的p值都远小于0.05,说明它们对销售额有显著正向影响。

  • 其他诊断指标

    • Durbin-Watson: 2.108,接近2,说明残差无自相关问题。
    • Omnibus、Jarque-Bera等用于检验残差的正态性。
  1. 预测与置信区间
ActualPredicted_MeanLower_CIUpper_CI
16.917.0313.7420.33
22.420.4117.0923.73
7.39.275.9512.60
24.721.6818.3225.05
  • Predicted_Mean:模型对每个样本的销售额预测值。
  • Lower_CI / Upper_CI:该预测值的95%置信区间,表示模型预测的区间范围,反映了不确定性。
  • Actual:实际观测值。可以看到,大部分实际值都落在置信区间内,说明模型预测可靠。

3. 可视化:通过散点图和置信区间带,直观展示了模型预测的准确性和可信度。
在这里插入图片描述

五、结论

结果显示,TV和Radio广告投入对销售额有显著正向影响,报纸广告影响不显著。模型拟合优良,预测值大多落在置信区间内,说明模型不仅准确,而且能量化预测的不确定性。通过statsmodels输出的详细统计量和置信区间,提升了模型的可解释性和业务参考价值。

代码附录

# 导入必要的库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns# 导入机器学习相关库
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score# 导入 statsmodels
import statsmodels.api as sm# 1. 读取数据
df = pd.read_csv('advertising.csv')# 2. 定义特征 X 和目标 y
X = df[['TV', 'Radio', 'Newspaper']]
y = df['Sales']# 3. 数据划分
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
print("数据准备完成。")
print(f"训练集特征形状: {X_train.shape}")
print(f"测试集特征形状: {X_test.shape}")# 4. 构建并拟合 Scikit-learn 管道
# 管道包含标准化和线性回归模型
pipeline = Pipeline([('scaler', StandardScaler()),('regressor', LinearRegression())
])# 拟合整个管道到训练数据
pipeline.fit(X_train, y_train)# 使用管道进行预测 (获取点预测)
predictions_sklearn = pipeline.predict(X_test)# 评估 Scikit-learn 管道模型
mse_sklearn = mean_squared_error(y_test, predictions_sklearn)
r2_sklearn = r2_score(y_test, predictions_sklearn)
print('\n--- Scikit-learn Pipeline 评估 ---')
print(f'Mean Squared Error (MSE): {mse_sklearn:.2f}')
print(f'R-squared (R²): {r2_sklearn:.2f}')# 访问管道内部的线性回归模型参数
linear_model_in_pipeline = pipeline.named_steps['regressor']
print(f'Pipeline Model Intercept: {linear_model_in_pipeline.intercept_:.2f}')
print(f'Pipeline Model Coefficients (Standardized Data): {linear_model_in_pipeline.coef_}')# --- 结合 Statsmodels 获取置信区间 ---
# 5. 从管道中提取经过标准化处理的训练和测试数据
scaler = pipeline.named_steps['scaler']
X_train_scaled = scaler.transform(X_train)
X_test_scaled = scaler.transform(X_test)# 将标准化后的数据转换回 DataFrame
X_train_scaled_df = pd.DataFrame(X_train_scaled, columns=X_train.columns, index=X_train.index)
X_test_scaled_df = pd.DataFrame(X_test_scaled, columns=X_test.columns, index=X_test.index)
print(X_train_scaled_df.head())# 6. 使用 statsmodels 训练模型并获取置信区间
# statsmodels 需要手动添加截距项
X_train_sm = sm.add_constant(X_train_scaled_df)
model_sm = sm.OLS(y_train, X_train_sm)
results_sm = model_sm.fit()print("\n--- Statsmodels 模型摘要 (基于标准化数据) ---")
print(results_sm.summary())# 为标准化后的测试集数据添加常数项,用于预测
X_test_sm = sm.add_constant(X_test_scaled_df)# 获取预测值和95%的预测区间 (Prediction Interval)
# 'obs_ci_lower' 和 'obs_ci_upper' 是单个观测值的预测区间
predictions_sm_df = results_sm.get_prediction(X_test_sm).summary_frame(alpha=0.05)predicted_mean_sm = predictions_sm_df['mean']
lower_bound_sm = predictions_sm_df['obs_ci_lower']
upper_bound_sm = predictions_sm_df['obs_ci_upper']print("\n测试集预测结果及95%置信区间 (来自Statsmodels):")
output_df = pd.DataFrame({'Actual': y_test,'Predicted_Mean': predicted_mean_sm,'Lower_CI': lower_bound_sm,'Upper_CI': upper_bound_sm
}).reset_index(drop=True)
print(output_df.head())# 7. 可视化预测值和置信区间
plt.figure(figsize=(12, 8))
# 绘制实际销售额
plt.scatter(range(len(y_test)), y_test, color='blue', label='Actual Sales', alpha=0.7)
# 绘制预测销售额
plt.scatter(range(len(y_test)), predicted_mean_sm, color='red', label='Predicted Sales (Mean)', alpha=0.7)
# 绘制预测区间
plt.fill_between(range(len(y_test)), lower_bound_sm, upper_bound_sm, color='gray', alpha=0.2, label='95% Prediction Interval')plt.xlabel('Test Sample Index')
plt.ylabel('Sales')
plt.title('Actual, Predicted Sales, and 95% Prediction Interval on Test

博客内容如有错误欢迎指正~

欢迎大家留言交流,也可以在评论区分享你的思路和改进建议!
请添加图片描述

http://www.dtcms.com/a/278154.html

相关文章:

  • CVE-2021-31201
  • 特征选择要解决什么问题
  • 算法题(174):全排列问题
  • 碳水循环(增肌、减脂)
  • AEC原理
  • 白盒测试方法深度解析:从理论到实践
  • Python协程进阶:优雅终止与异常处理详解
  • Mybatis 两级缓存可能导致的问题
  • 「小程序开发」新建页面设置启动页
  • alpinelinux的包管理
  • 力扣刷题记录(c++)09
  • ‘make_unique’ is not a member of ‘std’
  • win10下的wsl2扩充空间
  • 20250713 保存 PBM / PGM / PPM 图片 C++
  • 拼写纠错模型Noisy Channel(上)
  • 中华心法问答系统的解读(1)
  • XCZU2CG-2SFVC784I Xilinx FPGA AMD Zynq UltraScale+ MPSoC
  • if-constexpr,编译报错expected a “(“
  • JavaScript 中一些常见算法的实现及详细解析
  • 问题 E: Connecting Territories(DP)
  • 理解volatile:并发编程的核心机制
  • 能说说MyBatis的工作原理吗?
  • 柯西不等式
  • CATIA许可价格高,设计部门如何精细化分配?
  • 【时时三省】(C语言基础)通过指针引用数组元素2
  • 未来航空电子系统
  • 浮点数的乘法与除法运算耗时对比
  • 洛谷 P13014:[GESP202506 五级] 最大公因数
  • 基于python的栅格数据标准差椭圆
  • Can201-Introduction to Networking:Transport Layer 传输层