Ders 04 / 11
Uygulama Alanları
Aynı kurgu abone tablosuna dört soru sorulur ve dört ayrı taban çizgisi seçilir: sınıflandırmada en sık sınıf ayrılmış kümede 0,7533 verir, ağaç 0,8594; bağlanımda genel ortalama 5,2255 m³ ortalama mutlak hata verir, en küçük kareler 4,1275 m³; kümelemede rastgele dört gruplama 2,7683 küme içi uzaklık verir, öğrenilen dört merkez 2,1551; sıralamada rastgele sıra ilk 100 ziyarette 20 kaçak bulur, en yüksek tüketimden başlayan sıra 30, dokuz ağaçlık topluluk 71. Dört ölçünün ikisinde büyük sayı iyi, ikisinde küçük sayı iyidir; sayılar birbiriyle değil yalnız kendi tabanlarıyla karşılaştırılabilir.
İçindekiler
Üç derste tek bir soru soruldu: bu abone şüpheli mi. Soru ikili olduğu için taban çizgisi de hep aynı kaldı — en sık sınıfı söylemek. Aynı tablo başka soruları da kaldırır. Bu abone önümüzdeki dönem kaç metreküp tüketir. Aboneler kaç doğal öbeğe ayrılıyor. Sahaya bugün çıkacak ekip hangi yüz aboneyi hangi sırayla gezmeli.
Bu ders aynı veriye dört soru sorar. Ders boyunca değişmeyen tek şey tablodur; değişen şey soru, sorunun ölçüsü ve sorunun taban çizgisidir. Dördü de aynı ayrılmış kümede ölçülür.
- MK20. Bir veri kümesi tek bir problem tanımlamaz. Problemi belirleyen şey veri değil, sorulan sorudur; aynı tabloda hangi sütunun etiket olduğu soruyla birlikte değişir.
- MK21. Sınıflandırma (classification): çıktı sonlu bir etiket kümesinden bir değerdir. Tabanı en sık sınıftır, çünkü hiç bakmadan verilebilecek en iyi tek karar odur.
- MK22. Bağlanım (regression): çıktı sayısal bir değerdir. Tabanı genel ortalamadır; ortalama mutlak hata ölçülüyorsa ortanca daha iyi bir taban olur ve seçim yazılır.
- MK23. Kümeleme (clustering): etiket yoktur, çıktı bir gruplamadır. Tabanı rastgele gruplamadır, çünkü aynı sayıda grup üretir ve hiçbir yapı kullanmaz.
- MK24. Sıralama (ranking): çıktı tek bir karar değil bir sıradır ve ölçü sıranın başındaki bütçeye bakar. Tabanı rastgele sıradır; yanına öğrenmeyen bir sezgisel sıra da konur, çünkü sahada gerçekten kullanılan yordam odur.
- MK25. Dört ölçünün ikisinde büyük sayı, ikisinde küçük sayı iyidir. Modellerin sayıları birbiriyle değil, yalnız kendi tabanlarıyla karşılaştırılabilir.
Kurgu Kümenin Yeniden Kurulması
# kurulum.py — 01. dersin kurgu kumesi ayni tohumla yeniden kurulur: okuma # tablosu, abone ozeti, kurgu etiket, egitim / ayrilmis ayrimi ve agac ogrenici. import math TOHUM, HAM, M32 = 20260218, 1400, 0xFFFFFFFF BOLGE = [("kuzey", 0.28, 21), ("guney", 0.22, 17), ("dogu", 0.18, 26), ("bati", 0.14, 14), ("merkez", 0.18, 23)] OZNITELIK = ["ortalama", "kisi_basi", "dusus", "sifir_okuma", "okuma_sayisi", "memnuniyet", "hane_kisi", "en_yuksek", "en_dusuk"] 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 def ayrik(u, w): t = 0.0 for i, x in enumerate(w): t += x if u < t: return i return len(w) - 1 _ab, _el, _seri = [], [], {} for i in range(HAM): r = uretec(TOHUM + i) b = BOLGE[ayrik(r(), [x[1] for x in BOLGE])] k = {"abone_no": 10001 + i, "bolge": b[0], "taban": b[2], "hane_kisi": ayrik(r(), [0.06, 0.24, 0.30, 0.24, 0.11, 0.05]), "memnuniyet": ayrik(r(), [0.08, 0.14, 0.27, 0.34, 0.17]) + 1} (_el if r() < 0.046 else _ab).append(k) _gecerli = {a["abone_no"] for a in _ab} for k in _ab + _el: r = uretec(TOHUM + 7000 + k["abone_no"]) for d in range(ayrik(r(), [0.05, 0.12, 0.21, 0.62])): t = 0.0 if r() < 0.038 else math.floor(k["taban"] * math.exp( (r() + r() + r() - 1.5) * 0.62) * (1 - d * 0.05) * 100 + 0.5) / 100 if k["abone_no"] in _gecerli: _seri.setdefault(k["abone_no"], []).append(t) r() ABONE = [] for k in _ab: t = _seri.get(k["abone_no"]) if not t: continue ort = sum(t) / len(t) a = {"abone_no": k["abone_no"], "bolge": k["bolge"], "seri": t, "hane_kisi": k["hane_kisi"], "memnuniyet": k["memnuniyet"], "okuma_sayisi": len(t), "ortalama": ort, "en_yuksek": max(t), "en_dusuk": min(t), "sifir_okuma": sum(1 for v in t if v == 0), "kisi_basi": ort / max(1, k["hane_kisi"]), "dusus": (t[0] - t[-1]) / t[0] if len(t) > 1 and t[0] > 0 else 0.0} r = uretec(TOHUM + 31000 + a["abone_no"]) a["suphe"] = 1 if (1.30 * a["sifir_okuma"] + 1.25 * (a["dusus"] > 0.45) + 1.05 * (a["kisi_basi"] > 12.0) + 0.65 * (a["okuma_sayisi"] < 3) + 0.45 * (a["memnuniyet"] <= 2) - 1.55 + (r() + r() - 1.0) * 1.1) > 0 else 0 ABONE.append(a) r = uretec(TOHUM + 90001) EGITIM, AYRILMIS = [], [] for a in ABONE: (EGITIM if r() < 0.70 else AYRILMIS).append(a) poz = lambda k: sum(a["suphe"] for a in k) dogruluk = lambda f, k: sum(1 for a in k if f(a) == a["suphe"]) / len(k) _saf = lambda k: 2 * (poz(k) / len(k)) * (1 - poz(k) / len(k)) if k else 0.0 def ogren(k, derinlik=3, en_az=40): """01. dersin acgozlu karar agaci: bolme olcutu ve durma kurali orada.""" en, secim = _saf(k) * len(k), None if derinlik and len(k) >= en_az: for oz in OZNITELIK: for e in sorted({a[oz] for a in k})[1:]: sol = [a for a in k if a[oz] < e] sag = [a for a in k if a[oz] >= e] m = _saf(sol) * len(sol) + _saf(sag) * len(sag) if m < en - 1e-9: en, secim = m, (oz, e, sol, sag) if secim is None: return 1 if 2 * poz(k) > len(k) else 0 s, g = ogren(secim[2], derinlik - 1, en_az), ogren(secim[3], derinlik - 1, en_az) return s if s == g else (secim[0], secim[1], s, g) def uygula(d, a): while isinstance(d, tuple): d = d[2] if a[d[0]] < d[1] else d[3] return d print(f"kurgu kume (tohum {TOHUM}): {len(ABONE)} abone, {len(EGITIM)} egitim, " f"{len(AYRILMIS)} ayrilmis, {poz(ABONE)} supheli")
kurgu kume (tohum 20260218): 1260 abone, 883 egitim, 377 ayrilmis, 327 supheli
İkili Karar ve Sayısal Değer
İlk iki soru etiketlidir ve birbirinden yalnız çıktının türüyle ayrılır. Birincisi bir sınıf ister: bu abone şüpheli mi. İkincisi bir sayı ister: bu abone ortalama kaç metreküp tüketir. İkinci soru saha ekibi için değil şebeke planlaması içindir ve okuma gelmeden önce yanıtlanabilmesi gerekir; bu yüzden bağlanım modeline yalnız abone kaydından gelen sütunlar ve bölge verilir.
Tabanlar ayrı seçilir çünkü ölçüler ayrıdır. Doğruluk için en sık sınıf, ortalama mutlak hata için genel ortalama. İkinci seçim tartışmalıdır: ortalama mutlak hata ölçülüyorsa öğrenmeyen en iyi tek sayı ortalama değil ortancadır. Burada ortalama seçilmiştir, çünkü sonraki kurslarda kare hata da kullanılacak ve iki ölçü arasında tek bir taban tutulacaktır; seçim tartışmalı olduğu için yazılır.
# iki_problem.py — ayni tabloya iki soru: ikili bir karar ve sayisal bir deger. # Her sorunun tabani ayri secilir; ikili soruda en sik sinif, sayisal soruda # genel ortalama, cunku olculer farklidir. import statistics from collections import Counter SONUC = [] BASLIK = ["problem", "olcu", "taban eg.", "taban ayr.", "model eg.", "model ayr."] E = [16, 26, 11, 11, 11, 11] y = lambda h: str(h[0]).ljust(E[0]) + str(h[1]).ljust(E[1]) + "".join( str(v).rjust(E[i + 2]) for i, v in enumerate(h[2:])) def kaydet(ad, olcu, te, ta, me, ma, bicim="{:.4f}"): SONUC.append([ad, olcu] + [bicim.format(v) for v in (te, ta, me, ma)]) print(y(SONUC[-1])) en_sik = Counter(a["suphe"] for a in EGITIM).most_common(1)[0][0] AGAC = ogren(EGITIM) BOLGE_AD = [b[0] for b in BOLGE] def gx(a): return ([1.0, float(a["hane_kisi"]), float(a["memnuniyet"]), float(a["okuma_sayisi"])] + [1.0 if a["bolge"] == b else 0.0 for b in BOLGE_AD[1:]]) def coz(A, b): n = len(b) M = [A[i][:] + [b[i]] for i in range(n)] for i in range(n): p = max(range(i, n), key=lambda s: abs(M[s][i])) M[i], M[p] = M[p], M[i] if abs(M[i][i]) < 1e-12: continue for s in range(n): if s != i and M[s][i]: f = M[s][i] / M[i][i] for c in range(i, n + 1): M[s][c] -= f * M[i][c] return [M[i][n] / M[i][i] if abs(M[i][i]) > 1e-12 else 0.0 for i in range(n)] k = len(gx(EGITIM[0])) X, t = [gx(a) for a in EGITIM], [a["ortalama"] for a in EGITIM] W = coz([[sum(x[i] * x[j] for x in X) for j in range(k)] for i in range(k)], [sum(x[i] * v for x, v in zip(X, t)) for i in range(k)]) GENEL = statistics.fmean(t) kestir = lambda a: sum(c * v for c, v in zip(W, gx(a))) hata = lambda f, s: statistics.fmean(abs(f(a) - a["ortalama"]) for a in s) print(y(BASLIK)) kaydet("siniflandirma", "dogruluk (buyuk iyi)", dogruluk(lambda a: en_sik, EGITIM), dogruluk(lambda a: en_sik, AYRILMIS), dogruluk(lambda a: uygula(AGAC, a), EGITIM), dogruluk(lambda a: uygula(AGAC, a), AYRILMIS)) kaydet("baglanim", "mutlak hata m3 (kucuk)", hata(lambda a: GENEL, EGITIM), hata(lambda a: GENEL, AYRILMIS), hata(kestir, EGITIM), hata(kestir, AYRILMIS))
problem olcu taban eg. taban ayr. model eg. model ayr. siniflandirma dogruluk (buyuk iyi) 0.7350 0.7533 0.8709 0.8594 baglanim mutlak hata m3 (kucuk) 4.8767 5.2255 3.7226 4.1275
İki satır iki ayrı yönde okunur. Sınıflandırmada model tabanın 0,1061 üstündedir; bağlanımda 1,0980 m³ altındadır ve iyi olan budur. Sayıların büyüklüğü de kıyaslanamaz: 0,8594 birimsizdir, 4,1275 metreküptür.
Etiketsiz Gruplama ve Sıra
Üçüncü soru etiketi hiç kullanmaz: aboneler kaç doğal öbeğe ayrılıyor. Ölçü, her abonenin kendi grubunun merkezine uzaklığının ortalamasıdır; küçük olması grupların sıkı olduğunu gösterir. Öğrenmeyen yordam burada aboneleri rastgele dört gruba dağıtır ve her grubun merkezini kendi üyelerinden hesaplar; böylece aynı sayıda grup üretilir ama hiçbir yapı kullanılmaz.
Dördüncü soru bir sıra ister. Saha ekibinin günlük kapasitesi yüz ziyarettir ve ölçü, sıranın ilk yüzünde kaç kaçak bulunduğudur. Burada iki taban yazılır. Rastgele sıra öğrenmeyen yordamın kendisidir; en yüksek ortalama tüketimden başlayan sıra ise sahada gerçekten kullanılan sezgisel yordamdır ve model onu da geçmek zorundadır.
# iki_problem_daha.py — ucuncu soru etiketsizdir, dorduncusu bir sayi degil bir # sira ister. Ucuncunun tabani rastgele gruplama, dorduncununki rastgele siradir. ORT = {o: statistics.fmean(a[o] for a in EGITIM) for o in OZNITELIK} SAP = {o: statistics.pstdev(a[o] for a in EGITIM) or 1.0 for o in OZNITELIK} vek = lambda a: [(a[o] - ORT[o]) / SAP[o] for o in OZNITELIK] uzak = lambda v, m: math.sqrt(sum((x - y) ** 2 for x, y in zip(v, m))) ic_uzaklik = lambda s, M: statistics.fmean(min(uzak(vek(a), m) for m in M) for a in s) K = 4 MERKEZ = [vek(a) for a in EGITIM[:K]] for _ in range(25): gr = [[] for _ in range(K)] for a in EGITIM: gr[min(range(K), key=lambda i: uzak(vek(a), MERKEZ[i]))].append(vek(a)) for i in range(K): if gr[i]: MERKEZ[i] = [sum(c) / len(c) for c in zip(*gr[i])] r = uretec(TOHUM + 6104) rasgele_gr = [[] for _ in range(K)] for a in EGITIM: rasgele_gr[int(r() * K)].append(vek(a)) RASGELE = [[sum(c) / len(c) for c in zip(*g)] for g in rasgele_gr] UST = 100 r = uretec(TOHUM + 6205) TOPLULUK = [ogren([EGITIM[int(r() * len(EGITIM))] for _ in EGITIM]) for _ in range(9)] puan = lambda a: sum(uygula(d, a) for d in TOPLULUK) r = uretec(TOHUM + 6206) kura = {a["abone_no"]: r() for a in ABONE} ilk = lambda f, s: poz(sorted(s, key=f)[:UST]) print(y(BASLIK)) kaydet("kumeleme", "kume ici uzaklik (kucuk)", ic_uzaklik(EGITIM, RASGELE), ic_uzaklik(AYRILMIS, RASGELE), ic_uzaklik(EGITIM, MERKEZ), ic_uzaklik(AYRILMIS, MERKEZ)) kaydet("siralama", f"ilk {UST}'de kacak (buyuk)", ilk(lambda a: kura[a["abone_no"]], EGITIM), ilk(lambda a: kura[a["abone_no"]], AYRILMIS), ilk(lambda a: (-puan(a), a["abone_no"]), EGITIM), ilk(lambda a: (-puan(a), a["abone_no"]), AYRILMIS), "{:.0f}") print(f"\nsiralamada ikinci taban — en yuksek ortalama tuketimden basla: " f"egitimde {ilk(lambda a: (-a['ortalama'], a['abone_no']), EGITIM)}, " f"ayrilmista {ilk(lambda a: (-a['ortalama'], a['abone_no']), AYRILMIS)}") print(f"karsilastirma icin: egitimde {poz(EGITIM)} supheli / {len(EGITIM)} abone, " f"ayrilmista {poz(AYRILMIS)} supheli / {len(AYRILMIS)} abone")
problem olcu taban eg. taban ayr. model eg. model ayr. kumeleme kume ici uzaklik (kucuk) 2.7237 2.7683 2.1678 2.1551 siralama ilk 100'de kacak (buyuk) 29 20 86 71 siralamada ikinci taban — en yuksek ortalama tuketimden basla: egitimde 38, ayrilmista 30 karsilastirma icin: egitimde 234 supheli / 883 abone, ayrilmista 93 supheli / 377 abone
Kümelemede öğrenilen dört merkez, rastgele dört grubun 2,7683’lük uzaklığını 2,1551’e indiriyor; kazanç 0,6132. Bu sayının yanında bir uyarı durur: kümelemenin ölçüsü etikete hiç bakmaz, yani “iyi” bir kümeleme kaçağı bulan bir kümeleme değildir. Önceki derste altı kümeli bir bölmenin kaçak sorusunda tabana ne kadar yaklaştığı ayrıca ölçülmüştü; bu iki sayı aynı şeyin iki ölçüsü değil, iki ayrı problemin iki ayrı ölçüsüdür.
Sıralamada üç sayı yan yana duruyor. Rastgele sıra ayrılmış kümedeki ilk yüz ziyarette 20 kaçak buluyor — 377 abonenin 93’ü şüpheli olduğuna göre beklenen budur. En yüksek tüketimden başlayan sezgisel sıra 30 buluyor; alan bilgisi rastgeleyi 10 kaçak geçiyor. Dokuz ağaçlık topluluğun sırası 71 buluyor. Model sezgiselin 41, rastgelenin 51 kaçak üstündedir ve hangi tabanın yazıldığına göre modelin kazancı 41 mi 51 mi olduğu değişir. Taban seçimi bir ölçüm kararıdır.
Dört Problem, Dört Taban
# dort_taban.py — dort problem, dort ayri taban, dort ayri olcu ve iki ayri yon. print(y(BASLIK)) for s in SONUC: print(y(s))
problem olcu taban eg. taban ayr. model eg. model ayr. siniflandirma dogruluk (buyuk iyi) 0.7350 0.7533 0.8709 0.8594 baglanim mutlak hata m3 (kucuk) 4.8767 5.2255 3.7226 4.1275 kumeleme kume ici uzaklik (kucuk) 2.7237 2.7683 2.1678 2.1551 siralama ilk 100'de kacak (buyuk) 29 20 86 71
Tablo tek bir veri kümesinden çıktı ve dört ayrı satır verdi. Model sütunları birbirleriyle karşılaştırılamaz: 0,8594 ile 4,1275’i yan yana koyup birini büyük saymanın hiçbir anlamı yoktur, çünkü biri oran biri metreküptür ve birinde büyük sayı iyi, diğerinde kötüdür. Karşılaştırılabilir olan tek şey her satırın kendi içindeki iki sütun arasındaki farktır.
Taban sütunlarının kendisi de bilgi taşıyor. Sınıflandırmada taban zaten 0,7533’tür; modelin kazanabileceği en fazla pay 0,2467’dir ve 0,1061 bunun yüzde 43,0’ıdır. Sıralamada taban yalnız 20’dir ve tavan 93’tür; model 71 ile aradaki açığın yüzde 69,9’unu kapatmıştır. Aynı model, aynı veri, aynı gün — ama iki soruda iki ayrı başarı öyküsü.
Özet
- Bir veri kümesi tek bir problem tanımlamaz; aynı kurgu abone tablosu sınıflandırma, bağlanım, kümeleme ve sıralama sorularının dördünü de kaldırır.
- Dört sorunun dört ayrı tabanı vardır: en sık sınıf 0,7533, genel ortalama 5,2255 m³, rastgele dört gruplama 2,7683 küme içi uzaklık, rastgele sıra ilk 100 ziyarette 20 kaçak.
- Modellerin ayrılmış küme sayıları sırasıyla 0,8594, 4,1275 m³, 2,1551 ve 71 kaçaktır; ikisinde büyük sayı, ikisinde küçük sayı iyidir.
- Sıralamada ikinci bir taban yazıldı: en yüksek tüketimden başlayan sezgisel sıra 30 kaçak buluyor, yani modelin kazancı yazılan tabana göre 41 ya da 51 kaçaktır.
- Model sayıları birbiriyle karşılaştırılamaz; karşılaştırılabilir olan tek şey her satırın kendi tabanına olan uzaklığıdır.
Sonraki Adım
Dört problem de tek bir noktadan okundu: hazır bir tablo, hazır bir öznitelik kümesi, hazır bir ayrım ve tek bir ölçüm. Bu dersler bir modelin nasıl kurulduğunu gösterdi, bir işin nasıl yürüdüğünü değil. Gerçekte problem tanımı ölçümden sonra değişir, öznitelik kümesi değerlendirmeden sonra genişler, eşik dağıtımdan sonra kaydırılır ve akış hiçbir zaman baştan sona bir kez akmaz. Sonraki ders bu akışı yedi adım olarak kurar ve ölçtüğü şey adımların kendisi değil geri dönüşlerdir: hangi adımda hangi adıma dönüldüğü sayılır ve her dönüşün ayrılmış küme sayısını ne kadar oynattığı basılır.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.