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ı)

Yazar Hakkında
Toplam 6 yazı
Eyüp Kaan Ülgen
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 ...
Yorumlar (3 yorum)
Hakan
Hakan Yanıtla
- 16:22

Hocam iyi günler. Projenizi çalıştırmaya deniyorum ancak input_dim=xtrain kısmında hata veriyor. Bunun sebebi x train daha önce tanımlanmadığı için. Öğrenmek amaçlı kendi kendime uygulamaya çalışıyorum ancak kodların tamamı yok sanırım. Kodların tamamının olduğu bir link var mı? Çok teşekkür ederim.

    Eyüp Kaan Ülgen
    Eyüp Kaan Ülgen Yanıtla
    - 02:01

    Merhaba Hakan, kodun hepsini bilerek paylaşmadım 🙂 Bunun temel sebebi sizleri araştırmaya sevk etmek.

    1) VBO üzerinde mevcut 3 yazımı incelersen ilişkili olduğunu görüceksin.
    2) Ufak bir GitHub araştırmasıyla ilk yazımdaki sonucları elde edecek kodları bulabilirsin. Bulabilmeme ihtimaline karşılık yine de linki paylaşıyorum (https://github.com/kaanulgen/Sirius/blob/master/fakenewsdetection.ipynb)
    3) Veriye ulaşmak için ise kaynaklar kısmında verilen datacamp linkini incelemen yeterli olacaktır. (https://www.datacamp.com/community/tutorials/scikit-learn-fake-news)
    4) Github üzerinde paylaştığım kodlar 1. yazıma ait kodlar (“Sahte Haberlerin Belirlenmesi” – Makine Öğrenimi yaklaşımıyla). Metin ön işleme ve sayısallaştırma adımlarını oradan takip edebilirsin.
    5) Son olarak ise 2.yazımdaki derin öğrenme kodlarını kullanman yeterli olacaktır.

    Yazıdaki sonuçları görmek için uygulama yapman çok güzel. Unutma veriyle uğraşıyoruz. İncelediğin uygulamalarda sorular sorman ve ufak dedektiflikler yapman daha da güzel olacaktır diye düşünüyorum. Son olarak Sherlock Holmes ile sözlerimi bitiriyorum.

    “You see, but you do not observe.” (Sir Arthur Conan Doyle, A Scandal in Bohemia)

    İyi akşamlar, iyi çalışmalar diliyorum 🙂

      Hakan
      Hakan Yanıtla
      - 00:24

      İyi akşamlar hocam,
      Değerli açıklamanız için çok teşekkür ederim. Gerçekten belirttiğiniz gibi; You see, but you do not observe ‘imiş 🙂

      İyi çalışmalar ve sağlıklı günlerim dilerim.

Bir yanıt yazın

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

×

Bir Şeyler Ara