# 回归分析Python实现:超详细手把手实验教程
我将以**完全零基础**的角度,带你一步步完成这个回归分析实验,包括每一步的鼠标点击位置、代码输入位置等所有细节。
## 📁 第一步:准备工作(15分钟)
### 1.1 打开Python环境(3种方式任选)
**方式一:使用Anaconda(推荐新手)**
```
1. 在电脑桌面找到Anaconda Navigator图标 → 双击打开
2. 在打开的界面中找到"Jupyter Notebook" → 点击"Launch"按钮
3. 浏览器会自动打开新页面,这就是你的编程环境
```
**方式二:使用VS Code(推荐有一定基础)**
```
1. 打开VS Code软件
2. 点击左上角"文件" → 选择"新建文件"
3. 点击右下角选择语言 → 输入"Python" → 按回车
4. 按Ctrl+S保存文件 → 命名为"regression.py"
```
**方式三:使用在线环境(无需安装)**
```
1. 打开浏览器,访问:https://colab.research.google.com
2. 点击"新建笔记本"
3. 直接开始编写代码
```
### 1.2 安装必要库(第一次运行时需要)
在Jupyter Notebook或Python文件中,**新建一个代码单元格**,输入:
```python
# 点击这里输入代码(如果在线环境,可能需要先运行这个)
!pip install pandas numpy matplotlib seaborn statsmodels scikit-learn
```
**操作步骤:**
1. 在单元格中点击鼠标左键
2. 输入上面的代码
3. 按键盘上的 **Shift + Enter** 运行
4. 等待安装完成(看到"Successfully installed"字样)
## 📊 第二步:创建数据文件(10分钟)
### 2.1 创建数据生成脚本
**在第一个代码单元格下面,点击"+"号添加新单元格**,输入:
```python
# 点击这里开始输入
import pandas as pd
import numpy as np
# 设置随机种子,确保每次运行结果一致
np.random.seed(42)
# 生成200个样本数据
n_samples = 200
# 生成广告投入数据
TV_ads = np.random.normal(150, 50, n_samples) # 电视广告
Radio_ads = np.random.normal(30, 10, n_samples) # 广播广告
Newspaper_ads = np.random.normal(40, 15, n_samples) # 报纸广告
Online_ads = np.random.normal(80, 25, n_samples) # 线上广告
# 生成销售额数据(有线性关系+随机噪声)
Sales = (
2.5 * TV_ads +
1.8 * Radio_ads +
0.5 * Newspaper_ads +
1.2 * Online_ads +
np.random.normal(0, 20, n_samples) + 50
)
# 创建数据框
data = pd.DataFrame({
'TV': TV_ads,
'Radio': Radio_ads,
'Newspaper': Newspaper_ads,
'Online': Online_ads,
'Sales': Sales
})
# 查看前5行数据
print("数据预览:")
print(data.head())
# 保存为CSV文件(方便后续使用)
data.to_csv('advertising_sales.csv', index=False)
print("\n数据已保存为 'advertising_sales.csv'")
```
**运行方法:**
1. 点击单元格左侧的空白区域(选中单元格)
2. 按 **Shift + Enter**
3. 你会看到输出的数据表格
### 2.2 检查数据是否保存成功
**新建单元格**,输入:
```python
# 检查文件是否存在
import os
if os.path.exists('advertising_sales.csv'):
print("✅ 数据文件创建成功!")
# 重新加载数据验证
df = pd.read_csv('advertising_sales.csv')
print(f"数据形状:{df.shape}")
print(f"列名:{list(df.columns)}")
else:
print("❌ 文件创建失败,请检查代码")
```
## 📈 第三步:数据可视化探索(15分钟)
### 3.1 绘制散点图(看关系)
**新建单元格**,输入:
```python
import matplotlib.pyplot as plt
import seaborn as sns
# 设置中文字体(如果显示乱码)
plt.rcParams['font.sans-serif'] = ['SimHei', 'Arial Unicode MS']
plt.rcParams['axes.unicode_minus'] = False
# 创建2x2的子图
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
# 第一个图:电视广告 vs 销售额
# 点击axes[0,0]表示第一行第一列
axes[0, 0].scatter(data['TV'], data['Sales'], alpha=0.6, color='blue')
axes[0, 0].set_xlabel('电视广告投入(千元)')
axes[0, 0].set_ylabel('销售额(万元)')
axes[0, 0].set_title('电视广告与销售额关系')
axes[0, 0].grid(True, alpha=0.3)
# 第二个图:广播广告 vs 销售额
axes[0, 1].scatter(data['Radio'], data['Sales'], alpha=0.6, color='green')
axes[0, 1].set_xlabel('广播广告投入(千元)')
axes[0, 1].set_ylabel('销售额(万元)')
axes[0, 1].set_title('广播广告与销售额关系')
axes[0, 1].grid(True, alpha=0.3)
# 第三个图:报纸广告 vs 销售额
axes[1, 0].scatter(data['Newspaper'], data['Sales'], alpha=0.6, color='red')
axes[1, 0].set_xlabel('报纸广告投入(千元)')
axes[1, 0].set_ylabel('销售额(万元)')
axes[1, 0].set_title('报纸广告与销售额关系')
axes[1, 0].grid(True, alpha=0.3)
# 第四个图:线上广告 vs 销售额
axes[1, 1].scatter(data['Online'], data['Sales'], alpha=0.6, color='purple')
axes[1, 1].set_xlabel('线上广告投入(千元)')
axes[1, 1].set_ylabel('销售额(万元)')
axes[1, 1].set_title('线上广告与销售额关系')
axes[1, 1].grid(True, alpha=0.3)
# 调整布局并显示
plt.tight_layout()
plt.show()
# 保存图片
plt.savefig('scatter_plots.png', dpi=300, bbox_inches='tight')
print("✅ 散点图已保存为 'scatter_plots.png'")
```
### 3.2 绘制相关性热力图
**新建单元格**,输入:
```python
# 计算相关性矩阵
corr_matrix = data.corr()
# 绘制热力图
plt.figure(figsize=(10, 8))
sns.heatmap(corr_matrix,
annot=True, # 显示数值
cmap='coolwarm', # 颜色
center=0, # 中心为0
square=True, # 正方形
linewidths=1, # 线宽
cbar_kws={"shrink": 0.8}) # 颜色条大小
plt.title('变量间相关性热力图')
plt.tight_layout()
plt.show()
# 打印相关性数值
print("相关系数矩阵:")
print(corr_matrix)
```
## 🔧 第四步:建立回归模型(20分钟)
### 4.1 简单线性回归(先试一个变量)
**新建单元格**,输入:
```python
import statsmodels.api as sm
# 选择自变量和因变量
X = data['TV'] # 只使用电视广告
y = data['Sales']
# 添加常数项(截距)
X_with_const = sm.add_constant(X)
# 建立模型
model_simple = sm.OLS(y, X_with_const).fit()
# 查看结果
print("="*60)
print("简单线性回归结果(电视广告 vs 销售额)")
print("="*60)
print(model_simple.summary())
# 绘制回归线
plt.figure(figsize=(10, 6))
plt.scatter(X, y, alpha=0.6, label='实际数据')
# 生成预测值
x_line = np.linspace(X.min(), X.max(), 100)
x_line_with_const = sm.add_constant(x_line)
y_pred_line = model_simple.predict(x_line_with_const)
plt.plot(x_line, y_pred_line, color='red', linewidth=3, label='回归线')
plt.xlabel('电视广告投入(千元)')
plt.ylabel('销售额(万元)')
plt.title('简单线性回归:电视广告对销售额的影响')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
# 解读关键指标
print("\n🔍 结果解读:")
print(f"1. R-squared = {model_simple.rsquared:.4f}")
print(f" 模型能解释{model_simple.rsquared*100:.1f}%的销售额变化")
print(f"2. 电视广告的系数 = {model_simple.params['TV']:.4f}")
print(f" 每增加1千元电视广告,销售额增加{model_simple.params['TV']:.2f}万元")
print(f"3. P值 = {model_simple.pvalues['TV']:.4e}")
print(f" P值 < 0.05,说明电视广告的影响是显著的")
```
### 4.2 多元线性回归(使用所有变量)
**新建单元格**,输入:
```python
# 使用所有广告变量
X_multi = data[['TV', 'Radio', 'Newspaper', 'Online']]
X_multi_const = sm.add_constant(X_multi)
# 建立多元回归模型
model_multi = sm.OLS(y, X_multi_const).fit()
print("\n" + "="*60)
print("多元线性回归结果(所有广告渠道)")
print("="*60)
print(model_multi.summary())
# 提取重要信息
print("\n📊 关键结果表格:")
results_df = pd.DataFrame({
'变量': ['常数'] + list(X_multi.columns),
'系数': model_multi.params.values,
'标准误': model_multi.bse.values,
't值': model_multi.tvalues.values,
'P值': model_multi.pvalues.values,
'是否显著': ['是' if p < 0.05 else '否' for p in model_multi.pvalues]
})
print(results_df.to_string(index=False))
# 业务解读
print("\n💡 业务建议:")
print("1. 电视广告效果最好,每投入1千元带来销售额增长约",
f"{model_multi.params['TV']:.2f}万元")
print("2. 广播广告次之,每投入1千元带来销售额增长约",
f"{model_multi.params['Radio']:.2f}万元")
print("3. 报纸广告效果相对较弱")
```
## 📝 第五步:模型诊断(15分钟)
### 5.1 残差分析
**新建单元格**,输入:
```python
# 获取残差和拟合值
residuals = model_multi.resid
fitted = model_multi.fittedvalues
# 创建诊断图
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
# 1. 残差 vs 拟合值图
axes[0, 0].scatter(fitted, residuals, alpha=0.6)
axes[0, 0].axhline(y=0, color='red', linestyle='--', linewidth=2)
axes[0, 0].set_xlabel('拟合值')
axes[0, 0].set_ylabel('残差')
axes[0, 0].set_title('残差图(检查同方差性)')
axes[0, 0].grid(True, alpha=0.3)
# 2. Q-Q图(检查正态性)
from statsmodels.graphics.gofplots import qqplot
qqplot(residuals, line='45', ax=axes[0, 1])
axes[0, 1].set_title('Q-Q图(检查正态性)')
# 3. 残差直方图
axes[1, 0].hist(residuals, bins=20, edgecolor='black', alpha=0.7)
axes[1, 0].set_xlabel('残差')
axes[1, 0].set_ylabel('频数')
axes[1, 0].set_title('残差分布直方图')
# 4. 残差 vs 自变量图(示例:TV)
axes[1, 1].scatter(data['TV'], residuals, alpha=0.6)
axes[1, 1].axhline(y=0, color='red', linestyle='--', linewidth=2)
axes[1, 1].set_xlabel('电视广告投入')
axes[1, 1].set_ylabel('残差')
axes[1, 1].set_title('残差 vs TV广告')
plt.tight_layout()
plt.show()
print("✅ 诊断图已生成")
print("\n🔍 诊断解读:")
print("1. 残差图:点应随机分布在0线两侧,无明显模式")
print("2. Q-Q图:点应近似在45度线上,说明残差正态")
print("3. 直方图:应近似钟形分布")
```
### 5.2 多重共线性检验
**新建单元格**,输入:
```python
from statsmodels.stats.outliers_influence import variance_inflation_factor
# 计算VIF(方差膨胀因子)
vif_data = pd.DataFrame()
vif_data["变量"] = X_multi.columns
vif_data["VIF"] = [variance_inflation_factor(X_multi.values, i)
for i in range(X_multi.shape[1])]
print("多重共线性检验:")
print(vif_data.to_string(index=False))
print("\n📋 VIF判断标准:")
print(" VIF < 5: 多重共线性可接受 ✓")
print(" 5 ≤ VIF < 10: 存在中等多重共线性 ⚠️")
print(" VIF ≥ 10: 存在严重多重共线性 ❌")
```
## 🚀 第六步:使用模型预测(10分钟)
### 6.1 进行预测
**新建单元格**,输入:
```python
# 创建新的广告投入方案
new_data = pd.DataFrame({
'TV': [200, 150, 250], # 电视广告投入
'Radio': [40, 30, 50], # 广播广告
'Newspaper': [50, 40, 60], # 报纸广告
'Online': [100, 80, 120] # 线上广告
})
print("新的广告投入方案:")
print(new_data)
# 添加常数项
new_data_const = sm.add_constant(new_data, has_constant='add')
# 进行预测
predictions = model_multi.predict(new_data_const)
print("\n📈 预测结果:")
for i in range(len(new_data)):
print(f"\n方案{i+1}:")
print(f" 电视广告: {new_data.iloc[i, 0]}千元")
print(f" 广播广告: {new_data.iloc[i, 1]}千元")
print(f" 报纸广告: {new_data.iloc[i, 2]}千元")
print(f" 线上广告: {new_data.iloc[i, 3]}千元")
print(f" 预测销售额: {predictions.iloc[i]:.2f}万元")
# 计算投入产出比
total_investment = sum(new_data.iloc[i])
roi = predictions.iloc[i] / total_investment * 100 # 每千元投入产出
print(f" 每千元广告投入产出: {roi:.2f}%")
```
### 6.2 保存模型结果
**新建单元格**,输入:
```python
# 保存模型结果到文件
import json
# 创建结果字典
results = {
'模型类型': '多元线性回归',
'样本数量': len(data),
'R平方': float(model_multi.rsquared),
'调整R平方': float(model_multi.rsquared_adj),
'系数': {var: float(coef) for var, coef in model_multi.params.items()},
'预测示例': [
{
'方案': f'方案{i+1}',
'投入': dict(new_data.iloc[i]),
'预测销售额': float(predictions.iloc[i])
}
for i in range(len(predictions))
]
}
# 保存为JSON文件
with open('regression_results.json', 'w', encoding='utf-8') as f:
json.dump(results, f, ensure_ascii=False, indent=2)
print("✅ 模型结果已保存为 'regression_results.json'")
print("✅ 实验完成!")
```
## 📋 第七步:实验报告(5分钟)
### 7.1 生成实验总结
**新建单元格**,输入:
```python
print("="*80)
print("回归分析实验总结报告")
print("="*80)
print("\n一、实验目的")
print("分析不同广告渠道(电视、广播、报纸、线上)对销售额的影响")
print("\n二、数据概况")
print(f"1. 样本数量: {len(data)}")
print(f"2. 变量数量: {len(data.columns)}")
print(f"3. 数据文件: advertising_sales.csv")
print("\n三、主要发现")
print(f"1. 模型解释力: R² = {model_multi.rsquared:.4f}")
print(f" 能解释{model_multi.rsquared*100:.1f}%的销售额变化")
print(f"2. 最有效广告渠道: 电视广告")
print(f" 每千元投入带来 {model_multi.params['TV']:.2f}