[한국어 번역] Detecting political bias in online articles using NLP and classification models

2023. 7. 13. 11:44자연어처리

우리는 매일 새로운 정보를 받아드리고 그것을 통해 우리의 생각을 형성해나간다.

 

정보가 편향되지않고 중립적인것은 우리가 이성적이고 영향받지않는 결단을 내리기 위해 꼭 필요한 것이다.

 

이 게시물은 맥시도니아어로 작성된 언론 기사에서 정치적 편향을 감지하기 위한 

다양한 자연어 처리(NLP) 알고리즘과 기계 학습 모델을 탐구합니다.

 

 


이 데이터셋은 2020년부터 2022년까지 약 6000개의 기사 텍스트로 구성되어 있습니다. 

각 기사는 다음 세 가지 클래스 중 하나로 레이블링되어 있습니다:

N - 중립 (편향되지 않음). 이러한 기사들은 독자 조사에 기반하여 거의 또는 전혀 편향이 없는 언론사에서 가져온 것입니다.
V - 오른쪽 편향. 이러한 기사들은 오른쪽 정당의 언론센터에서 가져온 것입니다.
S - 왼쪽 편향. 이러한 기사들은 왼쪽 정당의 언론센터에서 가져온 것입니다.

 

주요 목표는 기사의 텍스트를 이 세개중 하나의 클래스로 분류하는 것 입니다.

주목할 점: 중립적인 언론사는 정치 외의 다른 주제(스포츠, 세계 뉴스 등)도 다룹니다. 

이 데이터셋은 중립적이지 않은 텍스트에서의 편향을 감지하는 것에 초점을 맞추기 위해 

지역 뉴스/정치 카테고리에서만 기사를 추출한 것입니다.

 

데이터 준비

#Deep Learning libraries
from tensorflow import keras
import tensorflow as tf
from keras.models import Sequential
from keras.layers import Dense
from keras import backend as K#Graphing libraries
import matplotlib.pyplot as plt
import seaborn as sns#NLP libraries
import nltk
from gensim.models import Doc2Vec
import gensim
from gensim.models.doc2vec import TaggedDocument#Machine learning libraries
from sklearn import utils
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import GaussianNB
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC#Helper libraries
import multiprocessing
import numpy as np
import pandas as pd
import math
from bs4 import BeautifulSoup
import re


nltk.download('punkt')

데이터셋을 판다스 데이터프레임으로 다운로드하고, 불필요한 컬럼을 제거하며 행을 섞는 과정을 거친다.

# Load and shuffle the data
dataset = pd.read_csv('/content/dataset.csv', header=0)
dataset = dataset.drop('url',axis=1)
dataset = dataset.iloc[np.random.permutation(len(dataset))]

편향 열은 숫자가 아닌 값으로 구성되어 있으므로 인코딩이 필요합니다. 

대부분의 모델에는 간단한 라벨 인코딩(label encoding)이 적용될 수 있지만, 딥 러닝 모델의 경우 다른 인코딩 방법이 필요합니다.

dataset['bias'] = dataset['bias'].replace(['S','N','V'],[0,1,2])

분포를 살펴보면

bias_vals = dataset['bias'].value_counts()
plt.figure()
sns.barplot(x=bias_vals.index, y=bias_vals.values)
plt.show();

데이터셋이 균형을 이루지 않은 것은 명백합니다. 중립 샘플이 다른 클래스보다 훨씬 많습니다. 

중립 클래스를 항상 예측하는 가장 기본적인 모델은 경우에 따라 약 44%의 정확도를 가질 것입니다.

먼저, 기사 텍스트를 "정리(clean)"해야 합니다. 불필요한 문장 부호와 기호를 제거하고, 모든 텍스트를 소문자로 만들어야 합니다. 또한 불용어(stopwords)를 제거해야 합니다. 불용어란 예를 들어 "in", "next", "from" 등과 같이 모든 텍스트에 공통적으로 등장하지만 정치적 편향을 예측하는 데 큰 가치를 제공하지 않는 일반적인 언어 단어들의 목록입니다. 

def clean(text):
    text = BeautifulSoup(text, "lxml").text
    text = re.sub(r'\|\|\|', r' ', text) 
    text = text.replace('„','')
    text = text.replace('“','')
    text = text.replace('"','')
    text = text.replace('\'','')
    text = text.replace('-','')
    text = text.lower()
    return text
def remove_stopwords(content):
    for word in _stopwords:
        content = content.replace(' '+word+' ',' ')
    return content
dataset['content'] = dataset['content'].apply(clean)
dataset['content'] = dataset['content'].apply(remove_stopwords)

데이터셋 분할을 진행

train, test = train_test_split(dataset, test_size=0.2)

 

Natural language processing — NLP

자연어 처리(NLP)는 컴퓨터가 사람과 같이 언어를 이해할 수 없기 때문에 텍스트를 숫자로 인코딩하면서 의미 정보를 유지하기 위해 특정 알고리즘이 필요합니다. 이것은 NLP의 연구 영역이며, 사용할 수 있는 몇 가지 알고리즘이 있습니다.

Doc2Vec은 텍스트를 인코딩하기 위한 최신 알고리즘 중 하나입니다. 이전의 Word2Vec 알고리즘의 고급 버전입니다. Doc2Vec은 텍스트의 전체 문서를 우리가 선택한 크기의 벡터로 인코딩합니다.

Doc2Vec을 사용하기 위해서는 NLTK 라이브러리를 사용하여 기사의 토큰화된 텍스트를 사용하여 태그가 지정된 문서를 구성해야 합니다.

 

def tokenize_text(text):
    tokens = []
    for sent in nltk.sent_tokenize(text):
        for word in nltk.word_tokenize(sent):
            if len(word) < 3:
                continue
            tokens.append(word.lower())
    return tokens
train_tagged = train.apply(
   lambda r: TaggedDocument(words=tokenize_text(r['content']), tags=  [r.bias]), axis=1)
test_tagged = test.apply(
   lambda r: TaggedDocument(words=tokenize_text(r['content']), tags=[r.bias]), axis=1)

Doc2Vec에는 두 가지 "변형"이 있습니다:

1. 분산 메모리 (PV-DM) - 원래의 Word2Vec 알고리즘에서 영감을 받았습니다.
2. 분산 가방 모델 (PV-DBOW) - 보통 짧은 텍스트에서 가장 잘 작동합니다.

이 게시물에서는 이러한 두 가지 알고리즘을 훈련하고 비교할 것입니다.

 

cores = multiprocessing.cpu_count()
models = [
    # PV-DBOW 
    Doc2Vec(dm=0, vector_size=300, negative=5, hs=0, sample=0, min_count=2, workers=cores),
    # PV-DM
    Doc2Vec(dm=1, vector_size=300, negative=5, hs=0, sample=0,    min_count=2, workers=cores)
]

어휘 사전을 구축하고 모델을 훈련하고 저장

for model in models:
  model.build_vocab(train_tagged.values)
  model.train(utils.shuffle(train_tagged.values),
    total_examples=len(train_tagged.values),epochs=30)

models[0].save("doc2vec_articles_0.model")
models[1].save("doc2vec_articles_1.model")

훈련된 모델을 사용하여 기사의 텍스트를 300 길이의 벡터로 인코딩합니다.

def vec_for_learning(model, tagged_docs):
    sents = tagged_docs.values
    classes, features = zip(*[(doc.tags[0],
      model.infer_vector(doc.words, steps=20)) for doc in sents])
    return features, classes# PV_DBOW encoded text
train_x_0, train_y_0 = vec_for_learning(models[0], train_tagged)
test_x_0, test_y_0 = vec_for_learning(models[0], test_tagged)# PV_DM encoded text
train_x_1, train_y_1 = vec_for_learning(models[1], train_tagged)
test_x_1, test_y_1 = vec_for_learning(models[1], test_tagged)

Classification ML models

Naive Bayes 분류기는 기계 학습에서 가장 간단한 모델 중 하나입니다. 이 모델은 모든 특성이 서로 독립적이라고 가정하며 기본적인 확률 원리를 사용하여 결과를 계산합니다.

Naive Bayes는 분류에 사용되는 모든 특성이 서로 독립적이라고 가정하는 것을 바탕으로 합니다. 이는 "순진한" 가정이라고도 알려져 있습니다. 이러한 단순성과 독립성 가정에도 불구하고, Naive Bayes는 많은 실제 응용에서 잘 동작하는 경우가 많습니다.

이 알고리즘은 베이즈 정리에 기반하여 특성 값에 의해 주어진 증거에 대한 특정 이벤트(여기서는 특정 클래스 레이블)의 확률을 계산합니다. Naive Bayes는 각 클래스 레이블에 대해 특성 값에 대한 조건부 확률을 계산하고, 확률이 가장 높은 레이블을 예측 클래스로 선택합니다.

Naive Bayes는 특히 감성 분석이나 스팸 탐지와 같은 텍스트 분류 작업에 적합합니다. 이외에도 다양한 분야에 성공적으로 적용되었습니다. 이 알고리즘은 레이블이 지정된 예제를 포함하는 학습 데이터셋이 필요하며, 분류 과정에서 사용되는 확률을 추정하기 위해 이 데이터셋을 활용합니다. 학습 과정에서는 각 클래스의 사전 확률과 각 클래스에 대한 각 특성의 조건부 확률을 계산합니다.

새로운 인스턴스에 Naive Bayes를 적용할 때는 베이즈 정리를 사용하여 인스턴스의 특성에 대한 각 클래스 레이블의 사후 확률을 계산합니다. 사후 확률이 가장 높은 클래스 레이블이 인스턴스의 예측 클래스로 선택됩니다.

종합적으로, Naive Bayes는 분류 작업에 있어서 간단하면서도 효과적인 알고리즘입니다. 특히 주어진 데이터에 대해 독립성 가정이 상당히 잘 유지되는 경우에 잘 동작합니다.

 

SVM, Random Forest 등등 여러가지 분류기를 사용하여 성능을 테스트함


Final notes

이 글에서는 자연어 처리와 분류 기계 학습 모델을 활용하여 뉴스 기사의 편향을 탐지하는 방법에 대해 알아보았습니다. 

또한 이러한 모델이 실제 적용과 새로운 데이터 분석에 어떻게 활용될 수 있는지 살펴보았습니다.

이러한 모델을 개선할 수 있는 분야는 다양한 출처에서의 다양한 편향된 데이터입니다. 이를 통해 알고리즘의 일반화를 더욱 강화하고 더 나은 결과를 얻을 수 있습니다. 예를 들어, 하나의 언론 센터에서는 동일한 문장을 게시하거나 일반적인 순서로 단어를 사용할 수 있습니다. 모델은 이러한 발생을 학습하고 실제 편향과 상관없이 유사한 순서를 포함하는 새로운 기사를 편향된 것으로 분류할 수 있습니다.

또 다른 중요한 점은 뉴스 기사를 편향된 것으로 분류하는 것이 상대적으로 논란이 되는 주제라는 것입니다. 사람마다 다른 편향성을 가지고 있습니다. 어떤 사람에게는 편향된 기사가 있을 수 있지만, 다른 사람에게는 그렇지 않을 수 있습니다. 따라서 중립적인 기사는 다양한 사고 방식을 가진 다양한 인구 세그먼트를 대표하는 설문조사를 기반으로 선택되며, 편향된 기사는 당사자의 언론 센터에서 직접 가져옵니다.