Bloğa geri dön

Spark kullanarak Twitter Duygu Analizi

Spark kullanarak Twitter Duygu Analizi

Bir önceki yazımızda, gerçek zamanlı Twitter verilerini Apache Flume kullanarak ayıklamanın bir yolunu bulmuştum. Şu anda Twitter'dan çok fazla veri elde ettim. Bu nedenle, bu verileri analiz etmek ve bunlardan bazı trendler çıkarmak istiyorum. Twitter verilerinin duygu analizini gerçekleştirmek için başka bir Büyük Veri aracı olan Apache Spark.

Göre: Hortonworks, “Apache Spark, veri çalışanlarının veri kümelerine hızlı yinelemeli erişim gerektiren akış, makine öğrenimi veya SQL iş yüklerini verimli bir şekilde yürütmelerine olanak tanıyan zarif ve ifade gücü yüksek geliştirme API'lerine sahip hızlı, bellek içi bir veri işleme motorudur. Spark'ın Apache Hadoop YARN üzerinde çalışmasıyla, her yerdeki geliştiriciler artık Spark'ın gücünden yararlanmak, içgörüler elde etmek ve Hadoop'taki tek bir paylaşılan veri kümesi içinde veri bilimi iş yüklerini zenginleştirmek için uygulamalar oluşturabilirler.”

Bir Spark programı JAVA, Scala, Python veya R dillerinde yazılabilir. Bu durumda, şununla birlikte JAVA kullanacağız: Maven. Ek olarak Spark, hem HDP hem de Cloudera dağıtımıyla birlikte gelir. Spark 2 şu anda kullanılan sürümdür.

Spark ile duygu analizini gerçekleştirmek için yeni bir Maven projesi oluşturuyorum. Adını 'Twitter Sentiment Analyzer’ koyuyorum. Ardından, gerekli tüm yöntemleri uygulayacağım “TwitterDataFlow.java” adında bir sınıf oluşturuyorum.

Dil Aracı: Yazım Düzeltici

Başlangıçta, POC'ta, tweet'lerdeki yazım yanlışsa Duygu Analizi sonuçlarının olumsuz etkilendiğini gördüm. Bu nedenle, bir SpellChecker (Yazım Denetleyicisi) tanıtıyorum. Bu, tweet'leri Duygu Analizi için kullanmadan önce yazımlarını düzeltmemize yardımcı olacak.

Bunu ‘CorrectSpell’ adında yeni bir statik yöntem oluşturarak yapacağım. Ayrıca, yazımları kontrol etmek ve düzeltmek için bir LanguageTool kullanacağım.

Göre: LanguageTool’un GIT'i, “LanguageTool; İngilizce, Fransızca, Almanca, Lehçe, Rusça ve 20'den fazla diğer dil için açık kaynaklı bir düzeltme okuma yazılımıdır. Basit bir yazım denetleyicinin tespit edemediği birçok hatayı bulur.”

Ardından, pom.xml dosyasına dil aracı için bir bağımlılık ekliyorum:

<dependency>
<groupId>org.languagetool</groupId>
<artifactId>language-en</artifactId>
<version>4.0</version>
</dependency>

Bundan sonra, JLanguageTool sınıfından statik bir sınıf düzeyi değişkeni olan langTool'u tanımlıyorum. Ardından, langTool'u AmericanEnglish sınıfından bir nesne ile başlatıyorum.

Ardından, girdi olarak String text (normal metin) ve dönüş türü olarak da String (Doğru Yazımlı Metin) alan SpellChecker adlı yöntemi kodluyorum. JLanguageTool'un check yöntemini, parametre olarak denetlenmemiş metin ile kullanıyorum. Sonrasında, bu yöntem bir RuleMatch listesi döndürür. JLanguageTool Java Belgelerine göre, RuleMatch sınıfı şunları sağlar: “metinle eşleşen bir hata kuralı ve eşleşmenin konumu hakkında bilgi.”

Bunu takiben, String türünde ‘result’, tamsayı (integer) türünde ‘lastPos’ ve String türünde ‘tmp’ olmak üzere üç değişken tanımlıyorum. Ek olarak, her RuleMatch ile, araçtan gelen ilk önerilen yazımla cümleyi yeniden oluşturuyorum. Bununla birlikte, gereken her yere gerekli try-catch bloklarını ekledim.

 

Duygu Analizörü: Stanford CoreNLP

Spark ile duygu analizindeki bir sonraki adım, metinden duyguları bulmaktır. Bunu yapmak için, duygu değerlerini bulmak üzere Stanford’un Core NLP Kütüphanesini kullanıyorum. Ardından, metnimizdeki duyguları bulmak için kütüphaneyi uygulayacağım ‘StanfordSentiment’ adında bir sınıf oluşturuyorum.

Bunu yapmak için, pom.xml dosyasına aşağıdaki bağımlılıkları ekliyorum:

<!– Bu, stanford Core NLP Kütüphanesidir –>
<dependency>
<groupId>edu.stanford.nlp</groupId>
<artifactId>stanford-corenlp</artifactId>
<version>3.8.0</version>
</dependency>

<!– Bu, stanford Core NLP’nin modeller dosyasıdır –>
<dependency>
<groupId>edu.stanford.nlp</groupId>
<artifactId>stanford-corenlp</artifactId>
<version>3.8.0</version>
<classifier>models</classifier>
</dependency>

Stanford Core NLP’nin işlem hattı için özellikleri tanımlayan statik bir nesne değişkeni olan ‘props’u oluşturuyorum. Mümkün olduğunca hafif olması için minimum özellikleri seçtim. Bundan sonra, annotator'ları tokenize, ssplit, pos, parse, sentiment olarak ayarlıyorum. StanfordCoreNLP sınıfından başka bir statik nesne değişkeni olan ‘pipeline’ı oluşturuyorum. Son olarak, işlem hattını ‘props’ özellikleri ile başlatıyorum.

GetSentiment:

Girdisi String ve çıktısı Double olan GetSentiment adında bir metot oluşturdum. LanguageCheck.java dosyasında oluşturduğum CorrectSpell metodunu kullanıyorum. LanguageCheck nesnesinin CorrectSpell metodu bana girilen tweet'in doğru yazılışını döndürüyor. Bu düzeltilmiş metinle StanfordCoreNLP'nin annotate metodunu kullanıyorum. Bu kütüphane tarafından verilen duygu değerleri şunlardır:

0 => çok olumsuz

1 => olumsuz

2 => nötr

3 => olumlu

4 => çok olumlu

 

Aşağıdaki yeni Duygu kategorilerini elde etmek için cümle başına sonucu 2 çıkarıyorum:

-2 => çok olumsuz

-1 => olumsuz

0 => nötr

1 => olumlu

2 => çok olumlu

 

Her bir tweet'in duygu sonucunu, tweet'teki her bir cümlenin duygusunun ortalaması olarak döndürüyorum. Tweetler yapılandırılmış bir biçimde yazılmaz. Bu nedenle, bir tweet'in belirli bir satırına diğerlerinden daha yüksek bir ağırlık atayamam. Dolayısıyla, bir tweet'teki her satırın eşit öneme sahip olduğunu varsayıyorum. Tweet'in nihai duygu değerini içeren Double türündeki ‘total’ değişkenini döndürüyorum.

 

Program Başlatma:

Bu iki sınıf tamamlandığına göre, bunları kullanmak üzere ilerleyeceğiz. Bu nedenle, yeni bir sınıf olan “TwitterDataFlow.java” dosyasını oluşturuyorum. İlk olarak, yalnızca geçirilen girdi argümanlarının sayısı tam olarak 2 olduğunda programı çalıştıracak koşullu bir kontrol yazıyorum. Argüman sayısı 2'ye eşit değilse, yanlış kullanım mesajını yazdırır ve ayrıca 1 çıkış durumuyla sonlanır.

Uygulama adı Sentiment Analyzer olan bir SparkSession oluşturuyorum. Spark context’in hadoop yapılandırmasının “mapreduce input fileinputformat input dir recursive” özelliğini true olarak ayarlıyorum. Bu, klasörlerden dosyaları özyinelemeli olarak almama olanak tanıyacak. Girdi argümanının yanı sıra Flume tarafından depolanan bölümlenmiş verileri okumamı sağlayacak olan ‘/*/*’ ifadesini de atadığım String sınıfından bir ‘inputPath’ değişkeni oluşturuyorum. Flume'un json verilerini Dataset<Row> ‘data’ içinde okuyorum.

Ardından, Spark SQL Context ile bir String alan ve üzerinde StanfordSentiment’in GetSentiment yöntemini uygulayarak Double değer veri türü döndüren ‘Sentiment’ adında bir UDF (Kullanıcı Tanımlı Fonksiyon) kaydediyorum.

Şu anda flume'dan Apple, Google, Tesla, Infosys, TCS, Oracle, Microsoft ve Facebook anahtar kelimelerine ait verilere sahibim. Bu yüzden, bu anahtar kelimelerle bir String listesi oluşturuyorum. Bu şirketlerin her biri için aşağıdaki işlemleri çalıştırıyorum.

İşlem akışı:

İlk olarak, sonuçları kaydetmek istediğim bir outPath oluşturuyorum. ‘data’ veri kümesi üzerinde geçici bir görünüm olan ‘complete’ oluşturuyorum. Ardından, verilerden timestamp, partitionBy (sonuçları kaydederken verileri bölümlemek için), text, main_text (düzenli ifadeler için kullanmak üzere) ve followers bilgilerini çıkarıyorum.

Sonuçlar üzerinde geçici bir görünüm oluşturuyorum ve oradan belirli bir şirketin verilerini filtreliyorum. Ayrıca, bana ‘seVal’ sütunundaki duygu değerlerini döndüren Sentiment UDF'sini uyguluyorum. Serileştirilmiş verileri bellekte ve disk taşması olarak kalıcı hale getiriyorum. Bu verilerden, Takipçi Sayısı ile o tweet'in Duygu Değeri'nin çarpımı olan NetSentiment değerini elde ediyorum. Bu, o tweet'in sahip olabileceği etkiyi bilmeye yardımcı olur. Bunun için farklı formüllerim olabilir.

Duygu analizi hesaplama açısından yoğun bir görev olduğundan, tüm sonucun depolanmasını istediğimiz için serileştirilmiş verileri bellekte ve diskte kalıcı hale getiriyoruz. Bunu kalıcı hale getirmezsek ve NetSentiment veya etkiyi hesaplamak için birden fazla formül kullanmayı planlarsak, Sentiment yönteminin değerini birden çok kez kullanacağımız önceki sorguda, tweet'in Duygu Analizini birden çok kez yapacaktır.

Veri gruplama:

Şimdi, verileri timestamp ve partitionBy sütununa göre gruplandırıyorum ve bu gruplandırma ile NetSentiment ortalamasını alıyorum. Bu bana şirketin belirli bir dakikadaki olumlu veya olumsuz ortalama etkisini veriyor. Sonuç olarak, her şirket için sonuçları partitionBy sütununa göre bölümlendirerek outPath içine yazıyorum.

Ayrıca, kod tamamlandıktan sonra, içindeki tüm bağımlılıklarla birlikte çalıştırılabilir bir jar dışa aktarıyorum ve bunu bu işi çalıştırmak istediğim sunucuya kopyalıyorum. Ardından, aşağıdaki komutu kullanarak gönderebilirim,

burada (Kaynak):

  • --master: Küme için master URL (örneğin spark://23.195.26.187:7077)
  • --deploy-mode: Sürücünüzün (driver) çalışan düğümlerde (küme) mi yoksa yerel olarak harici bir istemci (istemci) olarak mı dağıtılacağı (varsayılan: istemci)
  • uygulama-jar: Uygulamanızı ve tüm bağımlılıkları içeren paketlenmiş bir jar dosyasının yolu. URL'nin kümeniz içinde küresel olarak görünür olması gerektiğini göz önünde bulundurun, örneğin tüm düğümlerde mevcut olan bir hdfs:// yolu veya bir file:// yolu.
  • uygulama-argümanları: Varsa, ana sınıfınızın ana metoduna iletilen argümanlar. Burada, giriş ve çıkış yolu

Son Adımlar:

Ardından, Spark kullanarak yapılan duygu analizinin sonuçlarını çıkış yolundan alacağız. Örneğin, apple için olası bir sonuç şöyledir:

{“timestamp”:”Apr 30 2018 20:31:00″,”avg(NetSentiment)”:-3678.768518518518}
{“timestamp”:”Apr 30 2018 20:32:00″,”avg(NetSentiment)”:-883.002824858757}

Bu uygulamayı 5 düğümlü bir HDP kümesi ile CloudSigma üzerinde dağıttım. Özellikle, her bir düğüm aşağıdaki yapılandırmaya sahipti:

256 GB SSD
16 GB RAM
20 GHz CPU

Sonuç olarak, Spark kullanarak yapılan duygu analizinden yaklaşık 19 saat içinde sonuç alabildim. Ayrıca, 80+ GB'lık bir veri kümesi üzerinde programdan daha gelişmiş hesaplamalar ekledim.

Kod şurada bulunabilir: GITHUB.

 

author

Akshay Nagpal

Yazar · CloudSigma

Preslav Dobrev, CloudSigma'da Kreatif Tasarımcı olarak görev yapmakta olup geleneksel ve yenilikçi pazarlama kanallarını kullanarak tutarlı bir kurumsal kimlik oluşturmaya odaklanmaktadır. Sanatsal vizyonu stratejik pazarlamayla harmanlayarak etkili marka anlatıları oluşturma konusunda oldukça yeteneklidir.

Yorumlar

Henüz yorum yapılmamış. İlk siz olun.