👨🏻‍🏫IT 활동/인공지능교육 - NLP

[NLP] Day 28 - Project 5

728x90
반응형

Project 5

자동분류 성능평가

Naive Bayes

In [665]:
import os

def getFileList(base='./', ext='.txt'):
    fileList = list()
    
    for file in os.listdir(base):
        if file.endswith(ext): # == if file.split('.')[-1] == ext:
            fileList.append('{0}/{1}'.format(base, file))
            
    return fileList
In [666]:
def getContent(file):
    with open(file, encoding='utf-8') as f:
        content = f.read()
    
    return content
In [667]:
cat = getFileList('./News')
catList = list()
for c in cat:
    v = c.split('/')
    v2 = v[2].split('_')
    catList.append(v2[0])
    catList = list(set(catList))
In [668]:
import os
corpus = list()
for file in os.listdir("./News"):
    for cat in catList:
        if file.startswith(cat):
            with open("./News/" + file, encoding='utf-8') as f:
                corpus.append([f.read(),cat])
In [669]:
trainingSet = corpus
In [670]:
# 정치
trainingSetPol = [d for d in trainingSet if d[1] == "정치"]
# 사회
trainingSetSoc = [d for d in trainingSet if d[1] == "사회"]
# 경제
trainingSetFin = [d for d in trainingSet if d[1] == "경제"]
# 세계
trainingSetWorld = [d for d in trainingSet if d[1] == "세계"]
# 생활문화
trainingSetLife = [d for d in trainingSet if d[1] == "생활문화"]
# IT과학
trainingSetIT = [d for d in trainingSet if d[1] == "IT과학"]
In [671]:
# doc의 전체 갯수 구하기
N = len(trainingSet)
N
Out[671]:
185
In [672]:
len(trainingSetPol), len(trainingSetSoc), len(trainingSetFin), len(trainingSetWorld), len(trainingSetWorld), len(trainingSetLife), len(trainingSetIT)
Out[672]:
(30, 31, 31, 31, 31, 31, 31)

전처리

In [673]:
from string import punctuation
In [674]:
range(len(trainingSetPol))
Out[674]:
range(0, 30)
In [675]:
import re
PolNews = list()
SocNews = list()
FinNews = list()
WorldNews = list()
LifeNews = list()
ITNews = list()

pattern = re.compile(r'[%s]' % re.escape(punctuation))
for i in range(len(trainingSetPol)):
    trainingSetPol[i][0] = trainingSetPol[i][0].translate(str.maketrans('', '', punctuation))
    trainingSetPol[i][0] = trainingSetPol[i][0].replace('flash 오류를 우회하기 위한 함수 추가\nfunction flashremoveCallback', '')
    PolNews.append((trainingSetPol[i][0],trainingSetPol[i][1]))
    
for i in range(len(trainingSetSoc)):
    trainingSetSoc[i][0] = trainingSetSoc[i][0].translate(str.maketrans('', '', punctuation))
    trainingSetSoc[i][0] = trainingSetSoc[i][0].replace('flash 오류를 우회하기 위한 함수 추가\nfunction flashremoveCallback', '')
    SocNews.append((trainingSetSoc[i][0],trainingSetSoc[i][1]))

for i in range(len(trainingSetFin)):
    trainingSetFin[i][0] = trainingSetFin[i][0].translate(str.maketrans('', '', punctuation))
    trainingSetFin[i][0] = trainingSetFin[i][0].replace('flash 오류를 우회하기 위한 함수 추가\nfunction flashremoveCallback', '')
    FinNews.append((trainingSetFin[i][0],trainingSetFin[i][1]))

for i in range(len(trainingSetWorld)):
    trainingSetWorld[i][0] = trainingSetWorld[i][0].translate(str.maketrans('', '', punctuation))
    trainingSetWorld[i][0] = trainingSetWorld[i][0].replace('flash 오류를 우회하기 위한 함수 추가\nfunction flashremoveCallback', '')
    WorldNews.append((trainingSetWorld[i][0],trainingSetWorld[i][1]))

for i in range(len(trainingSetLife)):
    trainingSetLife[i][0] = trainingSetLife[i][0].translate(str.maketrans('', '', punctuation))
    trainingSetLife[i][0] = trainingSetLife[i][0].replace('flash 오류를 우회하기 위한 함수 추가\nfunction flashremoveCallback', '')
    LifeNews.append((trainingSetLife[i][0],trainingSetLife[i][1]))

for i in range(len(trainingSetIT)):
    trainingSetIT[i][0] = trainingSetIT[i][0].translate(str.maketrans('', '', punctuation))
    trainingSetIT[i][0] = trainingSetIT[i][0].replace('flash 오류를 우회하기 위한 함수 추가\nfunction flashremoveCallback', '')
    ITNews.append((trainingSetIT[i][0],trainingSetIT[i][1]))

Cross - Validation

In [676]:
# 총 125개니까  25개씩 5-folds
trainAll = PolNews + SocNews + FinNews + WorldNews + LifeNews + ITNews
len(trainAll)
Out[676]:
185
In [677]:
trainAll = list(enumerate(trainAll))
In [760]:
# random으로 data 섞기

from random import shuffle
        
for i in range(0,1):
    shuffle(trainAll)
print(len(trainAll))
print(trainAll[4])
185
(179, ('\n\n\n\n\n  \n\n\t\n\t서울신문 나우뉴스사진NASAJPLCaltechCornellASU지난달 13일현지시간 머나먼 화성 땅에서 잠든 탐사로봇 오퍼튜니티Opportunity의 마지막 유작이 공개됐다최근 미 항공우주국NASA은 15년 간의 기념비적인 임무를 완수하고 작별한 오퍼튜니티의 마지막 선물인 파노라마 사진을 공개했다 지난해 오퍼튜니티가 임무를 종료하기 직전까지 파노라마 카메라로 촬영한 이 사진은 풋볼 경기장의 2배 만한 ‘인내의 계곡Perseverance Valley이라 불리는 지점을 담은 것이다 인내의 계곡은 엔데버 분화구Endeavour Crater 서쪽 가장자리 안쪽 경사면에 위치해 있다오퍼튜니티는 지난해 5월 13일6월 10일 사이 총 354장의 사진을 찍어 지구로 보내왔다 안타까운 것은 바로 이곳이 오퍼튜니티의 무덤이라는 사실 지난해 5월 말부터 불어온 화성의 강력한 모래폭풍으로 태양빛이 차단돼 에너지원이 사라지자 오퍼튜니티는 스스로 휴면상태에 들어간 후 깨어나지 못했다화성을 탐사 중인 오퍼튜니티 출처NASAJPLCaltechCornellArizona State UnivTexas AM그리고 결국 지난달 13일 NASA는 오퍼튜니티의 마지막 임무 보고 기자회견을 열고 탐사로봇의 ‘공식 사망’을 선언했다 NASA 제트추진연구소 오퍼튜니티 프로젝트 매니저 존 칼라스 박사는 화성에 어둠이 내리기 직전까지 오퍼튜니티는 마치 관광객처럼 사진을 촬영했다면서 이 마지막 파노라마는 우리의 오퍼튜니티가 얼마나 대단한 탐사와 발견을 했는지 보여준다고 밝혔다 \u3000마치 인기 애니메이션의 주인공 ‘월E’를 연상시키는 오퍼튜니티는 15년 전인 지난 2004년 1월 24일 밤 화성 메리디아니 평원에 내려앉았다 대선배 소저너Sojourner·1997년와 20일 먼저 도착한 쌍둥이 형제 스피릿Sprit에 이어 사상 3번 째 그러나 두 로봇이 착륙 후 각각 83일 2269일 만에 작별을 고한 반면 오퍼튜니티는 지난해 6월까지 왕성하게 탐사하며 ‘노익장’을 과시했다오퍼튜니티는 예상을 훌쩍 뛰어넘어 총 45㎞를 굴러다녔으며 지난해 2월에는 ‘5000솔’SOL·화성의 하루 단위으로 1솔은 24시간 37분 23초로 지구보다 조금 더 길다 넘게 화성에서 보냈다 오퍼튜니티가 화성 땅에서 그냥 굴러만 다닌 것은 아니다 그간 총 22만 5000장의 사진을 지구로 보내왔으며 이 데이터를 바탕으로 전문가들은 고대 화성에 물이 존재했다는 지질학적 증거를 찾아냈다박종익 기자 pjiseoulcokr★ 나우뉴스에서 일본 통신원을 모집합니다 ▶ 네이버에서 서울신문 구독하기 우주 소식 네이버 밴드로 보세요ⓒ 서울신문wwwseoulcokr 무단전재 및 재배포금지\n\t\n', 'IT과학'))
In [719]:
# 5-folds
fold1  = train[:25]
fold2 = train[25:50]
fold3 = train[50:75]
fold4 = train[75:100]
fold5 = train[100:125]
In [679]:
# 5-folds
fold1  = trainAll[:37]
fold2 = trainAll[37:74]
fold3 = trainAll[74:111]
fold4 = trainAll[111:148]
fold5 = trainAll[161:185]
In [720]:
# 1 fold
X_val = fold1
X_train = fold2+fold3+fold4+fold5
In [681]:
# 2 fold
X_val = fold2
X_train = fold1+fold3+fold4+fold5
In [703]:
# 3 fold
X_val = fold3
X_train = fold1+fold2+fold4+fold5
In [683]:
# 4 fold
X_val = fold4
X_train = fold1+fold2+fold3+fold5
In [761]:
# 5 fold
X_val = fold5
X_train = fold1+fold2+fold3+fold4

평가

In [762]:
trainingSet = X_train
In [763]:
# 정치
trainingSetPol = [d for d in trainingSet if d[1][1] == "정치"]
# 사회
trainingSetSoc = [d for d in trainingSet if d[1][1] == "사회"]
# 경제
trainingSetFin = [d for d in trainingSet if d[1][1] == "경제"]
# 세계
trainingSetWorld = [d for d in trainingSet if d[1][1] == "세계"]
# 생활문화
trainingSetLife = [d for d in trainingSet if d[1][1] == "생활문화"]
# IT과학
trainingSetIT = [d for d in trainingSet if d[1][1] == "IT과학"]
In [764]:
# 사전 정보 구하기 prior[c]
# MLE : 주어진 데이터를 이용해 확률값 추정 
priorPol = len(PolNews) / N
priorSoc = len(SocNews) / N
priorFin = len(FinNews) / N
priorWorld = len(WorldNews) / N
priorLife = len(LifeNews) / N
priorIT = len(ITNews) / N
In [765]:
# 확률 누적시키기 
from collections import defaultdict

tokensPol = defaultdict(int)
tokensSoc = defaultdict(int)
tokensFin = defaultdict(int)
tokensWorld = defaultdict(int)
tokensLife = defaultdict(int)
tokensIT = defaultdict(int)

for d in PolNews:
    for t in d[0].split():
        tokensPol[t] += 1
        
for d in SocNews:
    for t in d[0].split():
        tokensSoc[t] += 1
        
for d in FinNews:
    for t in d[0].split():
        tokensFin[t] += 1
               
for d in WorldNews:
    for t in d[0].split():
        tokensWorld[t] += 1
        
for d in LifeNews:
    for t in d[0].split():
        tokensLife[t] += 1
        
for d in ITNews:
    for t in d[0].split():
        tokensIT[t] += 1
        
vocabulary = set(list(tokensPol.keys()) + list(tokensSoc.keys()) + list(tokensFin.keys()) + list(tokensWorld.keys()) + list(tokensLife.keys()) + list(tokensIT.keys()))
In [766]:
# 조건부 확률
sumPol = sum(tokensPol.values())
sumSoc = sum(tokensSoc.values())
sumFin = sum(tokensFin.values())
sumWorld = sum(tokensWorld.values())
sumLife = sum(tokensLife.values())
sumIT = sum(tokensIT.values())
In [767]:
from math import log 

cpPol = defaultdict(float)
cpSoc = defaultdict(float)
cpFin = defaultdict(float)
cpWorld = defaultdict(float)
cpLife = defaultdict(float)
cpIT = defaultdict(float)

B = len(vocabulary)

for t in vocabulary:
    cpPol[t] = log((tokensPol[t]+1) / (sumPol + B))  # 1 더해서 smoothing / 분모에 1씩더하는 것은 B를 더하면 됨 
    cpSoc[t] = log((tokensSoc[t]+1) / (sumSoc + B))
    cpFin[t] = log((tokensFin[t]+1) / (sumFin + B))
    cpWorld[t] = log((tokensWorld[t]+1) / (sumWorld + B))
    cpLife[t] = log((tokensLife[t]+1) / (sumLife + B))
    cpIT[t] = log((tokensIT[t]+1) / (sumIT + B))
In [768]:
B
Out[768]:
28297
In [769]:
from math import log, exp
from sklearn.metrics import confusion_matrix, classification_report

prob = 0
xlist = list()
trueClass = list()
predClass = list()

for d in X_val:
    scorePol = log(priorPol)
    scoreSoc = log(priorSoc)
    scoreFin = log(priorFin)
    scoreWorld = log(priorWorld)
    scoreLife = log(priorLife)
    scoreIT = log(priorIT)
    
    for t in d[1][0].split():
        # 원래는 곱셈인데 로그 취해서 + 가능 
        scorePol += cpPol[t]   
        scoreSoc += cpSoc[t]
        scoreFin += cpFin[t]
        scoreWorld += cpWorld[t]
        scoreLife += cpLife[t]
        scoreIT += cpIT[t]
#     print(scorePol)
    
    AddScoreList = dict({"정치":scorePol,"사회":scoreSoc, "경제": scoreFin, "세계":scoreWorld, "생활문화":scoreLife, "IT과학":scoreIT})    
#     print(scorePol, scoreSoc, scoreFin, scoreWorld, scoreLife, scoreIT)  # 로그 상태로 지수 취해서 원래대로 나타냄
    key_max = max(AddScoreList.keys(), key=(lambda k: AddScoreList[k]))
#     print("real : {0} , pred : {1}".format(d[1][1],key_max))
    trueClass.append(d[1][1])
    predClass.append(key_max)

    if d[1][1] == key_max:
        prob += 1
    else:
        xlist.append([d[1][1],key_max])

        
acc = prob / len(X_val)
print("맞춘 비율 : {0}".format(acc))

conf = confusion_matrix(trueClass,predClass)
print(conf)
print(classification_report(trueClass,predClass))


    
    
# 빈도 수를 따라 training보고 판단했을 것. 
# testSet의 chinese를 하나로 줄이면 No를 반환함 
맞춘 비율 : 0.96
[[1 0 0 0 0 0]
 [0 6 0 0 0 0]
 [0 0 3 0 0 1]
 [0 0 0 5 0 0]
 [0 0 0 0 5 0]
 [0 0 0 0 0 4]]
              precision    recall  f1-score   support

        IT과학       1.00      1.00      1.00         1
          경제       1.00      1.00      1.00         6
          사회       1.00      0.75      0.86         4
        생활문화       1.00      1.00      1.00         5
          세계       1.00      1.00      1.00         5
          정치       0.80      1.00      0.89         4

   micro avg       0.96      0.96      0.96        25
   macro avg       0.97      0.96      0.96        25
weighted avg       0.97      0.96      0.96        25

In [770]:
fold1_acc = 0.96
fold2_acc = 1
fold3_acc = 0.92
fold4_acc = 1
fold5_acc = 0.92

Testing

In [771]:
import os
corpus2 = list()
for file in os.listdir("./Testing_Data"):
    for cat in catList:
        if file.startswith(cat):
            with open("./Testing_Data/" + file, encoding='utf-8') as f:
                corpus2.append([f.read(),cat])
In [772]:
corpus2[0]
Out[772]:
['코스피가 8일 외국인 매수에 힘입어 7거래일째 상승세로 마감했다.\n\n이날 코스피는 전 거래일보다 0.99포인트(0.04%) 오른 2,210.60으로 장을 마쳤다.\n\n지수는 전장보다 8.05포인트(0.36%) 오른 2,217.66으로 출발해 등락하다가 강보합으로 마무리했다.\n\n유가증권시장에서는 외국인이 2천759억원어치를 순매수했다. 반면 기관은 1천738억원, 개인은 1천32억원을 각각 순매도했다.\n\n이원 부국증권 연구원은 "그동안 증시가 상승한 여파로 기관·개인의 차익실현 매물이 나왔지만, 그보다는 외국인이 매수세를 이어갔다는 점이 유의미하다"면서 "이는 반도체 업황 및 글로벌 경기둔화에 대한 우려가 어느 정도 불식됐다는 의미"라고 설명했다.\n\n시가총액 상위 종목 가운데는 현대차(1.59%), LG화학(1.59%), 셀트리온(1.82%), POSCO(0.55%), 삼성바이오로직스(0.44%), LG생활건강(0.50%) 등이 올랐다. 삼성전자(-0.43%), SK하이닉스(-1.39%), 현대모비스(-0.67%) 등은 내렸다.\n\n업종별로는 음식료품(0.82%), 섬유·의복(2.02%), 화학(0.64%), 의약품(0.51%), 철강·금속(0.10%) 등이 강세를 보였고 기계(-0.55%), 전기·전자(-0.55%), 건설(-0.11%), 통신(-0.42%) 등은 약세였다.\n\n오른 종목은 429개였고 내린 종목은 397개였다. 72개 종목은 보합 마감했다.\n\n프로그램 매매는 차익거래가 매도 우위, 비차익거래는 매수 우위로 전체적으로는 약 1천743억원의 순매수로 집계됐다.\n\n유가증권시장의 거래량은 약 3억3천257만주, 거래대금은 4조5천380억원가량이었다.\n\n코스닥 소폭 상승 [제작 최자윤] 일러스트\n\n코스닥 소폭 상승 [제작 최자윤] 일러스트\n코스닥지수는 전장보다 0.21포인트(0.03%) 오른 751.92로 종료했다.\n\n지수는 3.61포인트(0.48%) 오른 755.32로 개장해 등락하다가 우상향 곡선을 그렸다.\n\n코스닥시장에서는 외국인이 109억원, 개인이 263억원을 순매수했다. 기관은 160억원을 순매도했다.\n\n시총 상위주 중에서는 셀트리온헬스케어(2.06%), 에이치엘비(0.92%), 펄어비스(0.11%), 셀트리온제약(1.05%), 파라다이스(0.56%) 등이 올랐다. CJ ENM(-0.26%), 신라젠(-0.77%), 메디톡스(-0.28%), 스튜디오드래곤(-1.95%) 등은 내렸다.\n\n코스닥시장의 거래량은 약 7억2천260만주, 거래대금은 4조1천872억원이었다.\n\n코넥스시장에서는 109개 종목이 거래됐고 거래량은 24만5천여주, 거래대금은 23억6천억원가량이었다.\n\n이날 서울 외환시장에서 원/달러 환율은 전 거래일보다 8.1원 오른 1,144.7원에 마감했다.\n',
 '경제']

1. ADD

In [773]:
from math import log 

cpPol = defaultdict(float)
cpSoc = defaultdict(float)
cpFin = defaultdict(float)
cpWorld = defaultdict(float)
cpLife = defaultdict(float)
cpIT = defaultdict(float)

B = len(vocabulary)

for t in vocabulary:
    cpPol[t] = log((tokensPol[t]+1) / (sumPol + B))  # 1 더해서 smoothing / 분모에 1씩더하는 것은 B를 더하면 됨 
    cpSoc[t] = log((tokensSoc[t]+1) / (sumSoc + B))
    cpFin[t] = log((tokensFin[t]+1) / (sumFin + B))
    cpWorld[t] = log((tokensWorld[t]+1) / (sumWorld + B))
    cpLife[t] = log((tokensLife[t]+1) / (sumLife + B))
    cpIT[t] = log((tokensIT[t]+1) / (sumIT + B))
In [774]:
from math import log, exp
from sklearn.metrics import confusion_matrix, classification_report

prob = 0
xlist = list()
trueClass = list()
predClass = list()

for d in corpus2:
    scorePol = log(priorPol)
    scoreSoc = log(priorSoc)
    scoreFin = log(priorFin)
    scoreWorld = log(priorWorld)
    scoreLife = log(priorLife)
    scoreIT = log(priorIT)
    
    for t in d[0].split():
        # 원래는 곱셈인데 로그 취해서 + 가능 
        scorePol += cpPol[t]   
        scoreSoc += cpSoc[t]
        scoreFin += cpFin[t]
        scoreWorld += cpWorld[t]
        scoreLife += cpLife[t]
        scoreIT += cpIT[t]
#     print(scorePol)
    
    AddScoreList = dict({"정치":scorePol,"사회":scoreSoc, "경제": scoreFin, "세계":scoreWorld, "생활문화":scoreLife, "IT과학":scoreIT})    
#     print(scorePol, scoreSoc, scoreFin, scoreWorld, scoreLife, scoreIT)  # 로그 상태로 지수 취해서 원래대로 나타냄
    key_max = max(AddScoreList.keys(), key=(lambda k: AddScoreList[k]))
#     print("real : {0} , pred : {1}".format(d[1][1],key_max))
    trueClass.append(d[1])
    predClass.append(key_max)

    if d[1] == key_max:
        prob += 1
    else:
        xlist.append([d[1],key_max])

        
acc = prob / len(X_val)
# print("맞춘 비율 : {0}".format(acc))

conf = confusion_matrix(trueClass,predClass)
print(conf)
print(classification_report(trueClass,predClass))


    
    
# 빈도 수를 따라 training보고 판단했을 것. 
# testSet의 chinese를 하나로 줄이면 No를 반환함 
[[2 0 0 0 0 0]
 [0 2 0 0 0 0]
 [1 0 0 0 1 0]
 [0 0 0 1 1 0]
 [0 0 1 0 1 0]
 [0 0 0 0 0 2]]
              precision    recall  f1-score   support

        IT과학       0.67      1.00      0.80         2
          경제       1.00      1.00      1.00         2
          사회       0.00      0.00      0.00         2
        생활문화       1.00      0.50      0.67         2
          세계       0.33      0.50      0.40         2
          정치       1.00      1.00      1.00         2

   micro avg       0.67      0.67      0.67        12
   macro avg       0.67      0.67      0.64        12
weighted avg       0.67      0.67      0.64        12

2. Laplas

In [775]:
from math import log 

cpPol = defaultdict(float)
cpSoc = defaultdict(float)
cpFin = defaultdict(float)
cpWorld = defaultdict(float)
cpLife = defaultdict(float)
cpIT = defaultdict(float)

K = 0.5

for t in vocabulary:
    cpPol[t] = log((tokensPol[t]+K) / (sumPol + K*2))  # 1 더해서 smoothing / 분모에 1씩더하는 것은 B를 더하면 됨 
    cpSoc[t] = log((tokensSoc[t]+K) / (sumSoc + K*2))
    cpFin[t] = log((tokensFin[t]+K) / (sumFin + K*2))
    cpWorld[t] = log((tokensWorld[t]+K) / (sumWorld + K*2))
    cpLife[t] = log((tokensLife[t]+K) / (sumLife + K*2))
    cpIT[t] = log((tokensIT[t]+K) / (sumIT + K*2))
In [776]:
from math import log, exp
from sklearn.metrics import confusion_matrix, classification_report

prob = 0
xlist = list()
trueClass = list()
predClass = list()

for d in corpus2:
    scorePol = log(priorPol)
    scoreSoc = log(priorSoc)
    scoreFin = log(priorFin)
    scoreWorld = log(priorWorld)
    scoreLife = log(priorLife)
    scoreIT = log(priorIT)
    
    for t in d[0].split():
        # 원래는 곱셈인데 로그 취해서 + 가능 
        scorePol += cpPol[t]   
        scoreSoc += cpSoc[t]
        scoreFin += cpFin[t]
        scoreWorld += cpWorld[t]
        scoreLife += cpLife[t]
        scoreIT += cpIT[t]
#     print(scorePol)
    
    LapScoreList = dict({"정치":scorePol,"사회":scoreSoc, "경제": scoreFin, "세계":scoreWorld, "생활문화":scoreLife, "IT과학":scoreIT})    
#     print(scorePol, scoreSoc, scoreFin, scoreWorld, scoreLife, scoreIT)  # 로그 상태로 지수 취해서 원래대로 나타냄
    key_max = max(LapScoreList.keys(), key=(lambda k: LapScoreList[k]))
#     print("real : {0} , pred : {1}".format(d[1][1],key_max))
    trueClass.append(d[1])
    predClass.append(key_max)

    if d[1] == key_max:
        prob += 1
    else:
        xlist.append([d[1],key_max])

        
acc = prob / len(X_val)
# print("맞춘 비율 : {0}".format(acc))

conf = confusion_matrix(trueClass,predClass)
print(conf)
print(classification_report(trueClass,predClass))


    
    
# 빈도 수를 따라 training보고 판단했을 것. 
# testSet의 chinese를 하나로 줄이면 No를 반환함 
[[2 0 0 0 0 0]
 [0 2 0 0 0 0]
 [1 0 0 0 1 0]
 [0 0 0 1 1 0]
 [0 0 1 0 1 0]
 [0 0 0 0 0 2]]
              precision    recall  f1-score   support

        IT과학       0.67      1.00      0.80         2
          경제       1.00      1.00      1.00         2
          사회       0.00      0.00      0.00         2
        생활문화       1.00      0.50      0.67         2
          세계       0.33      0.50      0.40         2
          정치       1.00      1.00      1.00         2

   micro avg       0.67      0.67      0.67        12
   macro avg       0.67      0.67      0.64        12
weighted avg       0.67      0.67      0.64        12

Naive Bayes의 Test 성능이 매우 좋지 못한 것을 알 수 있다. 그 이유로는

먼저, 트레이닝 데이터를 수집한 시기와 테스트 셋을 구성한 시기가 한 달 차이 정도 났다.

그렇기에 Model이 그 이전 데이터만을 가지고 세계를 꾸렸기에 Validation에서는 좋지만 Test에서 좋지 못했던 것 같다.

그래서 Bias가 높게 나온 형태로 볼 수 있는 것이다. 이를 줄이기 위해서는 데이터를 조금 더 많이 수집하는 것이 방법이 될 수 있다.

그리고 수집한 학습데이터는 네이버 뉴스의 것이지만 테스트 데이터는 각종 다른 사이트의 뉴스에서 가져옴.


728x90
반응형