Gini Coefficient and Lorenz Curve
Gini 系数和洛伦兹曲线 (Lorenz Curve) 是用于衡量推荐列表中物品流行度分布不均衡程度的两个重要指标. 洛伦兹曲线则通过绘制推荐物品流行度的累计分布曲线来分析推荐物品的集中程度.
Gini 系数的取值范围是从 0 到 1,用于衡量分布的不平等程度:
- Gini 系数为 0:表示完全平等的分布,每个项的推荐次数都相同。
- Gini 系数为 1:表示极端不平等的分布,所有的推荐次数都集中在一个项上。
在推荐系统中:
- 较低的 Gini 系数 表示推荐系统推荐的物品较为均衡,较少集中在少数流行物品上。
- 较高的 Gini 系数 表示推荐系统推荐的物品集中在少数流行物品上,存在较大的流行度偏差。
通过计算 Gini 系数,可以评估推荐系统在推荐物品时的多样性和公平性。
计算 Gini 系数可以通过以下步骤实现:
- 准备数据: 获取推荐列表中每个物品的推荐次数.
- 排序: 对推荐次数进行排序.
- 计算累积分布: 计算累积推荐次数和累积推荐比例.
- 计算 Gini 系数: 使用公式计算 Gini 系数.
以下是详细的 Python 实现:
1. 数据准备
假设已经有推荐列表 user_recs
, 格式为: {user_id: [(item_id, rating), ...]}
.
from collections import defaultdict
# 计算推荐列表中每个物品的推荐次数
rec_item_count = defaultdict(int)
for user, recs in user_recs.items():
for item, _ in recs:
rec_item_count[item] += 1
# 将推荐次数转化为列表
item_counts = list(rec_item_count.values())
2. 排序
# 将推荐次数排序
item_counts.sort()
3. 计算累积分布
import numpy as np
# 计算累积推荐次数和累积推荐比例
cumulative_counts = np.cumsum(item_counts)
cumulative_proportion = cumulative_counts / cumulative_counts[-1]
item_proportion = np.arange(1, len(item_counts) + 1) / len(item_counts)
4. 计算 Gini 系数
Gini 系数可以通过以下公式计算:
Gini Coefficient = 1 − 2 × Area Under Lorenz Curve \text{Gini Coefficient} = 1 - 2 \times \text{Area Under Lorenz Curve} Gini Coefficient=1−2×Area Under Lorenz Curve
使用数值积分的方法计算洛伦兹曲线下的面积, 然后计算 Gini 系数.
# 计算 Gini 系数
area_under_lorenz_curve = np.trapz(cumulative_proportion, item_proportion)
gini_coefficient = 1 - 2 * area_under_lorenz_curve
print(f'Gini Coefficient: {gini_coefficient}')
完整代码
以下是完整的代码, 包含所有步骤:
from collections import defaultdict
import numpy as np
import matplotlib.pyplot as plt
# 计算推荐列表中每个物品的推荐次数
rec_item_count = defaultdict(int)
for user, recs in user_recs.items():
for item, _ in recs:
rec_item_count[item] += 1
# 将推荐次数转化为列表,并按推荐次数排序
item_counts = list(rec_item_count.values())
item_counts.sort()
# 计算累积推荐次数和累积推荐比例
cumulative_counts = np.cumsum(item_counts)
cumulative_proportion = cumulative_counts / cumulative_counts[-1]
item_proportion = np.arange(1, len(item_counts) + 1) / len(item_counts)
# 计算 Gini 系数
area_under_lorenz_curve = np.trapz(cumulative_proportion, item_proportion)
gini_coefficient = 1 - 2 * area_under_lorenz_curve
print(f'Gini Coefficient: {gini_coefficient}')
# 绘制洛伦兹曲线(可选)
plt.figure(figsize=(10, 6))
plt.plot(item_proportion, cumulative_proportion, label='Lorenz Curve')
plt.plot([0, 1], [0, 1], linestyle='--', color='r', label='Equality Line')
plt.xlabel('Cumulative Share of Items')
plt.ylabel('Cumulative Share of Recommendations')
plt.legend()
plt.title('Lorenz Curve')
# plt.show()
plt.tight_layout()
plt.savefig('./Lorenz Curve.png', dpi=300)
总结
通过上述步骤, 您可以计算 Gini 系数以衡量推荐系统中物品推荐次数的分布不均衡程度. 如果 Gini 系数较高, 说明推荐系统倾向于推荐少数流行物品. 反之, 如果 Gini 系数较低, 说明推荐系统推荐的物品较为均衡.