3. 探索性数据分析(EDA):用户行为分布分析、商品流行度分析、用户-商品交互矩阵可视化

好,咱们进入第三讲。说实话,EDA 这一步,很多人觉得就是画几张图,没啥技术含量。但我告诉你,我见过太多项目,模型跑出来效果差,回头一查,全是 EDA 阶段埋的坑。你想想看,数据长什么样你都不清楚,你怎么敢往上堆模型?

这一章,咱们就聚焦三个核心问题:用户都在干什么?什么东西好卖?用户和商品之间到底怎么连接的?

3.1 用户行为分布分析

先看用户行为。电商里最常见的四种行为:浏览、收藏、加购、购买。它们的分布,直接决定了你的推荐策略。

我个人习惯,第一步先看整体数量级。用 Python 跑一下:

import pandas as pd
import matplotlib.pyplot as plt

# 假设 df 是原始行为数据
behavior_counts = df['behavior_type'].value_counts()
print(behavior_counts)

# 画个柱状图
behavior_counts.plot(kind='bar')
plt.title('用户行为类型分布')
plt.xlabel('行为类型')
plt.ylabel('次数')
plt.show()

跑完之后,你大概率会看到一个「长尾分布」。什么意思?就是浏览行为占了绝大多数,购买行为少得可怜。嗯,这里要注意,千万别觉得「购买少就是坏事」。我在项目中遇到过,有个客户一看购买率只有 2%,急得不行。其实这是正常的,电商的转化率普遍在 1%-5% 之间。

那我们要关注什么?关注的是行为之间的转化漏斗。比如:

  • 浏览 → 加购 的转化率是多少?
  • 加购 → 购买 的转化率是多少?

如果浏览到加购的转化率特别低,说明商品详情页可能有问题。如果加购到购买的转化率低,那可能是价格或者库存的问题。这些洞察,都是后续做特征工程的基础。

核心结论:用户行为分布不是均匀的。我们要抓住「关键行为节点」,比如加购和购买,这些才是推荐系统真正要优化的目标。

3.2 商品流行度分析

接下来看商品。说白了,就是看看哪些商品是「明星」,哪些是「长尾」。我习惯用两个指标:商品被交互的总次数交互它的用户数

代码很简单:

# 商品流行度:按商品ID统计交互次数
item_popularity = df.groupby('item_id')['behavior_type'].count().sort_values(ascending=False)
print(item_popularity.head(10))

# 画个分布图
item_popularity.hist(bins=50)
plt.title('商品流行度分布')
plt.xlabel('交互次数')
plt.ylabel('商品数量')
plt.show()

你会发现,又是长尾分布。少数头部商品占据了大部分交互,大量商品几乎无人问津。这就是经典的「二八法则」——20% 的商品贡献了 80% 的流量。

我曾经帮一个跨境电商做分析,发现他们的头部商品全是低价小饰品,而高客单价的电子产品几乎没人看。后来调整了推荐策略,把长尾商品通过关联推荐推给精准用户,整体转化率提升了 15%。

这里有个避坑指南:不要只看交互次数。比如一个商品被浏览了 1000 次,但购买为 0,这其实是个「虚假繁荣」。我建议同时看「购买转化率」:

# 计算每个商品的购买转化率
item_behavior = df.groupby('item_id')['behavior_type'].apply(lambda x: (x == 'buy').sum() / len(x))
print(item_behavior.sort_values(ascending=False).head(10))

小技巧:把商品按流行度分成三档——头部(前 10%)、腰部(10%-50%)、尾部(后 50%)。不同档位的商品,推荐策略完全不同。头部商品做曝光,腰部商品做关联,尾部商品做探索。

3.3 用户-商品交互矩阵可视化

最后,咱们把用户和商品放到一起看。交互矩阵,说白了就是一个大表格:行是用户,列是商品,格子里的值表示交互强度(比如 0 表示没交互,1 表示浏览,2 表示加购,3 表示购买)。

但现实情况是,用户和商品数量都很大,矩阵会非常稀疏。比如 10 万用户 × 10 万商品,矩阵里 99.9% 都是 0。直接可视化?不现实。

我一般会抽样。随机选 100 个活跃用户和 100 个热门商品,画个热力图:

import seaborn as sns
import numpy as np

# 抽样
top_users = df['user_id'].value_counts().head(100).index
top_items = df['item_id'].value_counts().head(100).index
sample_df = df[df['user_id'].isin(top_users) & df['item_id'].isin(top_items)]

# 构建矩阵
matrix = sample_df.pivot_table(index='user_id', columns='item_id', 
                               values='behavior_type', aggfunc='max', fill_value=0)

# 画热力图
plt.figure(figsize=(12, 10))
sns.heatmap(matrix, cmap='YlOrRd', cbar=True)
plt.title('用户-商品交互矩阵热力图(抽样)')
plt.xlabel('商品ID')
plt.ylabel('用户ID')
plt.show()

你会看到什么?大部分区域是深色(0),只有零星几个亮点。这就是稀疏性。但亮点集中的地方,就是「热点区域」——这些用户和商品之间有强交互。

注意:交互矩阵的稀疏度,直接决定了你能不能用协同过滤。如果稀疏度超过 99.9%,传统的基于用户的协同过滤效果会很差。这时候我建议改用基于物品的协同过滤,或者直接上矩阵分解。

另外,我还会看矩阵的行和列的分布。比如:

  • 行均值:每个用户平均交互了多少商品?如果大部分用户只交互了 1-2 个商品,那这个数据集「冷启动」问题会很严重。
  • 列均值:每个商品平均被多少用户交互?如果大部分商品只有个位数用户交互,那推荐系统很难学到有效的商品表征。

我记得有一次,分析一个音乐推荐的数据集,发现交互矩阵的列均值只有 0.3。也就是说,平均每个歌曲只有不到 1 个用户听过。这种数据,你直接跑协同过滤,结果就是「推荐了个寂寞」。后来我们用了内容增强的方法,把歌曲的元数据(风格、歌手、时长)加进去,才勉强把推荐做起来。

3.4 小结

这一章咱们干了三件事:

  1. 用户行为分布:看清浏览、加购、购买的比例,找到转化漏斗的瓶颈。
  2. 商品流行度:识别头部和长尾商品,制定差异化推荐策略。
  3. 交互矩阵可视化:直观感受数据的稀疏性,为后续算法选型提供依据。

说白了,EDA 就是给你的数据「拍个 X 光片」。哪里有问题,哪里有机会,一目了然。下一章,咱们就要基于这些发现,开始做特征工程了。到时候你会发现,EDA 做得越细,特征工程就越顺手。

一句话总结:别急着建模,先跟你的数据「聊聊天」。聊透了,模型自然就听话了。