[ํ ์คํธ ๋ถ์] 4-(1). ์ง๋ํ์ต ๊ธฐ๋ฐ ๊ฐ์ฑ ๋ถ์ - IMDB์ํํ
ํ ์คํธ ๋ถ์์์ ์ ์ฒ๋ฆฌ๋ถํฐ BOW๊น์ง ๊ณต๋ถ๋ฅผ ํด๋ณด์๋๋ฐ์! ์ด์ ์ง์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง๊ณ ์ค์ต์ ํด๋ณด๋ ค๊ณ ํฉ๋๋ค. ๊ฐ์ฑ๋ถ์์ด๋? : ๋ฌธ์์ ์ฃผ๊ด์ ์ธ ๊ฐ์ฑ/์๊ฒฌ/๊ฐ์ /๊ธฐ๋ถ ๋ฑ์ ํ์ ํ๊ธฐ ์ํ ๋ฐฉ๋ฒ
xod22.tistory.com
์ง๋ํ์ต๊ธฐ๋ฐ ๊ฐ์ฑ๋ถ์์ ์ด์ด ๋น์ง๋ ํ์ต๊ธฐ๋ฐ ๊ฐ์ฑ๋ถ์ ์ค์ต์ ํด๋ณด๋ ค๊ณ ํฉ๋๋ค!
๋น์ง๋ ํ์ต ๊ธฐ๋ฐ ๊ฐ์ฑ ๋ถ์
: ๋น์ง๋ ๊ฐ์ฑ๋ถ์์ Lexicon์ ๊ธฐ๋ฐ์ผ๋ก ํ๋ค.
Lexicon์ ์ผ๋ฐ์ ์ผ๋ก ์ดํ์ง์ ์๋ฏธํ๋๋ฐ, ์ฌ๊ธฐ์๋ ์ฃผ๋ก ๊ฐ์ฑ๋ง์ ๋ถ์ํ๊ธฐ ์ํด ์ง์ํ๋ ๊ฐ์ฑ ์ดํ ์ฌ์ ์ด๋ค.
๊ฐ์ฑ์ฌ์ ์ ๊ธ์ (Positive) ๋๋ ๋ถ์ (Negative) ๊ฐ์ฑ ์ ๋๋ฅผ ์๋ฏธํ๋ ์์น(๊ฐ์ฑ์ง์)๋ฅผ ๊ฐ๊ณ ์์ผ๋ฉฐ, ์ด๋ ๋จ์ด์ ์์น๋ ์ฃผ๋ณ๋จ์ด, ๋ฌธ๋งฅ, POS(Part of Speech) ๋ฑ์ ์ฐธ๊ณ ํด ๊ฒฐ์ ๋๋ค.
์ด๋ฌํ ๊ฐ์ฑ ์ฌ์ ์ ๊ตฌํํ ๋ํ์ ํจํค์ง๊ฐ NLTK์ด๋ค. NLTK๋ ๋ง์ ์๋ธ ๋ชจ๋์ ๊ฐ๊ณ ์์ผ๋ฉฐ, Lexicon๋ ํฌํจ๋์ด์๋ค.
WordNet
: ๊ฐ์ฑ์ฌ์ ์ ์ดํดํ๊ธฐ ์ํด์๋ ๋จผ์ WordNet์ ์์์ผ ํ๋ค.
WordNet๋ชจ๋์ NLTK์์ ์ ๊ณตํ๋ ๋ฐฉ๋ํ ์๋งจํฑ ๋ถ์์ ์ ๊ณตํ๋ ์ดํ์ฌ์ ์ด๋ค.
๋์ผํ ๋จ์ด๋ ๋ฌธ์ฅ์ด๋ผ๋ ๋ค๋ฅธ ํ๊ฒฝ, ๋ฌธ๋งฅ์์๋ ๋ค๋ฅด๊ฒ ํํ๋๊ฑฐ๋ ์ดํด๋ ์ ์๋ค.
์๋ฅผ๋ค์ด ์์ด ๋จ์ด 'Present'๋ ์ ๋ฌผ์ด๋ผ๋ ์๋ฏธ๋ ์์ง๋ง ํ์ฌ๋ผ๋ ์๋ฏธ๋ ์๋ค. ๋ํ ์ฐ๋ฆฌ๋ง์ '๋ฐฅ ๋จน์์ด?'๋ผ๋ ํํ์ ๋จ์ํ ์์ฌ๋ฅผ ํ๋์ง๋ฅผ ๋ฌป๋ ํํ์ผ ์๋ ์์ง๋ง ์๋ถ๋ฅผ ๋ฌป๋ ํํ์ผ์๋ ์๋ค..!
WordNet์ ์ด๋ ๊ฒ ๊ฐ์ ์ดํ๋ผ๋ ์ํฉ์ ๋ฐ๋ผ ๋ค๋ฅด๊ฒ ์ฌ์ฉ๋๋ ์ดํ์ ์๋งจํฑ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ค..
NLTK์ ํฌํจ๋ ๊ฐ์ฑ์ฌ์
- SentiWordNet : NLTKํจํค์ง์ WordNet๊ณผ ์ ์ฌํ๊ฒ ๊ฐ์ฑ๋จ์ด ์ ์ฉ WordNet์ ๊ตฌํํ๊ฒ์ผ๋ก 3๊ฐ์ง ๊ฐ์ฑ์ ์(sentiment score)๋ฅผ ์ ์ฉํ๋ค
- ๊ธ์ ๊ฐ์ฑ ์ง์ : ํด๋น ๋จ์ด๊ฐ ๊ฐ์ฑ์ ์ผ๋ก ์ผ๋ง๋ ๊ธ์ ์ ์ธ๊ฐ๋ฅผ ๋ํ๋ธ ์์น
- ๋ถ์ ๊ฐ์ฑ ์ง์ : ํด๋น ๋จ์ด๊ฐ ์ผ๋ง๋ ๊ฐ์ฑ์ ์ผ๋ก ๋ถ์ ์ ์ธ๊ฐ๋ฅผ ๋ํ๋ธ ์์น
- ๊ฐ๊ด์ฑ ์ง์ : ๊ธ์ /๋ถ์ ์ง์์ ์์ ํ ๋ฐ๋๋๋ ๊ฐ๋ ์ผ๋ก ๋จ์ด๊ฐ ๊ฐ์ฑ๊ณผ ๊ด๊ณ์์ด ์ผ๋ง๋ ๊ฐ๊ด์ ์ธ์ง๋ฅผ ๋ํ๋ธ ์์น
- VADER : ์์ ๋ฏธ๋์ด์ ํ ์คํธ์ ๋ํ ๊ฐ์ฑ ๋ถ์์ ์ ๊ณตํ๊ธฐ ์ํ ํจํค์ง๋ก ๋ฐ์ด๋ ๊ฐ์ฑ ๋ถ์ ๊ฒฐ๊ณผ๋ฅผ ์ ๊ณตํ๋ฉฐ, ๋น๊ต์ ๋น ๋ฅด์ํ ์๊ฐ์ ๋ณด์ฅํด ๋์ฉ๋ ํ ์คํธ ๋ฐ์ดํฐ์ ์ ์ฌ์ฉ๋๋ ํจํค์ง์ด๋ค.
- Pattern : ์์ธก ์ฑ๋ฅ ์ธก๋ฉด์์ ๊ฐ์ฅ ์ฃผ๋ชฉ๋ฐ๋ ํจํค์ง์ด์ง๋ง ํ์ด์ฌ 2.X๋ฒ์ ์์๋ง ๋์ํ๋ค.
=> SentiWordNet ๊ฐ์ฑ ์ฌ์ ์ ์ด์ฉํด ๊ฐ์ฑ ๋ถ์์ ์ํํด๋ณด๊ฒ ์ต๋๋ค!
์ค์ต
1. ํจํค์ง ์ํฌํธ
: SentiWordNet์ WrodNet๊ธฐ๋ฐ์ synset์ ์ด์ฉํ๋ฏ๋ก ๋จผ์ WordNet์ synset์ ๋ํด ์์๋ณด๊ฒ ์ต๋๋ค.
synset์ ๊ทธ ๋จ์ด๊ฐ ๊ฐ๋ ๋ฌธ๋งฅ, ์๋งจํฑ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ WordNet์ ํต์ฌ ๊ฐ๋ ์ ๋๋ค.
๋จผ์ NLTK์ ๋ชจ๋ ๋ฐ์ดํฐ ์ธํธ์ ํจํค์ง๋ฅผ ๋ด๋ ค๋ฐ์๋ค, WordNet์ synsets()๋ฅผ ์ฌ์ฉํค 'present' ๋จ์ด์ ๋ํ synset ๊ฐ์ฒด๋ฅผ ์ถ์ถํด๋ณด๊ฒ ์ต๋๋ค!
import nltk
import pandas as pd
from nltk.corpus import wordnet as wn
nltk.download('all')
2. 'present'๋ผ๋ ๋จ์ด๋ก synsets(์ดํ์ฌ์ ) ์์ฑ
synsets=wn.synsets('present')
print('synsets() ๋ฐํ type: ', type(synsets))
print('synsets() ๋ฐํ ๊ฐ ๊ฐ์: ', len(synsets))
print('synsets() ๋ฐํ ๊ฐ: ', synsets)
์ด 18๊ฐ์ ์๋ก ๋ค๋ฅธ ์๋ฏธ๋ฅผ ๊ฐ๋ synset ๊ฐ์ฒด๊ฐ ๋ฐํ๋์์ต๋๋ค.
Synset('present.n.01')๊ณผ ๊ฐ์ด Synset ๊ฐ์ฒด์ ํ๋ผ๋ฏธํฐ 'present.n.01'์ POS(Part Of Speech: ํ์ฌ) ํ๊ทธ๋ฅผ ๋ํ๋ ๋๋ค.
n์ ๋ช ์ฌ ํ์ฌ, 01์ present๊ฐ ๋ช ์ฌ๋ก์ ์ฌ๋ฌ ์๋ฏธ๋ฅผ ๊ฐ๊ธฐ ๋๋ฌธ์ ์ด๋ฅผ ๊ตฌ๋ถํ๊ธฐ ์ํ ์ธ๋ฑ์ค ์ ๋๋ค.
for synset in synsets :
print('##### Synset name: ', synset.name(),'#####') #synset ์ด๋ฆ
print('POS: ',synset.lexname()) #๋จ์ด์ ํ์ฌ
print('Definition: ',synset.definition()) #๋จ์ด์ ์๋ฏธ
print('Lemmas: ',synset.lemma_names()) #๋จ์ด์ ๋ถ๋ช
์ , ๋ค๋ฅด๋์ฒด ๋จ์ด
ํ ๋จ์ด์ ๋ํด์ ์ฌ๋ฌ ์๋ฏธ๋ฅผ ํํํ๊ธฐ ์ํด์ ๋ค์ํ synsets๋ค์ด ์กด์ฌํฉ๋๋ค. ์ด synset ํ๋ํ๋ ํ์ฌ์ ์ ์ ๊ทธ๋ฆฌ๊ณ ๋์ฒด ๋จ์ด๋ค์ ์ดํด๋ณผ ์ ์์ต๋๋ค!
- Synset('present.n.01')๊ณผ Synset('present.n.02')๋ ๋ช ์ฌ์ง๋ง ์๋ก ๋ค๋ฅธ ์๋ฏธ๋ฅผ ๊ฐ๊ณ ์์ต๋๋ค.
-Synset('present.n.01')์ POS๊ฐ noun.time์ด๋ฉฐ Definition์ ์ดํด๋ณด๋ฉด '์๊ฐ์ ์ธ ์๋ฏธ๋ก ํ์ฌ'๋ฅผ ๋ํ๋ ๋๋ค.
-Synset('present.n.02')๋ POS๊ฐ noun.possession์ด๋ฉฐ Definition์ '์ ๋ฌผ'์ ๋๋ค.
์ด์ฒ๋ผ synset์ ํ๋์ ๋จ์ด๊ฐ ๊ฐ์ง์ ์๋ ์ฌ๋ฌ ๊ฐ์ง ์๋งจํฑ ์ ๋ณด๋ฅผ ๊ฐ๋ณ ํด๋์ค๋ก ๋ํ๋ธ ๊ฒ์ ๋๋ค.
3. ์ดํ๊ฐ์ ์ ์ฌ๋ ํ์ธ
# ๋จ์ด ์์ฑ
tree = wn.synset('tree.n.01')
lion = wn.synset('lion.n.01')
tiger = wn.synset('tiger.n.02')
cat = wn.synset('cat.n.01')
dog = wn.synset('dog.n.01')
synset๊ฐ์ฒด์ path_similarity() ๋ฉ์๋๋ฅผ ์ฌ์ฉํด 'tree', 'lion', 'tiger', 'cat', 'dog' ๋จ์ด์ ์ํธ ์ ์ฌ๋๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
entities = [tree , lion , tiger , cat , dog]
similarities = []
entity_names = [ entity.name().split('.')[0] for entity in entities]
#๋จ์ด๋ณ synset ๋ค์ iteration ํ๋ฉด์ ๋ค๋ฅธ ๋จ์ด๋ค์ synset๊ณผ ์ ์ฌ๋๋ฅผ ์ธก์
for entity in entities:
similarity = [round(entity.path_similarity(compared_entity), 2) for compared_entity in entities]
similarities.append(similarity)
#๊ฐ๋ณ ๋จ์ด๋ณ synset๊ณผ ๋ค๋ฅธ ๋จ์ด์ synset๊ณผ์ ์ ์ฌ๋๋ฅผ DataFrameํํ๋ก ์ ์ฅ
similarity_df = pd.DataFrame(similarities , columns=entity_names,index=entity_names)
similarity_df
4. SentiWordNet - ๊ฐ์ฑ์ฌ์
: ๋ณดํต WordNet ์ฌ์ ๋ณด๋จ SentiWordNet ์ฌ์ ์ ๋ ๋ง์ด ์ฌ์ฉ
SentiWordNet๋ WordNet Synset๊ณผ ์ ์ฌํ Senti_Synset ํด๋์ค๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค!
SentiWordNet ๋ชจ๋์ Senti_Synsets()๋ Synsets()์ฒ๋ผ Senti_Synsetํด๋์ค๋ฅผ ๋ฆฌ์คํธ ํํ๋ก ๋ฐํํฉ๋๋ค.
import nltk
from nltk.corpus import sentiwordnet as swn
senti_synsets = list(swn.senti_synsets('slow'))
print('senti_synsets() ๋ฐํ type: ', type(senti_synsets))
print('senti_synsets() ๋ฐํ ๊ฐ ๊ฐฏ์: ', len(senti_synsets))
print('senti_synsets() ๋ฐํ ๊ฐ: ', senti_synsets)
์ด 11๊ฐ์ ์๋ก ๋ค๋ฅธ ์๋ฏธ๋ฅผ ๊ฐ๋ Senti_Synset ๊ฐ์ฒด๊ฐ ๋ฐํ๋์์ต๋๋ค.
5. SentiWordNet - father/fabulous ๋น๊ต
import nltk
from nltk.corpus import sentiwordnet as swn
father = swn.senti_synset('father.n.01')
print('father ๊ธ์ ๊ฐ์ฑ ์ง์: ', father.pos_score())
print('father ๋ถ์ ๊ฐ์ฑ ์ง์: ', father.neg_score())
print('father ๊ฐ๊ด์ฑ ์ง์: ', father.obj_score())
print('\n')
fabulous = swn.senti_synset('fabulous.a.01')
print('fabulous ๊ธ์ ๊ฐ์ฑ ์ง์: ',fabulous .pos_score())
print('fabulous ๋ถ์ ๊ฐ์ฑ ์ง์: ',fabulous .neg_score())
๊ฐ๊ด์ฑ ์ง์๋ ๊ฐ์ฑ๋จ์ด์ผ ๋ 0, ๊ฐ์ฑ๋จ์ด๊ฐ ์๋ ๊ฐ๊ด์ ์ธ ๋จ์ด์ผ๋ 1๋ก ํํ.
๊ฐ์ฑ๋จ์ด์ผ ๋(=0)๋ ๋์ ๊ธ์ ๊ฐ์ฑ ์ง์/๋ถ์ ๊ฐ์ฑ ์ง์๋ก ๊ธ์ /๋ถ์ ์ด ํํ๋จ!
-father์ ๊ฐ๊ด์ ์ธ ๋จ์ด๋ก ๊ฐ๊ด์ฑ ์ง์๊ฐ 1.0์ด๊ณ , ๊ธ์ ๊ฐ์ฑ/๋ถ์ ๊ฐ์ฑ ์ง์ ๋ชจ๋ 0์ ๋๋ค.
-fabulous๋ ๊ฐ์ฑ๋จ์ด๋ก์ ๊ธ์ ๊ฐ์ฑ ์ง์๊ฐ 0.975, ๋ถ์ ๊ฐ์ฑ ์ง์๊ฐ 0.125์ ๋๋ค.