Pyspark-Sms Spam Detection
Merhaba arkadaşlar ,
Bugün ki konumuz Pyspark ile Sms spam algılayıcı yapmak olacak.Bu proje için internette bulunan Sms Spam Detector csv dosyasını kullanıcam. Ortam olarak Jupyter Notebook kullanıcam.
Pyspark ile kodlamaya başlarken ilk yapmanız gereken tabiki bir Session oluşturmaktır, daha sonra ise ML İle ilgili kodlarınızı yazmanız gerekir.Projemizin adını appName ile nlp-sms koyuyoruz.
from pyspark.sql import SparkSession
spark=SparkSession.builder.appName(“nlp-sms”).getOrCreate()
Verimiz bir csv dosyası olduğu için read.csv methoduyla dosyamızı içeri import edip seperator olarak tab kullanıyoruz.
data=spark.read.csv(“/home/os/Desktop/SMSSpamCollection.csv”,inferSchema=True,sep=”\t”)
Bu noktadan sonra importun sorunsuz gerçekleştiğini anlamak için.
data.show() yaparak veriyi görüntülemekte yarar var.
Verimizde sutun isimleri biraz saçma gibi onları değiştirelim.
data=data.withColumnRenamed(‘_c0’,’class’).withColumnRenamed(“_c1”,”text”)
Sutun isimlerimiz class ve text olarak değişti. Dilerseniz bir kontrol edelim. Yine aynı komutu yazıyoruz : data.show()
Bir smsin spam olup olmadığını anlamak için o smsin uzunluğuda bizim için iyi bir özelliktir.Onun için sms uzunluğunu bulan bir kod yazıyoruz ve bunu verimize ekliyoruz.
from pyspark.sql.functions import length
data=data.withColumn(“length”,length(data[‘text’])) #length adında yeni sutun oluştur.
Uzunluğun gerçekten önemini göstermek için şu kodu yazarsak anlayacağız.
data.groupby(“class”).mean().show()
Çıktımız aşağıdaki gibi olacak. Görüldüğü gibi ham ile spam sms arasında yaklaşık 2 katı uzunluk farkı var.
+-----+-----------------+
|class| avg(length)|
+-----+-----------------+
| ham|71.45431945307645|
| spam|138.670682730923
Eğer NLP ile uğraşıyorsanız veyahut metin sınıflandırma ile uğraşıyorsanız.Kelimeleri bölme , stopwordsleri kaldırma, Count Vectorizer kullanarak vektör yaratma,IDF kullanarak kelime sıklığını bulma ve Stringİndexer kullanarak Labelları stringe çevirmeyi bilmelisiniz.
Bu noktada size bunları anlatmayacağım ama siz bu terimleri duyduğunuz için artık bir araştırma konusu olacaktır sizin için. Burada sms detector için kod yazıyoruz ve kod üzerinden anlatılarak gidilecektir detaya girmeden.
from pyspark.ml.feature import (Tokenizer,StopWordsRemover,CountVectorizer,IDF,StringIndexer)
->Tokenizer komutuyla giriş sutunumuz olan text sutununu parçalayarak tok_text sutununa yazmasını söyledik.
tokenizer=Tokenizer(inputCol=’text’,outputCol=”tok_text”)
İkinci işlemimiz stopwords kelimeleri kaldırma yani şöyle söyleyelim bir dilde bir anlam ifade etmeyen kelimeler. İngilizce’de örnek vermek gerekirse the, I , and gibi Türkçe’de ise ama,fakat,bu gibi kelimeler stopwordsler arasındadır.
Aşağıdaki kod bize bunu sağlıyor.Bu sefer inputColdaki değere dikkat edelim.Tokenizer dan çıkan parçalanmış tok_text sutunu stopwords komutuna inputCol olarak giriyor ve stop_tok olarak çıkıyor.
stop_remove=StopWordsRemover(inputCol=”tok_text”,outputCol=”stop_tok”)
Artık verimizde the,and,I gibi stopwords kelimeler bulunmuyor.
Bir sonra ki işlemimiz verileri temizlediğimize göre bir vektör matrisi oluşturmaktır.Bunuda bize sağlayan CountVectorizer komutudur.
countVec=CountVectorizer(inputCol=”stop_token”,outputCol=”c_vec”)
IDF -> Ters döküman sıklığı olarak bilinir.Bir terimin diğer derlemlerde geçme sıklığını ifade eder.
idf=IDF(inputCol=”c_vec”,outputCol=”tf_idf”)
Dikkat ederseniz countvec değişkeninin çıkışını idf değişkenimizin girişine bağladık.
Artık geldik StringIndexer kullanmaya bu nokta class sutunumuzdaki veriler ham ve spam olarak ayrılıyordu ancak modellerimiz bu sutunu string olarak kabul edemez onun için stringindexer yaparak onları 0–1 moduna çeviriyoruz.
hamspam_num=StringIndexer(inputCol=”class”,outputCol=”Label”)
Eğer sparkta bir ML yapısını kurmak istiyorsanız vektörlerle çalışmaya alışmalısınız.Bizim için önemli olan iki özelliğimizi vektörsel ifadelere çeviriyoruz. Tf-idf ve length özelliğimiz bizim için önemli değerler olduğu için onları vectorsel ifadeye çeviriyoruz.
from pyspark.ml.feature import VectorAssembler
clean_up=VectorAssembler(inputCols=[‘tf_idf’,’length’],outputCol=’features’)
Algoritma olarak Bayes algoritmasını kullanacağız.
from pyspark.ml.classification import NaiveBayes
nb=NaiveBayes()
Spark’ın bir diğer teknolojisi Pipeline teknolojisidir. Yazdığım tüm değişkenleri bir Pipeline’a taşıyorum.
from pyspark.ml import Pipeline
data_pipe=Pipeline(stages=[hamspam_num,tokenizer,stop_remove,countVec,idf,clean_up])
Ve sıra geldi modelimizi eğitmeye…
cleaner=data_pipe.fit(data)
clean_data=cleaner.transform(data)
clean_data.show()
Dikkat ederseniz oluşturduğumuz pipeline üzerinden modelimizi fit ettik.
Bizim için önemli olan iki sutunu alıyoruz. label ve features #features sutunu kendi içinde 2 farklı sutundan oluşuyor,length ve tf-idf.
clean_data=clean_data.select(“label”,”features”)
clean_data.show()
Sistemimizi %70 train olacak şekilde random olarak ayırıyoruz ve Bayes modelimizi fit ediyoruz.
train,test=clean_data.randomSplit([0.7,0.3])
smsspamdetection=nb.fit(train)
Daha sonra test olarak oluşturduğumuz %30 luk veriyi sistemimize göndererek olası sonuçları görüyoruz.
test_results=smsspamdetection.transform(test)
test_results.show(100)
Elbette accuracy skorunu görmeden herşeye karar vermek olmaz. Şimdi accuracy skorunu göreceğiz.
from pyspark.ml.evaluation import MulticlassClassificationEvaluator
acc_eval=MulticlassClassificationEvaluator()
acc=acc_eval.evaluate(test_results)
print(acc)
Bende başarı : 0.9262641491794753 çıktı sizde daha farklı çıkabilir.
Yani 100 mesajdan yaklaşık 93 tanesini doğru tahmin ediyoruz. Oldukça iyi bir skor.
Bugünlük bu kadar sevgili arkadaşlar.
Son Kararlarınız Size Hep Mutluluk Versin.SEVGİYLE KALIN
Referans
https://www.oreilly.com/ideas/training-and-serving-nlp-models-using-spark-mllib