1.项目背景
本项目基于模拟的阿迪达斯电商销售数据,通过AI辅助完成分析代码,旨在展示数据分析在电商领域的实际应用价值,尽管使用的是虚构数据,但分析方法、思路与结论仍具有参考意义,可作为电商数据分析的学习案例与方法论示范,本分析涵盖用户价值评估、销售周期与促销效果、产品组合优化以及区域消费差异等多个维度,为运动品牌电商决策提供了数据驱动的思考框架。
2.导入必要的库和设置
!pip install squarify -i https://pypi.tuna.tsinghua.edu.cn/simple/
!pip install mlxtend -i https://pypi.tuna.tsinghua.edu.cn/simple/
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple/
Collecting squarifyDownloading https://pypi.tuna.tsinghua.edu.cn/packages/b7/3c/eedbe9fb07cc20fd9a8423da14b03bc270d0570b3ba9174a4497156a2152/squarify-0.4.4-py3-none-any.whl (4.1 kB)
Installing collected packages: squarify
Successfully installed squarify-0.4.4
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple/
Collecting mlxtendDownloading https://pypi.tuna.tsinghua.edu.cn/packages/4c/43/2fc7f76c8891aef148901f1ba3dee65c1cbac00a85ae5ee0dabc2b861256/mlxtend-0.23.4-py3-none-any.whl (1.4 MB)
[2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m1.4/1.4 MB[0m [31m2.4 MB/s[0m eta [36m0:00:00[0m00:01[0m00:01[0m
[?25hRequirement already satisfied: scipy>=1.2.1 in /opt/conda/lib/python3.11/site-packages (from mlxtend) (1.12.0)
Requirement already satisfied: numpy>=1.16.2 in /opt/conda/lib/python3.11/site-packages (from mlxtend) (1.26.4)
Requirement already satisfied: pandas>=0.24.2 in /opt/conda/lib/python3.11/site-packages (from mlxtend) (2.2.1)
Requirement already satisfied: scikit-learn>=1.3.1 in /opt/conda/lib/python3.11/site-packages (from mlxtend) (1.4.1.post1)
Requirement already satisfied: matplotlib>=3.0.0 in /opt/conda/lib/python3.11/site-packages (from mlxtend) (3.8.3)
Requirement already satisfied: joblib>=0.13.2 in /opt/conda/lib/python3.11/site-packages (from mlxtend) (1.3.2)
Requirement already satisfied: contourpy>=1.0.1 in /opt/conda/lib/python3.11/site-packages (from matplotlib>=3.0.0->mlxtend) (1.2.0)
Requirement already satisfied: cycler>=0.10 in /opt/conda/lib/python3.11/site-packages (from matplotlib>=3.0.0->mlxtend) (0.12.1)
Requirement already satisfied: fonttools>=4.22.0 in /opt/conda/lib/python3.11/site-packages (from matplotlib>=3.0.0->mlxtend) (4.50.0)
Requirement already satisfied: kiwisolver>=1.3.1 in /opt/conda/lib/python3.11/site-packages (from matplotlib>=3.0.0->mlxtend) (1.4.5)
Requirement already satisfied: packaging>=20.0 in /opt/conda/lib/python3.11/site-packages (from matplotlib>=3.0.0->mlxtend) (24.0)
Requirement already satisfied: pillow>=8 in /opt/conda/lib/python3.11/site-packages (from matplotlib>=3.0.0->mlxtend) (10.2.0)
Requirement already satisfied: pyparsing>=2.3.1 in /opt/conda/lib/python3.11/site-packages (from matplotlib>=3.0.0->mlxtend) (3.1.2)
Requirement already satisfied: python-dateutil>=2.7 in /opt/conda/lib/python3.11/site-packages (from matplotlib>=3.0.0->mlxtend) (2.9.0)
Requirement already satisfied: pytz>=2020.1 in /opt/conda/lib/python3.11/site-packages (from pandas>=0.24.2->mlxtend) (2024.1)
Requirement already satisfied: tzdata>=2022.7 in /opt/conda/lib/python3.11/site-packages (from pandas>=0.24.2->mlxtend) (2024.1)
Requirement already satisfied: threadpoolctl>=2.0.0 in /opt/conda/lib/python3.11/site-packages (from scikit-learn>=1.3.1->mlxtend) (3.4.0)
Requirement already satisfied: six>=1.5 in /opt/conda/lib/python3.11/site-packages (from python-dateutil>=2.7->matplotlib>=3.0.0->mlxtend) (1.16.0)
Installing collected packages: mlxtend
Successfully installed mlxtend-0.23.4
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
from datetime import datetime, timedelta
import warnings
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler, MinMaxScaler
from sklearn.decomposition import PCA
from sklearn.metrics import silhouette_score
from matplotlib.dates import MonthLocator, DateFormatter
import networkx as nx
from sklearn.model_selection import train_test_split
from sklearn.metrics.pairwise import cosine_similarity
import squarify
from wordcloud import WordCloud
import matplotlib.colors as mcolors
from collections import Counter
from sklearn.linear_model import LinearRegression
import joblib
import os
from mlxtend.frequent_patterns import apriori, association_rules
from matplotlib.font_manager import FontProperties, fontManager
# 设置警告过滤
warnings.filterwarnings('ignore')# 设置显示格式
pd.set_option('display.max_columns', None)
pd.set_option('display.width', 1000)
pd.set_option('display.float_format', '{:.2f}'.format)# 设置seaborn风格
sns.set(style="whitegrid")
sns.set_context("talk")# 设置matplotlib中文字体(放在seaborn设置之后)
# 指定字体文件的路径
simhei_path = '/home/mw/project/SIMHEI.TTF'# 注册字体
fontManager.addfont(simhei_path)# 设置matplotlib字体参数
plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置默认使用SimHei
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
3.数据加载与探索
def load_data():"""加载阿迪达斯电商用户和订单数据"""users_df = pd.read_csv('/home/mw/input/data7557/阿迪达斯用户数据.csv', encoding='utf-8-sig')orders_df = pd.read_csv('/home/mw/input/data7557/阿迪达斯订单数据.csv', encoding='utf-8-sig')print(f"成功加载数据 - 用户数: {len(users_df)}, 订单数: {len(orders_df)}")return users_df, orders_df# 加载数据
users_df, orders_df = load_data()
成功加载数据 - 用户数: 10000, 订单数: 500000
def explore_data(df, name):"""探索数据集的基本信息参数:df: 数据框name: 数据集名称"""print(f"{name}数据基本信息:")print(f"形状: {df.shape}")print("数据类型:")print(df.dtypes)print("数据预览:")display(df.head())# 检查缺失值missing = df.isnull().sum()if missing.sum() > 0:print("缺失值统计:")print(missing[missing > 0])else:print("没有缺失值")# 数值型变量的基本统计量numeric_cols = df.select_dtypes(include=[np.number]).columnsif len(numeric_cols) > 0:print("数值型变量统计描述:")display(df[numeric_cols].describe())# 类别型变量的基本统计量cat_cols = df.select_dtypes(exclude=[np.number]).columnsif len(cat_cols) > 0:print("类别型变量值计数(前5个):")for col in cat_cols[:5]: # 只显示前5个类别变量的统计print(f"{col}:")display(df[col].value_counts().head())# 探索用户数据
explore_data(users_df, "用户")
用户数据基本信息:
形状: (10000, 6)
数据类型:
用户ID int64
性别 object
年龄 int64
是否会员 object
常用省份 object
常用城市 object
dtype: object
数据预览:
用户ID | 性别 | 年龄 | 是否会员 | 常用省份 | 常用城市 | |
---|---|---|---|---|---|---|
0 | 1 | 男 | 20 | 是 | 广东 | 广州 |
1 | 2 | 女 | 18 | 是 | 河北 | 石家庄 |
2 | 3 | 女 | 22 | 是 | 内蒙古 | 呼和浩特 |
3 | 4 | 男 | 50 | 是 | 湖北 | 襄阳 |
4 | 5 | 女 | 31 | 是 | 山东 | 临沂 |
没有缺失值
数值型变量统计描述:
用户ID | 年龄 | |
---|---|---|
count | 10000.00 | 10000.00 |
mean | 5000.50 | 31.07 |
std | 2886.90 | 9.82 |
min | 1.00 | 18.00 |
25% | 2500.75 | 23.00 |
50% | 5000.50 | 30.00 |
75% | 7500.25 | 37.00 |
max | 10000.00 | 70.00 |
类别型变量值计数(前5个):
性别:性别
女 5081
男 4919
Name: count, dtype: int64是否会员:是否会员
否 5013
是 4987
Name: count, dtype: int64常用省份:常用省份
广东 543
北京 529
上海 518
江苏 483
浙江 457
Name: count, dtype: int64常用城市:常用城市
北京 529
上海 518
天津 421
重庆 373
厦门 114
Name: count, dtype: int64
基于对用户数据的初步探索,我们可以得出以下结论:
-
数据规模:共有10,000名用户记录,包含6个字段(用户ID、性别、年龄、是否会员、常用省份、常用城市)。
-
数据完整性:数据集中没有缺失值,为后续分析提供了良好基础。
-
性别分布:女性用户(5,081人)略多于男性用户(4,919人),性别比例基本平衡,女性占比50.8%。
-
年龄特征:
- 用户年龄范围为18-70岁
- 平均年龄31.07岁
- 中位数年龄为30岁
- 25%-75%分位数为23-37岁,表明主要用户群体为年轻和中年人群
-
会员情况:会员(4,987人)与非会员(5,013人)比例几乎各占一半,会员转化率约为49.9%。
-
地域分布:
- 用户主要集中在经济发达省份,前五大用户来源省份依次为:广东(543人)、北京(529人)、上海(518人)、江苏(483人)和浙江(457人)
- 城市分布上,北京(529人)和上海(518人)两个一线城市用户最多,其次是天津(421人)和重庆(373人)等直辖市
这些基础统计特征表明,该品牌的用户群体以年轻成年人为主,性别分布均衡,地域上主要覆盖经济发达地区,特别是一线城市和直辖市,会员转化还有提升空间。
# 探索订单数据
explore_data(orders_df, "订单")
订单数据基本信息:
形状: (500000, 14)
数据类型:
订单ID int64
用户ID int64
下单时间 object
商品大类 object
商品子类 object
商品名称 object
单价 float64
购买数量 int64
订单总额 float64
收货省份 object
收货城市 object
性别 object
年龄 int64
是否会员 object
dtype: object
数据预览:
订单ID | 用户ID | 下单时间 | 商品大类 | 商品子类 | 商品名称 | 单价 | 购买数量 | 订单总额 | 收货省份 | 收货城市 | 性别 | 年龄 | 是否会员 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 318477 | 9052 | 2024-01-01 00:00:47.416583 | 运动鞋 | 户外鞋 | 特锐斯山地系列 | 1241.82 | 1 | 1241.82 | 贵州 | 安顺 | 男 | 35 | 否 |
1 | 112481 | 4053 | 2024-01-01 00:02:40.515327 | 运动服装 | 上衣 | 篮球上衣 | 367.87 | 1 | 367.87 | 北京 | 北京 | 女 | 25 | 否 |
2 | 149467 | 458 | 2024-01-01 00:02:45.045488 | 运动服装 | 上衣 | 运动夹克 | 718.49 | 1 | 718.49 | 上海 | 上海 | 女 | 21 | 是 |
3 | 340464 | 6811 | 2024-01-01 00:04:50.465206 | 运动服装 | 套装 | 运动套装 | 803.27 | 1 | 803.27 | 四川 | 乐山 | 女 | 23 | 是 |
4 | 153344 | 4947 | 2024-01-01 00:08:07.517883 | 运动服装 | 外套 | 保暖外套 | 862.81 | 1 | 862.81 | 浙江 | 温州 | 男 | 23 | 否 |
没有缺失值
数值型变量统计描述:
订单ID | 用户ID | 单价 | 购买数量 | 订单总额 | 年龄 | |
---|---|---|---|---|---|---|
count | 500000.00 | 500000.00 | 500000.00 | 500000.00 | 500000.00 | 500000.00 |
mean | 250000.50 | 5000.71 | 524.58 | 1.55 | 776.57 | 29.55 |
std | 144337.71 | 2883.36 | 363.36 | 0.76 | 646.79 | 8.77 |
min | 1.00 | 1.00 | 38.56 | 1.00 | 39.52 | 18.00 |
25% | 125000.75 | 2511.00 | 208.57 | 1.00 | 292.62 | 23.00 |
50% | 250000.50 | 4987.00 | 432.98 | 1.00 | 616.83 | 28.00 |
75% | 375000.25 | 7489.00 | 781.61 | 2.00 | 1046.53 | 34.00 |
max | 500000.00 | 10000.00 | 1798.91 | 5.00 | 7158.95 | 70.00 |
类别型变量值计数(前5个):
下单时间:下单时间
2024-11-04 00:25:44.133782 8
2024-06-16 14:50:50.302207 8
2024-11-10 20:10:01.797755 7
2024-06-18 09:19:56.346795 7
2024-12-08 01:43:47.036755 7
Name: count, dtype: int64商品大类:商品大类
运动服装 199697
运动鞋 165847
运动配饰 71688
运动装备 62768
Name: count, dtype: int64商品子类:商品子类
上衣 64019
下装 57912
套装 41748
休闲鞋 38364
外套 36018
Name: count, dtype: int64商品名称:商品名称
训练套装 8429
运动套装 8411
足球套装 8406
运动长裤 8393
训练紧身裤 8379
Name: count, dtype: int64收货省份:收货省份
北京 26842
上海 26682
广东 26411
江苏 23618
浙江 22229
Name: count, dtype: int64
基于对订单数据的初步探索,我们可以得出以下关键结论:
-
数据规模:共有500,000条订单记录,包含14个字段,涵盖订单信息、商品信息、用户特征等多维度数据。
-
数据完整性:订单数据中没有缺失值,数据质量良好。
-
订单金额特征:
- 平均订单金额为776.57元
- 订单金额中位数为616.83元
- 金额分布在39.52元至7,158.95元之间
- 75%的订单金额低于1,046.53元
-
商品价格分布:
- 商品单价平均为524.58元
- 单价中位数为432.98元
- 价格范围从38.56元到1,798.91元不等
- 价格呈现正偏分布,大部分商品价格集中在中低价位
-
购买数量:
- 平均购买数量为1.55件
- 超过50%的订单仅购买1件商品
- 最大单次购买数量为5件
- 大多数订单为单品购买,多件购买占比较小
-
商品类别分布:
- 运动服装是最畅销品类,占比约40%(199,697件)
- 运动鞋次之,占比约33%(165,847件)
- 运动配饰和运动装备分别占14%和13%
- 细分品类中,上衣(64,019件)、下装(57,912件)和套装(41,748件)是最受欢迎的三类产品
-
热销商品:
- 训练套装、运动套装和足球套装是最畅销的具体商品
- 运动长裤和训练紧身裤也有较高的销量
-
地域分布:
- 订单主要集中在经济发达地区
- 前五大订单来源省份依次为:北京(26,842单)、上海(26,682单)、广东(26,411单)、江苏(23,618单)和浙江(22,229单)
- 一线城市和东部沿海省份是主要消费市场
-
用户购买特征:
- 订单中用户平均年龄为29.55岁,比用户数据库的平均年龄(31.07岁)略低
- 年龄中位数为28岁,表明购买频率更高的用户群体偏年轻
这些发现表明该品牌在年轻消费者中更受欢迎,产品以中端价位为主,运动服装和运动鞋是核心产品线。订单主要来自经济发达地区,大部分消费者倾向于单次购买单件商品,具有较为明确的购买目的。
4.数据预处理
def preprocess_data(users_df, orders_df):"""数据预处理:1. 数据类型转换2. 处理异常值3. 创建新的特征返回:处理后的用户数据和订单数据"""# 创建副本以避免警告users = users_df.copy()orders = orders_df.copy()# 1. 数据类型转换# 将下单时间转换为datetime类型orders['下单时间'] = pd.to_datetime(orders['下单时间'])# 2. 创建新的时间特征orders['下单日期'] = orders['下单时间'].dt.dateorders['下单年份'] = orders['下单时间'].dt.yearorders['下单月份'] = orders['下单时间'].dt.monthorders['下单日'] = orders['下单时间'].dt.dayorders['下单小时'] = orders['下单时间'].dt.hourorders['下单星期'] = orders['下单时间'].dt.dayofweekorders['是否周末'] = orders['下单星期'].apply(lambda x: 1 if x >= 5 else 0)# 创建季节特征seasons = {1: '冬季', 2: '冬季', 3: '春季', 4: '春季', 5: '春季', 6: '夏季', 7: '夏季', 8: '夏季', 9: '秋季', 10: '秋季', 11: '秋季', 12: '冬季'}orders['季节'] = orders['下单月份'].map(seasons)# 创建是否节假日特征(简化版)holiday_periods = [# 春节期间((1, 15), (2, 15)),# 五一假期((4, 25), (5, 5)),# 国庆假期((9, 25), (10, 7)),# 双十一期间((11, 1), (11, 15)),# 双十二期间((12, 1), (12, 15)),# 圣诞元旦期间((12, 20), (1, 5))]def is_holiday(date):month, day = date.month, date.dayfor start, end in holiday_periods:start_month, start_day = startend_month, end_day = end# 处理跨年的情况if end_month < start_month:if (month == start_month and day >= start_day) or (month == end_month and day <= end_day):return 1else:if (month == start_month and day >= start_day) or (month == end_month and day <= end_day) or \(start_month < month < end_month):return 1return 0orders['是否节假日'] = orders['下单时间'].apply(is_holiday)# 3. 检查并处理异常值# 检查价格、数量、总额的负值或异常高值print("检查异常值:")price_outliers = orders[orders['单价'] <= 0].shape[0]quantity_outliers = orders[orders['购买数量'] <= 0].shape[0]total_outliers = orders[orders['订单总额'] <= 0].shape[0]print(f"单价小于等于0的订单数: {price_outliers}")print(f"购买数量小于等于0的订单数: {quantity_outliers}")print(f"订单总额小于等于0的订单数: {total_outliers}")# 移除异常值orders = orders[(orders['单价'] > 0) & (orders['购买数量'] > 0) & (orders['订单总额'] > 0)]# 4. 将是否会员转换为数值型users['会员标志'] = users['是否会员'].map({'是': 1, '否': 0})orders['会员标志'] = orders['是否会员'].map({'是': 1, '否': 0})return users, orders# 预处理数据
processed_users, processed_orders = preprocess_data(users_df, orders_df)
检查异常值:
单价小于等于0的订单数: 0
购买数量小于等于0的订单数: 0
订单总额小于等于0的订单数: 0
def visualize_basic_distributions(users, orders):"""可视化用户和订单的基本分布"""# 创建4x2的图表布局fig, axes = plt.subplots(4, 2, figsize=(20, 25))# 用户性别分布gender_counts = users['性别'].value_counts()axes[0, 0].pie(gender_counts, labels=gender_counts.index, autopct='%1.1f%%', startangle=90)axes[0, 0].set_title('用户性别分布')# 用户年龄分布sns.histplot(users['年龄'], bins=20, kde=True, ax=axes[0, 1])axes[0, 1].set_title('用户年龄分布')axes[0, 1].set_xlabel('年龄')axes[0, 1].set_ylabel('用户数量')# 用户会员比例member_counts = users['是否会员'].value_counts()axes[1, 0].pie(member_counts, labels=member_counts.index, autopct='%1.1f%%', startangle=90)axes[1, 0].set_title('用户会员比例')# 用户地域分布(Top 10)region_counts = users.groupby('常用省份').size().sort_values(ascending=False).head(10)sns.barplot(x=region_counts.index, y=region_counts.values, ax=axes[1, 1])axes[1, 1].set_title('用户常用省份Top 10')axes[1, 1].set_xlabel('省份')axes[1, 1].set_ylabel('用户数量')plt.setp(axes[1, 1].xaxis.get_majorticklabels(), rotation=0)# 订单商品大类分布category_counts = orders['商品大类'].value_counts()axes[2, 0].pie(category_counts, labels=category_counts.index, autopct='%1.1f%%', startangle=90)axes[2, 0].set_title('订单商品大类分布')# 订单金额分布sns.histplot(orders['订单总额'], bins=50, kde=True, ax=axes[2, 1])axes[2, 1].set_title('订单金额分布')axes[2, 1].set_xlabel('订单金额(元)')axes[2, 1].set_ylabel('订单数量')# 订单月度分布monthly_orders = orders.groupby('下单月份').size()sns.barplot(x=monthly_orders.index, y=monthly_orders.values, ax=axes[3, 0])axes[3, 0].set_title('订单月度分布')axes[3, 0].set_xlabel('月份')axes[3, 0].set_ylabel('订单数量')# 订单星期分布weekday_orders = orders.groupby('下单星期').size()sns.barplot(x=weekday_orders.index, y=weekday_orders.values, ax=axes[3, 1])axes[3, 1].set_title('订单星期分布')axes[3, 1].set_xlabel('星期(0=周一,6=周日)')axes[3, 1].set_ylabel('订单数量')plt.tight_layout()plt.show()# 可视化基本分布
visualize_basic_distributions(processed_users, processed_orders)

用户特征分析
-
性别分布:
- 女性用户略占优势,占比50.8%
- 男性用户占比49.2%
- 性别分布基本平衡,表明品牌对两性具有同等吸引力
-
年龄分布:
- 用户年龄主要集中在18-40岁之间
- 有三个明显的年龄峰值:20岁左右、30岁左右、35岁左右
- 18-25岁的年轻群体和28-35岁的青年群体是最主要的用户群
- 40岁以上用户数量显著下降,50岁以上用户极少
-
会员比例:
- 会员与非会员比例接近,会员占49.9%
- 非会员占50.1%
- 会员转化率有提升空间
-
用户地域分布:
- 前十大用户省份依次为:广东、北京、上海、江苏、浙江、福建、天津、山东、四川、重庆
- 一线城市和东部沿海省份是主要用户来源地
- 华南、华东和华北地区用户较多
订单特征分析
-
商品类别分布:
- 运动服装是最畅销品类,占比39.9%
- 运动鞋位居第二,占比33.2%
- 运动配饰占比14.3%
- 运动装备占比12.6%
- 服装和鞋类合计占总销量的73.1%,是核心产品线
-
订单金额分布:
- 订单金额呈现明显的右偏分布
- 大多数订单集中在低于1,000元的价格区间
- 500元以下订单数量最多
- 高额订单(>3,000元)较少
- 订单金额分布形状表明多数消费者购买单件或少量中低价产品
-
月度销售趋势:
- 销售呈现明显的季节性波动
- 销售高峰月份是8月、11月和12月
- 销售低谷月份是2月、3月和4月
- 下半年(7-12月)的销售整体高于上半年
- 年末(11-12月)和夏季(8月)是两个主要销售高峰期
-
星期销售分布:
- 周末(星期5、6,对应周六日)订单量明显高于工作日
- 周六和周日的订单量基本相等,都显著高于平日
- 周一至周五订单量相对稳定,无明显波动
- 工作日订单量平均约为65,000单,而周末每天达到80,000单以上
综合结论
阿迪达斯电商平台的典型用户是18-35岁的年轻消费者,性别分布均衡,主要分布在经济发达地区和东部沿海省份。产品偏好以运动服装和运动鞋为主,消费行为呈现明显的季节性和周末效应。用户消费金额集中在中低价位,大多数订单金额低于1,000元。销售高峰出现在夏季(8月)和年末促销季(11-12月),周末购物意愿明显高于工作日。
这些特征表明,品牌应该重点关注年轻消费群体,优化服装和鞋类核心产品线,并针对季节性波动和周末消费高峰制定相应的营销策略。同时,会员转化有提升空间,可考虑加强会员激励计划。
5.用户画像分析
5.1 RFM分析
def create_user_profile(users, orders):"""创建用户画像特征返回:包含用户画像特征的数据框"""# 复制用户数据框user_profile = users.copy()# 按用户ID分组计算各种指标# 订单总数order_counts = orders.groupby('用户ID').size().reset_index(name='订单总数')# 购买金额相关指标purchase_amount = orders.groupby('用户ID')['订单总额'].agg(['sum', 'mean', 'min', 'max', 'count', 'std']).reset_index()purchase_amount.columns = ['用户ID', '总消费额', '平均订单金额', '最小订单金额', '最大订单金额', '订单数量', '订单金额标准差']# 购买时间相关指标orders['下单时间_datetime'] = pd.to_datetime(orders['下单时间'])time_metrics = orders.groupby('用户ID').agg(最早购买时间=('下单时间_datetime', 'min'),最近购买时间=('下单时间_datetime', 'max')).reset_index()# 计算购买间隔天数now = pd.Timestamp('2024-12-31') # 使用2024年末作为"当前"时间time_metrics['最近购买距今天数'] = (now - time_metrics['最近购买时间']).dt.daystime_metrics['购买时间跨度'] = (time_metrics['最近购买时间'] - time_metrics['最早购买时间']).dt.days# 购买频率 = 订单数 / 购买时间跨度(天)time_metrics = pd.merge(time_metrics, order_counts, on='用户ID')time_metrics['购买频率'] = time_metrics['订单总数'] / (time_metrics['购买时间跨度'] + 1) # 加1避免除以0# 商品类别偏好category_counts = pd.crosstab(orders['用户ID'], orders['商品大类'])category_counts = category_counts.reset_index()# 汇总用户画像user_profile = pd.merge(user_profile, purchase_amount, on='用户ID', how='left')user_profile = pd.merge(user_profile, time_metrics, on='用户ID', how='left')user_profile = pd.merge(user_profile, category_counts, on='用户ID', how='left')# 填充缺失值(没有购买记录的用户)user_profile.fillna(0, inplace=True)# 计算RFM值# R(Recency): 最近一次购买距今天数 (值越小越好)# F(Frequency): 购买频率 (值越大越好)# M(Monetary): 总消费额 (值越大越好)# 对R、F、M进行分段user_profile['R分数'] = pd.qcut(user_profile['最近购买距今天数'].clip(lower=0), q=5, labels=[5, 4, 3, 2, 1], duplicates='drop') # R值越小,分数越高user_profile['F分数'] = pd.qcut(user_profile['订单总数'].clip(lower=0), q=5, labels=[1, 2, 3, 4, 5], duplicates='drop')user_profile['M分数'] = pd.qcut(user_profile['总消费额'].clip(lower=0), q=5, labels=[1, 2, 3, 4, 5], duplicates='drop')# 转为数值型user_profile['R分数'] = user_profile['R分数'].astype(float).astype('Int64')user_profile['F分数'] = user_profile['F分数'].astype(float).astype('Int64')user_profile['M分数'] = user_profile['M分数'].astype(float).astype('Int64')# 计算RFM总分user_profile['RFM总分'] = user_profile['R分数'] + user_profile['F分数'] + user_profile['M分数']# 根据RFM总分对用户进行分级user_profile['用户价值分级'] = pd.cut(user_profile['RFM总分'], bins=[0, 5, 9, 12, 15], labels=['低价值', '一般价值', '高价值', '超高价值'])return user_profile# 创建用户画像
user_profile = create_user_profile(processed_users, processed_orders)
# 显示用户画像数据预览
display(user_profile.head())
用户ID | 性别 | 年龄 | 是否会员 | 常用省份 | 常用城市 | 会员标志 | 总消费额 | 平均订单金额 | 最小订单金额 | 最大订单金额 | 订单数量 | 订单金额标准差 | 最早购买时间 | 最近购买时间 | 最近购买距今天数 | 购买时间跨度 | 订单总数 | 购买频率 | 运动服装 | 运动装备 | 运动配饰 | 运动鞋 | R分数 | F分数 | M分数 | RFM总分 | 用户价值分级 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 男 | 20 | 是 | 广东 | 广州 | 1 | 113158.87 | 912.57 | 85.40 | 4021.35 | 124 | 727.78 | 2024-01-05 17:01:23.744208 | 2024-12-23 05:18:30.536360 | 7 | 352 | 124 | 0.35 | 33 | 26 | 8 | 57 | 2 | 5 | 5 | 12 | 高价值 |
1 | 2 | 女 | 18 | 是 | 河北 | 石家庄 | 1 | 78732.47 | 779.53 | 88.28 | 4791.80 | 101 | 764.50 | 2024-01-06 21:17:25.334686 | 2024-12-29 08:35:45.799921 | 1 | 357 | 101 | 0.28 | 58 | 9 | 16 | 18 | 5 | 5 | 5 | 15 | 超高价值 |
2 | 3 | 女 | 22 | 是 | 内蒙古 | 呼和浩特 | 1 | 46850.47 | 780.84 | 88.31 | 3485.13 | 60 | 647.69 | 2024-01-14 12:16:18.582673 | 2024-12-30 07:13:32.234239 | 0 | 350 | 60 | 0.17 | 24 | 7 | 15 | 14 | 5 | 4 | 4 | 13 | 超高价值 |
3 | 4 | 男 | 50 | 是 | 湖北 | 襄阳 | 1 | 28950.40 | 1033.94 | 73.88 | 4306.74 | 28 | 1056.36 | 2024-01-07 01:39:45.038661 | 2024-12-28 07:07:35.495178 | 2 | 356 | 28 | 0.08 | 12 | 7 | 0 | 9 | 4 | 2 | 3 | 9 | 一般价值 |
4 | 5 | 女 | 31 | 是 | 山东 | 临沂 | 1 | 35163.71 | 549.43 | 86.56 | 2356.70 | 64 | 487.44 | 2024-01-02 15:34:08.334255 | 2024-12-21 02:44:47.271578 | 9 | 353 | 64 | 0.18 | 30 | 9 | 17 | 8 | 2 | 4 | 3 | 9 | 一般价值 |
def rfm_analysis_visualization(user_profile):"""RFM分析结果可视化"""# 创建3x2的图表布局fig, axes = plt.subplots(3, 2, figsize=(20, 24))# 1. R分数分布sns.countplot(x='R分数', data=user_profile, ax=axes[0, 0])axes[0, 0].set_title('R分数分布(最近购买)')axes[0, 0].set_xlabel('R分数(5=最近购买)')axes[0, 0].set_ylabel('用户数量')# 2. F分数分布sns.countplot(x='F分数', data=user_profile, ax=axes[0, 1])axes[0, 1].set_title('F分数分布(购买频率)')axes[0, 1].set_xlabel('F分数(5=高频购买)')axes[0, 1].set_ylabel('用户数量')# 3. M分数分布sns.countplot(x='M分数', data=user_profile, ax=axes[1, 0])axes[1, 0].set_title('M分数分布(购买金额)')axes[1, 0].set_xlabel('M分数(5=高额购买)')axes[1, 0].set_ylabel('用户数量')# 4. RFM总分分布sns.histplot(user_profile['RFM总分'], bins=13, kde=True, ax=axes[1, 1])axes[1, 1].set_title('RFM总分分布')axes[1, 1].set_xlabel('RFM总分')axes[1, 1].set_ylabel('用户数量')# 5. 用户价值分级value_counts = user_profile['用户价值分级'].value_counts().sort_index()axes[2, 0].pie(value_counts, labels=value_counts.index, autopct='%1.1f%%', startangle=90)axes[2, 0].set_title('用户价值分级分布')# 6. 用户价值分级与平均消费额avg_spend_by_value = user_profile.groupby('用户价值分级')['总消费额'].mean().sort_index()sns.barplot(x=avg_spend_by_value.index, y=avg_spend_by_value.values, ax=axes[2, 1])axes[2, 1].set_title('不同价值等级用户的平均消费额')axes[2, 1].set_xlabel('用户价值等级')axes[2, 1].set_ylabel('平均消费额(元)')plt.tight_layout()plt.show()# 用户价值分级统计数据value_stats = user_profile.groupby('用户价值分级').agg({'用户ID': 'count','总消费额': 'sum','订单数量': 'sum','平均订单金额': 'mean'}).reset_index()value_stats = value_stats.rename(columns={'用户ID': '用户数量'})value_stats['人均消费额'] = value_stats['总消费额'] / value_stats['用户数量']value_stats['人均订单数'] = value_stats['订单数量'] / value_stats['用户数量']# 计算占比value_stats['用户占比'] = value_stats['用户数量'] / value_stats['用户数量'].sum() * 100value_stats['消费额占比'] = value_stats['总消费额'] / value_stats['总消费额'].sum() * 100value_stats['订单量占比'] = value_stats['订单数量'] / value_stats['订单数量'].sum() * 100# 显示价值分级统计display(value_stats)# 进行RFM分析可视化
rfm_analysis_visualization(user_profile)

用户价值分级 | 用户数量 | 总消费额 | 订单数量 | 平均订单金额 | 人均消费额 | 人均订单数 | 用户占比 | 消费额占比 | 订单量占比 | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 低价值 | 2193 | 26179954.96 | 35889 | 735.58 | 11937.96 | 16.37 | 21.93 | 6.74 | 7.18 |
1 | 一般价值 | 3006 | 76163166.69 | 101798 | 753.59 | 25337.05 | 33.86 | 30.06 | 19.62 | 20.36 |
2 | 高价值 | 2392 | 105243754.95 | 137007 | 770.06 | 43998.23 | 57.28 | 23.92 | 27.10 | 27.40 |
3 | 超高价值 | 2409 | 180700197.07 | 225306 | 803.17 | 75010.46 | 93.53 | 24.09 | 46.54 | 45.06 |
RFM各维度分布特征
-
最近购买时间®分布:
- R值为5(最近购买)的用户数量最多,超过3,000人
- R值为4的用户数量最少,约1,200人
- 总体呈现递减后急剧上升的分布,而非严格的U型分布
- R=1到R=4呈现逐步下降趋势(从约2,000人降至1,200人)
- R=5处出现显著的峰值(超过3,000人)
- 这表明有大量用户最近有购买行为,同时也有相当数量的用户较长时间未购买
-
购买频率(F)分布:
- F值分布相对均衡,在1,900-2,050之间
- F值为3(高频购买)的用户略多一些
- F值为1的用户也相对较多
- 总体购买频率分布较为平均,无明显偏态
-
购买金额(M)分布:
- M值分布非常均匀,五个等级的用户数量几乎相等,都接近2,000人
- 各档位用户消费金额差异不大,表明用户群体的消费额相对均衡
- 无明显的高消费或低消费群体集中现象
-
RFM综合评分分布:
- RFM总分分布呈双峰态势,在分数为3和15左右各有一个明显的波峰
- 分数为15的用户数量最多,表明高价值用户占比较大
- 分数在7-12之间的用户分布较为平稳
- 极低分值(3-4)和极高分值(14-15)的用户相对较多
用户价值分级结果
-
用户价值分布:
- 一般价值用户占比最大,为30.1%(3,006人)
- 超高价值用户占比24.1%(2,409人)
- 高价值用户占比23.9%(2,392人)
- 低价值用户占比21.9%(2,193人)
- 整体用户价值分布相对均衡,各价值段占比无极端偏差
-
消费贡献特征:
- 超高价值用户贡献了46.5%的消费额和45.1%的订单量,但仅占用户总数的24.1%
- 高价值用户贡献了27.1%的消费额,占用户总数的23.9%
- 一般价值用户贡献了19.6%的消费额,占用户总数的30.1%
- 低价值用户仅贡献了6.7%的消费额,占用户总数的21.9%
- 价值分级越高的用户群体,人均消费额和订单数明显增加
-
人均消费水平:
- 超高价值用户人均消费额达75,010元,是低价值用户(11,938元)的6.3倍
- 高价值用户人均消费额为43,998元
- 一般价值用户人均消费额为25,337元
- 各价值级别用户的人均消费额呈现明显的阶梯递增关系
-
购买行为差异:
- 超高价值用户平均下单93.5次,远高于其他群体
- 高价值用户平均下单57.3次
- 一般价值用户平均下单33.9次
- 低价值用户平均下单16.4次
- 用户价值与购买频次呈强正相关
-
平均订单金额:
- 超高价值用户的平均订单金额为803元,高于其他群体
- 高价值用户的平均订单金额为770元
- 一般价值用户的平均订单金额为754元
- 低价值用户的平均订单金额为736元
- 用户价值与单次消费金额也有正相关,但差距不如购买频次显著
核心洞察与商业价值
-
帕累托原则验证:
- 约24%的超高价值用户贡献了近47%的消费额,接近经典的80/20法则
- 超高价值和高价值用户合计占比48%,贡献了73.6%的消费额
- 这表明企业应重点维护高价值客户群体
-
用户发展策略指导:
- 超高价值用户的平均订单金额(803元)与低价值用户(736元)相差不大(约9%),但购买频次差异巨大(5.7倍)
- 这表明提高用户购买频率比提高单次消费额更有效
- 促进用户从低价值向高价值迁移的关键是增加购买频次,而非单次消费额
-
资源分配建议:
- 针对超高价值和高价值用户(共48%用户)的营销支出应占总预算的70%以上
- 为一般价值用户(30.1%)设计升级策略,鼓励增加购买频次
- 对低价值用户(21.9%)实施有选择性的激活措施,重点提高其复购率
这些发现表明,阿迪达斯的用户价值分布相对均衡,但贡献差异显著。维护高价值客户并促进一般价值客户升级应是核心营销策略,同时增加用户购买频次比提高单次消费额更为重要。
5.2 用户聚类分析
def user_clustering_analysis(user_profile):"""用户聚类分析通过K-means对用户进行聚类,识别不同用户群体"""# 选择用于聚类的特征cluster_features = ['年龄', '会员标志', '订单数量', '总消费额', '平均订单金额', '最近购买距今天数', '购买频率', '运动鞋', '运动服装', '运动配饰', '运动装备']# 确保所有特征都存在valid_features = [feat for feat in cluster_features if feat in user_profile.columns]# 提取聚类特征X = user_profile[valid_features].copy()# 进行标准化scaler = StandardScaler()X_scaled = scaler.fit_transform(X)# 使用肘部法则确定最佳K值wcss = []silhouette_avg = []k_range = range(2, 11)for k in k_range:kmeans = KMeans(n_clusters=k, random_state=15, n_init=10)kmeans.fit(X_scaled)wcss.append(kmeans.inertia_)# 计算轮廓系数cluster_labels = kmeans.labels_silhouette_avg.append(silhouette_score(X_scaled, cluster_labels))# 可视化肘部法则和轮廓系数fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(18, 7))ax1.plot(k_range, wcss, 'bo-')ax1.set_title('肘部法则')ax1.set_xlabel('聚类数量(K)')ax1.set_ylabel('WCSS值')ax1.grid(True)ax2.plot(k_range, silhouette_avg, 'ro-')ax2.set_title('轮廓系数法')ax2.set_xlabel('聚类数量(K)')ax2.set_ylabel('轮廓系数值')ax2.grid(True)plt.tight_layout()plt.show()best_k = 3# 使用最佳K进行聚类kmeans = KMeans(n_clusters=best_k, random_state=15, n_init=10)user_profile['用户群体'] = kmeans.fit_predict(X_scaled)# 分析各聚类的特征cluster_analysis = user_profile.groupby('用户群体').agg({'用户ID': 'count','年龄': 'mean','会员标志': 'mean','订单数量': 'mean','总消费额': 'mean','平均订单金额': 'mean','最近购买距今天数': 'mean','购买频率': 'mean','运动鞋': 'mean','运动服装': 'mean','运动配饰': 'mean','运动装备': 'mean'}).reset_index()cluster_analysis = cluster_analysis.rename(columns={'用户ID': '用户数量'})# 计算占比cluster_analysis['用户占比'] = cluster_analysis['用户数量'] / cluster_analysis['用户数量'].sum() * 100# 显示聚类分析结果print("用户聚类分析结果(每个群体的特征均值):")display(cluster_analysis)# 可视化聚类特征# 使用PCA将数据降至2维进行可视化pca = PCA(n_components=2)X_pca = pca.fit_transform(X_scaled)# 添加PCA结果和聚类标签pca_df = pd.DataFrame(data=X_pca, columns=['主成分1', '主成分2'])pca_df['用户群体'] = user_profile['用户群体']plt.figure(figsize=(12, 10))sns.scatterplot(x='主成分1', y='主成分2', hue='用户群体', data=pca_df, palette='viridis', s=100, alpha=0.7)plt.title('用户聚类PCA可视化')plt.legend(title='用户群体')plt.tight_layout()plt.show()# 对每个聚类进行标注# 基于聚类特征,给每个群体一个描述性标签cluster_labels = []for _, cluster in cluster_analysis.iterrows():cluster_id = cluster['用户群体']if cluster['订单数量'] > cluster_analysis['订单数量'].mean() and \cluster['总消费额'] > cluster_analysis['总消费额'].mean():if cluster['会员标志'] > 0.7:label = f"群体{cluster_id}: 高价值忠实会员"else:label = f"群体{cluster_id}: 高消费非会员客户"elif cluster['购买频率'] < cluster_analysis['购买频率'].mean() and \cluster['最近购买距今天数'] > cluster_analysis['最近购买距今天数'].mean():label = f"群体{cluster_id}: 流失风险客户"elif cluster['平均订单金额'] > cluster_analysis['平均订单金额'].mean() and \cluster['订单数量'] < cluster_analysis['订单数量'].mean():label = f"群体{cluster_id}: 高单价低频客户"else:label = f"群体{cluster_id}: 普通消费客户"# 获取描述特征字典desc_dict = get_cluster_description_expanded(cluster, cluster_analysis)# 创建包含所有信息的记录cluster_record = {'用户群体': cluster_id,'群体标签': label}# 添加所有描述特征cluster_record.update(desc_dict)cluster_labels.append(cluster_record)# 显示群体标签与详细特征cluster_labels_df = pd.DataFrame(cluster_labels)display(cluster_labels_df)# 创建简化版特征表,带有基本统计信息,便于快速浏览summary_labels = []for _, cluster in cluster_analysis.iterrows():cluster_id = cluster['用户群体']if cluster['订单数量'] > cluster_analysis['订单数量'].mean() and \cluster['总消费额'] > cluster_analysis['总消费额'].mean():if cluster['会员标志'] > 0.7:label = f"群体{cluster_id}: 高价值忠实会员"else:label = f"群体{cluster_id}: 高消费非会员客户"elif cluster['购买频率'] < cluster_analysis['购买频率'].mean() and \cluster['最近购买距今天数'] > cluster_analysis['最近购买距今天数'].mean():label = f"群体{cluster_id}: 流失风险客户"elif cluster['平均订单金额'] > cluster_analysis['平均订单金额'].mean() and \cluster['订单数量'] < cluster_analysis['订单数量'].mean():label = f"群体{cluster_id}: 高单价低频客户"else:label = f"群体{cluster_id}: 普通消费客户"summary_labels.append({'用户群体': cluster_id,'群体标签': label,'用户数量': cluster['用户数量'],'用户占比': f"{cluster['用户占比']:.1f}%",'人均消费': f"{cluster['总消费额']:.1f}元",'平均订单数': f"{cluster['订单数量']:.1f}",})# 显示用户群体概要print("用户群体概要:")summary_df = pd.DataFrame(summary_labels)display(summary_df)return user_profiledef get_cluster_description_expanded(cluster, cluster_analysis):"""生成聚类的描述性特征,拆分为多个部分"""avg_age = cluster['年龄']member_ratio = cluster['会员标志'] * 100order_count = cluster['订单数量']total_spend = cluster['总消费额']avg_order = cluster['平均订单金额']recency = cluster['最近购买距今天数']frequency = cluster['购买频率']# 产品偏好product_prefs = []if cluster['运动鞋'] > cluster_analysis['运动鞋'].mean():product_prefs.append("运动鞋")if cluster['运动服装'] > cluster_analysis['运动服装'].mean():product_prefs.append("运动服装")if cluster['运动配饰'] > cluster_analysis['运动配饰'].mean():product_prefs.append("运动配饰")if cluster['运动装备'] > cluster_analysis['运动装备'].mean():product_prefs.append("运动装备")product_preference = "、".join(product_prefs) if product_prefs else "无明显偏好"# 返回拆分后的特征描述return {'人口特征': f"平均年龄{avg_age:.1f}岁,会员比例{member_ratio:.1f}%",'消费能力': f"人均消费{total_spend:.1f}元,平均订单{order_count:.1f}单",'订单特征': f"平均订单金额{avg_order:.1f}元",'活跃情况': f"最近购买距今{recency:.1f}天,频率{frequency:.3f}次/天",'产品偏好': product_preference}def get_cluster_description(cluster, cluster_analysis):"""生成聚类的完整描述性文本 (保留原函数供需要时使用)"""avg_age = cluster['年龄']member_ratio = cluster['会员标志'] * 100order_count = cluster['订单数量']total_spend = cluster['总消费额']avg_order = cluster['平均订单金额']recency = cluster['最近购买距今天数']frequency = cluster['购买频率']# 产品偏好product_prefs = []if cluster['运动鞋'] > cluster_analysis['运动鞋'].mean():product_prefs.append("运动鞋")if cluster['运动服装'] > cluster_analysis['运动服装'].mean():product_prefs.append("运动服装")if cluster['运动配饰'] > cluster_analysis['运动配饰'].mean():product_prefs.append("运动配饰")if cluster['运动装备'] > cluster_analysis['运动装备'].mean():product_prefs.append("运动装备")product_preference = "、".join(product_prefs) if product_prefs else "无明显偏好"description = f"平均年龄{avg_age:.1f}岁,会员比例{member_ratio:.1f}%,"description += f"平均订单数{order_count:.1f},人均消费{total_spend:.1f}元,"description += f"平均订单金额{avg_order:.1f}元,最近购买距今{recency:.1f}天,"description += f"购买频率{frequency:.2f}次/天,产品偏好:{product_preference}"return description# 进行用户聚类分析
user_profile = user_clustering_analysis(user_profile)

用户聚类分析结果(每个群体的特征均值):
用户群体 | 用户数量 | 年龄 | 会员标志 | 订单数量 | 总消费额 | 平均订单金额 | 最近购买距今天数 | 购买频率 | 运动鞋 | 运动服装 | 运动配饰 | 运动装备 | 用户占比 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 4263 | 34.01 | 0.24 | 22.14 | 16349.15 | 742.41 | 15.76 | 0.07 | 7.28 | 8.94 | 3.17 | 2.75 | 42.63 |
1 | 1 | 3878 | 29.59 | 0.54 | 54.15 | 41625.04 | 771.83 | 4.15 | 0.15 | 17.77 | 21.83 | 7.79 | 6.77 | 38.78 |
2 | 2 | 1859 | 27.43 | 1.00 | 105.22 | 84544.78 | 805.37 | 2.09 | 0.29 | 35.46 | 41.39 | 15.04 | 13.32 | 18.59 |

用户群体 | 群体标签 | 人口特征 | 消费能力 | 订单特征 | 活跃情况 | 产品偏好 | |
---|---|---|---|---|---|---|---|
0 | 0.00 | 群体0.0: 流失风险客户 | 平均年龄34.0岁,会员比例24.3% | 人均消费16349.2元,平均订单22.1单 | 平均订单金额742.4元 | 最近购买距今15.8天,频率0.067次/天 | 无明显偏好 |
1 | 1.00 | 群体1.0: 普通消费客户 | 平均年龄29.6岁,会员比例53.9% | 人均消费41625.0元,平均订单54.2单 | 平均订单金额771.8元 | 最近购买距今4.1天,频率0.154次/天 | 无明显偏好 |
2 | 2.00 | 群体2.0: 高价值忠实会员 | 平均年龄27.4岁,会员比例99.9% | 人均消费84544.8元,平均订单105.2单 | 平均订单金额805.4元 | 最近购买距今2.1天,频率0.294次/天 | 运动鞋、运动服装、运动配饰、运动装备 |
用户群体概要:
用户群体 | 群体标签 | 用户数量 | 用户占比 | 人均消费 | 平均订单数 | |
---|---|---|---|---|---|---|
0 | 0.00 | 群体0.0: 流失风险客户 | 4263.00 | 42.6% | 16349.2元 | 22.1 |
1 | 1.00 | 群体1.0: 普通消费客户 | 3878.00 | 38.8% | 41625.0元 | 54.2 |
2 | 2.00 | 群体2.0: 高价值忠实会员 | 1859.00 | 18.6% | 84544.8元 | 105.2 |
6.购物推荐系统
def build_recommendation_system(orders, user_profile):"""构建简单的推荐系统包括:1. 基于协同过滤的推荐2. 基于内容的推荐3. 基于关联规则的推荐"""print("开始构建推荐系统...")# 合并订单数据和用户群体信息orders_with_cluster = pd.merge(orders, user_profile[['用户ID', '用户群体', '用户价值分级']], on='用户ID', how='left')# 1. 基于用户的协同过滤推荐# 构建用户-商品交互矩阵# 为简化计算,使用商品大类user_item_matrix = pd.crosstab(orders['用户ID'], orders['商品大类'])# 用户相似度矩阵user_user_sim = cosine_similarity(user_item_matrix)user_user_sim = pd.DataFrame(user_user_sim, index=user_item_matrix.index, columns=user_item_matrix.index)# 显示用户相似度矩阵样本print("用户相似度矩阵样本:")display(user_user_sim.iloc[:5, :5])# 2. 基于物品的协同过滤推荐# 构建商品相似度矩阵 (使用更细粒度的商品子类)item_user_matrix = pd.crosstab(orders['商品子类'], orders['用户ID'])# 物品相似度矩阵item_item_sim = cosine_similarity(item_user_matrix)item_item_sim = pd.DataFrame(item_item_sim, index=item_user_matrix.index, columns=item_user_matrix.index)# 显示商品相似度矩阵样本print("商品相似度矩阵样本:")display(item_item_sim.iloc[:5, :5])# 可视化物品相似度热力图plt.figure(figsize=(14, 12))sns.heatmap(item_item_sim.iloc[:10, :10], cmap='viridis', annot=True)plt.title('商品子类相似度热力图(前10个商品)')plt.tight_layout()plt.show()# 3. 基于关联规则的推荐(购物篮分析)# 准备数据 - 使用订单ID和商品子类basket = pd.crosstab(orders['订单ID'], orders['商品子类'])basket_encoded = (basket > 0).astype(int)# 使用Apriori算法找出频繁项集min_support = 0.01 # 最小支持度frequent_itemsets = apriori(basket_encoded, min_support=min_support, use_colnames=True)# 显示频繁项集print("频繁项集示例:")display(frequent_itemsets.head(10))# 生成关联规则rules = Noneif not frequent_itemsets.empty:try:# 尝试新版本的调用方式rules = association_rules(frequent_itemsets, metric="lift", min_threshold=1)except TypeError:# 尝试旧版本的调用方式rules = association_rules(frequent_itemsets, metric="lift", min_threshold=1, num_itemsets=1)# 显示关联规则if rules is not None and not rules.empty:print("商品关联规则示例:")display(rules.head(10))# 4. 内容推荐系统示例# 创建一个商品特征矩阵# 这里我们使用已有的商品分类和属性信息orders_sample = orders.sample(min(len(orders), 10000))# 获取热门商品top_products = orders_sample.groupby('商品名称').size().sort_values(ascending=False).head(20)print("热门商品Top 20:")display(top_products)# 为每个用户群体推荐商品# 基于各群体的商品偏好cluster_product_pref = orders_with_cluster.groupby(['用户群体', '商品名称']).size().reset_index(name='购买次数')# 为每个群体获取Top 10推荐商品cluster_recommendations = {}for cluster in user_profile['用户群体'].unique():cluster_prefs = cluster_product_pref[cluster_product_pref['用户群体'] == cluster]top_prefs = cluster_prefs.sort_values('购买次数', ascending=False).head(10)cluster_recommendations[f'群体{cluster}'] = top_prefs['商品名称'].tolist()# 显示群体推荐结果print("用户群体推荐商品:")recommendations_df = pd.DataFrame(cluster_recommendations)display(recommendations_df)print("推荐系统构建完成")return user_user_sim, item_item_sim, rules, cluster_recommendations# 构建推荐系统
user_sim, item_sim, association_rules, cluster_recs = build_recommendation_system(processed_orders, user_profile)
开始构建推荐系统...
用户相似度矩阵样本:
用户ID | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
用户ID | |||||
1 | 1.00 | 0.73 | 0.82 | 0.92 | 0.70 |
2 | 0.73 | 1.00 | 0.95 | 0.88 | 0.97 |
3 | 0.82 | 0.95 | 1.00 | 0.86 | 0.97 |
4 | 0.92 | 0.88 | 0.86 | 1.00 | 0.82 |
5 | 0.70 | 0.97 | 0.97 | 0.82 | 1.00 |
商品相似度矩阵样本:
商品子类 | 上衣 | 下装 | 休闲鞋 | 其他配饰 | 包袋 |
---|---|---|---|---|---|
商品子类 | |||||
上衣 | 1.00 | 0.78 | 0.57 | 0.76 | 0.77 |
下装 | 0.78 | 1.00 | 0.46 | 0.72 | 0.73 |
休闲鞋 | 0.57 | 0.46 | 1.00 | 0.54 | 0.55 |
其他配饰 | 0.76 | 0.72 | 0.54 | 1.00 | 0.69 |
包袋 | 0.77 | 0.73 | 0.55 | 0.69 | 1.00 |

频繁项集示例:
support | itemsets | |
---|---|---|
0 | 0.13 | (上衣) |
1 | 0.12 | (下装) |
2 | 0.08 | (休闲鞋) |
3 | 0.03 | (其他配饰) |
4 | 0.03 | (包袋) |
5 | 0.07 | (外套) |
6 | 0.08 | (套装) |
7 | 0.03 | (帽子) |
8 | 0.04 | (户外鞋) |
9 | 0.03 | (手套) |
热门商品Top 20:商品名称
训练套装 201
赛事套装 195
篮球短裤 191
跑步T恤 185
运动套装 181
阿尔法训练师 178
运动长裤 176
足球短裤 174
银河系列 171
运动七分裤 170
运动卫衣 166
锋锐系列 165
耐力系列 165
训练短裤 164
跑步紧身裤 164
训练背心 161
训练紧身裤 157
篮球套装 154
足球套装 152
阿尔法弹力 151
dtype: int64用户群体推荐商品:
群体2 | 群体1 | 群体0 | |
---|---|---|---|
0 | 阿尔法训练师 | 训练紧身裤 | 运动长裤 |
1 | 银河系列 | 训练短裤 | 训练紧身裤 |
2 | 足球套装 | 赛事套装 | 足球短裤 |
3 | 训练套装 | 运动套装 | 跑步紧身裤 |
4 | 锋锐系列 | 运动七分裤 | 训练短裤 |
5 | 耐力系列 | 跑步T恤 | 篮球短裤 |
6 | 运动套装 | 训练套装 | 运动七分裤 |
7 | 篮球套装 | 运动长裤 | 特锐斯AX |
8 | 运动夹克 | 篮球套装 | 特锐斯山地系列 |
9 | 足球球衣 | 足球套装 | 连帽外套 |
推荐系统构建完成
1. 用户相似度矩阵解析
用户相似度矩阵展示了前5名用户之间的购物偏好相似程度:
- 高度相似的用户组:用户2、3和5形成了一个紧密相关的群体,他们之间的相似度都达到0.95以上,表明这三位用户有极为相似的购物习惯。
- 中等相似度:用户1和4之间也有较高相似度(0.92),可能构成另一个偏好相近的群组。
- 跨群体连接:用户3与用户1的相似度为0.82,是连接两个用户群体的"桥梁"。
应用价值:系统可以针对用户2向其推荐用户3和5喜欢但用户2尚未购买的商品,反之亦然,这是协同过滤推荐的核心原理。
2. 商品相似度矩阵与热力图分析
商品相似度热力图展示了不同类别商品之间的关联程度:
-
强相关组合:
- 上衣与套装(0.81):最高相关性,表明购买上衣的用户也非常可能购买套装
- 上衣与下装(0.78):第二高相关性,符合消费者成套购买服装的习惯
- 下装与外套(0.77):也有较高相关性
-
中等相关组合:
- 大多数服装类别之间相关性在0.65-0.75之间,如包袋与多种服装类别的相关性
-
弱相关组合:
- 户外鞋与其他类别普遍相关性低,尤其与上衣(0.39)和套装(0.38)的相关性最低
- 休闲鞋与下装(0.46)相关性较低
特殊发现:热力图显示服装类商品之间形成一个高相关度集群,而鞋类(尤其是户外鞋)与服装的关联较弱,这可能反映出消费者在选购鞋类时更注重专业性而非搭配性。
3. 频繁项集分析
频繁项集展示了单个商品类别在订单中出现的频率:
- 上衣(13%)和下装(12%)是最常被购买的单品类别
- 休闲鞋和套装各占8%,外套占7%
- 其他配饰、包袋、帽子和手套的购买频率相对较低,均为3-4%
这表明核心服装品类(上衣、下装)是商店的主要销售商品,而配饰类产品多作为辅助购买项。
4. 热门商品分析
热门商品Top 20显示:
- 运动细分市场:热门商品主要分布在跑步、篮球、足球和训练四个细分市场
- 品类构成:T恤/上衣类(5项)、裤装类(5项)、套装类(5项)占据主导
- 套装受欢迎:多种套装出现在热门榜单中,包括运动套装、篮球套装、训练套装等
- 系列产品:特定系列产品如"银河系列"、“耐力系列”、"阿尔法训练师"等表现突出
5. 用户群体推荐商品分析
三个不同用户群体的推荐商品展示了明显的偏好差异:
- 群体0:偏好基础训练和实用性商品,如运动长裤、训练紧身裤、跑步紧身裤等,及一些特定系列产品
- 群体1:偏好训练和比赛类商品,推荐中有"训练"和"赛事"相关产品,以及跑步和足球类商品
- 群体2:偏好高端和专业系列产品,如"阿尔法训练师"、“银河系列”、"锋锐系列"等,同时也喜欢完整套装
综合商业洞察与建议
-
捆绑销售策略:
- 利用上衣与套装(0.81)的高相关性,设计"套装优惠"活动
- 为下装与外套(0.77)组合提供特别促销
-
商品陈列优化:
- 将相关性高的品类(如上衣和下装)在店内或网站相邻位置展示
- 户外鞋与其他产品相关性低,应独立陈列并强调其专业性
-
个性化营销:
- 针对群体2推广高端系列产品和完整套装
- 向群体1推送训练和赛事相关商品
- 为群体0提供基础实用性商品促销
-
库存管理:
- 保证跑步T恤、篮球上衣、训练短裤等热门单品的充足库存
- 对相关性高的商品组合进行库存协同管理
-
新品开发方向:
- 基于热门商品列表,继续开发训练、跑步和篮球类产品
- 考虑扩充套装类产品线,满足消费者一站式购物需求
通过这些数据驱动的洞察,企业可以更精准地设计产品组合、优化营销策略,从而提高客户满意度和销售转化率。
7.销售趋势分析
def sales_trend_analysis(orders):"""销售趋势分析分析订单量和销售额随时间的变化趋势"""# 转换下单时间为日期类型orders['下单日期'] = pd.to_datetime(orders['下单时间']).dt.date# 按日期统计销售数据daily_sales = orders.groupby('下单日期').agg({'订单ID': 'count','订单总额': 'sum'}).reset_index()daily_sales.columns = ['日期', '订单数', '销售额']# 计算7日移动平均线daily_sales['订单数_7日均值'] = daily_sales['订单数'].rolling(window=7, min_periods=1).mean()daily_sales['销售额_7日均值'] = daily_sales['销售额'].rolling(window=7, min_periods=1).mean()# 可视化每日销售数据fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(18, 14), sharex=True)# 订单数趋势ax1.plot(daily_sales['日期'], daily_sales['订单数'], 'b-', alpha=0.3, label='每日订单数')ax1.plot(daily_sales['日期'], daily_sales['订单数_7日均值'], 'r-', label='7日移动平均')ax1.set_title('每日订单量趋势')ax1.set_ylabel('订单数量')ax1.legend()ax1.grid(True)# 销售额趋势ax2.plot(daily_sales['日期'], daily_sales['销售额'], 'g-', alpha=0.3, label='每日销售额')ax2.plot(daily_sales['日期'], daily_sales['销售额_7日均值'], 'r-', label='7日移动平均')ax2.set_title('每日销售额趋势')ax2.set_xlabel('日期')ax2.set_ylabel('销售额(元)')ax2.legend()ax2.grid(True)# 设置日期格式ax2.xaxis.set_major_locator(MonthLocator())ax2.xaxis.set_major_formatter(DateFormatter('%Y-%m'))plt.tight_layout()plt.show()# 月度销售趋势orders['年月'] = pd.to_datetime(orders['下单时间']).dt.strftime('%Y-%m')monthly_sales = orders.groupby('年月').agg({'订单ID': 'count','订单总额': 'sum'}).reset_index()monthly_sales.columns = ['年月', '订单数', '销售额']# 可视化月度销售数据fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(16, 12))# 月度订单数ax1.bar(monthly_sales['年月'], monthly_sales['订单数'], color='skyblue')ax1.set_title('月度订单数')ax1.set_ylabel('订单数量')plt.setp(ax1.xaxis.get_majorticklabels(), rotation=0)ax1.grid(axis='y')# 月度销售额ax2.bar(monthly_sales['年月'], monthly_sales['销售额'], color='lightgreen')ax2.set_title('月度销售额')ax2.set_xlabel('年月')ax2.set_ylabel('销售额(元)')plt.setp(ax2.xaxis.get_majorticklabels(), rotation=0)ax2.grid(axis='y')plt.tight_layout()plt.show()# 按商品大类的季度销售额orders['下单时间'] = pd.to_datetime(orders['下单时间'])orders['年季'] = orders['下单时间'].dt.year.astype(str) + '-Q' + orders['下单时间'].dt.quarter.astype(str)quarterly_category_sales = orders.groupby(['年季', '商品大类'])['订单总额'].sum().reset_index()# 将年季转为pivot表格式quarterly_pivot = quarterly_category_sales.pivot(index='年季', columns='商品大类', values='订单总额').fillna(0)# 可视化季度商品大类销售额ax = quarterly_pivot.plot(kind='bar', stacked=True, figsize=(16,10), colormap='viridis')ax.set_title('季度各品类销售额', fontsize=16)ax.set_xlabel('年-季度', fontsize=14)ax.set_ylabel('销售额(元)', fontsize=14)ax.legend(title='商品大类', bbox_to_anchor=(1.05, 1), loc='upper left')plt.xticks(rotation=0)ax.grid(axis='y')plt.tight_layout()plt.show()# 销售额预测(简单趋势线)# 为了简化,这里只使用简单的线性趋势# 将日期转换为数值型特征daily_sales['日期_数值'] = (pd.to_datetime(daily_sales['日期']) - pd.to_datetime(daily_sales['日期'].min())).dt.days# 简单线性回归X = daily_sales[['日期_数值']]y_orders = daily_sales['订单数']y_sales = daily_sales['销售额']model_orders = LinearRegression()model_sales = LinearRegression()model_orders.fit(X, y_orders)model_sales.fit(X, y_sales)# 预测未来30天last_date = pd.to_datetime(daily_sales['日期'].max())future_dates = [last_date + timedelta(days=i) for i in range(1, 31)]future_df = pd.DataFrame({'日期': future_dates})future_df['日期_数值'] = (pd.to_datetime(future_df['日期']) - pd.to_datetime(daily_sales['日期'].min())).dt.daysfuture_df['订单数预测'] = model_orders.predict(future_df[['日期_数值']])future_df['销售额预测'] = model_sales.predict(future_df[['日期_数值']])# 显示预测结果print("未来30天销售预测:")display(future_df.head(10))# 可视化预测结果plt.figure(figsize=(18, 10))# 历史数据plt.plot(pd.to_datetime(daily_sales['日期']), daily_sales['销售额'], 'b-', alpha=0.5, label='历史销售额')# 预测数据plt.plot(future_df['日期'], future_df['销售额预测'], 'r--', label='销售额预测')# 添加预测区间的阴影plt.axvspan(last_date, future_df['日期'].max(), alpha=0.2, color='gray')plt.title('销售额趋势与预测')plt.xlabel('日期')plt.ylabel('销售额(元)')plt.legend()plt.grid(True)plt.tight_layout()plt.show()print("销售趋势分析完成")# 进行销售趋势分析
sales_trend_analysis(processed_orders)



未来30天销售预测:
日期 | 日期_数值 | 订单数预测 | 销售额预测 | |
---|---|---|---|---|
0 | 2024-12-31 | 365 | 1772.56 | 1328063.48 |
1 | 2025-01-01 | 366 | 1774.76 | 1329507.55 |
2 | 2025-01-02 | 367 | 1776.96 | 1330951.61 |
3 | 2025-01-03 | 368 | 1779.16 | 1332395.67 |
4 | 2025-01-04 | 369 | 1781.36 | 1333839.73 |
5 | 2025-01-05 | 370 | 1783.56 | 1335283.79 |
6 | 2025-01-06 | 371 | 1785.76 | 1336727.85 |
7 | 2025-01-07 | 372 | 1787.97 | 1338171.91 |
8 | 2025-01-08 | 373 | 1790.17 | 1339615.98 |
9 | 2025-01-09 | 374 | 1792.37 | 1341060.04 |

销售趋势分析完成
1. 年度销售周期与季节性特征
1.1日订单量和销售额趋势
- 明显的季节性波动:全年数据呈现出4-5个明显的销售高峰,分别出现在2月初、6月中、8月底、11月中,以及12月末
- 节假日效应:最大峰值出现在11月(约4000订单/日,销售额约2.5百万元/日),很可能对应"双11"电商购物节
- 周期性底谷:2月底至3月初出现了全年最低点,订单量降至约300单/日,销售额降至约25万元/日,可能与春节假期结束有关
1.2月度表现分析
- 旺季月份:最强劲的销售月份是8月、11月和12月,月订单量超过50,000单,销售额超过4,000万元
- 淡季月份:2-4月为全年表现最弱时期,月订单量在25,000-28,000单之间,销售额仅为2,000万元左右
- 年初异常表现:1月销售表现较强(约47,000单,3,600万元),与其后的2-4月形成鲜明对比
1.3季度销售分布
- 全年增长趋势:第三季度(Q3)销售额达到全年最高点,Q4>Q3>Q2>Q1
- 季度商品结构变化:
- Q3和Q4的运动服装类销售额显著高于前两个季度
- 运动鞋类销售在所有季度中占比最大,但在Q3和Q4中相对占比降低
- 运动配饰在Q3和Q4的销售额显著增加
2. 商品类别销售分析
2.1类别销售趋势
- 运动服装:Q1至Q3持续强劲增长,Q3达到顶峰后在Q4略有回落
- 运动鞋:全年呈现先增后稳趋势,在Q3销售额达到最高点(约6,000万元),Q4略有下降
- 运动配饰:Q3达到全年最高,Q4保持接近Q3的水平,较前两季明显增长35-40%
- 运动装备:四个季度中占比最小,在Q3达到最高后Q4略有回落
2.3品类结构变化
- 服装占比提升:运动服装的销售占比从Q1的约35%上升到Q4的近50%
- 鞋类占比下降:尽管绝对值增长,运动鞋类的销售占比从Q1的约40%下降到Q4的约30%
- 季节性影响:Q3和Q4整体销售规模明显扩大,显示下半年是运动产品销售旺季
3. 短期预测分析
根据提供的30天预测数据:
- 稳定增长趋势:预测显示日均订单量从1773单逐日小幅上升至1792单
- 日均销售额:从约133万元逐日增长至约134万元
- 增长率:30天内订单量预计增长约1.1%,销售额增长约1%
- 2025年开局预期:与2024年1月初相比,预测的日均订单量高出约60%,表明企业可能进入加速增长阶段
4. 战略洞察与建议
4.1营销策略优化
-
季节性促销调整:
- 强化11月双11和12月年终促销活动,把握销售高峰
- 为2-3月淡季设计专项促销活动,如"春季焕新"主题活动提振销售
-
商品结构优化:
- 下半年增加运动服装类产品库存,特别是Q3和Q4季度
- Q1和Q2可适当提高运动鞋类产品的促销力度
-
销售高峰准备:
- 提前30-45天为6月、8月、11月的销售高峰备货
- 高峰期增强物流和客服支持,确保用户体验
4.2库存管理建议
-
动态库存调整:
- Q4季度(10-12月)应保持最高库存水平,较平均水平提高25-30%
- Q1季度末(3月)可降低库存水平至平均值的80%左右
- 建立动态安全库存机制,根据7日移动平均订单量调整
-
品类侧重:
- Q3和Q4增加运动服装和配饰库存比例
- Q1和Q2可适当降低服装库存,增加运动鞋比例
4.3增长机会
-
元旦促销计划:
- 基于预测数据,2025年1月初销售增长趋势明显,应设计有针对性的元旦促销活动
- 目标应设定为日销售额突破150万元,较预测值提升约15%
-
销售低谷应对:
- 针对历史数据显示的2月底低谷,提前准备"春季新品预售"活动
- 在低谷期可考虑开展会员专属促销,提高客户忠诚度
运动服装类产品增长最为显著,已成为销售额的主要贡献者,而运动鞋虽然占比下降但仍是销售额的重要组成部分。公司应根据季节性波动和商品品类变化趋势,优化营销策略和库存管理,以最大化销售机会并提高资源利用效率。
8.地域消费分析
def regional_analysis(orders, users):"""地域消费分析分析不同地域的消费特征"""# 合并订单和用户数据,获取用户常用省份信息regional_orders = pd.merge(orders,users[['用户ID', '常用省份']],on='用户ID',how='left')# 按省份统计消费数据province_stats = regional_orders.groupby('收货省份').agg({'订单ID': 'count','订单总额': 'sum','用户ID': pd.Series.nunique}).reset_index()province_stats.columns = ['省份', '订单数', '销售额', '用户数']province_stats['人均订单数'] = province_stats['订单数'] / province_stats['用户数']province_stats['人均消费额'] = province_stats['销售额'] / province_stats['用户数']province_stats['客单价'] = province_stats['销售额'] / province_stats['订单数']# 按销售额排序province_stats = province_stats.sort_values('销售额', ascending=False)# 显示省份消费统计print("各省份消费统计:")display(province_stats.head(15))# 可视化省份销售额(Top 15)top_provinces = province_stats.head(15)plt.figure(figsize=(16, 10))sns.barplot(x='销售额', y='省份', data=top_provinces, palette='viridis')plt.title('各省份销售额Top 15')plt.xlabel('销售额(元)')plt.ylabel('省份')plt.grid(axis='x')plt.tight_layout()plt.show()# 可视化省份客单价plt.figure(figsize=(16, 10))sns.barplot(x='客单价', y='省份', data=top_provinces, palette='rocket')plt.title('各省份客单价Top 15')plt.xlabel('客单价(元/订单)')plt.ylabel('省份')plt.grid(axis='x')plt.tight_layout()plt.show()# 按城市统计消费数据city_stats = regional_orders.groupby(['收货省份', '收货城市']).agg({'订单ID': 'count','订单总额': 'sum','用户ID': pd.Series.nunique}).reset_index()city_stats.columns = ['省份', '城市', '订单数', '销售额', '用户数']city_stats['人均订单数'] = city_stats['订单数'] / city_stats['用户数']city_stats['人均消费额'] = city_stats['销售额'] / city_stats['用户数']city_stats['客单价'] = city_stats['销售额'] / city_stats['订单数']# 按销售额排序city_stats = city_stats.sort_values('销售额', ascending=False)# 显示城市消费统计print("各城市消费统计:")display(city_stats.head(20))# 可视化城市销售额(Top 20)top_cities = city_stats.head(20)plt.figure(figsize=(16, 12))sns.barplot(x='销售额', y='城市', hue='省份', data=top_cities, palette='viridis')plt.title('各城市销售额Top 20')plt.xlabel('销售额(元)')plt.ylabel('城市')plt.grid(axis='x')plt.tight_layout()plt.show()# 区域商品偏好分析region_category_pivot = pd.crosstab(index=regional_orders['收货省份'],columns=regional_orders['商品大类'],values=regional_orders['订单总额'],aggfunc='sum',normalize='index') * 100 # 转为百分比# 显示区域商品偏好print("区域商品偏好分析:")display(region_category_pivot.head(10))# 可视化区域商品偏好(Top 10省份)top_region_prefs = region_category_pivot.loc[top_provinces['省份'][:10]]ax = top_region_prefs.plot(kind='bar', stacked=True, figsize=(16, 10), colormap='viridis')ax.set_title('各省份商品大类偏好Top 10', fontsize=16)ax.set_xlabel('省份', fontsize=14)ax.set_ylabel('消费占比(%)', fontsize=14)ax.legend(title='商品大类', bbox_to_anchor=(1.05, 1), loc='upper left')ax.grid(axis='y')plt.xticks(rotation=0)plt.tight_layout()plt.show()# 按季节分析地区消费regional_orders['季节'] = regional_orders['下单月份'].map({1: '冬季', 2: '冬季', 3: '春季', 4: '春季', 5: '春季', 6: '夏季', 7: '夏季', 8: '夏季', 9: '秋季', 10: '秋季', 11: '秋季', 12: '冬季'})season_region_sales = regional_orders.groupby(['季节', '收货省份'])['订单总额'].sum().reset_index()# 只选择Top 10省份top_10_provinces = top_provinces['省份'][:10].tolist()season_region_sales = season_region_sales[season_region_sales['收货省份'].isin(top_10_provinces)]# 可视化季节地区消费season_pivot = season_region_sales.pivot(index='收货省份', columns='季节', values='订单总额')ax = season_pivot.plot(kind='bar', figsize=(16, 10), colormap='viridis')ax.set_title('各省份季节消费特征Top 10', fontsize=16)ax.set_xlabel('省份', fontsize=14)ax.set_ylabel('销售额(元)', fontsize=14)ax.legend(title='季节', bbox_to_anchor=(1.05, 1), loc='upper left')ax.grid(axis='y')plt.xticks(rotation=0)plt.tight_layout()plt.show()print("地域消费分析完成")# 进行地域消费分析
regional_analysis(processed_orders, processed_users)
各省份消费统计:
省份 | 订单数 | 销售额 | 用户数 | 人均订单数 | 人均消费额 | 客单价 | |
---|---|---|---|---|---|---|---|
3 | 北京 | 26842 | 20793139.89 | 784 | 34.24 | 26521.86 | 774.65 |
0 | 上海 | 26682 | 20675778.75 | 730 | 36.55 | 28322.98 | 774.90 |
11 | 广东 | 26411 | 20510680.19 | 757 | 34.89 | 27094.69 | 776.60 |
14 | 江苏 | 23618 | 17998439.53 | 695 | 33.98 | 25897.04 | 762.06 |
18 | 浙江 | 22229 | 17387437.20 | 657 | 33.83 | 26464.90 | 782.20 |
9 | 山东 | 21714 | 16906267.84 | 571 | 38.03 | 29608.17 | 778.59 |
6 | 天津 | 21262 | 16768610.81 | 608 | 34.97 | 27579.95 | 788.67 |
23 | 福建 | 21662 | 16561199.30 | 596 | 36.35 | 27787.25 | 764.53 |
5 | 四川 | 19284 | 15172627.41 | 537 | 35.91 | 28254.43 | 786.80 |
20 | 湖北 | 18305 | 14629758.77 | 529 | 34.60 | 27655.50 | 799.22 |
27 | 重庆 | 18676 | 14485875.27 | 533 | 35.04 | 27178.00 | 775.64 |
17 | 河南 | 18190 | 14242938.52 | 497 | 36.60 | 28657.82 | 783.01 |
16 | 河北 | 16237 | 12574203.23 | 459 | 35.37 | 27394.78 | 774.42 |
21 | 湖南 | 15525 | 11916416.18 | 452 | 34.35 | 26363.75 | 767.56 |
28 | 陕西 | 15238 | 11791317.12 | 436 | 34.95 | 27044.31 | 773.81 |


各城市消费统计:
省份 | 城市 | 订单数 | 销售额 | 用户数 | 人均订单数 | 人均消费额 | 客单价 | |
---|---|---|---|---|---|---|---|---|
8 | 北京 | 北京 | 26842 | 20793139.89 | 784 | 34.24 | 26521.86 | 774.65 |
0 | 上海 | 上海 | 26682 | 20675778.75 | 730 | 36.55 | 28322.98 | 774.90 |
17 | 天津 | 天津 | 21262 | 16768610.81 | 608 | 34.97 | 27579.95 | 788.67 |
95 | 重庆 | 重庆 | 18676 | 14485875.27 | 533 | 35.04 | 27178.00 | 775.64 |
82 | 福建 | 厦门 | 6247 | 4841900.96 | 164 | 38.09 | 29523.79 | 775.08 |
64 | 浙江 | 杭州 | 5469 | 4358809.96 | 139 | 39.35 | 31358.35 | 797.00 |
83 | 福建 | 泉州 | 5685 | 4296836.67 | 150 | 37.90 | 28645.58 | 755.82 |
74 | 湖北 | 襄阳 | 5217 | 4220695.51 | 147 | 35.49 | 28712.21 | 809.03 |
6 | 内蒙古 | 呼和浩特 | 5566 | 4214660.37 | 154 | 36.14 | 27367.92 | 757.22 |
35 | 广东 | 佛山 | 5270 | 4150003.45 | 144 | 36.60 | 28819.47 | 787.48 |
61 | 河南 | 许昌 | 5141 | 4129709.50 | 122 | 42.14 | 33850.08 | 803.29 |
60 | 河南 | 洛阳 | 5233 | 4097244.17 | 145 | 36.09 | 28256.86 | 782.96 |
85 | 福建 | 福州 | 5174 | 3919772.49 | 151 | 34.26 | 25958.76 | 757.59 |
103 | 黑龙江 | 大庆 | 4929 | 3898872.59 | 134 | 36.78 | 29096.06 | 791.01 |
19 | 宁夏 | 银川 | 4905 | 3875505.37 | 144 | 34.06 | 26913.23 | 790.11 |
58 | 河北 | 石家庄 | 4933 | 3830695.23 | 133 | 37.09 | 28802.22 | 776.54 |
69 | 海南 | 儋州 | 4952 | 3826166.11 | 135 | 36.68 | 28341.97 | 772.65 |
28 | 山东 | 青岛 | 4886 | 3820121.87 | 122 | 40.05 | 31312.47 | 781.85 |
72 | 湖北 | 武汉 | 4769 | 3786675.50 | 150 | 31.79 | 25244.50 | 794.02 |
50 | 江苏 | 苏州 | 4994 | 3754432.89 | 154 | 32.43 | 24379.43 | 751.79 |

区域商品偏好分析:
商品大类 | 运动服装 | 运动装备 | 运动配饰 | 运动鞋 |
---|---|---|---|---|
收货省份 | ||||
上海 | 40.82 | 4.06 | 6.04 | 49.09 |
云南 | 40.63 | 3.92 | 6.28 | 49.17 |
内蒙古 | 41.06 | 4.09 | 6.33 | 48.51 |
北京 | 40.84 | 3.91 | 6.11 | 49.14 |
吉林 | 42.26 | 3.82 | 5.92 | 48.00 |
四川 | 42.22 | 3.75 | 5.98 | 48.05 |
天津 | 40.39 | 3.78 | 5.92 | 49.91 |
宁夏 | 41.18 | 4.04 | 6.47 | 48.30 |
安徽 | 41.71 | 4.01 | 5.63 | 48.65 |
山东 | 41.29 | 3.81 | 6.21 | 48.68 |


地域消费分析完成
1. 省份销售额分布
- 一线主导型格局:北京、上海、广东位居销售额前三位,均超过20亿元
- 经济发达省份集中:江苏、浙江、山东、天津形成第二梯队,销售额在1.7亿左右
- 区域梯度明显:从东部沿海到中西部地区,销售额整体呈递减趋势
- "北上广"消费能力:尽管人口基数不同,三地总销售额非常接近(相差不到3百万元)
2. 客单价与消费模式
- 高度一致的客单价:15个省份客单价都在760-800元之间,表明运动产品定价策略全国一致
- 区域消费力差异:
- 山东人均消费额最高(29,608元),是全国平均水平的约10%以上
- 河南(28,658元)和上海(28,323元)分别位列第二三位
- 江苏(25,897元)和湖南(26,364元)人均消费额相对较低
- 购买频次差异:山东(38.03)、河南(36.60)和上海(36.55)人均订单数最高
3. 城市消费力分析
- 巨大城市差距:北京和上海销售额超过20亿元,而排名靠后的城市仅为4亿左右,形成"断崖式"差距
- 直辖市优势:四个直辖市占据城市销售榜前四位
- 区域中心城市:厦门、杭州、泉州等二线城市形成区域消费中心
- 隐藏的消费热点:
- 许昌:人均订单数(42.14)和人均消费额(33,850元)全国最高
- 杭州:人均消费额(31,358元)位居第二,客单价(797元)较高
- 襄阳:客单价最高(809.03元),表明高端产品消费倾向
4. 商品品类偏好
- 全国一致的品类结构:运动鞋(48-50%)和运动服装(40-42%)占据绝大部分市场
- 微妙的区域差异:
- 天津运动鞋占比最高(49.91%),服装占比最低(40.39%)
- 吉林(42.26%)和四川(42.22%)运动服装占比最高
- 宁夏运动配饰占比最高(6.47%),反映区域文化差异
- 安徽运动配饰占比最低(5.63%)
- 装备市场小众:运动装备在所有地区占比均不超过4.1%,是最小的品类
5. 季节性消费模式
- 夏季消费高峰:所有地区夏季消费额最高,上海、北京和广东夏季消费均超过6百万元
- 区域季节特征:
- 北方地区(北京、天津)冬季消费明显高于南方(广东、福建)
- 上海和北京四季差异最为明显,反映时尚引领特性
- 四川春季消费占比最低,可能与气候特点相关
- 秋季普遍强于冬季:所有TOP10地区秋季消费均高于冬季,表明"开学季"和"金秋促销"效应显著
6. 战略营销建议
-
区域定制策略:
- 京沪地区:发展全季节平衡的高端产品组合
- 山东、河南:发挥高人均订单量优势,强化会员营销体系
- 二线城市:针对许昌、杭州等高人均消费城市,提供独家产品线
-
季节性营销重点:
- 全国市场夏季营销投入应最高,增加30-40%预算
- 北方地区冬季产品线应更丰富,南方地区可减少冬季重型产品
- 春季作为全国普遍淡季,开展"春季唤醒"主题活动
-
产品组合优化:
- 运动鞋类作为核心品类(占比近50%),应保持产品创新和库存充足
- 运动服装在吉林、四川等地可提高营销占比
- 运动配饰在宁夏等地有增长潜力,可开发区域特色产品
-
渠道下沉策略:
- 关注许昌、青岛等消费力强但市场份额不足的城市
- 襄阳客单价最高(809元),可考虑增设高端门店或体验中心
运动用品市场整体呈现"东强西弱、北上广领先、品类结构一致、季节差异明显"的特点,企业需在保持全国一致品牌形象的同时,针对区域差异制定精细化营销策略。
9.产品分析
def product_analysis(orders):"""产品分析分析产品销售情况、定价和利润率"""# 按商品大类统计category_stats = orders.groupby('商品大类').agg({'订单ID': 'count','订单总额': 'sum','用户ID': pd.Series.nunique}).reset_index()category_stats.columns = ['商品大类', '订单数', '销售额', '购买用户数']category_stats['平均订单金额'] = category_stats['销售额'] / category_stats['订单数']category_stats['用户渗透率'] = category_stats['购买用户数'] / orders['用户ID'].nunique() * 100# 按销售额排序category_stats = category_stats.sort_values('销售额', ascending=False)# 显示商品大类统计print("商品大类统计:")display(category_stats)# 可视化商品大类销售额plt.figure(figsize=(14, 8))sns.barplot(x='商品大类', y='销售额', data=category_stats, palette='viridis')plt.title('各商品大类销售额')plt.xlabel('商品大类')plt.ylabel('销售额(元)')plt.grid(axis='y')plt.tight_layout()plt.show()# 可视化商品大类用户渗透率plt.figure(figsize=(14, 8))sns.barplot(x='商品大类', y='用户渗透率', data=category_stats, palette='rocket')plt.title('各商品大类用户渗透率')plt.xlabel('商品大类')plt.ylabel('用户渗透率(%)')plt.grid(axis='y')plt.tight_layout()plt.show()# 按商品子类统计subcategory_stats = orders.groupby(['商品大类', '商品子类']).agg({'订单ID': 'count','订单总额': 'sum','用户ID': pd.Series.nunique}).reset_index()subcategory_stats.columns = ['商品大类', '商品子类', '订单数', '销售额', '购买用户数']subcategory_stats['平均订单金额'] = subcategory_stats['销售额'] / subcategory_stats['订单数']subcategory_stats['用户渗透率'] = subcategory_stats['购买用户数'] / orders['用户ID'].nunique() * 100# 按销售额排序subcategory_stats = subcategory_stats.sort_values('销售额', ascending=False)# 显示商品子类统计print("商品子类统计:")display(subcategory_stats.head(15))# 可视化Top 15商品子类销售额top_subcategories = subcategory_stats.head(15)plt.figure(figsize=(16, 10))sns.barplot(x='销售额', y='商品子类', hue='商品大类', data=top_subcategories, palette='viridis')plt.title('各商品子类销售额Top 15')plt.xlabel('销售额(元)')plt.ylabel('商品子类')plt.grid(axis='x')plt.tight_layout()plt.show()# 按具体商品名称统计product_stats = orders.groupby(['商品大类', '商品子类', '商品名称']).agg({'订单ID': 'count','订单总额': 'sum','用户ID': pd.Series.nunique,'单价': 'mean'}).reset_index()product_stats.columns = ['商品大类', '商品子类', '商品名称', '订单数', '销售额', '购买用户数', '平均单价']product_stats['用户渗透率'] = product_stats['购买用户数'] / orders['用户ID'].nunique() * 100# 按销售额排序product_stats = product_stats.sort_values('销售额', ascending=False)# 显示具体商品统计print("具体商品统计:")display(product_stats.head(20))# 可视化Top 20具体商品销售额top_products = product_stats.head(20)plt.figure(figsize=(16, 12))sns.barplot(x='销售额', y='商品名称', data=top_products, palette='viridis')plt.title('各商品销售额Top 20')plt.xlabel('销售额(元)')plt.ylabel('商品名称')plt.grid(axis='x')plt.tight_layout()plt.show()# 商品定价分析# 计算不同价格段的销售情况orders['价格段'] = pd.cut(orders['单价'], bins=[0, 100, 200, 500, 1000, 2000, 10000],labels=['0-100元', '100-200元', '200-500元', '500-1000元', '1000-2000元', '2000元以上'])price_range_stats = orders.groupby('价格段').agg({'订单ID': 'count','订单总额': 'sum','用户ID': pd.Series.nunique}).reset_index()price_range_stats.columns = ['价格段', '订单数', '销售额', '购买用户数']price_range_stats['订单占比'] = price_range_stats['订单数'] / price_range_stats['订单数'].sum() * 100price_range_stats['销售额占比'] = price_range_stats['销售额'] / price_range_stats['销售额'].sum() * 100# 显示价格段统计print("价格段统计:")display(price_range_stats)# 可视化价格段销售情况fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(16, 14))# 订单数占比sns.barplot(x='价格段', y='订单占比', data=price_range_stats, palette='Blues_d', ax=ax1)ax1.set_title('各价格段订单数占比')ax1.set_xlabel('价格段')ax1.set_ylabel('订单数占比(%)')ax1.grid(axis='y')# 销售额占比sns.barplot(x='价格段', y='销售额占比', data=price_range_stats, palette='Reds_d', ax=ax2)ax2.set_title('各价格段销售额占比')ax2.set_xlabel('价格段')ax2.set_ylabel('销售额占比(%)')ax2.grid(axis='y')plt.tight_layout()plt.show()# 商品销售分布的树形图plt.figure(figsize=(16, 12))category_sales = category_stats[['商品大类', '销售额']].copy()category_sales['标签'] = category_sales['商品大类'] + '\n' + category_sales['销售额'].apply(lambda x: f'{x:,.0f}元')squarify.plot(sizes=category_sales['销售额'], label=category_sales['标签'], alpha=0.8, color=sns.color_palette("viridis", len(category_sales)))plt.axis('off')plt.title('商品大类销售额树形图', fontsize=18)plt.tight_layout()plt.show()# 商品词云# 基于销售额创建商品词云product_data = product_stats[['商品名称', '销售额']].copy()word_dict = dict(zip(product_data['商品名称'], product_data['销售额']))# 创建colormapcolormap = plt.cm.viridis# 生成词云wordcloud = WordCloud(font_path='/home/mw/project/SIMHEI.TTF',width=1200, height=800, background_color='white',colormap=colormap,max_words=100,prefer_horizontal=0.9,min_font_size=10,max_font_size=150,random_state=42).generate_from_frequencies(word_dict)plt.figure(figsize=(16, 10))plt.imshow(wordcloud, interpolation='bilinear')plt.axis('off')plt.title('商品销售额词云', fontsize=18)plt.tight_layout()plt.show()# 商品季节性分析seasonal_product = orders.groupby(['季节', '商品大类'])['订单总额'].sum().reset_index()season_pivot = seasonal_product.pivot(index='商品大类', columns='季节', values='订单总额')# 计算各季节占比season_pct = season_pivot.div(season_pivot.sum(axis=1), axis=0) * 100# 显示季节性商品销售数据print("季节商品销售占比(%):")display(season_pct)# 可视化季节性商品销售plt.figure(figsize=(14, 10))sns.heatmap(season_pct, annot=True, fmt='.1f', cmap='YlGnBu')plt.title('各商品大类在不同季节的销售占比(%)')plt.xlabel('季节')plt.ylabel('商品大类')plt.tight_layout()plt.show()print("产品分析完成")# 进行产品分析
product_analysis(processed_orders)
商品大类统计:
商品大类 | 订单数 | 销售额 | 购买用户数 | 平均订单金额 | 用户渗透率 | |
---|---|---|---|---|---|---|
3 | 运动鞋 | 165847 | 189584751.01 | 9911 | 1143.13 | 99.11 |
0 | 运动服装 | 199697 | 159874462.97 | 9962 | 800.59 | 99.62 |
2 | 运动配饰 | 71688 | 23616413.18 | 9581 | 329.43 | 95.81 |
1 | 运动装备 | 62768 | 15211446.51 | 9469 | 242.34 | 94.69 |


商品子类统计:
商品大类 | 商品子类 | 订单数 | 销售额 | 购买用户数 | 平均订单金额 | 用户渗透率 | |
---|---|---|---|---|---|---|---|
3 | 运动服装 | 套装 | 41748 | 57754132.83 | 8469 | 1383.40 | 84.69 |
17 | 运动鞋 | 跑步鞋 | 33565 | 41070183.12 | 7130 | 1223.60 | 71.30 |
14 | 运动鞋 | 篮球鞋 | 27677 | 39531206.21 | 6786 | 1428.31 | 67.86 |
2 | 运动服装 | 外套 | 36018 | 39497886.89 | 8629 | 1096.62 | 86.29 |
12 | 运动鞋 | 休闲鞋 | 38364 | 36729779.56 | 8003 | 957.40 | 80.03 |
0 | 运动服装 | 上衣 | 64019 | 36293670.85 | 9026 | 566.92 | 90.26 |
13 | 运动鞋 | 户外鞋 | 21837 | 30744180.89 | 6944 | 1407.89 | 69.44 |
1 | 运动服装 | 下装 | 57912 | 26328772.40 | 9206 | 454.63 | 92.06 |
15 | 运动鞋 | 训练鞋 | 33288 | 24655344.84 | 7146 | 740.67 | 71.46 |
16 | 运动鞋 | 足球鞋 | 11116 | 16854056.39 | 5815 | 1516.20 | 58.15 |
8 | 运动配饰 | 包袋 | 14379 | 8048320.99 | 6540 | 559.73 | 65.40 |
4 | 运动装备 | 篮球装备 | 20964 | 5480587.72 | 7684 | 261.43 | 76.84 |
6 | 运动装备 | 足球装备 | 21064 | 5383770.18 | 7668 | 255.59 | 76.68 |
10 | 运动配饰 | 手套 | 14227 | 5039691.04 | 6533 | 354.23 | 65.33 |
5 | 运动装备 | 训练装备 | 20740 | 4347088.61 | 7646 | 209.60 | 76.46 |

具体商品统计:
商品大类 | 商品子类 | 商品名称 | 订单数 | 销售额 | 购买用户数 | 平均单价 | 用户渗透率 | |
---|---|---|---|---|---|---|---|---|
23 | 运动服装 | 套装 | 赛事套装 | 8205 | 12799104.30 | 4515 | 901.98 | 45.15 |
21 | 运动服装 | 套装 | 篮球套装 | 8297 | 12497215.20 | 4538 | 875.31 | 45.38 |
24 | 运动服装 | 套装 | 足球套装 | 8406 | 11600344.19 | 4556 | 805.67 | 45.56 |
16 | 运动服装 | 外套 | 羽绒服 | 5948 | 11140687.08 | 3992 | 1080.89 | 39.92 |
22 | 运动服装 | 套装 | 训练套装 | 8429 | 11030578.53 | 4614 | 765.94 | 46.14 |
25 | 运动服装 | 套装 | 运动套装 | 8411 | 9826890.61 | 4597 | 673.63 | 45.97 |
91 | 运动鞋 | 跑步鞋 | 阿迪达斯超动力 | 6605 | 9817440.17 | 3590 | 1129.50 | 35.90 |
88 | 运动鞋 | 跑步鞋 | 极速系列 | 6794 | 9291669.65 | 3631 | 1037.96 | 36.31 |
71 | 运动鞋 | 户外鞋 | 特锐斯徒步者 | 5511 | 9194064.56 | 3504 | 1263.21 | 35.04 |
75 | 运动鞋 | 篮球鞋 | 哈登系列 | 5563 | 8265132.81 | 3162 | 1124.30 | 31.62 |
87 | 运动鞋 | 跑步鞋 | 太阳能动力 | 6605 | 8239593.37 | 3615 | 946.32 | 36.15 |
73 | 运动鞋 | 篮球鞋 | D罗斯系列 | 5518 | 8148391.75 | 3202 | 1123.98 | 32.02 |
63 | 运动鞋 | 休闲鞋 | NMD系列 | 6488 | 8107153.37 | 3882 | 946.93 | 38.82 |
76 | 运动鞋 | 篮球鞋 | 特雷杨系列 | 5577 | 8087767.78 | 3225 | 1084.47 | 32.25 |
81 | 运动鞋 | 训练鞋 | 阿尔法训练师 | 8379 | 8011026.19 | 4145 | 726.10 | 41.45 |
70 | 运动鞋 | 户外鞋 | 特锐斯山地系列 | 5409 | 7956636.81 | 3415 | 1127.32 | 34.15 |
74 | 运动鞋 | 篮球鞋 | 利拉德系列 | 5529 | 7863602.77 | 3160 | 1082.11 | 31.60 |
3 | 运动服装 | 上衣 | 足球球衣 | 8076 | 7553048.87 | 4597 | 539.57 | 45.97 |
7 | 运动服装 | 上衣 | 运动夹克 | 8094 | 7520378.54 | 4698 | 538.56 | 46.98 |
89 | 运动鞋 | 跑步鞋 | 超新星 | 6813 | 7327599.28 | 3661 | 810.65 | 36.61 |

价格段统计:
价格段 | 订单数 | 销售额 | 购买用户数 | 订单占比 | 销售额占比 | |
---|---|---|---|---|---|---|
0 | 0-100元 | 21665 | 2949203.86 | 7403 | 4.33 | 0.76 |
1 | 100-200元 | 95566 | 23160436.70 | 9764 | 19.11 | 5.96 |
2 | 200-500元 | 154451 | 80253255.19 | 9937 | 30.89 | 20.67 |
3 | 500-1000元 | 166706 | 180700852.14 | 9938 | 33.34 | 46.54 |
4 | 1000-2000元 | 61612 | 101223325.78 | 9571 | 12.32 | 26.07 |
5 | 2000元以上 | 0 | 0.00 | 0 | 0.00 | 0.00 |



季节商品销售占比(%):
季节 | 冬季 | 夏季 | 春季 | 秋季 |
---|---|---|---|---|
商品大类 | ||||
运动服装 | 28.65 | 27.83 | 15.63 | 27.88 |
运动装备 | 25.93 | 29.12 | 18.15 | 26.81 |
运动配饰 | 24.60 | 29.52 | 18.77 | 27.11 |
运动鞋 | 21.26 | 31.33 | 21.91 | 25.49 |

产品分析完成
1. 商品类别销售格局
1.1核心品类分析
- 销售额分布:运动鞋(1.9亿元)和运动服装(1.6亿元)构成销售主体,共占总销售额的90%以上
- 品类差异:运动鞋平均订单金额(1,143元)显著高于运动服装(801元),反映其高单价特性
- 用户渗透率:几乎所有消费者都购买过运动服装(99.62%)和运动鞋(99.11%),形成双核心消费结构
1.2辅助品类表现
- 运动配饰:贡献2,362万元销售额,平均订单金额329元
- 运动装备:销售额最低(1,521万元),但用户渗透率仍达94.69%,表明是低频但必需品类
2. 热销商品与消费偏好
2.1细分产品表现
- 套装系列霸主:套装以5,775万元的销售额遥遥领先,单价高达1,383元,特别是赛事套装(1,280万元)和篮球套装(1,250万元)最为畅销
- 鞋类细分表现:
- 跑步鞋(4,107万元)和篮球鞋(3,953万元)是鞋类主力
- 足球鞋单价最高(1,516元),但市场份额较小
- 休闲鞋订单量大(38,364单)但单价较低(957元)
- 服装品类亮点:
- 上衣订单量最大(64,019单),用户渗透率高达90.26%
- 羽绒服是单品销售额前十的唯一非套装服装产品(1,114万元)
- 下装虽单价低(455元)但用户渗透率最高(92.06%)
2.2品牌系列影响力
- 顶级系列产品:
- 阿迪达斯超动力(982万元)领衔跑步鞋市场
- 特锐斯徒步者(919万元)主导户外鞋市场
- 哈登系列(827万元)和D罗斯系列(815万元)是篮球鞋市场的主力
3. 价格结构与消费层级
3.1价格段分布
- 销售额集中区间:500-1000元价格段贡献了46.54%的销售额,是绝对主力
- 订单数分布:
- 500-1000元(33.34%)和200-500元(30.89%)价格段订单数最多
- 高价区间(1000-2000元)仍占12.32%的订单量,贡献26.07%的销售额
- 市场定位:中高档产品(500元以上)贡献了72.61%的销售额,表明市场定位偏中高端
3.2高频vs高价值
- 低价高频:100-500元区间贡献了50%的订单,但仅创造26.63%的销售额
- 高价高价值:1000-2000元区间虽仅有12.32%的订单,却创造了26.07%的销售额
- 极低价区间:0-100元产品虽有4.33%的订单量,但仅贡献0.76%的销售额,边际贡献极低
4. 季节性消费特征
4.1品类季节差异
- 运动鞋季节特性:夏季销售占比最高(31.33%),远超冬季(21.26%),反映夏季跑步、户外活动高峰
- 运动服装均衡性:冬季(28.7%)、夏季(27.8%)和秋季(27.9%)销售占比相近,体现四季需求
- 春季普遍低谷:所有品类在春季销售占比最低,运动服装春季销售占比仅15.63%
- 装备夏季高峰:运动装备和配饰在夏季销售占比均接近30%,反映夏季户外活动热潮
4.2季节消费动因
- 冬季服装主导:冬季是运动服装销售占比最高的季节(28.7%),主要由羽绒服、外套等高单价产品带动
- 夏季全面高峰:各品类夏季销售均处于高位,特别是鞋类(31.33%),表明夏季是整体消费旺季
- 换季消费模式:秋季各品类表现稳定(约25-28%),维持较高水平,体现换季消费习惯
5. 商业启示与策略建议
5.1产品策略优化
- 套装主导战略:加强套装产品线开发,特别是赛事套装、篮球套装和足球套装的设计创新
- 运动鞋差异化:
- 专业细分:强化跑步鞋(阿迪达斯超动力、极速系列)和篮球鞋(哈登系列)的技术创新
- 高端户外:扩大特锐斯徒步者等高单价户外鞋产品线,提高毛利贡献
- 价格段策略:
- 重点布局500-1000元价格带产品,确保品类齐全
- 保持1000-2000元高端产品的设计领先性和独特性
- 减少100元以下低价产品投入,提升整体品牌形象
5.2营销策略调整
- 季节营销重点:
- 夏季:重点推广运动鞋和户外装备,设计夏季运动专属促销活动
- 冬季:围绕羽绒服、外套等高价值服装产品开展主题营销
- 春季:设计特别促销活动提振传统淡季销售
- 搭配销售策略:
- 上衣+下装组合营销(两者渗透率均超90%)
- 运动鞋+装备组合促销(提高装备销售额)
- 高频用户策略:针对高渗透率品类(上衣、下装)设计会员专属活动,提高购买频次
5.3库存管理建议
- 季节性调整:夏季备货应增加运动鞋库存25-30%;冬季增加服装库存20-25%
- 核心品类保障:确保套装、跑步鞋和篮球鞋的尺码和颜色选择充足
- 高价值产品管理:对500元以上产品实施更精细的库存管理,降低滞销风险
10.促销效果分析
def promotion_effect_analysis(orders):"""促销效果分析分析各个促销期间的销售效果"""# 定义主要促销期promotions = {'春节': ((1, 15), (2, 15)),'五一': ((4, 25), (5, 5)),'618': ((6, 1), (6, 18)),'开学季': ((8, 20), (9, 10)),'国庆': ((9, 25), (10, 7)),'双11': ((11, 1), (11, 15)),'双12': ((12, 1), (12, 15)),'年末': ((12, 20), (12, 31))}# 创建促销标记函数def mark_promotion(row):month, day = row['下单月份'], row['下单日']for promo, ((start_month, start_day), (end_month, end_day)) in promotions.items():if (month == start_month and day >= start_day) or (month == end_month and day <= end_day):if start_month == end_month:if start_day <= day <= end_day:return promoelse:return promoreturn '非促销期'# 添加促销标记orders['促销期'] = orders.apply(mark_promotion, axis=1)# 统计各促销期的销售数据promo_stats = orders.groupby('促销期').agg({'订单ID': 'count','订单总额': 'sum','用户ID': pd.Series.nunique}).reset_index()promo_stats.columns = ['促销期', '订单数', '销售额', '购买用户数']# 计算促销期天数(简化估算)promo_days = {'春节': 30,'五一': 10,'618': 18,'开学季': 20,'国庆': 12,'双11': 15,'双12': 15,'年末': 12,'非促销期': 365 - 30 - 10 - 18 - 20 - 12 - 15 - 15 - 12 # 233天}# 添加日均销售数据promo_stats['天数'] = promo_stats['促销期'].map(promo_days)promo_stats['日均订单数'] = promo_stats['订单数'] / promo_stats['天数']promo_stats['日均销售额'] = promo_stats['销售额'] / promo_stats['天数']# 计算促销提升倍数(相对于非促销期)non_promo = promo_stats[promo_stats['促销期'] == '非促销期']non_promo_daily_orders = non_promo['日均订单数'].values[0]non_promo_daily_sales = non_promo['日均销售额'].values[0]promo_stats['订单提升倍数'] = promo_stats['日均订单数'] / non_promo_daily_orderspromo_stats['销售额提升倍数'] = promo_stats['日均销售额'] / non_promo_daily_sales# 显示促销统计print("促销效果统计:")display(promo_stats)# 可视化促销期效果fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(16, 16))# 不包括非促销期的数据promo_only = promo_stats[promo_stats['促销期'] != '非促销期'].sort_values('销售额提升倍数', ascending=False)# 日均销售额sns.barplot(x='促销期', y='日均销售额', data=promo_only, palette='viridis', ax=ax1)ax1.set_title('各促销期日均销售额')ax1.set_xlabel('促销期')ax1.set_ylabel('日均销售额(元)')ax1.grid(axis='y')# 销售额提升倍数sns.barplot(x='促销期', y='销售额提升倍数', data=promo_only, palette='rocket', ax=ax2)ax2.set_title('各促销期销售额提升倍数(相对于非促销期)')ax2.set_xlabel('促销期')ax2.set_ylabel('销售额提升倍数')ax2.axhline(y=1, color='r', linestyle='--')ax2.grid(axis='y')plt.tight_layout()plt.show()# 促销期商品类别销售分析promo_category = orders.groupby(['促销期', '商品大类'])['订单总额'].sum().reset_index()promo_category_pivot = promo_category.pivot(index='促销期', columns='商品大类', values='订单总额')# 计算各促销期中商品大类的占比promo_category_pct = promo_category_pivot.div(promo_category_pivot.sum(axis=1), axis=0) * 100# 显示促销期商品类别销售占比print("促销期商品类别销售占比(%):")display(promo_category_pct)# 可视化促销期商品类别销售占比plt.figure(figsize=(16, 10))sns.heatmap(promo_category_pct, annot=True, fmt='.1f', cmap='YlGnBu')plt.title('各促销期商品大类销售占比(%)')plt.xlabel('商品大类')plt.ylabel('促销期')plt.tight_layout()plt.show()# 会员与非会员在促销期的购买行为对比promo_member = orders.groupby(['促销期', '是否会员']).agg({'订单ID': 'count','订单总额': 'sum','用户ID': pd.Series.nunique}).reset_index()promo_member.columns = ['促销期', '是否会员', '订单数', '销售额', '购买用户数']promo_member['客单价'] = promo_member['销售额'] / promo_member['订单数']promo_member['人均消费'] = promo_member['销售额'] / promo_member['购买用户数']# 显示会员促销购买数据print("促销期会员非会员购买对比:")display(promo_member)# 可视化促销期会员vs非会员# 只选择主要促销期major_promos = ['双11', '618', '双12', '春节', '非促销期']promo_member_filtered = promo_member[promo_member['促销期'].isin(major_promos)]fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(16, 16))# 客单价对比sns.barplot(x='促销期', y='客单价', hue='是否会员', data=promo_member_filtered, palette='Set2', ax=ax1)ax1.set_title('促销期会员与非会员客单价对比')ax1.set_xlabel('促销期')ax1.set_ylabel('客单价(元/订单)')ax1.grid(axis='y')# 人均消费对比sns.barplot(x='促销期', y='人均消费', hue='是否会员', data=promo_member_filtered, palette='Set2', ax=ax2)ax2.set_title('促销期会员与非会员人均消费对比')ax2.set_xlabel('促销期')ax2.set_ylabel('人均消费(元/人)')ax2.grid(axis='y')plt.tight_layout()plt.show()print("促销效果分析完成")# 进行促销效果分析
promotion_effect_analysis(processed_orders)
促销效果统计:
促销期 | 订单数 | 销售额 | 购买用户数 | 天数 | 日均订单数 | 日均销售额 | 订单提升倍数 | 销售额提升倍数 | |
---|---|---|---|---|---|---|---|---|---|
0 | 618 | 36127 | 25618364.77 | 8835 | 18 | 2007.06 | 1423242.49 | 1.92 | 1.68 |
1 | 五一 | 16019 | 13234214.65 | 7070 | 10 | 1601.90 | 1323421.47 | 1.53 | 1.56 |
2 | 双11 | 39936 | 26250008.67 | 9012 | 15 | 2662.40 | 1750000.58 | 2.55 | 2.07 |
3 | 双12 | 29375 | 19237176.14 | 8512 | 15 | 1958.33 | 1282478.41 | 1.87 | 1.52 |
4 | 国庆 | 20630 | 16498399.81 | 7738 | 12 | 1719.17 | 1374866.65 | 1.64 | 1.63 |
5 | 年末 | 20365 | 16028548.48 | 7639 | 12 | 1697.08 | 1335712.37 | 1.62 | 1.58 |
6 | 开学季 | 48391 | 39120170.67 | 9298 | 20 | 2419.55 | 1956008.53 | 2.31 | 2.31 |
7 | 春节 | 45500 | 35169640.41 | 9168 | 30 | 1516.67 | 1172321.35 | 1.45 | 1.39 |
8 | 非促销期 | 243657 | 197130550.07 | 9990 | 233 | 1045.74 | 846053.86 | 1.00 | 1.00 |

促销期商品类别销售占比(%):
商品大类 | 运动服装 | 运动装备 | 运动配饰 | 运动鞋 |
---|---|---|---|---|
促销期 | ||||
618 | 38.98 | 3.81 | 6.10 | 51.10 |
五一 | 33.63 | 3.57 | 5.88 | 56.93 |
双11 | 42.92 | 4.00 | 6.15 | 46.92 |
双12 | 47.42 | 4.03 | 6.13 | 42.41 |
国庆 | 42.92 | 4.02 | 6.39 | 46.67 |
年末 | 47.51 | 4.01 | 6.23 | 42.25 |
开学季 | 40.40 | 3.77 | 5.92 | 49.91 |
春节 | 47.97 | 4.25 | 6.05 | 41.73 |
非促销期 | 39.40 | 3.89 | 6.08 | 50.63 |

促销期会员非会员购买对比:
促销期 | 是否会员 | 订单数 | 销售额 | 购买用户数 | 客单价 | 人均消费 | |
---|---|---|---|---|---|---|---|
0 | 618 | 否 | 12093 | 7975699.94 | 4142 | 659.53 | 1925.57 |
1 | 618 | 是 | 24034 | 17642664.83 | 4693 | 734.07 | 3759.36 |
2 | 五一 | 否 | 5275 | 4003733.65 | 3008 | 759.00 | 1331.03 |
3 | 五一 | 是 | 10744 | 9230481.00 | 4062 | 859.13 | 2272.40 |
4 | 双11 | 否 | 13419 | 8287354.60 | 4278 | 617.58 | 1937.20 |
5 | 双11 | 是 | 26517 | 17962654.07 | 4734 | 677.40 | 3794.39 |
6 | 双12 | 否 | 9755 | 5951122.07 | 3955 | 610.06 | 1504.71 |
7 | 双12 | 是 | 19620 | 13286054.07 | 4557 | 677.17 | 2915.53 |
8 | 国庆 | 否 | 6899 | 5124166.63 | 3440 | 742.74 | 1489.58 |
9 | 国庆 | 是 | 13731 | 11374233.18 | 4298 | 828.36 | 2646.40 |
10 | 年末 | 否 | 6915 | 5055859.10 | 3431 | 731.14 | 1473.58 |
11 | 年末 | 是 | 13450 | 10972689.38 | 4208 | 815.81 | 2607.58 |
12 | 开学季 | 否 | 16053 | 12049123.38 | 4466 | 750.58 | 2697.97 |
13 | 开学季 | 是 | 32338 | 27071047.29 | 4832 | 837.13 | 5602.45 |
14 | 春节 | 否 | 15168 | 10940069.04 | 4357 | 721.26 | 2510.92 |
15 | 春节 | 是 | 30332 | 24229571.37 | 4811 | 798.81 | 5036.29 |
16 | 非促销期 | 否 | 81601 | 61493966.25 | 5004 | 753.59 | 12288.96 |
17 | 非促销期 | 是 | 162056 | 135636583.82 | 4986 | 836.97 | 27203.49 |

促销效果分析完成
1.促销期整体效果评估
1.1销售表现排名
- 开学季: 以1,956万元/日的销售额和2.31倍的提升倍数领先,全面夺冠
- 双11: 1,750万元/日,提升倍数2.07,日均订单数最高(2,662单)
- 618: 1,423万元/日,提升倍数1.68,具有稳定表现
- 春节: 虽总销量高(3,517万元),但日均销售最低(117万元),提升效果最弱(1.39倍)
1.2关键绩效指标
- 订单数量: 开学季(48,391)和春节(45,500)总订单量最大,但原因不同
- 用户覆盖: 开学季激活最多用户(9,298),双11次之(9,012)
- 客单价提升: 五一期间客单价提升最明显,会员客单价达859元
2.促销活动效率比较
2.1高效率促销活动
- 开学季: 销售额和订单数提升倍数双高(2.31倍),投入产出比最优
- 双11: 日均订单数最高(2,662单),是非促销期(1,046单)的2.55倍
2.2低效率促销活动
- 春节: 虽然持续30天,但销售提升倍数仅1.39倍,活动周期过长导致效率下降
- 双12: 销售额提升倍数仅1.52倍,紧随双11后的时间窗口限制了效果
3.商品结构变化特征
3.1促销期品类转换规律
-
季节性偏好:
- 春节、双12和年末: 运动服装占比高(47-48%),鞋类占比低(41-42%)
- 五一和618: 运动鞋占比最高(51-57%),显示夏季户外活动高峰期特征
-
活动特性差异:
- 开学季: 运动鞋(49.9%)和运动服装(40.4%)均衡发展,满足学生全面需求
- 双11: 运动服装占比(42.9%)较非促销期(39.4%)明显提高,可能与服装类打折力度相关
-
配饰和装备稳定性:
- 运动配饰: 各促销期占比稳定在5.9-6.4%
- 运动装备: 春节期间略高(4.25%),其余促销期稳定在3.8-4.0%
4.会员与非会员消费行为对比
4.1客单价差异
- 整体差异: 会员客单价普遍高于非会员10-20%
- 最大差距: 非促销期(会员837元 vs 非会员754元,差距11%)
- 特殊表现: 国庆期间会员客单价(828元)与非会员(743元)差距最大(11.5%)
4.2人均消费差异
- 非促销期异常: 会员人均消费达27,203元,非会员为12,289元,差距显著
- 促销期表现: 开学季会员人均消费最高(5,602元),是非会员(2,698元)的2.08倍
- 会员响应度: 双11和618期间会员人均消费约为非会员的2倍,显示会员对主要电商节日反应更积极
5.策略建议
5.1促销节奏优化
- 重点强化开学季: 增加营销预算20-30%,拓展活动时间窗口
- 调整春节策略: 缩短促销周期,提高单日促销力度,避免长期低效促销
- 差异化双11/12: 双11侧重服装类折扣,双12针对运动鞋和高客单价商品
5.2商品结构调整
-
季节性备货:
- 五一/618前: 增加运动鞋库存25-30%
- 春节/双12前: 提升运动服装占比至50%以上
-
套装组合策略:
- 开学季: 设计"学生特惠套装",提高客单价
- 双11: 强化运动服装搭配促销,提升单品销量
5.3会员营销策略
-
会员专属活动:
- 开学季和双11设置"会员优先购"和"额外折扣"
- 春节期间推出会员专属礼品,提升客单价
-
非会员转化策略:
- 双12针对非会员设计入会优惠
- 五一期间面向非会员推广会员体系价值
11.结论
本项目对模拟阿迪达斯电商数据进行了全面分析,揭示了用户行为、销售趋势、区域差异和产品偏好等多维度的商业洞察。以下是关键发现及其战略意义:
一、用户价值与分层策略
-
高价值群体贡献巨大:超高价值用户(24%)贡献了近47%的总销售额,验证了经典的80/20法则。
-
用户分层明确:通过聚类分析识别出三个核心用户群体:
- 高价值忠实会员(18.6%):平均消费8.4万元,105单/人,有明确的全品类偏好
- 普通消费客户(38.8%):平均消费4.1万元,54单/人,无明显品类偏好
- 流失风险客户(42.6%):平均消费1.6万元,22单/人,购买频率低,最近购买时间远
-
购买频次是关键:高价值用户与低价值用户的客单价差异仅9%,但购买频次差异达5.7倍,表明提高复购率比提升单次消费额更为关键。
二、销售季节性与促销效果
-
销售高峰期明确:全年呈现多个销售高峰,其中Q3(7-9月)表现最佳,开学季与双11是年度最强促销期。
-
促销效率差异大:
- 开学季:销售额提升2.31倍,投入产出比最优
- 双11:订单数提升2.55倍,客单价增长不显著
- 春节:提升仅1.39倍,周期过长导致效率低下
-
会员响应率更高:会员在促销期的客单价和人均消费均显著高于非会员,特别是在开学季和双11。
三、产品结构与价格策略
-
双核心产品线:运动鞋(38%)和运动服装(32%)构成销售主体,几乎100%用户都有购买。
-
高毛利产品表现:
- 套装类产品(1,383元/单)是最大贡献者,占销售额12%
- 赛事套装、篮球套装和足球套装均表现出色
- 特锐斯徒步者(1,263元/单)是最畅销的高价鞋类
-
最佳价格带:500-1000元价格段贡献了46.5%的销售额,是绝对主力,而0-100元产品虽占4.3%的订单量,但贡献不足1%的销售额。
四、区域消费特征
-
区域销售格局:北京、上海、广东三地领先,各约2亿元销售额,其次是江浙沪和天津区域。
-
城市差异明显:一线城市与二线城市之间存在"断崖式"差距;许昌、杭州等城市人均消费超过31,000元,远高于平均水平。
-
区域品类偏好趋同:全国各地商品类别结构相似,但天津运动鞋占比最高(49.9%),吉林和四川运动服装占比最高(42%)。
-
季节响应差异:北方地区冬季消费明显高于南方地区,所有地区夏季均为消费高峰。
五、战略建议
用户策略
-
忠诚度管理:为高价值会员(18.6%)制定专属权益体系,确保留存率。
-
流失预防计划:对43%的流失风险客户实施预警机制,触发自动化营销活动。
-
会员转化:针对非会员设计阶梯式入会激励,特别是在双12和五一期间。
产品策略
-
套装产品线扩展:增加体育赛事、训练和专业系列套装的设计和推广。
-
价格带优化:
- 增加500-1000元价格带产品的SKU数量
- 逐步减少200元以下低毛利产品
- 设置1000-2000元高端产品为品牌形象背书
-
季节性产品规划:
- 夏季:增加运动鞋和轻便服装比例
- 冬季:北方市场增加保暖外套和套装
- 春季:提前规划促销活动,应对销售低谷
促销策略
-
年度促销节奏:
- 重点投入:开学季(8-9月)和双11
- 优化调整:缩短春节促销周期,提高单日力度
- 深化会员:双12设计针对非会员的入会特权
-
区域差异化营销:
- 一线城市:发展全季节高端产品组合
- 二线城市高消费区:针对许昌、青岛等提供独家产品
- 季节性差异:南北方地区冬季产品组合差异化
-
商品结构匹配:
- 五一/618:运动鞋比例提升至55-60%
- 春节/双12:运动服装比例提升至50%以上
- 开学季:运动鞋和服装均衡发展,设计学生特惠套装
通过综合应用这些策略,企业可以提高用户终身价值,优化产品结构,实现区域精准营销,最终带来销售增长和利润提升。本分析展示了数据驱动决策如何帮助运动电商企业在竞争激烈的市场中脱颖而出。