Merhaba, bilindiği üzere bitcoinin fiyatı çıkan yeni haberlere göre (Çin bitcoini yasakladı, Amerikan bankaları bitcoin alımını yasakladı … ) değişkenlik gösterebiliyor.Bugün bitcoin hakkında atılan tweetlerin sınıflandırılmasıyla bitcoinin duygu analizini python ile nasıl gerçekleştirebileceğimizden bahsedeceğim.
Öncelikle tweetleri toplayabilmek için tweepy kütüphanesinden faydalanmamız gerekiyor.Daha önceki yazılarımdan birinde tweepy ile nasıl veri çekebileceğimizden bahsetmiştim, ilgili yazıya buradan ulaşabilirsiniz.
from tweepy import Stream from tweepy import OAuthHandler from tweepy.streaming import StreamListener import time import json import tweepy consumerKey="xxxx" consumerSecret="xxxx" accessToken="xxxx-xxxx" accessSecret="xxxx" class listener(StreamListener): def on_data(self, data): all_data = json.loads(data) tweet = all_data["text"] try: print(tweet) except: pass time.sleep(0.3) return(True) def on_error(self, status): print (status) def main(): auth = OAuthHandler(consumerKey, consumerSecret) auth.set_access_token(accessToken, accessSecret) while True: twitterStream = Stream(auth, listener()) twitterStream.filter(track=["bitcoin"], async = True, stall_warnings=True) time.sleep(6000) twitterStream.disconnect() if __name__ == "__main__": main() |
Yukarıdaki kod ile bitcoin hakkında atılan tweetleri çekebiliyoruz.Şimdi gelecek tweetleri sınıflandırmamız lazım, ben 3 tür sınıfa ayırmayı uygun gördüm.Olumlu tweetler için “pozitif”, olumsuzlar için “negatif” ve duygu içermeyenler için nötr (“Bitcoin price: 11.000 USD” gibi).
Sınıflandırma için ise naive bayes algoritmasını kullandım.Algoritmayı TextBlob kütüphanesinden faydalanarak kullanabiliriz.
from textblob.classifiers import NaiveBayesClassifier from textblob import TextBlob |
Algoritmadan faydalanmak için öncelikle onu beslememiz gerekiyor.Bunun için pozitif,negatif ve nötr olan tweetler bularak ayrı ayrı dosyalara yazdım, diziye atayarak train verisi olarak ekledim.
Ayrıca sonuçların ne kadar etkili olduğunu test edebilmek için aynı şekilde test verilerini de ekledim.
def getData(filename,group,arr): for i in open(filename): example_sent = i.rstrip('\n') word_tokens = word_tokenize(example_sent) arr.append([word_tokens , group]) |
def main(): auth = OAuthHandler(consumerKey, consumerSecret) auth.set_access_token(accessToken, accessSecret) train = [] test = [] getData('data/pos.txt', 'pos',train) getData('data/neg.txt', 'neg',train) getData('data/neut.txt', 'neut',train) getData('data/test/testNeut.txt', 'neut',test) getData('data/test/testPos.txt', 'pos', test) getData('data/test/testNeg.txt', 'neg', test) global cl cl = NaiveBayesClassifier(train) while True: print(cl.accuracy(test)) twitterStream = Stream(auth, listener()) twitterStream.filter(track=["bitcoin"], async = True, stall_warnings=True) time.sleep(6000) twitterStream.disconnect() |
Ardından gelen tweetleri hemen sınıflandırmaya sokarak pozitif veya negatif olmasına göre sayaca +1/-1 puan ekleyerek gelecek verilerden bir grafik elde etmeyi düşündüm. Matplotlib ile verileri görselleştirerek daha hoş bir inceleme yapılabilir.
Ayrıca sınıflandırılacak tweetlerin farklı dillerde olabiliyor olması sıkıntı oluşturuyordu.Bu yüzden sadece ingilizce atılan tweetleri kullanmaya karar verdim.TextBlob kütüphenesi içerisinde detect_language() fonksiyonunu kullanarak ingilizce tweetleri ayıkladım.
import matplotlib.pyplot as plt |
class listener(StreamListener): x = 0 y = 0 def on_data(self, data): all_data = json.loads(data) tweet = all_data["text"] analysis = TextBlob(tweet) try: if analysis.detect_language() == 'en': if analysis not in check: print(tweet,cl.classify(filtered_words)) check.append(analysis) if cl.classify(tweet) == 'pos': listener.y += 1 elif cl.classify(tweet) == 'neut': pass else: listener.y -= 1 plt.ion() listener.x += 1 # x ekseni plt.scatter(listener.x,listener.y) plt.pause(0.05) else: pass except: pass |
Gelen tweetlerde filtrelemeler yaparak (Gereksiz kelimeleri kaldırma (he,she,do,herself …), Tweet içerisindeki url ve etiketleri kaldırma) başarı oranını artırdım.Çok sayıda bot hesap sürekli olarak belirli tweetleri retweet yaptığı için retweet olanları da işleme almadım.
class listener(StreamListener): x = 0 y = 0 def on_data(self, data): all_data = json.loads(data) tweet = all_data["text"] tweet = re.sub(r"http\S+", "", tweet) analysis = TextBlob(tweet) stop_words = set(stopwords) filtered_words = set(analysis.words.lower()) - stop_words for i in set(filtered_words): if i[:1] == '@': set(filtered_words).remove(i) try: if analysis.detect_language() == 'en': if analysis[:2] == 'RT': pass else: if analysis not in check: print(tweet,cl.classify(filtered_words)) check.append(analysis) if len(check) > 10: del check[:] if cl.classify(tweet) == 'pos': listener.y += 1 elif cl.classify(tweet) == 'neut': pass else: listener.y -= 1 plt.ion() listener.x += 1 plt.scatter(listener.x,listener.y) plt.pause(0.05) else: pass except: pass time.sleep(0.3) return(True) def on_error(self, status): print (status) |
Ve sonuçlar aşağıdaki gibi oldu. Tabi ki veriler genişletildiğinde oran değişebilir.


Kodların tamamına github üzerinden ulaşabilirsiniz.
İlk Yorumu Siz Yapın