關聯規則的經典算法有哪些?關聯規則是以規則的方式呈現項目之間的相關性:關聯規則(Association Rules)是反映一個事物與其他事物之間的相互依存性和關聯性,是數據挖掘的一個重要技術,用于從大量數據中挖掘出有價值的數據項之間的相關關系,下面我們就來說一說關于關聯規則的經典算法有哪些?我們一起去了解并探讨一下這個問題吧!
關聯規則是以規則的方式呈現項目之間的相關性:關聯規則(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
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!