客户消费数据分析

客户消费数据分析

程序主要功能模块说明:

  1. 数据生成模块

    • 使用Faker库生成真实感的用户信息
    • 通过正态分布模拟收入和消费金额等连续变量
    • 设置合理的业务逻辑关系(如会员才有会员等级)
  2. 数据处理模块

    • 缺失值处理:针对不同字段特点采用不同填充策略
    • 异常值过滤:移除不符合实际业务场景的极端值
    • 特征工程:创建衍生变量"购买活跃度"用于分层分析
  3. 数据分析模块

    • 描述性统计:获取数据整体概况
    • 分组分析:对比会员与非会员、不同地区的消费差异
    • 相关性分析:识别影响消费金额的关键因素
  4. 数据可视化模块

    • 多张子图布局:一次性展示多个维度的分析结果
    • 统计图表:直方图、柱状图、散点图、热图、饼图等
    • 图表保存:将结果保存为图片文件便于后续使用

所有核心步骤都有详细的错误处理和进度提示,确保程序运行的稳定性和可维护性。

数据结构说明:

这个程序实现了完整的数据处理流程,包括模拟数据生成、数据保存、数据清洗、数据分析和可视化。以下是数据结构说明:

字段名称字段描述数据类型
用户ID唯一标识用户的ID字符串
性别用户性别字符串
年龄用户年龄整数
教育程度用户教育水平字符串
收入用户月收入整数
地区用户所在地区字符串
是否会员用户是否为会员布尔值
会员天数用户成为会员的天数整数
会员等级用户的会员等级字符串
上次购买日期用户上次购买的日期日期
购买频率用户在一定时期内的购买次数整数
总消费金额用户的总消费金额整数
平均订单金额用户平均每次订单的金额浮点数
是否响应促销用户是否对促销活动做出响应布尔值
折扣力度用户使用的折扣比例浮点数
购买活跃度根据购买频率划分的活跃度等级分类变量

程序运行后会生成以下分析结果:

  1. 保存模拟数据到CSV文件
  2. 输出基本统计信息和关键分析指标
  3. 生成多张子图展示用户特征分布、地区消费差异、消费行为模式和相关性分析
  4. 生成会员等级分布图

所有图表都会保存为PNG文件,方便进一步分析和展示。

代码

import pandas as pd  # 数据处理和分析库
import numpy as np  # 数值计算库
import matplotlib.pyplot as plt  # 数据可视化库
import seaborn as sns  # 高级数据可视化库
from faker import Faker  # 生成模拟数据
import random  # 随机数生成
from datetime import datetime, timedelta  # 日期时间处理

# 配置matplotlib支持中文字体和LaTeX数学符号
plt.rcParams.update({
    # 优先使用中文字体,同时保留serif用于LaTeX数学符号
    "font.family": ["SimHei", "serif"],
    "mathtext.fontset": "cm",  # 使用Computer Modern字体渲染数学符号
    "axes.unicode_minus": False,  # 解决负号显示问题
    "text.usetex": False,  # 不强制使用外部LaTeX,依赖matplotlib内置渲染
})

# 设置随机种子确保结果可复现
np.random.seed(42)
random.seed(42)

# 模拟数据生成函数
def generate_sample_data(n=1000):
    fake = Faker('zh_CN')  # 创建中文数据生成器
    data = []  # 存储生成的数据
    
    for _ in range(n):  # 生成n条记录
        # 用户基本信息
        user_id = fake.uuid4()  # 生成唯一用户ID
        gender = random.choice(['男', '女'])  # 随机选择性别
        age = random.randint(18, 70)  # 随机生成18-70岁的年龄
        education = random.choice(['高中及以下', '本科', '硕士', '博士'])  # 随机教育程度
        income = max(0, int(np.random.normal(8000, 3000)))  # 收入符合正态分布
        region = random.choice(['华东', '华南', '华北', '西南', '西北', '东北', '华中'])  # 随机地区
        
        # 会员信息
        is_member = random.choice([True, False])  # 是否为会员
        member_days = random.randint(0, 365) if is_member else None  # 会员天数
        membership_level = random.choice(['普通会员', '银卡会员', '金卡会员', '钻石会员']) if is_member else None  # 会员等级
        
        # 消费信息
        last_purchase_date = (datetime.now() - timedelta(days=random.randint(0, 180))).strftime('%Y-%m-%d')  # 上次购买日期
        purchase_frequency = max(0, int(np.random.normal(5, 3)))  # 购买频率符合正态分布
        total_spend = max(0, int(np.random.normal(2000, 1000)))  # 总消费金额符合正态分布
        avg_order_value = total_spend / max(1, purchase_frequency)  # 平均订单金额
        
        # 促销响应
        responded_to_promo = random.choices([True, False], weights=[0.3, 0.7])[0]  # 30%概率响应促销
        discount_used = round(random.uniform(0.05, 0.3), 2) if responded_to_promo else None  # 折扣力度
        
        # 将生成的数据添加到列表
        data.append({
            '用户ID': user_id,
            '性别': gender,
            '年龄': age,
            '教育程度': education,
            '收入': income,
            '地区': region,
            '是否会员': is_member,
            '会员天数': member_days,
            '会员等级': membership_level,
            '上次购买日期': last_purchase_date,
            '购买频率': purchase_frequency,
            '总消费金额': total_spend,
            '平均订单金额': avg_order_value,
            '是否响应促销': responded_to_promo,
            '折扣力度': discount_used
        })
    
    return pd.DataFrame(data)  # 转换为DataFrame返回

# 数据保存函数
def save_to_csv(df, filename='customer_data.csv'):
    try:
        df.to_csv(filename, index=False, encoding='utf-8-sig')  # 保存为CSV文件
        print(f"数据已成功保存到 {filename}")
    except Exception as e:
        print(f"保存文件时出错: {e}")  # 异常处理

# 数据清洗函数
def clean_data(df):
    cleaned_df = df.copy()  # 复制数据避免修改原始数据
    
    # 处理缺失值:将会员相关的缺失值填充为合理值
    cleaned_df['会员天数'] = cleaned_df['会员天数'].fillna(0)
    cleaned_df['会员等级'] = cleaned_df['会员等级'].fillna('非会员')
    cleaned_df['折扣力度'] = cleaned_df['折扣力度'].fillna(0)
    
    # 处理异常值:过滤掉收入和消费金额过高的异常记录
    cleaned_df = cleaned_df[(cleaned_df['收入'] < 50000) & (cleaned_df['总消费金额'] < 100000)]
    
    # 转换数据类型:将日期字符串转换为日期类型
    cleaned_df['上次购买日期'] = pd.to_datetime(cleaned_df['上次购买日期'])
    
    # 添加派生特征:根据购买频率创建分类特征
    cleaned_df['购买活跃度'] = pd.cut(cleaned_df['购买频率'], 
                                   bins=[0, 2, 5, 10, float('inf')], 
                                   labels=['低', '中', '高', '极高'])
    
    return cleaned_df

# 数据分析函数
def analyze_data(df):
    # 输出基本统计信息
    print("\n数据基本统计信息:")
    print(df.describe())  # 描述性统计
    
    # 分析会员与非会员消费差异
    member_stats = df.groupby('是否会员')['总消费金额'].mean()
    print("\n会员与非会员平均消费金额对比:")
    print(member_stats)
    
    # 分析不同地区消费差异
    region_stats = df.groupby('地区')['总消费金额'].mean().sort_values(ascending=False)
    print("\n各地区平均消费金额:")
    print(region_stats)
    
    # 相关性分析:计算数值列与总消费金额的相关性
    numeric_cols = ['年龄', '收入', '会员天数', '购买频率', '总消费金额', '平均订单金额', '折扣力度']
    correlation = df[numeric_cols].corr()
    print("\n变量相关性分析:")
    print(correlation['总消费金额'].sort_values(ascending=False))
    
    return correlation  # 返回相关系数矩阵

# 数据可视化函数
def visualize_data(df, correlation):
    plt.figure(figsize=(15, 10))  # 设置图表大小
    
    # 1. 年龄分布直方图
    plt.subplot(2, 2, 1)  # 创建2x2网格的第1个子图
    sns.histplot(df['年龄'], bins=20, kde=True)  # 绘制直方图和核密度估计
    plt.title('用户年龄分布')  # 设置标题
    
    # 2. 不同地区消费金额对比
    plt.subplot(2, 2, 2)
    region_spend = df.groupby('地区')['总消费金额'].mean().reset_index()
    # 修复FutureWarning:添加hue参数并设置legend=False
    sns.barplot(x='地区', y='总消费金额', data=region_spend, palette='viridis', 
                hue='地区', legend=False)  
    plt.title('各地区平均消费金额对比')
    
    # 3. 消费金额与购买频率散点图
    plt.subplot(2, 2, 3)
    sns.scatterplot(x='购买频率', y='总消费金额', hue='是否会员', data=df)  # 绘制散点图
    plt.title('购买频率与总消费金额关系')
    
    # 4. 相关性热图
    plt.subplot(2, 2, 4)
    sns.heatmap(correlation, annot=True, cmap='coolwarm', fmt='.2f', square=True)  # 绘制热图
    plt.title('变量相关性热图')
    
    plt.tight_layout()  # 自动调整子图布局
    plt.savefig('data_visualization.png', dpi=300, bbox_inches='tight')  # 保存图表
    plt.show()  # 显示图表
    
    # 5. 会员等级分布饼图
    plt.figure(figsize=(8, 6))  # 创建新图表
    member_levels = df[df['是否会员']]['会员等级'].value_counts()  # 统计会员等级分布
    plt.pie(member_levels, labels=member_levels.index, autopct='%1.1f%%', startangle=90)  # 绘制饼图
    plt.title('会员等级分布')
    plt.axis('equal')  # 使饼图为正圆形
    plt.savefig('member_distribution.png', dpi=300, bbox_inches='tight')
    plt.show()

# 主函数:程序入口点
def main():
    # 1. 生成模拟数据
    print("正在生成模拟数据...")
    df = generate_sample_data(1000)
    
    # 2. 保存数据
    save_to_csv(df)
    
    # 3. 读取数据
    print("\n正在读取数据...")
    loaded_df = pd.read_csv('customer_data.csv')
    
    # 4. 数据清洗
    print("\n正在进行数据清洗...")
    cleaned_df = clean_data(loaded_df)
    
    # 5. 数据分析
    print("\n正在进行数据分析...")
    correlation = analyze_data(cleaned_df)
    
    # 6. 数据可视化
    print("\n正在生成数据可视化图表...")
    visualize_data(cleaned_df, correlation)

if __name__ == "__main__":
    main()    

运行结果

正在生成模拟数据...
数据已成功保存到 customer_data.csv

正在读取数据...

正在进行数据清洗...

正在进行数据分析...

数据基本统计信息:
                年龄            收入         会员天数                         上次购买日期  \
count  1000.000000   1000.000000  1000.000000                           1000   
mean     44.775000   8166.665000    94.670000  2025-02-27 21:15:50.400000256   
min      18.000000      0.000000     0.000000            2024-12-05 00:00:00   
25%      32.000000   6246.000000     0.000000            2025-01-13 00:00:00   
50%      45.000000   8170.000000    21.000000            2025-02-28 12:00:00   
75%      58.000000   9992.500000   188.000000            2025-04-11 00:00:00   
max      70.000000  19778.000000   365.000000            2025-06-03 00:00:00   
std      15.287841   2904.390826   117.978184                            NaN   

              购买频率        总消费金额       平均订单金额         折扣力度  
count  1000.000000  1000.000000  1000.000000  1000.000000  
mean      4.560000  2054.679000   739.530832     0.050890  
min       0.000000     0.000000     0.000000     0.000000  
25%       2.000000  1395.750000   263.900000     0.000000  
50%       4.000000  2041.500000   455.137500     0.000000  
75%       7.000000  2679.250000   874.750000     0.080000  
max      14.000000  5852.000000  4445.000000     0.300000  
std       2.898068   961.284906   779.612809     0.089239  

会员与非会员平均消费金额对比:
是否会员
False    2035.957983
True     2071.685115
Name: 总消费金额, dtype: float64

各地区平均消费金额:
地区
西南    2141.916667
西北    2079.544828
华南    2067.291045
华北    2058.568345
华东    2029.803150
东北    2016.153333
华中    1984.161074
Name: 总消费金额, dtype: float64

变量相关性分析:
总消费金额     1.000000
平均订单金额    0.446292
购买频率      0.030452
会员天数      0.024801
折扣力度      0.010037
年龄       -0.006626
收入       -0.019257
Name: 总消费金额, dtype: float64

正在生成数据可视化图表...

data_visualization

member_distribution

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李昊哲小课

桃李不言下自成蹊

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值