网易首页 > 网易号 > 正文 申请入驻

利用关联规则实现推荐算法

0
分享至

关联规则是以规则的方式呈现项目之间的相关性:关联规则(Association Rules)是反映一个事物与其他事物之间的相互依存性和关联性,是数据挖掘的一个重要技术,用于从大量数据中挖掘出有价值的数据项之间的相关关系。

关联规则的经典例子是通过发现顾客放入其购物篮中的不同商品之间的联系,可分析顾客的购买习惯。通过了解哪些商品频繁地被顾客同时购买,可以帮助零售商制定营销策略。在医学方面,研究人员希望能够从已有的成千上万份病历中找到患某种疾病的病人的共同特征,从寻找出更好的预防措施。

Apriori Algorithm(先验)

它是一种购物车的分析方法,用于揭示产品之间的关联关系。

他有三个简单的公式:

Support(X, Y) = Freq(X, Y) / N :它表示 X 和 Y 一起出现的概率。它是 X 和 Y 一起出现的频率除以 N。

Confidence(X, Y) = Freq(X, Y) / Freq(X) :表示购买产品X时购买产品Y的概率。 X 和 Y 一起出现的频率除以 X 出现的频率。

Lift = Support(X, Y) / (Support(x) * Support (Y)) :当购买X时,购买Y的概率增加了lift的倍数。 X 和 Y 一起出现的概率是 X 和 Y 分别出现的概率的乘积。它陈述了一个表达式,例如当我们购买一种产品时,购买另一种产品的概率会增加多少倍。

下面我们将使用Apriori Algorithm向用户推荐相应的产品

数据预处理

这里我们使用的数据集是online retail II dataset

!pip install mlxtend
import pandas as pd
pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', None)
pd.set_option('display.width', 500)
# It ensures that the output is on one line.
pd.set_option('display.expand_frame_repr', False)
from mlxtend.frequent_patterns import apriori, association_rules
df_ = pd.read_excel("datasets/online_retail_II.xlsx", sheet_name = "Year 2010-2011")
df = df_.copy()
df.info()
# Column Non-Null Count Dtype
# --- ------ -------------- -----
# 0 Invoice 541910 non-null object
# 1 StockCode 541910 non-null object
# 2 Description 540456 non-null object
# 3 Quantity 541910 non-null int64
# 4 InvoiceDate 541910 non-null datetime64[ns]
# 5 Price 541910 non-null float64
# 6 Customer ID 406830 non-null float64
# 7 Country 541910 non-null objectdf.head()
# Invoice StockCode Description Quantity InvoiceDate Price Customer ID Country
# 0 536365 85123A WHITE HANGING HEART T-LIGHT HOLDER 6 2010-12-01 08:26:00 2.55 17850.0 United Kingdom
# 1 536365 71053 WHITE METAL LANTERN 6 2010-12-01 08:26:00 3.39 17850.0 United Kingdom
# 2 536365 84406B CREAM CUPID HEARTS COAT HANGER 8 2010-12-01 08:26:00 2.75 17850.0 United Kingdom
# 3 536365 84029G KNITTED UNION FLAG HOT WATER BOTTLE 6 2010-12-01 08:26:00 3.39 17850.0 United Kingdom
# 4 536365 84029E RED WOOLLY HOTTIE WHITE HEART. 6 2010-12-01 08:26:00 3.39 17850.0 United Kingdom

我们使用这个函数来确定数据的阈值。

def outlier_thresholds(dataframe, variable):
quartile1 = dataframe[variable].quantile(0.01)
quartile3 = dataframe[variable].quantile(0.99)
interquantile_range = quartile3 - quartile1
up_limit = quartile3 + 1.5 * interquantile_range
low_limit = quartile1 - 1.5 * interquantile_range
return low_limit, up_limit

下面这个函用阈值替换了异常值。

def replace_with_thresholds(dataframe, variable):
low_limit, up_limit = outlier_thresholds(dataframe, variable)
dataframe.loc[(dataframe[variable] < low_limit), variable] = low_limit
dataframe.loc[(dataframe[variable] > up_limit), variable] = up_limit

第三个函数中我们从数据中提取包含“C”的值。 “C”表示退回的物品。 要计算总价,变量数量和价格必须大于零。 在这个函数中还调用了 Outlier 和 Threshold 函数。

def retail_data_prep(dataframe):
dataframe.dropna(inplace=True)
dataframe = dataframe[~dataframe["Invoice"].str.contains("C", na=False)]
dataframe = dataframe[dataframe["Quantity"] > 0]
dataframe = dataframe[dataframe["Price"] > 0]
replace_with_thresholds(dataframe, "Quantity")
replace_with_thresholds(dataframe, "Price")
return dataframedf = retail_data_prep(df)

准备购买-物品的矩阵

数据集中的收据(Invoice)包含了产品的购买,所以我们先处理这个

df_gr = df[df['Country'] == 'Germany']
df_gr.head()
Invoice StockCode Description Quantity InvoiceDate Price Customer ID Country
1109 536527 22809 SET OF 6 T-LIGHTS SANTA 6.0 2010-12-01 13:04:00 2.95 12662.0 Germany
1110 536527 84347 ROTATING SILVER ANGELS T-LIGHT HLDR 6.0 2010-12-01 13:04:00 2.55 12662.0 Germany
1111 536527 84945 MULTI COLOUR SILVER T-LIGHT HOLDER 12.0 2010-12-01 13:04:00 0.85 12662.0 Germany
1112 536527 22242 5 HOOK HANGER MAGIC TOADSTOOL 12.0 2010-12-01 13:04:00 1.65 12662.0 Germany
1113 536527 22244 3 HOOK HANGER MAGIC GARDEN 12.0 2010-12-01 13:04:00 1.95 12662.0 Germany

根据 Invoice 和 Description,我们通过 groupby 计算 Quantities,可以计算产品的数量。

df_gr.groupby(['Invoice', 'Description']).agg({"Quantity": "sum"}).head(20)
# Invoice Description
# 536527 3 HOOK HANGER MAGIC GARDEN 12.0
# 5 HOOK HANGER MAGIC TOADSTOOL 12.0
# 5 HOOK HANGER RED MAGIC TOADSTOOL 12.0
# ASSORTED COLOUR LIZARD SUCTION HOOK 24.0
# CHILDREN'S CIRCUS PARADE MUG 12.0
# HOMEMADE JAM SCENTED CANDLES 12.0
# HOT WATER BOTTLE BABUSHKA 4.0
# JUMBO BAG OWLS 10.0
# JUMBO BAG WOODLAND ANIMALS 10.0
# MULTI COLOUR SILVER T-LIGHT HOLDER 12.0
# PACK 3 FIRE ENGINE/CAR PATCHES 12.0
# PICTURE DOMINOES 12.0
# POSTAGE 1.0
# ROTATING SILVER ANGELS T-LIGHT HLDR 6.0
# SET OF 6 T-LIGHTS SANTA 6.0
# 536840 6 RIBBONS RUSTIC CHARM 12.0
# 60 CAKE CASES VINTAGE CHRISTMAS 24.0
# 60 TEATIME FAIRY CAKE CASES 24.0
# CAKE STAND WHITE TWO TIER LACE 2.0
# JAM JAR WITH GREEN LID 12.0

我们使用 unstack 来避免重复的索引,使用 iloc 来显示前 5 个观察结果。 如果产品不在收据中,则 使用NA 表示。

df_gr.groupby(['Invoice', 'Description']).agg({"Quantity": "sum"}).unstack().iloc[0:5, 0:5]
# Description 50'S CHRISTMAS GIFT BAG LARGE DOLLY GIRL BEAKER I LOVE LONDON MINI BACKPACK RED SPOT GIFT BAG LARGE SET 2 TEA TOWELS I LOVE LONDON
# Invoice
# 536527 NaN NaN NaN NaN NaN
# 536840 NaN NaN NaN NaN NaN
# 536861 NaN NaN NaN NaN NaN
# 536967 NaN NaN NaN NaN NaN
# 536983 NaN NaN NaN NaN NaN

进行独热编码。 把 NA 的地方写 0。

df_gr.groupby(['Invoice', 'Description']).agg({"Quantity": "sum"}).unstack().fillna(0).iloc[0:5, 0:5]
# Description 50'S CHRISTMAS GIFT BAG LARGE DOLLY GIRL BEAKER I LOVE LONDON MINI BACKPACK RED SPOT GIFT BAG LARGE SET 2 TEA TOWELS I LOVE LONDON
# Invoice
# 536527 0.0 0.0 0.0 0.0 0.0
# 536840 0.0 0.0 0.0 0.0 0.0
# 536861 0.0 0.0 0.0 0.0 0.0
# 536967 0.0 0.0 0.0 0.0 0.0
# 536983 0.0 0.0 0.0 0.0 0.0

如果发票中的产品数量大于0,我们就写1,如果小于0或0,我们就写0。用apply对行或列进行操作。 这里将通过应用 applymap 并执行操作来遍历所有单元格。

df_gr.groupby(['Invoice', 'Description']).agg({"Quantity": "sum"}).unstack().fillna(0).applymap(lambda x: 1 if x > 0 else 0).iloc[0:5, 0:5]
# Description 50'S CHRISTMAS GIFT BAG LARGE DOLLY GIRL BEAKER I LOVE LONDON MINI BACKPACK RED SPOT GIFT BAG LARGE SET 2 TEA TOWELS I LOVE LONDON
# Invoice
# 536527 0 0 0 0 0
# 536840 0 0 0 0 0
# 536861 0 0 0 0 0
# 536967 0 0 0 0 0
# 536983 0 0 0 0 0

我们创建了一个名为 create_invoice_df 的函数。 如果想根据id变量搜索并得到结果,它会根据stockcode进行与上述相同的操作。 如果我们输入的id为False,它会根据Description执行上面的操作。

def create_invoice_product_df(dataframe, id=False):
if id:
return dataframe.groupby(['Invoice', "StockCode"])['Quantity'].sum().unstack().fillna(0). \
applymap(lambda x: 1 if x > 0 else 0)
else:
return dataframe.groupby(['Invoice', 'Description'])['Quantity'].sum().unstack().fillna(0). \
applymap(lambda x: 1 if x > 0 else 0)
gr_inv_pro_df = create_invoice_product_df(df_gr)
gr_inv_pro_df.head(20)
gr_inv_pro_df = create_invoice_product_df(df_gr, id=True)
gr_inv_pro_df.head()
def check_id(dataframe, stock_code):
product_name = dataframe[dataframe["StockCode"] == stock_code][["Description"]].values[0].tolist()
print(product_name)
check_id(df_gr, 16016)
# ['LARGE CHINESE STYLE SCISSOR']

所有可能的产品组合

frequent_itemsets = apriori(gr_inv_pro_df, min_support=0.01, use_colnames=True)
frequent_itemsets.sort_values("support", ascending=False).head()
# support itemsets
# 538 0.818381 (POST)
# 189 0.245077 (22326)
# 1864 0.225383 (POST, 22326)
# 191 0.157549 (22328)
# 1931 0.150985 (22328, POST)
check_id(df_gr, 22328)
#['ROUND SNACK BOXES SET OF 4 FRUITS ']

通过将我们用 Apriori 找到的Support插入到 association_rules 函数中,找到一些其他的统计数据,例如置信度和提升度。

rules = association_rules(frequent_itemsets, metric="support", min_threshold=0.01)
rules.sort_values("support", ascending=False).head()

POST产品和编号为22326的产品同时出现的概率为0.225383。 被一起买的概率是0.275401。 同时购买这两种产品的概率增加为1.123735。

# antecedents consequents antecedent support consequent support support confidence lift leverage conviction
# 2650 (POST) (22326) 0.818381 0.245077 0.225383 0.275401 1.123735 0.024817 1.041850
# 2651 (22326) (POST) 0.245077 0.818381 0.225383 0.919643 1.123735 0.024817 2.260151
# 2784 (22328) (POST) 0.157549 0.818381 0.150985 0.958333 1.171012 0.022049 4.358862
# 2785 (POST) (22328) 0.818381 0.157549 0.150985 0.184492 1.171012 0.022049 1.033038
# 2414 (22328) (22326) 0.157549 0.245077 0.131291 0.833333 3.400298 0.092679 4.529540

作者:Cem Bıkmaz

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
您有洗屁股的习惯吗?提醒:天天洗肛门的人,能收获4个惊人好处

您有洗屁股的习惯吗?提醒:天天洗肛门的人,能收获4个惊人好处

39健康网
2025-12-13 20:50:34
商业航天+AI应用,深度布局的五家公司!

商业航天+AI应用,深度布局的五家公司!

Thurman在昆明
2026-01-13 01:37:08
86年我放走一个越南女兵,33年后我刚出越南机场就被一排军车接走

86年我放走一个越南女兵,33年后我刚出越南机场就被一排军车接走

萧竹轻语
2025-12-05 17:38:25
2025年,内娱最赚钱的10位明星,刘德华第四,第一名让人意外

2025年,内娱最赚钱的10位明星,刘德华第四,第一名让人意外

林雁飞
2026-01-06 13:15:06
曝35岁徐冬冬已怀孕!50岁尹子维紧张护肚,两人将在2月举办婚礼

曝35岁徐冬冬已怀孕!50岁尹子维紧张护肚,两人将在2月举办婚礼

叶公子
2026-01-13 17:31:57
七旬老人做微创手术时心脏破裂转开胸,术后第三天死亡 “医疗器械临床试验”引发官司

七旬老人做微创手术时心脏破裂转开胸,术后第三天死亡 “医疗器械临床试验”引发官司

红星新闻
2026-01-14 15:26:48
16岁角色穿“情趣内衣”?网易武侠游戏陷擦边争议

16岁角色穿“情趣内衣”?网易武侠游戏陷擦边争议

南方都市报
2026-01-13 14:46:12
为什么女朋友觉得年入百万很简单?网友:她一定有个做足浴的闺蜜

为什么女朋友觉得年入百万很简单?网友:她一定有个做足浴的闺蜜

带你感受人间冷暖
2025-11-04 16:38:29
太离谱,闲鱼惊现 iPhone 18 Pro 工程机

太离谱,闲鱼惊现 iPhone 18 Pro 工程机

花果科技
2026-01-12 12:46:04
看懂史上真实的慈安,才明白慈禧为何绞尽脑汁,一辈子都斗不过她

看懂史上真实的慈安,才明白慈禧为何绞尽脑汁,一辈子都斗不过她

近史谈
2026-01-06 16:28:59
央企“最牛女副处长”落马:两年与上司开房410次,细节曝光

央企“最牛女副处长”落马:两年与上司开房410次,细节曝光

西门老爹
2025-12-16 15:35:31
NBA裁判服了!主动给杨瀚森大拇指,244斤小杨撞头抢球感动太多人

NBA裁判服了!主动给杨瀚森大拇指,244斤小杨撞头抢球感动太多人

嘴炮体坛
2026-01-14 23:00:06
日本自卫队支持率飙至93.7% 创60年代以来历史峰值

日本自卫队支持率飙至93.7% 创60年代以来历史峰值

老马拉车莫少装
2026-01-12 19:17:59
瓦良格号送到中国后有多震撼?专家刮掉表面的锈迹:钢材品质极佳

瓦良格号送到中国后有多震撼?专家刮掉表面的锈迹:钢材品质极佳

古书记史
2026-01-06 16:31:56
王思聪向懒懒高调示爱,超大花束豪宅背景超吸睛,要结婚啦?

王思聪向懒懒高调示爱,超大花束豪宅背景超吸睛,要结婚啦?

草莓解说体育
2026-01-13 11:34:38
破案了!终于搞明白,李亚鹏的嫣然天使儿童医院为什么开不下去了

破案了!终于搞明白,李亚鹏的嫣然天使儿童医院为什么开不下去了

乐悠悠娱乐
2026-01-14 10:42:33
美股异动丨百度盘前拉升涨超2%,据报考虑将香港上市地位提升为主要上市

美股异动丨百度盘前拉升涨超2%,据报考虑将香港上市地位提升为主要上市

格隆汇APP
2026-01-14 17:42:14
看不懂!北京国安续约“玄冥二老”,球迷:不是要培养年轻球员吗

看不懂!北京国安续约“玄冥二老”,球迷:不是要培养年轻球员吗

足球大腕
2026-01-14 12:35:24
1975年,基辛格给毛主席下了一道命令,主席写了张纸条回击,尼克松看后直摇头:这气魄谁能比?

1975年,基辛格给毛主席下了一道命令,主席写了张纸条回击,尼克松看后直摇头:这气魄谁能比?

老杉说历史
2026-01-12 22:07:15
没了热度,没了爱情,没了兄弟的李晨,在《跑男》里慢慢被边缘化

没了热度,没了爱情,没了兄弟的李晨,在《跑男》里慢慢被边缘化

山谷里的怒吼
2026-01-13 19:54:07
2026-01-15 01:32:49
deephub incentive-icons
deephub
CV NLP和数据挖掘知识
1890文章数 1443关注度
往期回顾 全部

科技要闻

携程因涉嫌垄断被市场监管总局调查

头条要闻

媒体:公开鼓动抗议者 特朗普新表态让全球嗅到火药味

头条要闻

媒体:公开鼓动抗议者 特朗普新表态让全球嗅到火药味

体育要闻

你是个好球员,我们就拿你交易吧

娱乐要闻

网红彭十六偷税被封杀 曾成功转型明星

财经要闻

携程被立案调查,最高或被罚超50亿

汽车要闻

曝Model Y或降到20万以内!

态度原创

手机
时尚
旅游
公开课
军事航空

手机要闻

REDMI Turbo 5 MAX现身跑分,天玑9500s芯片加持

最时髦的单品,难道不是背肌吗?

旅游要闻

俄旅游业:美禁发签证“不会造成灾难”

公开课

李玫瑾:为什么性格比能力更重要?

军事要闻

中东气氛愈发紧张 伊朗处于最高战备状态

无障碍浏览 进入关怀版