Anasayfa / Makine Öğrenmesi / Derin Öğrenme / Derin Öğrenme ile Sahte Haberlerin Belirlenmesi

Derin Öğrenme ile Sahte Haberlerin Belirlenmesi

Herkese Merhabalar! Bu yazımda sahte haberlerin belirlenmesinde derin öğrenme yaklaşımını inceleyeceğiz. Derin öğrenmeye giriş seviyesinde bir yazı demekte doğru olacaktır. Bu yazının içeriği bir önceki yazının devamı niteliğindedir. VBO için hazırlamış olduğum ilk yazımda, sahte haberlerin belirlenmesinde kullanılan makine öğrenimi algoritmalarından elde edilen sonuçlardan bahsetmiştim. Bu yazıda ise derin öğrenme yaklaşımını kullanarak ikili sınıflandırma problemini ele alacağız. Yani Sahte ve Gerçek haberler arasında ayrım yapabilen bir derin öğrenme modeli oluşturmaya çalışacağız.

Derin Öğrenme Nedir?

Derin öğrenme, makine öğrenmesinin bir alt alanıdır. Temel olarak birbirini takip eden katmanlar aracılığıyla verilerden daha anlamlı sonuçlar elde edilmesidir. Buradaki derinden kast edilen gizli, spiritüel, mistik sonuçların elde edilmesi değil, modelde kullanılan katmanların ifade edilmesidir. Yani modeldeki katman sayısı modelin derinliğini oluşturmaktadır. Günümüzde kullanılan derin öğrenme modelleri bazı durumda birbirini takip eden yüzlerce katman içermektedir. Literatürde bu katmanlı öğrenme yaklaşımına hiyerarşik öğrenmede denilmektedir (François Chollet, Bilgin Aksoy). Bu uygulanan hiyerarşik öğrenme sürecinde her katman bir önceki katmandan girdi alır ve bu veriyi işleyerek bir sonraki katmana girdi olacak şekilde aktarır. Örneğin 2 katmanlı bir derin öğrenme modelinde, ilk katman ham veriye karşılık gelirken son katmanın çıktısı ise ilgili nesne sınıflarına ait olma olasılıklarını gösterir. Binlerce örnek üzerinden gerçekleşen öğrenme esnasında bu karmaşık ağ yapısı içinde yer alan nöronlar arasındaki bazı bağlar kuvvetlenir veya zayıflar ki ilgili derin ağ modeli girdi verisinden daha doğru sinyalleri yakalayabilsin. (Aykut – Erkut Erden).

Veri Seti

Sahte haberlerle mücadele bir metin sınıflandırma projesidir. Bu çalışmanın kapsamında sadece ingilizce haberlerden yararlanıldı. Kullanılan veri seti “Katharine Jarmul” tarafından hazırlanmıştır. Veri seti toplam 6336 haberden oluşuyor. Bunların yarısı sahte yarısı gerçek olarak sınıflandırılmış. Kendisi bu veri setini George McIntire’in çalışmasından elde etmiştir. McIntire’in veri setinde ise toplam 10558 haber yer alıyor. Hepsi politik haberlerden oluşan bu veri setinin dağılımı yarı yarıyadır (%50 sahte, %50 gerçek).

Metnin Ön İşleme ve Sayısallaştırma Süreci

6336 haber için gerçekleştirilen metin ön işleme adımlarından bir önceki yazımda bahsetmiştim. Aynı yaklaşımımı burada da kullandım. Özetle aşağıdaki işlemler yapılmıştır:

  • Lower-case
  • Noktalama işaretleri, özel karakterlerin ve sayıların silinmesi
  • Tokenize işlemi
  • Stop-words’lerin silinmesi
  • Stemming / Lemmatization

Metnin sayısallaştırılması için ise vektör uzay modelinden yararlanılmıştır. Vektör uzayları, metinlerin yapısal olmayan formdan sayısal hale getirilmesini sağlayan en geniş kabul gören yöntemdir. Her metin, mevcut kelimelerden oluşan MxN büyüklüğünde bir vektördür. Kısacası vektörler üst üste eklenerek döküman-terim matrisi oluşturulur. Bu matris, M adet haber ve n adet terimden oluşmaktadır. Terim ağırlığını hesaplamak için ise TF-IDF metodundan yararlanılmıştır. TF-IDF yaklaşımında hem ilgili terimin haber içerisindeki sıklığına (Term Frequency – TF) hem de bütün haberler içerisindeki önemine bakılır (Inverse Document Frequency – IDF).

Aşağıdaki kod parçasında TF-IDF yönteminin Python ile nasıl gerçekleştirildiği gösterilmiştir.

from sklearn.feature_extraction.text import TfidfVectorizer

tfidf_vector = TfidfVectorizer(min_df = 0., max_df = 1., use_idf = True)
tfidf_matris = tfidf_vector.fit_transform(df.mix)
tfidf_matris = tfidf_matris.toarray()

Ağın İnşa Edilmesi

Derin ağların temel yapıtaşı, katmanlardır. Veri, katmana girdikten sonra daha anlamlı bir formda çıkar. Yani katmanlar, kendisini besleyen verilerden problemin çözümüne ışık tutacak şekilde daha kullanışlı, anlamlı gösterimler çıkarmaya çalışır. Hedef ve amaç bu olsada her zaman anlamlı sonuçlar elde edilemiyor.

Haberlerin sınıflandırılması için kullanılacak modelimiz, 3 adet katmandan oluşuyor. İlk ikisi gizli katman (hidden layer). Her iki katmanda 32 adet düğüme sahip. Son katmanımız yani çıktı katmanı ise 1 adet düğümden oluşuyor. İlk 2 katmanda aktivasyon fonksiyonu olarak “ReLU” (Rectified Linear Unit) kullanılırken çıktı katmanında “sigmoid” fonksiyonu kullanılmıştır. Aktivasyon fonksiyonları, doğrusal olmayan (non-linear) ilişkileri modellemek için kullanılmaktadır. Eğer aktivasyon fonksiyonu kullanmazsak modelimiz sığ öğrenme modelleri gibi davranacaktır. Bu durumda sadece doğrusal durumlar için anlamlı sonuçlar elde edebiliriz. Bununla birlikte aktivasyon fonksiyonu seçilirken dikkat edilmesi gereken bir diğer nokta ise fonksiyonun türevinin kolay hesaplanabilir olmasıdır. Günümüzde kullanılan bir çok aktivasyon fonksiyonu mevcuttur (Softmax, ReLU, Leaky ReLU, Hiperbolik Tanjant, vb.).

input_dim = x_train.shape[1]  # Öznitelik Sayısı

# Model oluşturuluyor
model = Sequential() 

# Modele iki gizli katman ekliyoruz. Katmandaların ikisinde de 32 düğüm var ve her ikisinde "relu" aktivasyon fonksiyonunu kullanıyor. 
model.add(layers.Dense(32, input_dim=input_dim, activation='relu')) 
model.add(layers.Dense(32, activation='relu'))

# Modelimizin ezberlemesini önlemek için Dropout katmanını kullanıyoruz. 
# Dropout katmanı her adımda belirtilen orandaki girdiyi rassal olarak sıfıra eşitleyerek modelin veriye aşırı uyum sağlamasının önüne geçer.
# Dropout değeri 0 ile 1 arasındadır.
model.add(Dropout(0.5))

# Son eklediğimiz katman ise çıktı katmanıdır. İkili sınıflandırma problemi üzerine çalıştığımız için "sigmoid" aktivasyon fonksiyonunu kullanıyoruz.
model.add(layers.Dense(1, activation='sigmoid'))

Ağımızı eğitmeden önce 3 önemli kısım mevcut:

  • Kayıp Fonksiyonu (Loss Function)
  • Eniyileme (Optimizer) Algoritması
  • Metrik

Sahte haberlerin belirlenmesi, ikili sınıflandırma problemi olduğu için kayıp fonksiyonu olarak “binary_crossentropy” kullanılmıştır. Bunun haricinde kullanılan farklı kayıp fonksiyonlarıda mevcuttur (huber_loss, categorical_crossentropy, mean_squared_error, vb.). Eniyileme yöntemi olarak “rmsprob” (root mean square error propability) ve takip edilecek “ölçüt” (metric) olarak “accuracy” (doğruluk) kullanıldı.

model.compile(loss='binary_crossentropy', 
              optimizer='rmsprop', 
              metrics=['accuracy'])

model.summary()

Model eğitilirken verilerin tamamı aynı anda eğitime katılmaz. Belli sayıda parçalar halinde eğitimde yer alırlar. “Batch_size” (Mini-yığın), kabaca bir seferde yapay sinir ağını eğitmek için kullanılacak örnek sayısını belirtir. “Epoch” (epok, devir) ise bütün veri kümesinin yapay sinir ağından bir kere geçmesi olarak tanımlanmaktadır.

Bu örnekte modelimiz 20 epokta, 128’lik mini-yığınlar kullanılarak eğitilmiştir. Ayrıca kayıp değeri ve modelin başarısı doğrulama veri setinden gözlenmiştir. Bunun için %10’luk bir veri seti ayrılmıştır.

history = model.fit(x_train, y_train,
                      epochs=20,
                      verbose=1,
                      validation_split=0.1,
                      batch_size=128)

Yukarıdaki history nesnesi içerisinde, eğitim boyunca elde edilen bilgileri içeren history elemanı mevcuttur (history.history). Bu şekilde modelimize ait kayıp ve başarı değerlerini inceleyebiliriz.

Aşağıdaki kod bloğuyla modelimize ait başarı ve kayıp (eğitim ve doğrulama için) değerlerini çizdirelim. Bunun için Matplotlib kütüphanesinden yararlanıldı.

import matplotlib.pyplot as plt
plt.style.use('ggplot')

def plot_history(history):
    acc = history.history['acc']
    val_acc = history.history['val_acc']
    loss = history.history['loss']
    val_loss = history.history['val_loss']
    x = range(1, len(acc) + 1)

    plt.figure(figsize=(12, 5))
    plt.subplot(1, 2, 1)
    plt.plot(x, acc, 'ro', label='Eğitim Başarısı')
    plt.plot(x, val_acc, 'r', label='Doğrulama Başarısı')
    plt.title('Eğitim ve Doğrulama Başarısı')
    plt.legend()
    plt.subplot(1, 2, 2)
    plt.plot(x, loss, 'bo', label='Eğitim Kaybı')
    plt.plot(x, val_loss, 'b', label='Doğrulama Kaybı')
    plt.title('Eğitim ve Doğrulama Kaybı')
    plt.legend()

plot_history(history)

Şekil-1: Sol tarafta eğitim ve doğrulama başarısı. Sağ tarafta ise eğitim ve doğrulama kaybı görülmektedir.

Şekil-1’de görüldüğü üzere eğitim kaybı her epokta düşerken eğitimin başarısı artmaktadır. Bununla birlikte sağ taraftaki grafikte eğitim ve doğrulama kaybının gittikçe düştüğü, yani modelin başarısının gittikçe arttığı, bununla birlikte ortalama 6. epoktan sonra eğitim veri seti için kaybın düşmeye devam ettiği fakat buna karşılık doğrulama veri seti için bu değerin arttığı görülmektedir. Bu durum literatürde “aşırı uydurma” (over fitting) olarak adlandırılmaktadır. Aşırı uydurma, eğitim esnasında çok iyi performans gösteren modelin, daha önce varlığından haberdar olmadığı bir veri içinde aynı iyi performansı göstermemesi durumudur. Bu durumu önlemek için kabaca 6. epoktan sonra eğitimi durdurmalıyız.

Bu sefer 6. epokta duracak şekilde ağımızı tekrardan eğitelim.

model = Sequential()
model.add(layers.Dense(32, input_dim=input_dim, activation='relu'))
model.add(layers.Dense(32, activation='relu'))
model.add(Dropout(0.5))
model.add(layers.Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy', 
              optimizer='rmsprop', 
              metrics=['accuracy'])

history2 = model.fit(x_train, one_hot_train_labels,
                     epochs=6,
                     verbose=1,
                     validation_split=0.1,
                     batch_size=128)
sonuc = model.evaluate(x_test, y_test, batch_size=128)
>>> sonuc
[0.17783838578709046, 0.9289847438991352]

Bu model sonucunda elde edilen başarı oranı % 93 olarak belirlenmiştir. Bununla birlikte kullanılan modelin değerlendirmesini yapmak için karmaşıklık matriside (Confusion Matrix) üretilmiştir. Bunun için scikit-learn kütüphanesinden yararlanılmıştır.

from sklearn.metrics import accuracy_score
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix

y_pred = model.predict(x_test)
>>> confusion_matrix(y_test, y_pred.round())
array([[928,  40],
       [ 95, 838]])

Sırada elde edilen karmaşıklık matrisini görselleştirme kısmına geldik.

import itertools

def plot_confusion_matrix(cm, classes, normalize=False, title='Confusion matrix', cmap=plt.cm.Blues, fig=""):

    if normalize:
        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
        print("Normalize edilmiş karmaşıklık matrisi")
    else:
        print('Normalize edilmemiş karmaşıklık matrisi')
    print(cm)

    plt.imshow(cm, interpolation='nearest', cmap=cmap)
    plt.title(title)
    plt.colorbar()
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes, rotation=45)
    plt.yticks(tick_marks, classes)

    fmt = '.2f' if normalize else 'd'
    thresh = cm.max() / 2.
    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
        plt.text(j, i, format(cm[i, j], fmt),
                 horizontalalignment="center",
                 color="white" if cm[i, j] > thresh else "black")

    plt.tight_layout()
    plt.ylabel('True label')
    plt.xlabel('Predicted label')
    plt.grid(b=None)
    plt.savefig(fig + ".png")
    plt.show()

dl = confusion_matrix(y_test, y_pred.round())
plot_confusion_matrix(dl, classes=['Fake', 'Real'], title='Confusion Matrix', fig="confusion_matrix")

Şekil-2: Elde edilen karmaşıklık matrisi (Confusion Matrix)

Unutulmamalıdır ki elde edilen başarı oranı seçilen hiper parametrelere göre değişiklik gösterebilmektedir.

Sonuçlar

Bir önceki yazımda sahte haberlerin belirlenmesi için sınıflandırma algoritmalarından yararlanmıştım. İlgili çalışma kapsamında 7 farklı sınıflandırma algoritmasını karşılaştırıldı. Sahte ve gerçek haber ayrımı için en yüksek doğruluğu (accuracy) %93 oranında Lojistik Regresyon’un vermiş olduğu belirlendi.

Bu çalışma kapsamında ise Derin Öğrenme modeli kullanılmıştır. Elde edilen doğruluk oranı ise yine %93’tür.

Bu yazı kapsamında sizlere aktaracaklarım bu kadar. Derin öğrenmeye giriş seviyesinde bir yazı okudunuz. Umarım faydalı olabilmişimdir.

Bilimin mihraplarında bilginin peşinde koşmanız dileğiyle. Sağlıcakla Kalın 🙂

Kaynaklar

1- Deep Learning with Python, François Chollet, Manning – (Python ile Derin Öğrenme, Bilgin Aksoy, Buzdağı Yayınevi)

2- https://sarkac.org/2019/02/bilgisayarlar-dusunebilir-mi2/

3- https://www.datacamp.com/community/tutorials/scikit-learn-fake-news

4- https://medium.com/deep-learning-turkiye/derin-ogrenme-uygulamalarinda-en-sik-kullanilan-hiper-parametreler-ece8e9125c4

5- http://www.veridefteri.com/2019/02/06/keras-ile-derin-ogrenmeye-giris/

6- https://medium.com/@ayyucekizrak/derin-öğrenme-için-aktivasyon-fonksiyonlarının-karşılaştırılması-cee17fd1d9cd

7- http://www.bbc.co.uk/newsbeat/article/37992793/i-write-fake-news-that-gets-shared-on-facebook (Kapak fotografı)

Hakkında Eyüp Kaan Ülgen

İstanbul Üniversitesi, Astronomi ve Uzay Bilimleri Bölümünde Doktora Öğrencisi. Doktora çalışma konusu: Galaksi kümelerindeki parlak galaksilerin çevreyle olan ilişkisi. İlgi alanları; Galaksi Evrimi, Veri Bilimi, Makine Öğrenimi, Derin Öğrenme ...

GÖZ ATMAK İSTEYEBİLİRSİNİZ

Word2Vec

Aralık ayı blog yazımın konusu olan, word2vec'ten yani kelime temsil (word embedding) yöntemini teoride açıkladıktan sonra Pyhton programlama dili ile uygulamasını yaptım.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir