Open Source

Apache SPARK ile Öneri Sistemleri – Spark Recommendation System – Bölüm 1

Spark ile en küçük kareler yöntemini (ALS) kullanarak bir öneri uygulamasını gerçekleştireceğiz. Bunun içinde öncelikle bir rating.csv isimli veri seti elimizde mevcut ve bizler bu veri seti üzerinde çalışmalarımızı sürdüreceğiz.

Çalışmalarımızı gerçekleştireceğimiz veri setlerini aşağıda bulunan link üzerinden indirebilirsiniz.

http://tinyurl.com/y3a34bse

Uygulamamızı geliştirirken Jupyter notebook üzerinde python kullanarak gerçekleştireceğiz.

Öncelikle Jupyter Notebook üzerinde yeni çalışma başlatırıyoruz. Bu çalışmalarımızın tamamını ise Spark üzerinde gerçekleştireceğimiz için platformumuzda bir spark oturumunu oluştururak çalışmamıza başlayacağız.

from pyspark.sql import SparkSession

spark = SparkSession \

    .builder \

     .appName(‘Film Oneri Application-Yenal’) \

     .getOrCreate()

rawData = spark.read \

            .format(‘csv’) \

            .option(‘header’, ‘true’) \

            .load(‘../datasets/movielens/ratings.csv’)

Standart spark uygulamasını ise SparkSession ile başlatacağız ve yine elimizde olan rating.csv datasını spark ortamına vererek işleme başlıyoruz. Spark.read ile csv dosyasımızı ve ilgili kaynak dosyamızın pathini vererek artık mevcut datamızı bir data frame içerisine aldık.

Almış olduğumu ve data frame içerisine verdiğimiz datamızı toPandas().head() fonksiyonumuz ile çağırıyor ve oluşturmuş olduğumuz bu data frame’i görüntülüyoruz.

Datamızı inceldiğimizde kullanıcı bilgisi, film bilgisi, o filme ait olan derecelendirilmesi ve bir zaman damgası olduğunu gördük.

Şimdi ise elimizde bulunan dataları sayısal forma dönüştüreceğiz ve yeni bir data frame içerisine alacağız. Alırken bu dataları zaman damgası isimli kolonu data frame dışında bırakacağız çünkü bizlerin öneri sistemimiz içerisinde zaman damgasını kullanmayacağımız için dışarıda bırakacağız. Kullanılmayacak olan kolonlarımızı data frame ‘ler içerisinde bulundurmakta özellikle herhangi bir hesaplama ve algoritma içerisinde kullanılmayacaksa son derece gereksiz bir yük oluşturur. Bu sebeple kullanılmayacak olan kolonları mümkün olduğu kadar dışarıda bırakacağız.

Bu arada spark üzerinde çalışırken sürekli olarak bir data frame yapısından bahsediyoruz ve bir sonraki yapılacak bir veri işlemesi ya da veri dönüştürülmesi işlemleri sonrasında yeni bir data frame oluşturduğumuzu göreceğiz. Bunun nedeni Spark oturumunda gelen her bir veri bir RDD yani data frame yapısı içerisine girer ve bu data frameler değiştirilemezdir. Eğer ki mevcut gelen data herhangi bir değişime ya da filtrelemeye gidecek ise o data frame içerisinden alınan data başka bir data frame içerisine alınarak devam eder. Bu konuyla ilgili farklı bir makale ile detaylıca bahsedeceğim. 

Bunun için ;

from pyspark.sql.functions import col

dataset = rawData.select(col(‘userId’).cast(‘int’),

                        col(‘movieId’).cast(‘int’),

                        col(‘rating’).cast(‘int’)

                        )

dataset.toPandas().head()

Ekran görüntüsünde de görüldüğü gibi rawData ‘mız içerisinde select fonksiyonunu kullanarak bir önceki data frame içerisinde ilgilendiğimiz ve kullanacağımız kolonları aldık. Bununla birlikte elimizdeki veri numerik bir veri olsa da yine bunu sayısal forma dönüştürerek yeni bir data frame içerisine aldık. Yeni oluşturduğumuz bu data frame ‘i görüntülemek için toPandas().head() fonksiyonunu kullandık ve yeni data framemizi görüntüledik.

Şimdi bir sonraki adımda mevcut verileri keşfedeceğiz. Bunun için derecelendirme alanını inceleyerek dağılımları gözlemleyelim. Yani elimizdeki veriyi anlayacağız. Bunun için ilgilendiğimiz kolon için describe() metodunu çağıracağız ve o kolona ait detaylı verileri alacağız.

dataset.select(‘rating’).toPandas().describe()

Görüldüğü gibi ilgilendiğimiz kolona ait verilerden satır sayısı, ortalama değerler, standart sapma, minimum ve maksimum değerler gibi verileri anladık. Özetle puanlamanın 0 – 5 arasında olduğu toplam kayıt sayımızın 100.000 olduğunu ve puanlamanın ortalama değerinin de 3.416 olduğunu gördük.

Evet sıra algoritmamız için kullanacağımız bu data frame verilerini RandomSplit yöntemini kullanarak bölme işlemini gerçekleştirmeliyiz. Yani train ve test datalarının oranlarını vererek data içerisinde random olarak iki adet data frame daha oluşturmasını sağlayacağız.

(trainingData, testData) = dataset.randomSplit([0.8, 0.2])

randomSplit([0.8 , 0.2]) olarak tanımladık. Yani elimizde ki data frame’in %80 oranında train için kullanılacak kalan %20 lik kısım ise mevcut algoritmamızın testi için kullanılacak.

Uygulamamızı geliştirirken anlattığımız matrisler ve matrislerin çarpımı gibi matematiksel işlemler olmayacak. Bu işi bizlere ALS kütüphanesi sağlayacak.

from pyspark.ml.recommendation import ALS

als = ALS(maxIter=5,

          regParam=0.1,

          userCol=’userId’,

          itemCol=’movieId’,

          ratingCol=’rating’,

          coldStartStrategy=’drop’)

Aslında ALS modelimizi eğitmek için kullanılan bir tahminleme kütüphanesi diyebiliriz. Ağırlıklı ALS eğitim verilerinde aşırı yüklenmeyi önlemek için regParam parametresi ile ağırlıklı regülasyonu kullanırız. Burada bizler 0.1 değerini kullandık. Bunun dışında kullanıcı bilgileri için kolonları, itemCol içerisine ise derecelendirmeleri kullanıcılar tarafından yapılmış ürünlerin bulunduğu kolon ismini belirtiriz. Bizim örneğimizde film datası üzerinde çalıştığımız için movieId kolonunu kullandık. Bunun dışında ALS  algoritması tarafından kullanılacak olan derecelendirme bilgisini de tanımlıyoruz.

Burada bir diğer önemli parametremizde Cold stratejimizdir. Yani eğer ki algoritmamız çalşırken yeni bir kullanıcı ya da yeni bir ürün ile karşılaşırsa davranışının ne olacağını tanımlıyoruz. Bizler burada böyle bir satır ile karşılaşırsa o satırı drop etmesini istediğimizi belirtiyoruz.

Şimdi ise elimizde son haline getirdiğimiz data frame mimizi yine bizim ALS algoritması için gerçekleştirdiğimiz tanımlarla eğitilmesi için yeniden ALS algoritmasına veriyoruz.

model = als.fit(trainingData)

ALS algoritmasına eğitim için vereceğimiz data daha öncede RandomSplit() yöntemi ile ayırdığımız %80 lik verimizi als.fit(trainingData) ile veriyoruz.

Elimizde artık eğitilmiş bir model bulunmakta. Sahip olduğumuz eğitilmiş modelimizi artık test için yine randomSplit() metodu ile ayırmış olduğumuz %20 lik datamız üzerinde gerçekleştireceğiz.

Bunun için model.transform(testData) komutlarını kullanacağız.

predictions = model.transform(testData)

predictions.toPandas().head()

Evet yukarıda artık %20 lik test datasına uygulanmış ve predictive edilmiş halini gözlemliyoruz.  Algoritmamızın eğitildiği giriş verilerine göre kullanıcılarımızın belirli filmlere atayacağı ya da değerlendirmelerini tahminledik ve gördük. Bu tahmin değerleri ise aslında bizim derecelendirme matrisimizin öğeleridir.

Şimdi bu verilerimizin içerisinde rating ve prediction verilerimizi describe() metodumuz ile inceleyerek ilgili değerleri gözlemleyelim ve yorumlayalım.

predictions.select(‘rating’, ‘prediction’).toPandas().describe()

Görüldüğü gibi karşılaştırmaları yaptığımızda değerlerin çok yakın olduğunu görebiliriz. Burada bir tek dikkat çekici nokta max değerinin predictive edilen datamızda 5.5 olduğudur. Bununda nedeni predictive edilen rating verisinde 5 ile bir sınırlandırılacağını belirten bir kısıt koymadığımızdan kaynaklanmaktadır.

Şimdi son adım olarak eğitilmiş olan algoritmamızın test datasına uygulandığında doğruluk oranını da görmemiz gerekmekte bunun için ise ;

from pyspark.ml.evaluation import RegressionEvaluator

evaluator = RegressionEvaluator(metricName=’rmse’,

                                labelCol=’rating’,

                                predictionCol=’prediction’)

rmse = evaluator.evaluate(predictions)

print(‘RMSE = ‘, rmse)

Eğitilmiş olan datamızın ya da algoritmamızın doğruluk oranını RegressionEvaluator ile görmek için yukarıda da belirttiğimiz pysaprk ml kütüphanesinden Evalator kullandık. Daha sonra rating kolonumuz ve predictive için tanımlamış olduğumuz alanların oranına baktığımız %95 oranında bir doğruluğun olduğunu gördük. İşte ALS ile yani alternatif en küçük kareler (ALS) algoritması için oldukça yüksek bir orana ulaşmış olduk.

Bu makale serimizin birinci bölümünde mevcut veri setlerimizi anlamlandırdık ve bu veri setimizin normalleştirilme işlemlerini gerçekleştirdik. Daha sonra ALS algoritmamız ile normalleştirilmiş olan datamızı train ve test datalarına bölerek algoritmamızın ne kadar doğru çalıştığını gözlemledik. Bir sonraki makalemizde ise bu tahminlemiş verileri kullanıcılarımıza ne şekilde öneri olarak sunacağımızı ve bunu nasıl yapmamız gerektiği konusunda çalışmalarımızı sürdüreceğiz.

İlgili Makaleler

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Başa dön tuşu