← Back to list

Sepetten Öneriye: Python ile Association Rule Learning

Python ile Association Rule Learning: Armut Verisi Üzerinden Hizmet Tavsiye Sistemi

Burcu İlayda Şentürk · 2026-07-12 18:23 · 106 claps · 9.6 min read
#python #data-science #machine-learning #recommendation-system #apriori-algorithm
Open on Medium ↗
Wiki topics: ML · Machine Learning EDU · Education & Learning 💻 · Programming 🔒 · Cybersecurity 🔬 · Science · General

Sepetten Öneriye: Python ile Association Rule Learning

Python ile Association Rule Learning: Armut Verisi Üzerinden Hizmet Tavsiye Sistemi

Bir kullanıcı temizlik hizmeti aldıktan sonra hangi hizmete ihtiyaç duyabilir? Nakliyat hizmeti alan müşterilere hangi hizmetler önerilebilir? Bir hizmeti satın alan kullanıcıların başka hangi hizmetleri birlikte tercih ettiğini veriden öğrenebilir miyiz?

Bu soruların cevabı Association Rule Learning, yani Birliktelik Kuralı Öğrenmesi ile bulunabilir.

Bu çalışmada, Armut hizmet platformuna ait kullanıcı ve hizmet verilerini kullanarak Python ile basit bir hizmet tavsiye sistemi geliştireceğiz.

Çalışmanın temel adımları:

  • Veriyi tavsiye sistemi için hazırlamak
  • Hizmetleri benzersiz şekilde tanımlamak
  • Kullanıcıların aylık hizmet alışverişlerinden sepetler oluşturmak
  • Apriori algoritması ile sık kullanılan hizmet kombinasyonlarını bulmak
  • Association Rules ile hizmetler arasındaki ilişkileri ortaya çıkarmak
  • Support, Confidence ve Lift metriklerini yorumlamak
  • Kullanıcının aldığı son hizmete göre yeni hizmetler önermek

1. İş Problemi

Armut, hizmet almak isteyen kullanıcılarla hizmet verenleri bir araya getiren çevrim içi bir hizmet platformudur.

Kullanıcılar platform üzerinden temizlik, tadilat, nakliyat ve benzeri birçok farklı hizmete ulaşabilir.

Elimizde kullanıcıların daha önce satın aldığı hizmetler varsa şu soruyu sorabiliriz:

Bir hizmeti alan kullanıcılar başka hangi hizmetleri alma eğilimindedir?

Örneğin veriler bize şunu gösterebilir:

“A hizmetini alan kullanıcılar, B hizmetini de normalden çok daha sık satın alıyor.”

Böyle bir bilgi;

  • kişiselleştirilmiş hizmet önerilerinde,
  • çapraz satış çalışmalarında,
  • kampanya tasarımlarında,
  • müşteri deneyiminin geliştirilmesinde kullanılabilir.

Bu problemi çözmek için Association Rule Learning yaklaşımından yararlanacağız.

2. Veri Setini Tanıyalım

Veri setimizde kullanıcıların satın aldığı hizmetler ve bu hizmetlerin kategorileri bulunuyor.

Temel değişkenler:

UserId

Hizmeti satın alan müşterinin benzersiz kullanıcı numarasıdır.

ServiceId

Kullanıcının aldığı hizmeti temsil eder.

Ancak burada önemli bir detay vardır:

Aynı ServiceId, farklı kategoriler altında farklı hizmetleri ifade edebilir.

Örneğin:

ServiceId = 4
CategoryId = 7

bir hizmeti temsil ederken;

ServiceId = 4
CategoryId = 2

tamamen farklı bir hizmet olabilir.

Bu nedenle yalnızca ServiceId kullanmak yeterli değildir.

CategoryId

Hizmetin ait olduğu kategoriyi temsil eder.

CreateDate

Hizmetin satın alındığı tarih ve saat bilgisidir.

3. Gerekli Kütüphanelerin Yüklenmesi

Çalışmada iki temel kütüphane kullanıyoruz:

import pandas as pd
from mlxtend.frequent_patterns import apriori
from mlxtend.frequent_patterns import association_rules

Burada:

  • pandas, veri okuma ve veri manipülasyonu için,
  • apriori, sık görülen hizmet kombinasyonlarını bulmak için,
  • association_rules, hizmetler arasındaki birliktelik kurallarını oluşturmak için kullanılmaktadır.

4. Veri Setinin Okunması

İlk olarak CSV dosyamızı pandas ile okuyalım.

df = pd.read_csv("armut_data.csv")

Verinin ilk satırlarını incelemek için:

df.head()

kullanabiliriz.

Pandas çıktılarının daha rahat görüntülenmesi için bazı görüntüleme ayarlarını da değiştirebiliriz:

pd.set_option("display.max_columns", None)
pd.set_option("display.width", 500)
pd.set_option("display.expand_frame_repr", False)

Bu ayarlar analiz sonucunu değiştirmez.

Yalnızca DataFrame çıktılarının daha okunabilir görünmesini sağlar.

5. ServiceId ve CategoryId Neden Birleştiriliyor?

Veri setimizde aynı ServiceId, farklı kategoriler altında farklı hizmetleri temsil edebilmektedir.

Bu nedenle hizmetleri benzersiz şekilde tanımlamak için:

df["Service_Category"] = (
    df["ServiceId"].astype(str)
    + "_"
    + df["CategoryId"].astype(str)
)

kodunu kullanıyoruz.

Örneğin:

ServiceId = 4
CategoryId = 7

şu hale gelir:

4_7

Başka bir kategorideki aynı servis:

ServiceId = 4
CategoryId = 2

ise:

4_2

olarak temsil edilir.

Sonucu kontrol etmek için:

print(
    df[
        ["ServiceId", "CategoryId", "Service_Category"]
    ].head()
)

kullanabiliriz.

Buradaki kritik nokta şudur:

Tavsiye sistemi yalnızca ServiceId değerine bakarsa farklı kategorilerdeki farklı hizmetleri aynı hizmet zannedebilir.

Bu nedenle ServiceId ve CategoryId birlikte kullanılmaktadır.

6. Association Rule Learning İçin “Sepet” Oluşturmak

Market sepeti analizlerinde genellikle doğal bir sepet tanımı vardır.

Örneğin:

Fatura No: 1001
-----------------
Ekmek
Süt
Yumurta

Bu üç ürün aynı faturada bulunduğu için aynı sepete aittir.

Ancak Armut veri setinde doğrudan bir:

InvoiceId

veya:

BasketId

değişkeni bulunmamaktadır.

Bu nedenle kendimiz bir sepet tanımlamamız gerekir.

Bu çalışmada şu yaklaşımı kullanıyoruz:

Bir kullanıcının aynı ay içerisinde aldığı tüm hizmetler bir sepet olarak kabul edilir.

Örneğin:

UserId = 7256
Tarih = 2017-08

kullanıcının Ağustos 2017 içerisinde aldığı tüm hizmetleri bir sepet olarak kabul ederiz.

Aynı kullanıcının:

2017-10

ayındaki hizmetleri ise başka bir sepet oluşturur.

7. Tarih Değişkenini Düzenlemek

İlk olarak CreateDate değişkenini tarih formatına dönüştürüyoruz.

df["CreateDate"] = pd.to_datetime(
    df["CreateDate"]
)

Bu işlem önemlidir çünkü pandas’ın tarih fonksiyonlarını kullanabilmesi için değişkenin gerçek bir datetime formatında olması gerekir.

Ardından yalnızca yıl ve ay bilgisini alıyoruz:

df["Date"] = (
    df["CreateDate"]
    .dt
    .strftime("%Y-%m")
)

Örneğin:

2017-08-06 14:30:00

şu hale gelir:

2017-08

8. Benzersiz Sepet ID Oluşturmak

Şimdi kullanıcının kimliği ile alışveriş yaptığı ayı birleştiriyoruz.

df["ID"] = (
    df["UserId"].astype(str)
    + "_"
    + df["Date"]
)

Örneğin:

UserId = 7256
Date = 2017-08

sonucunda:

7256_2017-08

şeklinde bir sepet ID oluşturulur.

Başka bir ay:

7256_2017-10

ise başka bir sepet olarak değerlendirilir.

Böylece elimizde artık Association Rule Learning algoritmasının kullanabileceği bir sepet tanımı vardır.

9. Sepet-Hizmet Matrisinin Oluşturulması

Apriori algoritmasının çalışabilmesi için veriyi özel bir formata dönüştürmemiz gerekir.

İstediğimiz yapı şöyledir:

Burada:

1

hizmetin o sepette bulunduğunu;

0

ise bulunmadığını ifade eder.

Bu yapıyı şu kodla oluşturuyoruz:

invoice_service_df = (
    df.groupby(
        ["ID", "Service_Category"]
    )["Service_Category"]
    .count()
    .unstack()
    .fillna(0)
)

Bu kodu parçalara ayıralım.

groupby()

df.groupby(
    ["ID", "Service_Category"]
)

verileri:

  • sepet ID
  • hizmet

kombinasyonuna göre gruplar.

count()

["Service_Category"].count()

bir hizmetin ilgili sepette kaç kez bulunduğunu sayar.

unstack()

.unstack()

hizmetleri sütunlara dönüştürür.

Yani veri uzun formattan geniş formata geçer.

fillna(0)

.fillna(0)

bir sepette bulunmayan hizmetler NaN değerine sahip olur.

Bu değerleri sıfıra dönüştürürüz.

10. Veriyi True / False Formatına Dönüştürmek

Apriori algoritması için bizim asıl ilgilendiğimiz şey bir hizmetin kaç kez satın alındığı değil, sepette bulunup bulunmadığıdır.

Bu nedenle:

invoice_service_df = (
    invoice_service_df > 0
)

kodunu kullanıyoruz.

Artık:

True

hizmetin sepette bulunduğunu;

False

ise bulunmadığını gösterir.

Örneğin:

Bu yapı Apriori algoritmasının kullanabileceği formattır.

11. Apriori Algoritması Nedir?

Apriori algoritması veri içerisinde sık birlikte görülen öğeleri bulmaya çalışır.

Bu çalışmada öğelerimiz fiziksel ürünler değil, hizmetlerdir.

Örneğin algoritma şunu araştırır:

2_0 ve 22_0

hizmetleri kaç farklı sepette birlikte bulunuyor?

Ya da:

9_4 ve 38_4

hizmetleri birlikte satın alınma eğiliminde mi?

Sık görülen hizmet kombinasyonlarını bulmak için:

frequent_itemsets = apriori(
    invoice_service_df,
    min_support=0.01,
    use_colnames=True
)

kullanıyoruz.

min_support = 0.01 Ne Anlama Geliyor?

Bu değer:

%1

minimum support sınırını ifade eder.

Yani bir hizmet veya hizmet kombinasyonu tüm sepetlerin en az %1'inde bulunuyorsa sonuçlara dahil edilir.

Çok düşük bir değer kullanırsak çok fazla ve anlamsız kombinasyon elde edebiliriz.

Çok yüksek bir değer kullanırsak daha nadir fakat anlamlı ilişkileri kaçırabiliriz.

use_colnames = True

Bu parametre sayesinde sonuçlarda sütun numaraları yerine gerçek hizmet isimleri gösterilir.

Yani:

17

yerine:

2_0

gibi gerçek hizmet kodlarını görürüz.

12. Birliktelik Kurallarını Oluşturmak

Apriori bize sık kullanılan hizmet kombinasyonlarını verir.

Ancak bizim asıl istediğimiz şudur:

Bir kullanıcı A hizmetini aldıysa hangi B hizmetini önermeliyiz?

Bunun için birliktelik kuralları oluşturuyoruz.

rules = association_rules(
    frequent_itemsets,
    metric="support",
    min_threshold=0.01
)

Bu işlem sonucunda şöyle kurallar elde edebiliriz:

25_0 → 22_0

Burada:

25_0

kuralın sol tarafıdır ve antecedent olarak adlandırılır.

22_0

ise kuralın sağ tarafıdır ve consequent olarak adlandırılır.

Kuralı şöyle okuyabiliriz:

25_0 hizmetini alan kullanıcılar 22_0 hizmetini de alma eğilimi göstermektedir.

13. Support, Confidence ve Lift Nedir?

Birliktelik kurallarını yorumlarken en önemli üç metrik şunlardır:

Support

Support, ilgili hizmet kombinasyonunun tüm sepetler içerisinde ne kadar sık görüldüğünü gösterir.

Basit olarak:

Support(A → B)
= 
A ve B'nin birlikte bulunduğu sepet sayısı / Toplam sepet sayısı

Support bize kuralın ne kadar yaygın olduğunu söyler.

Confidence

Confidence şu soruyu cevaplar:

A hizmetini alan kullanıcıların ne kadarı B hizmetini de alıyor?

Formül:

Confidence(A → B)
=
Support(A ve B)
/
Support(A)

Örneğin:

Confidence = 0.259

ise yaklaşık olarak:

%25.9

anlamına gelir.

Yani A hizmetini alan kullanıcıların yaklaşık %25.9'u B hizmetini de almıştır.

Lift

Lift en önemli metriklerden biridir.

Şu soruyu cevaplar:

A hizmetinin alınması, B hizmetinin satın alınma olasılığını gerçekten artırıyor mu?

Genel yorum:

Lift = 1

İki hizmet arasında özel bir ilişki yoktur.

Lift > 1

Pozitif bir ilişki vardır.

Lift < 1

Negatif bir ilişki olabilir.

Örneğin:

Lift = 5.45

A hizmeti alındığında B hizmetinin görülme eğiliminin bağımsız beklentiye kıyasla oldukça yüksek olduğunu gösterir.

14. Kuralları Lift Değerine Göre Sıralamak

Daha güçlü ilişkileri görmek için:

rules = rules.sort_values(
    by="lift",
    ascending=False
)

kullanabiliriz.

Bu işlem en yüksek lift değerine sahip kuralları listenin başına getirir.

Örnek olarak şu tür sonuçlarla karşılaşabiliriz:

Burada dikkat edilmesi gereken önemli bir nokta vardır:

Yalnızca Lift değerine bakarak karar vermek yeterli değildir.

Bir kuralın:

  • Support
  • Confidence
  • Lift

değerleri birlikte değerlendirilmelidir.

Çünkü lift yüksek olsa bile kural çok az kullanıcıda görülüyorsa gerçek hayattaki öneri performansı sınırlı olabilir.

15. Daha Güçlü Kuralları Filtrelemek

Tüm kuralları kullanmak yerine belirli eşiklerin üzerindeki kuralları seçebiliriz.

strong_rules = rules[
    (rules["support"] > 0.01)
    & (rules["confidence"] > 0.1)
    & (rules["lift"] > 1)
]

Ardından sonuçları tekrar lift değerine göre sıralayabiliriz:

strong_rules = (
    strong_rules
    .sort_values(
        "lift",
        ascending=False
    )
)

Buradaki filtre şu anlama gelir:

Support > 0.01

Kural veri içerisinde belirli bir yaygınlığa sahip olsun.

Confidence > 0.10

Kuralın tahmin gücü tamamen düşük olmasın.

Lift > 1

Hizmetler arasında pozitif bir ilişki olsun.

Bu eşikler her veri seti ve iş probleminde farklı şekilde belirlenebilir.

16. Artık Bir Tavsiye Sistemi Oluşturabiliriz

Şimdi asıl hedefimize geldik.

Bir kullanıcı son olarak:

2_0

hizmetini aldıysa, hangi hizmetleri önerebiliriz?

Bunun için bir fonksiyon oluşturuyoruz.

def arl_recommender(
    rules_df,
    service_id,
    rec_count=1
):

sorted_rules = rules_df.sort_values(
        "lift",
        ascending=False
    )
    recommendation_list = []
    for i, service in enumerate(
        sorted_rules["antecedents"]
    ):
        for j in list(service):
            if j == service_id:
                recommended_service = list(
                    sorted_rules.iloc[i]
                    ["consequents"]
                )[0]
                if (
                    recommended_service
                    not in recommendation_list
                ):
                    recommendation_list.append(
                        recommended_service
                    )
    return recommendation_list[
        0:rec_count
    ]

İlk bakışta biraz karmaşık görünebilir.

Adım adım inceleyelim.

17. arl_recommender() Fonksiyonu Nasıl Çalışıyor?

Fonksiyon üç parametre alıyor:

rules_df

Oluşturduğumuz birliktelik kuralları tablosudur.

service_id

Kullanıcının daha önce aldığı hizmettir.

rec_count

Kaç farklı hizmet önerileceğini belirler.

Adım 1: Kuralları Lift Değerine Göre Sıralamak

sorted_rules = rules_df.sort_values(
    "lift",
    ascending=False
)

En güçlü ilişkileri önce değerlendirmek istiyoruz.

Bu nedenle kuralları lift değerine göre büyükten küçüğe sıralıyoruz.

Adım 2: Boş Bir Öneri Listesi Oluşturmak

recommendation_list = []

Bulduğumuz hizmet önerilerini bu listede saklayacağız.

Adım 3: Antecedents Değerlerini Gezmek

for i, service in enumerate(
    sorted_rules["antecedents"]
):

Burada kural tablosunun:

antecedents

sütununu tek tek geziyoruz.

Antecedent, kuralın sol tarafıdır.

Örneğin:

2_0 → 22_0

kuralında:

2_0

antecedent’tır.

18. enumerate() Neden Kullanılıyor?

Normal bir döngü şöyle olabilirdi:

for service in sorted_rules["antecedents"]:

Ancak burada yalnızca hizmetin kendisine değil, bulunduğu satırın indeksine de ihtiyacımız vardır.

Bu nedenle:

enumerate()

kullanıyoruz.

enumerate() bize aynı anda:

i → sıra numarası
service → hizmet

verir.

Böylece ilgili satırın consequents değerine ulaşabiliriz.

19. Neden list(service) Kullanılıyor?

Association Rules çıktısında antecedents değerleri genellikle:

frozenset({"2_0"})

formatında bulunur.

Bu nedenle:

list(service)

ile bu yapıyı listeye dönüştürüyoruz.

Ardından içindeki hizmetleri kontrol ediyoruz:

for j in list(service):

20. Kullanıcının Hizmeti Kurallarda Aranıyor

if j == service_id:

Bu satır:

Kullanıcının aldığı hizmet kuralın sol tarafında mı?

sorusunu kontrol eder.

Örneğin kullanıcı:

2_0

hizmetini aldıysa algoritma:

2_0 → X

şeklindeki kuralları arar.

21. Önerilecek Hizmeti Bulmak

Eşleşen bir kural bulunduğunda:

recommended_service = list(
    sorted_rules.iloc[i]["consequents"]
)[0]

ile kuralın sağ tarafındaki hizmet alınır.

Örneğin:

2_0 → 22_0

kuralında önerilecek hizmet:

22_0

olacaktır.

22. Aynı Hizmetin Tekrar Önerilmesini Engellemek

Aynı hizmet farklı kurallardan dolayı birden fazla kez önerilebilir.

Bu nedenle:

if (
    recommended_service
    not in recommendation_list
):

kontrolü yapılır.

Hizmet daha önce listeye eklenmemişse:

recommendation_list.append(
    recommended_service
)

ile öneri listesine eklenir.

23. Kaç Öneri Döndürülecek?

Fonksiyonun sonunda:

return recommendation_list[
    0:rec_count
]

kullanıyoruz.

Örneğin:

rec_count=3

ise en fazla üç hizmet önerilir.

24. 2_0 Hizmetini Alan Kullanıcıya Öneri Yapmak

Artık fonksiyonumuzu kullanabiliriz:

arl_recommender(
    rules,
    "2_0",
    rec_count=3
)

Bu kod:

  1. 2_0 hizmetini antecedent tarafında arar.
  2. Bu hizmetle ilişkili kuralları bulur.
  3. Kuralları lift değerine göre değerlendirir.
  4. Consequent tarafındaki hizmetleri önerir.
  5. Tekrar eden hizmetleri çıkarır.
  6. En fazla üç farklı hizmet döndürür.

Böylece basit bir Association Rule Learning tabanlı tavsiye sistemi oluşturmuş oluruz.

25. Çalışmanın Tam Akışı

Tüm süreci özetlersek:

26. Bu Çalışmadan Ne Öğrendim?

Bu proje benim için yalnızca bir algoritmayı çalıştırmaktan ibaret değildi.

Özellikle şu noktalar önemliydi:

Veriyi doğru temsil etmek algoritma kadar önemlidir?

Ham veri doğrudan Apriori algoritmasına verilemedi.

Önce:

  • hizmetlerin benzersiz tanımlanması,
  • sepet yapısının oluşturulması,
  • verinin pivot tablo formatına dönüştürülmesi gerekti.

Bir tavsiye sistemi her zaman karmaşık modeller gerektirmez.

Derin öğrenme veya büyük yapay zekâ modelleri kullanılmadan da kullanıcı davranışlarından anlamlı öneriler üretilebilir.

Lift tek başına yeterli değildir.

Bir kuralın gerçek iş değerini değerlendirmek için:

  • Support
  • Confidence
  • Lift

metriklerinin birlikte değerlendirilmesi gerekir.

Tavsiye sisteminin temelinde kullanıcı davranışları vardır.

Bu çalışmada kullanıcıların hizmetlere verdiği puanları kullanmadık.

Bunun yerine:

“Hangi hizmetler birlikte satın alındı?”

sorusuna odaklandık.

Bu nedenle çalışma, kullanıcı-ürün puanlarından yararlanan Collaborative Filtering yöntemlerinden farklı bir yaklaşım sunmaktadır.

27. Gerçek Bir Sistemde Nasıl Geliştirilebilir?

Bu çalışma temel bir Association Rule Learning uygulamasıdır.

Gerçek bir üretim ortamında sistem daha ileri taşınabilir.

Örneğin:

  • yalnızca son alınan hizmet değil, kullanıcının tüm geçmişi değerlendirilebilir,
  • hizmetlerin ne kadar yakın zamanda alındığı hesaba katılabilir,
  • şehir ve bölge bilgileri modele eklenebilir,
  • hizmetlerin mevsimselliği incelenebilir,
  • müşteri segmentlerine özel kurallar üretilebilir,
  • yalnızca lift değil, confidence ve support değerlerinden oluşan birleşik bir skor kullanılabilir,
  • Association Rule Learning sonuçları Collaborative Filtering yöntemleriyle birleştirilerek hibrit bir tavsiye sistemi geliştirilebilir.

Örneğin bir kullanıcı geçmişte:

Temizlik
Nakliyat
Mobilya Montaj

hizmetlerini aldıysa yalnızca son hizmet yerine kullanıcının tüm hizmet geçmişinden öneriler oluşturulabilir.

Sonuç

Bu çalışmada Armut hizmet verisi üzerinden Python kullanarak uçtan uca bir Association Rule Learning tabanlı hizmet tavsiye sistemi geliştirdik.

Süreç boyunca:

  • veriyi hazırladık,
  • benzersiz hizmet kodları oluşturduk,
  • kullanıcıların aylık hizmet alışverişlerini sepet olarak tanımladık,
  • sepet-hizmet matrisi oluşturduk,
  • Apriori algoritması ile sık hizmet kombinasyonlarını bulduk,
  • Association Rules ile hizmetler arasındaki ilişkileri çıkardık,
  • Support, Confidence ve Lift metriklerini yorumladık,
  • kullanıcının son aldığı hizmete göre öneri yapan bir fonksiyon geliştirdik.

Bu çalışma bana tavsiye sistemlerinde önemli bir noktayı tekrar gösterdi:

İyi bir öneri sistemi yalnızca hangi algoritmayı kullandığımızla değil, kullanıcı davranışını veride nasıl temsil ettiğimizle başlar.

Bir sonraki adımda bu yaklaşımı Content-Based Filtering, Collaborative Filtering ve Hybrid Recommendation Systems gibi farklı tavsiye sistemi yöntemleriyle karşılaştırmak mümkün.

Kullanılan Teknolojiler

Python · Pandas · mlxtend · Apriori · Association Rule Learning · Recommendation Systems · Data Science


메타데이터
post_id
6a67bff5ff7c
slug
sepetten-öneriye-python-ile-association-rule-learning-6a67bff5ff7c
url
https://medium.com/@ssenturkilayda/sepetten-%C3%B6neriye-python-ile-association-rule-learning-6a67bff5ff7c
canonical_url
https://medium.com/@ssenturkilayda/sepetten-%C3%B6neriye-python-ile-association-rule-learning-6a67bff5ff7c
author_url
https://medium.com/@ssenturkilayda
status
ok
fetched_at
2026-09-01 16:14:49