Ders 08 / 14
Öneri Problemi
Kurgu abone-kalem etkileşim dizeyinde önerinin ölçülmesi: 360 abone ve 24 hizmet kalemi 8.640 hücrenin yalnız 577'sinde buluşur, seyreklik 0,9332'dir ve 80 abonenin hiçbir etkileşimi yoktur. Taban çizgisi eğitimde en çok seçilen kalemi herkese sunmaktır; ilk beş isabeti 0,6527, rastgele sıranınki 0,2036'dır. Aynı veri örtük okunduğunda ve açık puanla okunduğunda ilk beş kalemin yalnız biri ortaktır, ortalama puana göre öneri 0,1497 isabet verir, 24 kalemin 16'sının on taneden az puanı vardır ve hiç gösterilmemiş 5.638 hücrenin puan sayısı sıfırdır.
İçindekiler
Yedi derste ajan kendi eylemini seçti ve sonucunu ortamdan öğrendi: bir aboneye ekip gönderilince ne olduğu, gönderilmeyince ne olduğu adım adım kayda geçti. Şimdi eylem el değiştiriyor. Sistemin yapabildiği tek şey bir aboneye bir seçenek sunmak, ve sonucu ancak o abone seçerse görünür. Sunulmayan seçeneğin sonucu hiç doğmaz; sunulan ama seçilmeyen seçeneğin niçin seçilmediği kayda geçmez. Toplanan veri, sistemin kendi sunum kararlarının izidir.
Bu ders o düzenin verisini kurar ve iki sayı üretir: herkese aynı kalemi sunan tabanın ilk beş isabeti, ve aynı veriyi örtük ile açık okumanın ürettiği iki sıralamanın ne kadar ayrıldığı. Kursun kuralı burada ilk kez ödenir: gösterilmeyen kalem puanlanmaz, puanlanmayan kalem gösterilmez.
- ON1. Küme kurgudur, tohum 20260218: 360 abone, 24 hizmet kalemi, 8.640 hücre. Kalemler bölgesel ölçüm ağının hizmet başvurularıdır (tarife değişikliği, sayaç değişimi, taksitlendirme, uzaktan okuma başvurusu gibi).
- ON2. Üç olay ayrı ayrı üretilir: gösterim, seçim, puan. Bir kalem gösterilmeden seçilemez, seçilmeden puanlanamaz. Zincir kurgunun içine bilerek konmuştur.
- ON3. Abonenin bir kaleme gerçek eğilimi üretecin içindedir ve yalnız ölçüm için okunur; hiçbir yöntem onu görmez.
- ON4. Örtük geri bildirim seçimin kendisidir ve 0/1’dir. Açık geri bildirim 1 ile 5 arasında bir puandır ve yalnız seçimlerin bir kısmında bırakılır.
- ON5. Geçmişte hangi kalemin kime gösterildiği payına göre yanlıdır: sık başvurulan kalem çok, seyrek olan az sunulmuştur. Bu yanlılık kurguya bilerek konmuştur.
- ON6. Ayrılmış küme: en az iki etkileşimi olan her abonenin son etkileşimi. Kalanı eğitim kümesidir.
- ON7. Ölçüt ilk k isabetidir: abonenin ayrılmış kalemi ilk k öneri içinde mi. Kesinlik ve duyarlılık tanımları M27/K03’te kuruldu ve burada tekrarlanmaz.
- ON8. İki taban çizgisi kurulur: rastgele sıra ve eğitimde en çok seçilen kalem sırası. İkincisi asıl tabandır, çünkü hiçbir kişiselleştirme içermez ve yine de kataloğun eğrisinden beslenir.
Etkileşim Dizeyi ve Seyreklik
Dizeyin satırı abone, sütunu hizmet kalemidir. Bir hücrenin dolu olması abonenin o kalemi seçtiğini söyler; boş olması iki ayrı şeyin karışımıdır ve ayırt edilemez: kalem sunulmuş ama seçilmemiş olabilir, ya da hiç sunulmamış olabilir. Kurgu bu ikisini ayrı ayrı üretir, böylece ölçüm sırasında hangisinin ne kadar olduğu sayılabilir.
# ORTAK -- KURGUDUR. Abone x hizmet kalemi etkilesim dizeyi ders icinde kurulur. # Gosterim, secim ve puan ayri ayri uretilir: bir kalem once GOSTERILIR, sonra # secilebilir, ancak secilirse puanlanabilir. TOHUM, M32 = 20260218, 0xFFFFFFFF def uretec(t): x = ((t ^ (t >> 16)) * 2246822507) & M32 x = ((x ^ (x >> 13)) * 3266489909) & M32 s = [(x ^ (x >> 16)) & M32] def sonraki(): s[0] = (s[0] * 1664525 + 1013904223) & M32 return s[0] / 4294967296 return sonraki KALEM = [ # (ad, alan, kanal, ucretli, taahhut, randevu, taban_pay) ("otomatik_odeme_talimati", "odeme", "cevrimici", 0, 0, 0, 0.90), ("e_fatura_gecisi", "bildirim", "cevrimici", 0, 0, 0, 0.85), ("odeme_hatirlatma_sms", "bildirim", "cevrimici", 0, 0, 0, 0.78), ("taksitlendirme", "odeme", "sube", 0, 1, 0, 0.62), ("uzaktan_okuma_basvurusu", "olcum", "saha", 0, 1, 1, 0.55), ("kesinti_uyari_aboneligi", "bildirim", "cevrimici", 0, 0, 0, 0.50), ("borc_yapilandirma", "odeme", "sube", 0, 1, 0, 0.44), ("adres_guncelleme", "sozlesme", "cevrimici", 0, 0, 0, 0.40), ("sayac_degisimi", "olcum", "saha", 1, 0, 1, 0.36), ("tuketim_raporu_aboneligi", "bildirim", "cevrimici", 0, 0, 0, 0.32), ("fatura_itiraz_kaydi", "odeme", "sube", 0, 0, 0, 0.28), ("abonelik_devri", "sozlesme", "sube", 0, 0, 0, 0.25), ("kacak_kontrol_randevusu", "olcum", "saha", 0, 0, 1, 0.22), ("tesisat_bakim_paketi", "tesisat", "saha", 1, 1, 1, 0.19), ("ikinci_sayac_talebi", "olcum", "saha", 1, 0, 1, 0.16), ("isyeri_tarifesine_gecis", "sozlesme", "sube", 0, 1, 0, 0.14), ("basinc_duzenleyici_montaji", "tesisat", "saha", 1, 0, 1, 0.12), ("bahce_sulama_tarifesi", "sozlesme", "sube", 0, 1, 0, 0.10), ("sayac_yeri_degisikligi", "olcum", "saha", 1, 0, 1, 0.09), ("ortak_alan_paylasim_kaydi", "sozlesme", "sube", 0, 1, 0, 0.08), ("tesisat_uygunluk_raporu", "tesisat", "saha", 1, 0, 1, 0.07), ("gecikme_faizi_muafiyeti", "odeme", "sube", 0, 0, 0, 0.06), ("mobil_erisim_izni", "bildirim", "cevrimici", 0, 0, 0, 0.05), ("ek_hat_tesisati", "tesisat", "saha", 1, 1, 1, 0.04), ] KESIM = { # kesimin alanlara egilimi; yalniz uretecin icinde kullanilir "tasarruf": {"odeme": 0.5, "olcum": 1.7, "sozlesme": 0.6, "bildirim": 1.5, "tesisat": 0.6}, "odeme": {"odeme": 1.9, "olcum": 0.5, "sozlesme": 0.6, "bildirim": 1.1, "tesisat": 0.3}, "isyeri": {"odeme": 0.7, "olcum": 0.9, "sozlesme": 1.6, "bildirim": 0.7, "tesisat": 1.9}, "yeni": {"odeme": 0.8, "olcum": 0.7, "sozlesme": 1.8, "bildirim": 1.3, "tesisat": 0.7}, } KESIM_AD = list(KESIM) rk = uretec(TOHUM + 101) KALITE = [0.25 + 0.70 * rk() for _ in KALEM] # kalemin kendi doyuruculugu N_ABONE, N_KALEM = 360, len(KALEM) ABONE, GOSTERIM, ETKILESIM, PUAN, EGILIM = [], {}, {}, {}, {} for i in range(N_ABONE): r = uretec(TOHUM + 7919 * i) a, kesim = 20001 + i, KESIM_AD[int(r() * 4)] etkinlik = 0.35 + 1.15 * r() ** 1.6 ABONE.append(a) for j, (ad, alan, kanal, uc, ta, ra, pay) in enumerate(KALEM): egilim = min(0.95, KESIM[kesim][alan] * pay * etkinlik * 0.55) EGILIM[(a, j)] = egilim if r() < min(0.95, pay ** 0.55 * 0.72): # sunulmus mu GOSTERIM[(a, j)] = 1 if r() < egilim: # secilmis mi ETKILESIM[(a, j)] = r() # deger: sira damgasi if r() < 0.32: # puan birakmis mi ham = (0.16 + 0.50 * KESIM[kesim][alan] / 1.9 + 0.42 * KALITE[j] + 0.26 * (r() - 0.5)) PUAN[(a, j)] = max(1, min(5, int(round(ham * 5)))) else: r(), r(), r() HUCRE = N_ABONE * N_KALEM sayi = {} for (a, j) in ETKILESIM: sayi[a] = sayi.get(a, 0) + 1 print("dizey", N_ABONE, "abone x", N_KALEM, "kalem =", HUCRE, "hucre") for ad, d in (("gosterim", GOSTERIM), ("etkilesim", ETKILESIM), ("puan", PUAN)): print(f" {ad:10s} {len(d):5d} doluluk {len(d)/HUCRE:.4f} seyreklik {1-len(d)/HUCRE:.4f}") print("hic etkilesimi olmayan abone", N_ABONE - len(sayi), " abone basina ortalama", round(len(ETKILESIM) / N_ABONE, 3), " en cok", max(sayi.values()))
dizey 360 abone x 24 kalem = 8640 hucre gosterim 3002 doluluk 0.3475 seyreklik 0.6525 etkilesim 577 doluluk 0.0668 seyreklik 0.9332 puan 218 doluluk 0.0252 seyreklik 0.9748 hic etkilesimi olmayan abone 80 abone basina ortalama 1.603 en cok 7
Üç doluluk oranı üç ayrı problemi tarif ediyor. Gösterim dizeyi 0,3475 dolu, seçim dizeyi 0,0668, puan dizeyi 0,0252. Seyreklik seçim düzeyinde 0,9332’dir: her yüz hücrenin altmış yedisi sunulmuş ama seçilmemiş, yirmi altısı hiç sunulmamıştır. Abone başına ortalama 1,603 etkileşim düşer ve 360 abonenin 80’inin hiçbir etkileşimi yoktur. Bu tabloda bir aboneye ne önerileceğine karar vermek, satırların çoğunun neredeyse tümüyle boş olduğu bir dizeyden karar çıkarmaktır.
Herkese Aynı Kalemi Sunmak
Öneri alanının tabanı kişiselleştirmesiz bir yordamdır: eğitim kümesinde en çok seçilmiş kalemleri sıraya dizip herkese aynı listeyi sunmak. Bu taban hiçbir aboneyi diğerinden ayırt etmez, yine de kataloğun eğriliğinden beslenir ve şaşırtıcı biçimde yükseğe çıkar. Yanına ikinci bir taban konur: abonenin görmediği kalemleri rastgele sıraya dizmek.
# Ayirma: en az iki etkilesimi olan her abonenin SON etkilesimi ayrilmis kumeye. EGIT, AYRI, GORULEN = {}, {}, {} kayit = {} for (a, j), damga in ETKILESIM.items(): kayit.setdefault(a, []).append((damga, j)) for a, lst in kayit.items(): lst.sort() if len(lst) >= 2: AYRI[a] = lst[-1][1] lst = lst[:-1] for damga, j in lst: EGIT[(a, j)] = 1 GORULEN.setdefault(a, set()).add(j) pay = [0] * N_KALEM for (a, j) in EGIT: pay[j] += 1 sirali = sorted(range(N_KALEM), key=lambda j: -pay[j]) def isabet(oner, K): return sum(1 for a in AYRI if AYRI[a] in oner(a)[:K]) / len(AYRI) def taban_populerlik(a): return [j for j in sirali if j not in GORULEN.get(a, set())] rg = uretec(TOHUM + 31) def taban_rastgele(a): aday = [j for j in range(N_KALEM) if j not in GORULEN.get(a, set())] for i in range(len(aday) - 1, 0, -1): t = int(rg() * (i + 1)) aday[i], aday[t] = aday[t], aday[i] return aday print("egitim", len(EGIT), "etkilesim / ayrilmis", len(AYRI), "abone") print("egitimde en cok secilen bes kalem:") for j in sirali[:5]: print(f" {KALEM[j][0]:26s} {pay[j]:3d}") for K in (3, 5): p, s = isabet(taban_populerlik, K), isabet(taban_rastgele, K) print(f"ilk {K}: populerlik {p:.4f} rastgele {s:.4f} oran {p/s:.2f}") print("populerlik tabaninin katalog kapsamasi", len({j for a in AYRI for j in taban_populerlik(a)[:5]}), "/", N_KALEM)
egitim 410 etkilesim / ayrilmis 167 abone egitimde en cok secilen bes kalem: odeme_hatirlatma_sms 68 e_fatura_gecisi 64 otomatik_odeme_talimati 47 taksitlendirme 39 borc_yapilandirma 27 ilk 3: populerlik 0.5509 rastgele 0.1437 oran 3.83 ilk 5: populerlik 0.6527 rastgele 0.2036 oran 3.21 populerlik tabaninin katalog kapsamasi 9 / 24
Kişiselleştirmesiz taban, 167 abonenin 109’unun ayrılmış kalemini ilk beşte yakalıyor: isabet 0,6527. Rastgele sıra aynı ölçüde 0,2036’da kalıyor, aradaki oran 3,21. İlk üçe inildiğinde taban 0,5509 veriyor ve oran 3,83’e çıkıyor. Bu sayı bu kursun geri kalanı için bir eşik: bir öneri yöntemi 0,6527’yi geçmiyorsa, hiçbir abone ayrımı yapmayan bir listeden daha iyi değildir.
Tabanın ödediği bedel dördüncü satırda: 167 abonenin ilk beş listelerinde toplam 9 ayrı kalem geçiyor, katalogda 24 kalem var. On beş kalem hiçbir aboneye hiç önerilmiyor. Taban yüksek isabeti kataloğun on beş kalemini tümüyle görünmez kılarak alıyor, ve görünmeyen kalem bir sonraki dönemin verisine de girmiyor.
Örtük ile Açık Geri Bildirim
Örtük geri bildirim seçimin kendisidir: abone başvurdu ya da başvurmadı. Açık geri bildirim abonenin bıraktığı puandır. İkisi aynı kataloğu ölçüyor gibi görünür, ama farklı şeyleri sayarlar. Örtük sinyal hacmi ölçer ve gösterim sayısını içinde taşır; açık sinyal seçtikten sonraki doyumu ölçer ve yalnız seçenlerin bir kısmından gelir.
gos, sec, adet, toplam = ([0] * N_KALEM for _ in range(4)) for (a, j) in GOSTERIM: gos[j] += 1 for (a, j) in ETKILESIM: sec[j] += 1 for (a, j), p in PUAN.items(): adet[j] += 1 toplam[j] += p ort = [toplam[j] / adet[j] if adet[j] else 0.0 for j in range(N_KALEM)] s_ortuk = sorted(range(N_KALEM), key=lambda j: -sec[j]) s_acik = sorted([j for j in range(N_KALEM) if adet[j] > 0], key=lambda j: -ort[j]) print(f"{'kalem':26s} {'gosterim':>8s} {'secim':>6s} {'puan':>5s} {'ortalama':>9s}") for j in s_ortuk[:3] + s_acik[:3]: print(f"{KALEM[j][0]:26s} {gos[j]:8d} {sec[j]:6d} {adet[j]:5d} {ort[j]:9.2f}") print("ortuk ilk 5 ile acik ilk 5 kesisimi", len(set(s_ortuk[:5]) & set(s_acik[:5]))) print("hic secilmemis kalem", sum(1 for j in range(N_KALEM) if sec[j] == 0), " on tane puandan az kalem", sum(1 for j in range(N_KALEM) if adet[j] < 10)) print("hic gosterilmemis hucre", HUCRE - len(GOSTERIM), " bunlarin puan sayisi", sum(1 for k in PUAN if k not in GOSTERIM)) print("hic puan birakmamis abone", N_ABONE - len({a for (a, j) in PUAN})) s_puan = sorted(range(N_KALEM), key=lambda j: -ort[j]) print(f"ilk 5 isabet -- ortalama puana gore {isabet(lambda a: [j for j in s_puan if j not in GORULEN.get(a, set())], 5):.4f}")
kalem gosterim secim puan ortalama e_fatura_gecisi 215 93 30 3.27 odeme_hatirlatma_sms 236 89 31 3.06 otomatik_odeme_talimati 242 73 24 3.83 adres_guncelleme 158 37 14 4.79 ikinci_sayac_talebi 96 9 3 4.33 isyeri_tarifesine_gecis 91 5 4 4.25 ortuk ilk 5 ile acik ilk 5 kesisimi 1 hic secilmemis kalem 1 on tane puandan az kalem 16 hic gosterilmemis hucre 5638 bunlarin puan sayisi 0 hic puan birakmamis abone 205 ilk 5 isabet -- ortalama puana gore 0.1497
İki sıralamanın ilk beşinde ortak olan kalem sayısı 1. Örtük sıralamanın başındaki üç kalem ikişer yüzü aşan gösterim almış ve ortalama puanları 3,06 ile 3,83 arasında; açık sıralamanın başındaki kalemlerden ikisinin puan sayısı 3 ve 4. Ortalama puana göre öneri yapmak ilk beş isabetini 0,1497’ye düşürüyor, yani rastgele sıranın 0,2036’sının bile altına.
Sayının kaynağı üçüncü ve dördüncü satırda duruyor. Kataloğun 24 kaleminin 16’sının on taneden az puanı var, çünkü az gösterilen kalem az seçiliyor ve az seçilen kalem az puanlanıyor. Hiç gösterilmemiş 5.638 hücrenin puan sayısı sıfır; bu bir bulgu değil, zincirin tanımı. Abonelerin 205’i hiç puan bırakmamış. Açık geri bildirim daha zengin bir sinyal taşır, ama taşıdığı yerde taşır: sistemin daha önce gösterdiği kalemlerde. Gösterilmeyen kalem puanlanmaz, ve ortalama puanla sıralanan bir liste kataloğun görünmeyen kısmı hakkında hiçbir şey söylemez.
Toplanan veri bu dersin üçüncü sayısıdır ve iki parçadan oluşur: hiç gösterilmemiş 5.638 hücre, ve tabanın önerdiği listelerin dışında kalan 15 kalem. Bir öneri yöntemi ölçülürken bu iki sayı yazılmıyorsa, ölçünün hangi kataloğa ait olduğu bilinmez.
Özet
- Kurgu dizey 360 abone ile 24 hizmet kalemini 8.640 hücrede buluşturur; gösterim doluluğu 0,3475, seçim 0,0668, puan 0,0252’dir. Seçim düzeyinde seyreklik 0,9332 ve 80 abonenin hiç etkileşimi yoktur.
- Taban çizgisi eğitimde en çok seçilen kalemleri herkese aynı sırayla sunmaktır; ilk beş isabeti 0,6527, ilk üç isabeti 0,5509’dur. Rastgele sıra aynı ölçüde 0,2036 ve 0,1437 verir.
- Tabanın bedeli kapsamadır: 167 abonenin ilk beş listelerinde yalnız 9 ayrı kalem geçer, on beş kalem hiçbir aboneye önerilmez.
- Örtük ve açık geri bildirim aynı katalogda iki ayrı sıralama üretir; ilk beşlerinin kesişimi birdir ve ortalama puana göre öneri 0,1497 isabet verir.
- Açık sinyal seyrektir ve gösterime bağımlıdır: 24 kalemin 16’sının on taneden az puanı vardır, 205 abone hiç puan bırakmamıştır, hiç gösterilmemiş 5.638 hücrenin puan sayısı sıfırdır.
Sonraki Adım
Taban 0,6527 ile bir eşik koydu, ama bunu kataloğun on beş kalemini hiç göstermeyerek yaptı ve hiç etkileşimi olmayan 80 aboneye söyleyecek ayrı bir sözü yok. İlk soru şu: aboneden hiç veri gelmemişken bile kalemin kendisi hakkında bilinen bir şey var mı. Katalogda her kalemin alanı, kanalı, ücretli olup olmadığı, taahhüt ve randevu gerektirip gerektirmediği yazılı. Bir sonraki ders bu özniteliklerden abone başına bir profil çıkarır, önerileri profile benzerlikle sıralar ve iki sayıyı ölçer: kaç abone için hiç öneri üretilemiyor, ve üretilen öneriler birbirine ne kadar benziyor.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.