Elo Derecelendirme Sistemi
Sosyal Ağ filmini izlediğimde beni en çok etkileyen sahnelerden birisi Mark Zuckerberg’in okulu hacklediği, insanların fotoğraflarını alıp facemash adında fotoğraflarını kıyaslandığı bir site yaptığı sahneydi. O sahnede bana ilginç gelen arkadaşı Eduardo Saverin’den satranç turnuvasında kullandığı algoritmayı istemesiydi. Algoritma sayesinde insanların fotoğraflarını derecelendirebilecekti. Arkadaşı Eduardo’da yurt odalarında ki pencereye istediği algoritmayı yazdı. Film bittikten sonra bu algoritmanın tam olarak ne olduğunu bilmediğim için birkaç araştırma yaptım ve adının Elo Derecelendirme Sistemi(Elo Rating System) olduğunu öğrendim. Öğrendiklerimi küçük bir örnek ile burada paylaşmaya karar verdim.
Nedir?
Elo derecelendirme sistemi satranç gibi sıfır toplamlı oyunlarda oyuncuların yetenek seviyelerinin hesaplanmasında kullanılmakta. İsmini de yaratıcısı Macar-Amerikan fizikçi Arpad Elo’dan almakta.
Elo sistemine göre daha yüksek skora sahip oyuncular daha fazla kazanma oranına sahip. Daha düşük değerler için ise tam tersi geçerli.
Her eşleşmede oyuncuların skorları güncellenir. Eğer yüksek oranlı bir oyuncu kazanırsa düşük oranlı oyuncudan kendisine az puan transfer edilir. Olur da tam tersi olursa daha düşük oranlı oyuncuya çok daha fazla puan transfer edilir.
Formül
Oyuncu A için kazanma oranı aşağıda ki formül ile hesaplanır. RB değeri Oyuncu B’nin yani rakibin skorudur. RA ise oyuncu A’nın skorudur.
Oyuncu B için ise aynı formül aşağıda ki gibidir.
EA ve EB nin toplam değerleri 1'e eşittir.
Oyuncuların puanlarının güncellenmesi.
SA oyuncunun var olan skordur(kazanılan durum için 1, kaybedilen durum için 0). EA ise bir önceki formülde hesaplanan beklenen değerdir.K ise “K Faktörü” olarak bilinir değeri sabittir. 0 dan büyük herhangi bir değer verilebilir. Değerinin kaça sabit olması gerektiğini dair genel bir kural yoktur. Büyük haneli sayılar verildiğinde değişimin değeri büyük olur.
Örnek
Önceden seçmiş olduğum filmlere birer puan(puanlar imdb puanlarının 1000 katı 7,8=>7800) vererek bu filmler ana sayfada azalan şeklinde sıralancak. Elo Derecelendirme algoritması filmlerin puanlarını kullanacak. Oylama sayfasında ise filmler ikili kombinasyonları alınarak eşlenmesi sağlanacak. Bu sayede her film başka bir film ile eşleşmiş olacak. Oylama işlemi bittiğinde uygulama bizi ana sayfaya geri yönlendirecek.
Kodlama
Bu projeyi oluştururken kullanılan teknolojiler Dotnet Core ve Angular.
Dotnet Core ile bir api projesi oluşturuyorum daha sonra Models klasörü altında filmleri veri tabanında tutmak içim Movie
isminde bir model oluşturyorum. Modelimin alanları aşağıda ki gibidir.
Score
alanı filmlerin puanlarının tutulduğu alan. Sıralamada ve hesaplamada bu alanı kullanacağız.
Veritabanında filmleri okuma ve güncelleme işlerini yaptığım Repository sınıfı
Derecelendirme işlemlerini yapmak için IRatingService arayüzünden türettiğim EloRatingService sınıfı.
Probability
ilgili puanlara göre kazanma oranlarını hesaplayan fonskisyonumuz.Rate
metodu hesaplama işlemini yapacak olan fonksiyon.
Uygulamamızın haberleşeceği api için MoviesController
aşağıda ki gibidir.
Get
fonksiyonu ile veri tabanında olan filmleri döndürüyorum. Rate
fonksiyonu ile kıyaslaması yapılan filmleri gönderiyorum.
MoviesController altında Rate metodumun RateViewModel
aşağıda ki gibidir. Filmlerin idleri gönderilmesi yeterlidir.
Gelelim uygulamamızın client tarafına. Angular ile oluşturduğum projeye home
ve vote
isminde iki component oluşturuyorum. Home componenti Api’den gelen filmleri Score
alanlarına göre artan olarak sıralamakta. Sayfa içerisinde vote anchor'u
ile Vote component’e yönlendirme yapmakta.
Vote component ve Home component api ile haberleşmek için movieService sınıfını kullanmakta.
getAll
ile apiden filmlerimi çekiyorum. rate
ile api’ye seçili filmleri gönderiyorum.
k_combinations(this.movies,2)
methodu ise bu gistten faydalandığım bir typescript extensionı. Bu extension ile dizilerin kombinasyonlarını alıyorum.
Vote componentimde ngOnInit()
içerisinde önceden yazmış olduğum movieService ile filmlerin kombinasyonlarını çekiyorum. Dönen koleksiyonu shuffle()
fonksiyonu ile karıştırıyorum.
Vote component içerisinde nextVote
fonksiyonu ile kombinasyonların tutulduğu koleksiyondan shift
ile ilk elementi çıkararak sonraki kombinasyonu ekranda görüntülüyorum.
choose
fonksiyonunu aşağıda ki gibi filmlerin gösterildiği divlere click eventine bind ediyorum. Bu sayede seçilen,beğenilen filme erişebiliyorum.
Beğenilen, seçilen filme tıklama ile erişebildiğim gibi HostListener
dekoratörü sayesinde sağ veya sol ok tuşları ile seçili değeri alabiliyorum.
Bundan sonraki kısım projenin yayınlanması ile ilgili dilerseniz bu link üzerinden örneğe ulaşabilirsiniz.
Yayınlama
Oluşturduğum Dotnet Core projesi heroku üzerinde çalışmakta bunu sağlamak için de bu yazıdan yararlandım.
Ayrıca heroku uygulamama şu build packi ekledim.
Projenin içerisine dockerfile
oluşturup kullanacağım imajı belirttim. Benim projemde dotnetcore ile angular birlikte olduğu için dotnet buildi sırasında npm hatası alıyordum. Bu hatayı gidermek için dockerfile içerisinde npm’i yükledim.
Projenin bulunduğu repoya actions kurduktan sonra on:push:branches
altına master branchını ekledim. Bu sayede master brancha atılan her committe bu workflowun çalışmasını sağladım. Aynı wokrflow dosyası içerisinde secret parser’ı da kullandım böylece canlıda kullandığım connection string’i github secrettan çekerek appsettings.json
içerisinde değiştirdi.
Bütün bu işlemlerden sonra projemiz hazır.
Örnek link
Yararlanılan Kaynaklar