DEV Community

Ferhat Atagün
Ferhat Atagün

Posted on Originally published at ferhatatagun.com

SKOR24'ü yazarken skoru bozan bug'ı otomatik oynanışla buldum

SKOR24, 24 aylık bir kredi skoru simülasyonu: her ay bir finansal karar geliyor (ekstre ödemesi, kredi başvurusu, limit artışı, hesap kapatma, kefillik) ve bu kararlar skoru etkiliyor. Tek dosya, bağımlılık yok, saf HTML/CSS/JS. Bu yazıda skorlama motorunun nasıl kurulduğunu ve elle test ederken kaçırdığım, otomatik oynanışla yakaladığım bir kalibrasyon hatasını anlatıyorum.

Skorlama motoru

Skor modeli beş faktörü ağırlıklı topluyor — FICO'nun kamuya açık oranlarından esinlenerek:

var WEIGHTS = { payment: 0.35, utilization: 0.30, age: 0.15, inquiries: 0.10, mix: 0.10 };
Enter fullscreen mode Exit fullscreen mode

Ağırlıklı toplam, clamp(Math.round((w / 100) * 1900), 0, 1900) ile Findeks'in 0-1900 skalasına taşınıyor.

Her karar seçeneği, bu beş faktörden birine veya birkaçına bir delta uyguluyor. Örneğin ekstre ödeme kararı:

{
  id: "full", label: "Ekstrenin tamamını öde",
  delta: { payment: 2, utilization: 5 }, tone: "good"
},
{
  id: "skip", label: "Ödemeyi bu ay atla",
  delta: { payment: -9, utilization: -3 }, tone: "bad", lateFlag: true
}
Enter fullscreen mode Exit fullscreen mode

On dört farklı karar bloğu var, her biri kendi delta setiyle. Bu kısım basit: bir config objesi, seçilen delta'yı faktörlere ekleyen bir reducer, bitti.

Elle test bir şey söylemiyor

İlk sürümde oyunu elle oynarken ay 1'de "ekstrenin tamamını öde"ye bastım, skor 1197'den 1319'a çıktı. Tek karardan +122 puan. Matematiği kontrol ettim, hatasızdı: kullanım oranı faktörü %30 ağırlıkta, ekstreyi tam ödemek bu faktörü büyük oranda düşürüyordu, ölçeğe taşınınca seksen küsur puanlık hareket beklenen bir sonuçtu.

Sorun şu ki elle test yalnızca "kod çalışıyor mu" sorusuna cevap veriyor, "sonuç doğru bir şey öğretiyor mu" sorusuna değil. Bunu görmek için tek bir oynanış yetmiyor, 24 ayın uçlarını görmek gerekiyor.

Otomatik uç-durum testi

computeScore ve DECISIONS zaten saf fonksiyonlar olduğu için tarayıcı konsolunda kolayca izole edilebiliyordu. İki senaryoyu 24 ay boyunca koşturdum: her ay en kötü seçeneği seçen bir döngü, her ay en iyi seçeneği seçen başka bir döngü — kabaca:

function simulate(pickWorstOrBest) {
  var factors = { payment: 0, utilization: 0, age: 0, inquiries: 0, mix: 0 };
  for (var month = 0; month < 24; month++) {
    var delta = pickWorstOrBest(month); // her ay o karar bloğunun en kötü/en iyi seçeneği
    for (var k in delta) factors[k] += delta[k];
  }
  return computeScore(factors);
}
Enter fullscreen mode Exit fullscreen mode

Düzeltmeden önceki delta setiyle çalıştırınca sonuç şuydu: en kötü senaryo skoru düşük bir bantta tutuyordu, ama en iyi senaryo çok daha erken tavana yapışıyordu. 24 aylık bir oyun tasarlamıştım, ama iyi kararlar veren bir oyuncu için oyun fiilen ay 3-4 civarında bitmiş oluyordu — geri kalan yirmi ay için skor kıpırdamıyordu.

Bu, tek bir elle-oynanışta görülmeyen bir şeydi, çünkü hiçbir gerçek oyuncu 24 ayı baştan sona hep en iyi kararları seçerek oynamıyor. Ama iki-uç testinin gösterdiği şey nettti: pozitif deltalar fazla şişkindi.

Düzeltme ve doğrulama

On dört karar-sonuç çiftinin delta değerlerini tek tek gözden geçirdim ve özellikle iyi kararların ödülünü aşağı çektim. Kötü kararları (gecikme, art arda beş banka başvurusu gibi) büyük ölçüde olduğu gibi bıraktım — onların cezası zaten gerçekçiydi, asıl şişkinlik pozitif tarafta.

Aynı iki-uç testini düzeltilmiş deltalarla tekrar çalıştırdım: en kötü senaryo skoru ~193'e kadar düşürüyor, sürekli en iyi seçimlerle ~1660-1700 bandına çıkıyor. Aynı "ekstrenin tamamını öde" kararı artık +44 veriyor, +122 değil. Ve önemlisi: iki uç arasındaki mesafe artık tek bir ekrana sığmıyor, 24 ayın tamamını gerektiriyor — oyunun amacı zaten buydu.

Çıkarım

Bir kredi skoru simülasyonu yazarken asıl kontrol edilmesi gereken şey "her karar doğru delta'yı mı uyguluyor" değildi, "24 ayın sonunda ortaya çıkan aralık, öğretmek istediğim mesajı destekliyor mu" idi. Bunu elle test ederek göremedim; saf fonksiyonları izole edip iki uçta koşturmak, tek bir manuel denemenin veremeyeceği bir sinyal verdi.

Oyun burada, tarayıcıda çalışıyor, kurulum gerektirmiyor: ferhatatagun.github.io/skor24. Kaynak kod açık: github.com/ferhatatagun/skor24.

Skorlama ve düzeltme sürecinin finansal okuryazarlık açısından daha geniş anlatımı için: ferhatatagun.com/blog/bir-odeme-karari-skoru-122-puan-oynatti

Top comments (0)