数据挖掘 | 利用python进行商品亲和性分析

可以叫我才哥 2022-01-15 03:45:21 阅读数:755

Python 数据 利用 进行 挖掘

以下案例来自《Python数据挖掘入门与实践(第二版)》第一章1.3亲和性分析的简单示例。

我们先通过本案例了解下关于亲和性的一些概念和工作流程,然后再讨论一些相对更优化的处理方案。

注:该书明确说明为了便于理解,有时更加关注代码和工作流程是否清晰易懂,而不是所采用的方法效率是否最优。

1. 什么是亲和性分析

亲和性分析是一种用于计算样本相似度的数据挖掘方法,这个相似度可以出现在以下几种场景:

网站的用户,拓展服务项目或者定向投放广告;

销售的商品,推荐电影或其他商品(猜你喜欢)。

关于亲和性分析,大家估计都会看到以下这个经典的例子:

在美国的零售业有着这样一个传奇故事,沃尔玛百货将他们的纸尿裤和啤酒并排摆在一起销售,结果纸尿裤和啤酒的销量双双增长!

在今天的案例中,为了简化代码方便理解,我们仅考虑同时购买2件商品的情况,比如以下简单的规则:

用户如果购买了商品X,那么也倾向于购买商品Y

这里我们给出2个用来评价规则的数据指标概念:支持度置信度

支持度 是规则在数据集中出现的次数,即匹配规则的样本数,比如同时购买商品X和Y的交易数;

置信度 是衡量匹配规则的准确度的,比如在购买商品X的交易中同时购买商品Y的比例。

2. 案例详解

本节为书中案例介绍,其使用的工具库如下:

  • numpy
  • collections

2.1. 加载数据集

数据集后台回复 955 领取,有兴趣的同学也可以使用numpy自己构建随机数据组。

import numpy as np
dataset_filename = "affinity_dataset.txt"
X = np.loadtxt(dataset_filename)
n_samples, n_features = X.shape
print(f"这份数据集 有 {
n_samples} 行 和 {
n_features} 列")
print(X[:5])
这份数据集 有 100 行 和 5 列
[[0. 1. 0. 0. 0.]
[1. 1. 0. 0. 0.]
[0. 0. 1. 0. 1.]
[1. 1. 0. 0. 0.]
[0. 0. 1. 1. 1.]]

这份数据集比较小,一共100行5列数据。这里我们将每行数据看做是一次交易行为每列代表一种商品数字1代表有购买0代表没有购买

对于这5列,分别代表 面包、牛奶、奶酪、苹果和香蕉。比如第一行[0. 1. 0. 0. 0.]显示首次交易中的商品,消费者只购买了牛奶,而没有购买其它商品。

features = ["面包", "牛奶", "奶酪", "苹果", "香蕉"]

接下来,我们开始研究支持度和置信度的计算。

2.2. 求苹果->香蕉的亲和性

根据概念,置信度需要知道支持度中某商品交易数,这里我们拿香蕉举例,看看其交易数。

计算规则:遍历苹果列数据,值为1则计数+1

num_apple_purchases = 0
for sample in X:
if sample[3] == 1: # 第4列
num_apple_purchases += 1
print(f"含苹果的交易数为:{
num_apple_purchases}")
含苹果的交易数为:43

接着,我们计算苹果-香蕉的支持度。

计算规则:如果苹果列为1且香蕉列为1,则计数+1

rule_valid = 0
for sample in X:
if sample[3] == 1: # 购买了苹果
if sample[4] == 1:
# 同时也购买了香蕉
rule_valid += 1
else:
continue
print(f"同时购买苹果和香蕉的交易数为:{
rule_valid}")
同时购买苹果和香蕉的交易数为:27

以上两个数值都计算出来后,我们可以很方便的获取苹果—>香蕉置信度

计算规则:用苹果-香蕉的支持度/含苹果的交易数

support = rule_valid # 支持度
confidence = rule_valid / num_apple_purchases # 置信度
print(f"苹果-香蕉的支持度为 {
support}\n苹果—>香蕉的置信度为 {
confidence:.3f}")
# Confidence can be thought of as a percentage using the following:
print(f"苹果—>香蕉的置信度百分比为 {
confidence*100:.1f}%.")
苹果-香蕉的支持度为 27
苹果—>香蕉的置信度为 0.628
苹果—>香蕉的置信度百分比为 62.8%

至此,我们便计算出了苹果-香蕉的支持度为27,也就是同时购买苹果和香蕉的交易数为27;而购买苹果的用户中也购买了香蕉的比例为62.8%,这就是置信度。

接着,我们就可以计算全部组合之间的支持度与置信度数据,然后进行对比分析,接着安排相关策略了。

2.3. 亲和性分析

现在我们需要从数据集中计算所有规则(注意:这里的规则我们还是以2个商品为例,不拓展更多组合)。因此需要创建1个字典用于存储匹配的规则,字典的key是X—>Y,值则是支持度;另外一个字典用于存储对应的X—>Y中X出现的次数。

from collections import defaultdict
# 初始化2个字典
valid_rules = defaultdict(int)
num_occurences = defaultdict(int)
# 计算支持度及X->Y中X出现次数
for sample in X:
for premise in range(n_features):
if sample[premise] == 0:
continue
# 记录X—>Y中X出现的次数
num_occurences[premise] += 1
for conclusion in range(n_features):
if premise == conclusion: # X—>X是无意义的,跳过
continue
if sample[conclusion] == 1:
# X和Y同时出现,则匹配规则的次数+1
valid_rules[(premise, conclusion)] += 1
else:
continue
support = valid_rules
confidence = defaultdict(float)
# 计算置信度
for premise, conclusion in valid_rules.keys():
confidence[(premise, conclusion)] = valid_rules[(premise, conclusion)] / num_occurences[premise]
#输出结果
for premise, conclusion in confidence:
premise_name = features[premise]
conclusion_name = features[conclusion]
print(f"规则: {
premise_name}—>{
conclusion_name}")
print(f" - 置信度: {
confidence[(premise, conclusion)]*100:.2f}%")
print(f" - 支持度: {
support[(premise, conclusion)]}")
print('-'*20)

输出结果如下:

规则: 面包—>牛奶
- 置信度: 46.43%
- 支持度: 13
--------------------
规则: 牛奶—>面包
- 置信度: 25.00%
- 支持度: 13
--------------------
规则: 奶酪—>香蕉
- 置信度: 51.28%
- 支持度: 20
--------------------
规则: 香蕉—>奶酪
- 置信度: 35.09%
- 支持度: 20
--------------------
规则: 奶酪—>苹果
- 置信度: 56.41%
- 支持度: 22
--------------------
规则: 苹果—>奶酪
- 置信度: 51.16%
- 支持度: 22
--------------------
规则: 苹果—>香蕉
- 置信度: 62.79%
- 支持度: 27
--------------------
规则: 香蕉—>苹果
- 置信度: 47.37%
- 支持度: 27
--------------------
规则: 牛奶—>苹果
- 置信度: 34.62%
- 支持度: 18
--------------------
规则: 苹果—>牛奶
- 置信度: 41.86%
- 支持度: 18
--------------------
规则: 牛奶—>香蕉
- 置信度: 51.92%
- 支持度: 27
--------------------
规则: 香蕉—>牛奶
- 置信度: 47.37%
- 支持度: 27
--------------------
规则: 面包—>奶酪
- 置信度: 17.86%
- 支持度: 5
--------------------
规则: 奶酪—>面包
- 置信度: 12.82%
- 支持度: 5
--------------------
规则: 面包—>香蕉
- 置信度: 57.14%
- 支持度: 16
--------------------
规则: 香蕉—>面包
- 置信度: 28.07%
- 支持度: 16
--------------------
规则: 牛奶—>奶酪
- 置信度: 21.15%
- 支持度: 11
--------------------
规则: 奶酪—>牛奶
- 置信度: 28.21%
- 支持度: 11
--------------------
规则: 面包—>苹果
- 置信度: 32.14%
- 支持度: 9
--------------------
规则: 苹果—>面包
- 置信度: 20.93%
- 支持度: 9
--------------------

我们可以输出置信度前5的规则如下:(大家也可以试着输出支持度前5的规则)

def print_rule(premise, conclusion, support, confidence, features):
premise_name = features[premise]
conclusion_name = features[conclusion]
print(f"规则: {
premise_name}—>{
conclusion_name}")
print(f" - 置信度: {
confidence[(premise, conclusion)]*100:.2f}%")
print(f" - 支持度: {
support[(premise, conclusion)]}")
print('-'*20)
from operator import itemgetter
sorted_support = sorted(support.items(), key=itemgetter(1), reverse=True)
sorted_confidence = sorted(confidence.items(), key=itemgetter(1), reverse=True)
for index in range(5):
print("Rule #{0}".format(index + 1))
(premise, conclusion) = sorted_confidence[index][0]
print_rule(premise, conclusion, support, confidence, features)

输出结果如下:

Rule #1
规则: 苹果—>香蕉
- 置信度: 62.79%
- 支持度: 27
--------------------
Rule #2
规则: 面包—>香蕉
- 置信度: 57.14%
- 支持度: 16
--------------------
Rule #3
规则: 奶酪—>苹果
- 置信度: 56.41%
- 支持度: 22
--------------------
Rule #4
规则: 牛奶—>香蕉
- 置信度: 51.92%
- 支持度: 27
--------------------
Rule #5
规则: 奶酪—>香蕉
- 置信度: 51.28%
- 支持度: 20
--------------------

当我们得出以上数据后,就可以进行下一步的销售策略调整了,简单的比如 购买苹果可以获得购买香蕉折扣之类的。具体这里不深入讨论,我们放在后续 关联规则分析中做深入介绍。

3. 算法优化

关于亲和性分析,是有一些数据挖掘算法如Apriori算法来处理的,这里也不展开。那么,这里的算法优化其实是指对案例中非常直接的计算方式进行优化,这里用到的是pandas工具以及我们之前介绍过的itertools《》。

主要是计算支持度的逻辑优化,实现的方式有很多种,大家具体查看代码注释吧。

import pandas as pd
# 将数据集转化为Dataframe类型
df = pd.DataFrame(X, columns=features)
# 先引入该内置标准库
import itertools
# 求组合(顺序不同组合不同)
it = itertools.permutations(features,2)
rules = list(it)
for rule in rules:
num_occurence = df[rule[0]].sum() # X—>Y中X在整个数据集中出现次数
num_rule = df.query(f"{
rule[0]}+{
rule[1]}==2").shape[0] # 同时购买X和Y的交易次数(支持度),这里用两数相加=2来验证
# df.query(f"{rule[0]}*{rule[1]}==1").shape[0] # 用两数相乘=1 验证
# df[(df[rule[0]]==1) & (df[rule[1]]==1)].shape[0] # 直接用对应值都是1来验证
# df[df[rule[0]]==1][rule[1]].sum() # 用X—>Y中,X购买情况下Y列求和(毕竟购买为1,不购买为0)
# df[list(rule)].all(axis = 'columns').sum() # 由于数据为0和1,适用于all()方法进行bool判断,然后sum求和
confidence = num_rule / num_occurence # 置信度
print(f'规则:{
rule[0]}—>{
rule[1]}\n- 置信度:{
confidence*100:.2f}%\n- 支持度:{
num_rule}\n')

输出结果如下:(我们只展示部分)

规则:面包—>牛奶
- 置信度:46.43%
- 支持度:13
规则:面包—>奶酪
- 置信度:17.86%
- 支持度:5
规则:面包—>苹果
- 置信度:32.14%
- 支持度:9
规则:面包—>香蕉
- 置信度:57.14%
- 支持度:16
规则:牛奶—>面包
- 置信度:25.00%
- 支持度:13

为了更方便做后续的操作,我们可以将以上数据转化为DataFrame类型,操作如下:

columns=['规则','置信度','支持度']
data = pd.DataFrame(columns=columns)
for rule in rules:
num_occurence = df[rule[0]].sum() # X—>Y中X在整个数据集中出现次数
num_rule = df[df[rule[0]]==1][rule[1]].sum() # 用X—>Y中,X购买情况下Y列求和(毕竟购买为1,不购买为0)
confidence = num_rule / num_occurence # 置信度
data = data.append(pd.DataFrame([[f'{
rule[0]}—>{
rule[1]}',confidence,num_rule]],columns=columns),ignore_index=True)
data.nlargest(n=5, columns= '置信度', keep='first')

置信度前5

以上就是本文关于亲和性分析的基础介绍,案例来源《Python数据挖掘入门与实践(第二版)》第一章1.3亲和性分析的简单示例,并没有做太多的展开介绍。

我们后续将会拿实际生活中的具体场景再一次进行更详细的介绍,敬请期待哈。

如果你喜欢本篇介绍,还请点赞在看给个支持哈!

版权声明:本文为[可以叫我才哥]所创,转载请带上原文链接,感谢。 https://blog.csdn.net/dxawdc/article/details/118178675