الگوریتم آپریوری (apriori) چیست؟ به همراه پیاده سازی با پایتون

اول اجازه بدید نگاهی به تعریف ارائه شده در ویکیپدیا بندازیم:

یک الگوریتم برای استخراج مکرر مجموعه‌های مورد و یادگیری قوانین مرتبط با پایگاه‌های داده رابطه‌ای است. با شناسایی موارد فردی مکرر در پایگاه داده و گسترش آنها به مجموعه اقلام بزرگتر و بزرگتر تا زمانی که آن مجموعه موارد به طور کافی در پایگاه داده ظاهر شود، ادامه می‌یابد. مجموعه‌های مکرر موارد تعیین شده توسط ایپرایوری می‌تواند برای تعیین قوانین ارتباطی که روندهای کلی در پایگاه داده را برجسته می‌کند، مورد استفاده قرار گیرد: این الگوریتم در حوزه‌هایی مانند تجزیه و تحلیل سبد بازار کاربرد دارد.

در واقع طبق تعریف فوق الگوریم سعی می کنه موارد پر تکرار رو در سبد خرید مشتریان شناسایی و براساس روابط اونها، بتونه به مشتری پیشنهاد بده که اگر مثلا فلان محصول رو برداشت، چه محصول دیگه ای رو می تونه برداره.

تو این پست ابتدا یکی از روش های پیاده سازی این الگوریتم در پایتون رو با هم بررسی می کنیم. در ادامه درباره مزایا و معایب این الگوریتم هم صحبت می کنیم.

خب بریم سراغ پیاده سازی:

من از دیتای یکی از سوالات سایت کوئرا استفاده کردم. در این دیتا فرض شده که مجموعه خریدهای یک مشتری در هر روز یک سبد خرید هست. بنابراین من مشتری و تاریخ رو در یک ستون جدید تحت عنوان sabad به Dataframe اضافه کردم:

import pandas as pd
import numpy as np
from mlxtend.frequent_patterns import apriori, association_rules
data = pd.read_csv('supermarket.csv')
data['Sabad']=data['Customer Id']+data['Date']

حالا به یک ستون عددی نیاز داریم تا تعداد هر کالا در هر سبد رو نشون بده. از اونجایی که الگوریم آپریوری برای محاسبه ابتدا دیتا رو ترانسپوز می کنه (یعنی محصولات رو به عنوان ستون در نظر می گیره) برای جدولش نیاز به مقدار عددی داره.

data2 = data.groupby(['Sabad','Product']).size()
data2 = pd.DataFrame(data2).reset_index()
data2.columns = ['Sabad','Product','Count']

خب حالا می تونیم جدول ترانسپوزه رو ایجاد کنیم

Tdata = (data2.groupby(['Sabad', 'Product'])['Count'].sum().unstack().reset_index().fillna(0).set_index('Sabad'))

نتیجه شبیه عکس زیر میشه:

برای مرحله بعد نیازه دیتای شما one hot encode بشه. One hot encode به معنی تبدیل اون بخش از اطلاعات به اعدادی بین 0 و 1 هستش. در این مورد خاص الگوریم می خواد بودن یا نبودن کالا رو متوجه بشه و کاری به ارزش نداره. بنابراین یک تابع تعریف می کنه فقط مقادیر 0 و 1 رو در جدول بالا جایگزین کنه

def hot_encode(x):
     if(x<= 0):
          return 0
     if(x>= 1):
          return 1
Tdata_encoded = Tdata.applymap(hot_encode)

خب حالا فقط مونده پیاده سازی الگوریتم:

frq_items = apriori(Tdata_encoded, min_support = 0.01, use_colnames = True).sort_values('support', ascending = False)

این دو خط به شما مقدار support هر محصول رو میده. یه جورایی میشه محصولی که بیشترین حضور رو در سبدهای خرید داشته، یا همون پرطرفدارترین ها.

در خط بالا مقدار min_support به شما اجازه میده که حداقل مقدار اهمیت محصول رو مشخص کنید.

حالا روی این لیست دستورات زیر رو اجرامی کنیم تا به ما بگه که کدام محصول رو می تونیم با کدوم محصول یا گروه محصول ها پیشنهاد بدیم:

rules = association_rules(frq_items, metric =&quotlift&quot, min_threshold = 0.001)
rules = rules.sort_values(['confidence'], ascending =[False])
print(rules)

خروجی های اصلی کد بالا به شرح زیر هستن:

confidence:

به معنی میزان ارتباط بین سبد معرفی شده و کالای پیشنهادی که هر چه به یک نزدیک تر باشد، نشان دهنده رابطه قوی تری است. اما این عدد فقط در رابطه یک طرفه صدق می کند و برای رابطه برعکس معنی دار نیست.

leverage:

تفاوت فرکانس سبد و کالای پیشنهادی زمانی که کالای اصلی و پیشنهادی با هم باشند، نسبت به زمانی که مستق باشند.

min_threshold:

تابع به شما امکان می دهد متریک مورد علاقه و آستانه مطابق با آن را مشخص کنید. اینجا ما از متریک lift استفاده کردیم.

lift:

برای نشان تعداد دفعات یک ارتباط به کار می رود.

پینوشت:

برای مطالعه بیشتر روی کتابخانه mlxtend.frequent_patterns به این لینک مراجعه کنید.

کد بالا در گیت هاب من منتشر شده .