Python ile Birliktelik Kuralları Analizi (Association Rules Analysis with Python)
Merhabalar,
Bu gün sizlerde birlikte Python üzerinde Birliktelik Kuralları Analizi çalışmasını gerçekleştireceğiz. Çok daha evvel olması yazılması planlanan bu yazı için lütfen kusuruma bakmayınız. ☹ Birliktelik Kuralları Analizi (Association Rules Analysis) hakkındaki daha önceki yazılara aşağıdaki linklerden ulaşabilirsiniz.
- Birliktelik Kuralları Analizi (Association Rules Analysis) https://www.veribilimiokulu.com/associationrulesanalysis/
- R ile Birliktelik Kuralları Analizi (Association Rules Analysis with R Project) https://www.veribilimiokulu.com/association-rules-analysis-with-r/
- IBM SPSS Modeler ile Birliktelik Kuralları Analizi (Association Rules Analysis with IBM SPSS Modeler) https://www.veribilimiokulu.com/association-rules-analysis-with-ibm-spss-modeler/
Şimdi sıra Python’da 😊
Python üzerinde Birliktelik Kuralları Analizi için kullanacağım kütüphaneler başlıca kütüphaneler: mlxtend, pandas ve numpy
MLXTEND (Machine Learning Extensions)
MLXTEND modülü içerisinde; classifier, cluster, regressor, evaluate, feature extraction&selection, frequent_patterns, general concepts, image, preprocessing, , math, plotting vb. extension’lar yer almaktadır. Şuanki mevcut sürümü BSD lisansı altında 0.13.0’tür. Kendisi hakkında daha fazla bilgi elde etmek isterseniz resmi web sayfasını inceleyebilir ve yazarı Sebastian Raschka hakkında buradan bilgi edinebilirsiniz.
Numpy ve Pandas
Numpy ve Pandas paketleri ise, Matris İşlemleri ve Input&Output işlemleri için kullanmaktayım.
Not: Kullanmış olduğum; Python versiyonu 3.6.8 ve IDE(Integrated Development Environment) olarak Jupyter Notebook kullanmaktayım. Github repo’sunda .ipynb ve.py dosyasını paylaşacağım.
Gerekli Modüllerin Kurulması
Bu projeye ait Github reposu içerisinde requirements.txt dosyası yer alacaktır. Bu dosyayı ilgili dizinde iken komut istemi kısmında
pip install -r requirements.txt
ya da
conda install --file requirements.txt
olarak çalıştırmanız ve kurulumları yapmanız gerekmektedir. Ya da modülleri manuel olarak aşağıdaki gibi kurabilirsiniz.
pip install mlxtend pip install pandas pip install numpy
ya da Conda Package Manager ile
conda install mlxtend --channel conda-forge conda install pandas conda install numpy
Conda Forge mlxtend github reposu: https://github.com/conda-forge/mlxtend-feedstock
Modülleri Import Edelim
#Importing Modules import pandas as pd import numpy as np from mlxtend.preprocessing import TransactionEncoder from mlxtend.frequent_patterns import apriori from mlxtend.frequent_patterns import association_rules import mlxtend as ml #print(ml.__version__)
Veri Seti Oluşturma
Bu uygulama da daha öncekilerden farklı olarak veri setini kendimiz oluşturacağız. Hazır bir veri setinden ziyade kendimizin yazacağı ufak kodlar ile veri setini oluşturacağız. Burada oluşturacağımız veri seti gerçek dünya verisi olmadığı için birliktelik kuralları analizinde farklı çıktılar ile karşılaşmamız yüksek ile muhtemel 🙂
Veri setini oluştururken bazı kurallarımız olacak. Adımlar:
- Ürün listesinin belirlenmesi: 16 Adet (‘Apple’,’Corn’,’Dill’,’Eggs’, ‘Ice cream’,’Kidney Beans’,’Milk’,’Nutmeg’, ‘Onion’,’Unicorn’,’Yogurt’, ‘Bread’, ‘Cheese’, ‘Butter’, ‘Sugar’,’Chocolate’)
- Veri setinin içerisindeki gözlem sayısının belirlenmesi: 1000 Adet
dataset = [] import random items = ['Apple','Corn','Dill','Eggs', 'Ice cream','Kidney Beans','Milk','Nutmeg', 'Onion','Unicorn','Yogurt', 'Bread', 'Cheese', 'Butter', 'Sugar','chocolate'] for i in range(1, 1000): k = random.randrange(1, len(items)+1) #print('K Values:', k) dataset.append(random.choices(items, k=k)) #print(random.sample(items, k=k)) #liste.append(random.sample(items, k=k)) #print(random.sample(items, k=k)) #random.sample #dataset.append(random.sample(items, k=k)) #print(random.sample(items, k=k))
Ben 16 adet ürün belirleyerek bunları bir listeye yazdım. Devamında 1 ile bu ürünlerin sayısı olan 16 arasında rasgele bir üreterek random.choices fonksiyonu ile itemset listesi içerisinden ürünlerin seçilmesi sağlıyoruz. Bu veri seti içerisinde 1000 adet gözlem olması istediğim için de for döngüsü ile 2. adımı tekrarlıyoruz. Devamında veri setimiz oluşuyor.
Veri Seti Output: ./output/dataset.csv
df.to_csv('./output/dataset.csv', index=False)
Veri setinin boyutu: 1000 (0 – 999)
print(len(dataset))
999
İlk 5 Satırı Görelim:
print(dataset[1:5])
[['Onion', 'Cheese', 'Nutmeg', 'Corn', 'Sugar'], ['Corn', 'Unicorn', 'Chocolate', 'Apple', 'Apple', 'Corn'], ['Butter', 'Cheese', 'Bread', 'Sugar', 'Milk', 'Apple', 'Butter', 'Dill', 'Bread', 'Apple', 'Yogurt', 'Dill', 'Nutmeg', 'Kidney Beans'], ['Chocolate', 'Onion']]
Son 5 Satırı Görelim:
print(dataset[995:(len(dataset)+1)])
[['Apple', 'Unicorn', 'Kidney Beans', 'Cheese', 'Corn', 'Butter'], ['Onion'], ['Milk', 'Unicorn'], ['Butter', 'Yogurt'], ['Butter', 'Dill', 'Ice cream', 'Bread', 'Dill', 'Dill', 'Dill', 'Butter', 'Onion', 'Onion', 'Chocolate', 'Bread', 'Cheese', 'Bread', 'Ice cream', 'Bread']]
random.choices kullandığımız gibi random.sample fonksiyonunu da kullanabiliriz. Random.sample kullanmanız aynı satır içerisindeki ürünlerin benzersizliği sağlayacaktır. Yukarıda yorum satırı olarak bıraktığım (#random.sample) satırı çalıştırarak görebilirsiniz.
Veri setini oluşturduktan sonra nested list (iç içe liste) tipindeki verilerimizi tabular bir yapıya çevirmemiz gerekiyor. Bunun için mlxtend modülü içerisinde yer alan preprocessing sınıfı içerisinde TransactionEncoder fonksiyonunu kullanacağız.
Not: from mlxtend.preprocessing import TransactionEncoder
te = TransactionEncoder() te_ary = te.fit(dataset).transform(dataset) df = pd.DataFrame(te_ary, columns=te.columns_)
Not: TransactionEncoder hakkında daha fazla bilgi için: http://rasbt.github.io/mlxtend/user_guide/preprocessing/TransactionEncoder/
Şimdi de tabular formattaki verisetimizi görelim:
df.head()
Model Oluşturma
Veri setimizi birliktelik kuralları analizi için uygun hale getirdikten sonra artık Apriori algoritmasını kullanabiliriz. mlxtend modülü içerisinde yer alan apriori() fonksiyonu yukarıda import etmiştik.
Not: from mlxtend.frequent_patterns import apriori
min_support değerini 0.1 yani %10 vererek apriori algoritması için başlangıç değerlerini set ediyoruz.
apriori(df, min_support=0.15).[1:26]
print("Kural Sayısı:", len(apriori(df, min_support=0.15)))
apriori(df, min_support=0.15, use_colnames=True)[1:26]
frequent_itemsets = apriori(df, min_support=0.15, use_colnames=True) # frequent_itemsets # association_rules(frequent_itemsets, metric="confidence", min_threshold=0.30) rules1 = association_rules(frequent_itemsets, metric="confidence", min_threshold=0.30)
Not: from mlxtend.frequent_patterns import association_rules
print("Oluşan Kural Sayısı:", len(rules1))
rules1 = rules1.sort_values(['confidence'], ascending=False) rules1[1:11]
- Bread ve Ice Cream item’larının birlikte görülme olasılığı (support) %18 (0.18) olduğunu,
- Bread item’ının satın alan kişilerin (confidence) %48’inin (0.489130) olasılıkla Ice Cream item’ınıda satın aldığını,
- Bread item’ının yer aldığı alışveriş sepetlerin de Ice Cream item’ının satışı (lift) 1,224 kat arttığı,
- Bread ve Ice Cream item’larının birlikte satın alınmalarının ile birbirlerinden bağımsız olarak satın alınmalarından ne kadar fazla (leverage) 0.03 olduğunu,
- Bread ve Ice Cream item’larının birbirleri ile ilişkili (conviction) 1.17 değeri ile olduğunu söyleyebiliriz.
Daha önceki yazılarımızda tablo’da görülenler diğer değerlerin açıklamalarını ve hesaplamalarının nasıl yapıldığının üzerinden geçmiştik. Bu yüzden genel olarak önem atfedilen support, condifence, lift, leverage ve conviction metrikleri üzerinden yorumlar da bulundum. Diğer kısımlar için lütfen eski sayılara bakınız 🙂
Metrikler hakkında daha fazlasını görmek isterseniz Michael Hahsler sayfasına buradan ulaşabilirsiniz. Bu bağlantıya Dr. Tuğrul Taşçı bey’in ISE 302 sunumundan ulaştığımı belirtmek isterim.
rules1["antecedent_len"] = rules1["antecedents"].apply(lambda x: len(x)) rules1["consequents_len"] = rules1["consequents"].apply(lambda x: len(x)) rules1[1:6]
rules2 = association_rules(frequent_itemsets, metric="lift", min_threshold=1) rules2 = rules2.sort_values(['lift'], ascending=False) rules2[1:6]
rules2["antecedent_len"] = rules2["antecedents"].apply(lambda x: len(x)) rules2["consequents_len"] = rules2["consequents"].apply(lambda x: len(x)) rules2[1:6]
rules1[(rules1['antecedent_len'] >= 1) & (rules1['confidence'] >= 0.20) & (rules1['lift'] > 1) ].sort_values(['confidence'], ascending=False)[1:10]
rules1[rules1['antecedents'] == {'Bread'}].sort_values(['confidence'], ascending=False)[1:10]
rules1.to_json('./output/rules1.json') rules2.to_json('./output/rules2.json')
Not: PMML (Predictive Model Markup Language) gereksinimi doğrultusunda .xml olarak export edilmesi gerekmektedir.
Python üzerinden geçte olsa Birliktelik Kuralları Analizini gerçekleştirmiş bulunmaktayız. Malesef oluşan kurallar üzerinden görselleştirme yapamadık. Bu konuda mlxtend paketinin eksiklikleri olduğunu belirtebilirim. Burada başka bir şey kullanmalıyız. Bunu kendime görev addediyorum. Bulduğumda gerekli güncellemeleri geçeceğim.
Son olarak; Github üzerinde yer alan repository’e buradan (kod, input, output ve diğer dosyalara) ulaşabilirsiniz. Yazıyı beğenerek ve paylaşarak daha fazla kişiye ulaşmasına yardımcı olabilirsiniz. Görüş ve önerileriniz için uslumetin@gmail.com’dan bana ulaşabilirsiniz. Yeniden görüşmek üzere, Selamlar 🙂
Bağlantılı diğer yazılarım:
- Birliktelik Kuralları Analizi (Association Rules Analysis)
- R ile Birliktelik Kuralları Analizi (Association Rules Analysis with R Project)
- IBM SPSS Modeler ile Birliktelik Kuralları Analizi (Association Rules Analysis with IBM SPSS Modeler)