์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- ADP
- opencv
- numpy
- ์ฃผ์ฑ๋ถ๋ถ์
- ์ธ๋์ํ๋ง
- LDA
- ๋ฐ์ดํฐ๋ถ๊ท ํ
- Python
- Lambda
- ๋ ๋ฆฝํ๋ณธ
- ํ ์คํธ๋ถ์
- dataframe
- ๋์ํ๋ณธ
- ๋น ๋ฐ์ดํฐ๋ถ์๊ธฐ์ฌ
- ๋ฐ์ดํฐ๋ถ์์ค์ ๋ฌธ๊ฐ
- pandas
- DBSCAN
- ํฌ๋กค๋ง
- PCA
- ๋ฐ์ดํฐ๋ถ์์ ๋ฌธ๊ฐ
- ๋น ๋ฐ์ดํฐ
- ์ค๋ฒ์ํ๋ง
- ๊ตฐ์งํ
- iloc
- ์๋ํด๋ผ์ฐ๋
- ํ์ด์ฌ
- ๋ฐ์ดํฐ๋ถ์
- ADsP
- t-test
- datascience
Data Science LAB
[Python] SentiWordNet, VADER์ ์ด์ฉํ ์ํ ๊ฐ์ํ ๊ฐ์ฑ ๋ถ์ ๋ณธ๋ฌธ
[Python] SentiWordNet, VADER์ ์ด์ฉํ ์ํ ๊ฐ์ํ ๊ฐ์ฑ ๋ถ์
ใ ใ ใ ใ 2022. 2. 21. 10:57์ง๋ ํฌ์คํ ์์ WordNet๊ณผ SentiWordNet์ ๋ํด ๊ณต๋ถํ์์ผ๋ IMDB ์ํ ๊ฐ์ํ ๊ฐ์ฑ ๋ถ์์ SentiWordNet ๊ธฐ๋ฐ์ผ๋ก ์ํํด ๋ณด๋ ค๊ณ ํ๋ค.
https://suhye.tistory.com/entry/%E3%85%87-1?category=1040378
๊ฐ์ฑ ๋ถ์ ์์๋ ๋ค์๊ณผ ๊ฐ๋ค.
1. ๋ฌธ์๋ฅผ ๋ฌธ์ฅ ๋จ์๋ก ๋ถํด
2. ๋ฌธ์ฅ์ ๋จ์ด ๋จ์๋ก ํ ํฐํ ํ ๋ค ํ์ฌ ํ๊น
3. ํ์ฌ ํ๊น ๋ ๋จ์ด ๊ธฐ๋ฐ์ผ๋ก synset ๊ฐ์ฒด์ senti_synset ๊ฐ์ฒด ์์ฑ
4.Senti_synset์์ ๊ธ์ , ๋ถ์ ์ ๊ฐ์ฑ์ง์๋ฅผ ๊ตฌํ๊ณ ์ด๋ฅผ ๋ชจ๋ ํฉ์ฐํ์ฌ, ํน์ ๊ฐ ์ด์์ผ ๋ ๊ธ์ , ์๋ ๋์๋ ๋ถ์ ๊ฐ์ฑ์ผ๋ก ๊ฒฐ์
SentiWordNet
ํ์ฌ ํ๊น ๋ด๋ถ ํจ์ ์์ฑ
from nltk.corpus import wordnet as wn
def penn_to_wn(tag):
if tag.startswith('J'):
return wn.ADJ
elif tag.startswith('N'):
return wn.NOUN
elif tag.startswith('R'):
return wn.ADV
elif tag.startswith('V'):
return wn.VERB
ํ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ถ๋ฌ์จ ํ, NLTK์ PennTreebank Tag๋ฅผ ๊ธฐ๋ฐ์ผ๋ก WordNet์ ํ์ฌ Tag์ผ๋ก ๋ณํํด ์ฃผ๋ ํจ์๋ฅผ ์์ฑํ๋ค.
๋ฌธ์ฅ โจ ๋จ์ด โจ ํ์ฌ ํ๊น ํ SentiSynset ํด๋์ค ์์ฑ ํ Polarity Score ํฉ์ฐ ํจ์ ์์ฑ
from nltk.stem import WordNetLemmatizer
from nltk.corpus import sentiwordnet as swn
from nltk import sent_tokenize, word_tokenize, pos_tag
def swn_polarity(text):
#๊ฐ์ฑ ์ง์ ์ด๊ธฐํ
sentiment = 0.0
tokens_count = 0
lemmatizer = WordNetLemmatizer()
raw_sentences = sent_tokenize(text)
#๋ถํด๋ ๋ฌธ์ฅ๋ณ๋ก ๋จ์ด ํ ํฐ -> ํ์ฌ ํ๊น
ํ sentiSynset ์์ฑ -> ๊ฐ์ฑ ์ง์ ํฉ์ฐ
for raw_sentence in raw_sentences:
#NLTK ๊ธฐ๋ฐ์ ํ์ฌ ํ๊น
๋ฌธ์ฅ ์ถ์ถ
tagged_sentence = pos_tag(word_tokenize(raw_sentence))
for word, tag in tagged_sentence:
#WordNet ๊ธฐ๋ฐ ํ์ฌ ํ๊น
๊ณผ ์ด๊ทผ ์ถ์ถ
wn_tag = penn_to_wn(tag)
if wn_tag not in (wn.NOUN,wn.ADJ,wn.ADV):
continue
lemma = lemmatizer.lemmatize(word,pos=wn_tag)
if not lemma:
continue
#์ด๊ทผ์ ์ถ์ถํ ๋จ์ด์ WordNet ๊ธฐ๋ฐ ํ์ฌ ํ๊น
์ ์
๋ ฅํ์ฌ Synset ๊ฐ์ฒด๋ฅผ ์์ฑ
synsets = wn.synsets(lemma, pos=wn_tag)
if not synsets:
continue
#sentiwordnet์ ๊ฐ์ฑ ๋จ์ด ๋ถ์์ผ๋ก ๊ฐ์ฑ synset ์ถ์ถ
#๋ชจ๋ ๋จ์ด์ ๋ํด ๊ธ์ ๊ฐ์ฑ ์ง์๋ +๋ก, ๋ถ์ ๊ฐ์ฑ ์ง์๋ -๋ก ํฉ์ฐํ์ฌ ๊ฐ์ฑ ์ง์ ๊ณ์ฐ
synset = synsets[0]
swn_synset = swn.senti_synset(synset.name())
sentiment += (swn_synset.pos_score() - swn_synset.neg_score())
tokens_count += 1
if not tokens_count:
return 0
#์ด score๊ฐ 0์ด์์ด๋ฉด ๊ธ์ 1, ๊ทธ๋ ์ง ์์ผ๋ฉด ๋ถ์ 0 ๋ฐํ
if sentiment >= 0:
return 1
return 0
IMDB ๊ฐ์ํ์ ๊ฐ๋ณ ๋ฌธ์์ swn_polarity(text)ํจ์ ์ ์ฉ
review_df['preds'] = review_df['review'].apply(lambda x : swn_polarity(x))
y_target = review_df['sentiment'].values
preds = review_df['preds'].values
๊ฐ์ฑ ๋ถ์ ์ฑ๋ฅ ์์ธก
from sklearn.metrics import accuracy_score, confusion_matrix, precision_score
from sklearn.metrics import recall_score,f1_score, roc_auc_score
import numpy as np
print("confusion matrix : ",confusion_matrix(y_target,preds))
print("์ ํ๋ : {:.3f} ".format(accuracy_score(y_target,preds)))
print("์ ๋ฐ๋ : {:.3f}".format(precision_score(y_target,preds)))
print("์ฌํ์จ : {:.3f}".format(recall_score(y_target,preds)))
์ ํ๋์ ์ ๋ฐ๋, ์ฌํ์จ์ด 0.6-0.7์ฌ์ด๋ฅผ ๋ณด์ด๊ธฐ ๋๋ฌธ์ ๋์ง๋ ์๋ค.
VADER
VADER๋ ์์ ๋ฏธ๋์ด์ ๊ฐ์ฑ ๋ถ์ ์ฉ๋๋ก ๋ง๋ค์ด์ง ๋ฃฐ ๊ธฐ๋ฐ์ Lexicon์ด๋ค. SentimentInetensityAnalyzer ํด๋์ค๋ฅผ ์ด์ฉํ์ฌ ์ฝ๊ฒ ๊ฐ์ฑ ๋ถ์์ ์ ๊ณตํ๋ค.
์์ ํฌ์คํ ์์ nltk.download('all')์ ์ํํด ์ฃผ์์ผ๋ฏ๋ก ๋ฐ๋ก ์ค์น ์ฝ๋๋ ์คํํ์ง ์์๋ค.
์ด๋ฒ ํฌ์คํ ์์๋ ๊ฐ๋จํ๊ฒ revew_df์ ๊ฐ์ํ ์ค ํ๋๋ง ๊ฐ์ฑ ๋ถ์์ ์ํํด ๋ณด๊ณ ์ ํ๋ค.
VADER๋ ์ง์์ ์ผ๋ก ๋ฒ์ ์ด ์ ๋ฐ์ดํธ ๋๊ธฐ ๋๋ฌธ์ ์ค์นํ ๋ฒ์ ์ ๋ฐ๋ผ ๊ฒฐ๊ณผ๊ฐ ๋ค๋ฅด๊ฒ ์ถ๋ ฅ๋ ์ ์๋ค.
from nltk.sentiment.vader import SentimentIntensityAnalyzer
senti_analyzer = SentimentIntensityAnalyzer()
senti_scores = senti_analyzer.polarity_scores(review_df['review'][0])
print(senti_scores)
SentimentIntensityAnalyzer ๊ฐ์ฒด๋ฅผ ์์ฑํ ๋ค ๋ฌธ์๋ณ๋ก polarity_scores()๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด ์์ฝ๊ฒ ๊ฐ์ฑ ์ ์๋ฅผ ๊ตฌํ ์ ์๋ค.
'neg' : ๋ถ์ ๊ฐ์ฑ ์ง์
'neu' : ์ค๋ฆฝ์ ์ธ ๊ฐ์ฑ ์ง์
'pos' : ๊ธ์ ๊ฐ์ฑ ์ง์
'compound' : neg, neu, pos ์ง์๋ฅผ ์ ์ ํ๊ฒ ์กฐํฉํ์ฌ -1~1 ์ฌ์ด์ ๊ฐ์ฑ ์ง์๋ฅผ ํํํ ๊ฐ
def vader_polarity(review,threshold=0.1):
analyzer = SentimentIntensityAnalyzer()
scores = analyzer.polarity_scores(review)
#compound์ ๊ธฐ๋ฐํ์ฌ threshold ์
๋ ฅ๊ฐ ๋ณด๋ค ํฌ๋ฉด 1, ์๋๋ฉด 0 ๋ฐํ
agg_score = scores['compound']
final_sentiment = 1 if agg_score>= threshold else 0
return final_sentiment
#apply lambda ์์ ์ด์ฉํ์ฌ ๋ ์ฝ๋ ๋ณ vader_polarity() ์ํ ํ ๊ฒฐ๊ณผ 'vader_preds'์ ์ ์ฅ
review_df['vader_preds'] = review_df['review'].apply(lambda x: vader_polarity(x,0.1))
y_target = review_df['sentiment'].values
vader_preds = review_df['vader_preds'].values
print("Confusion matrix : ",confusion_matrix(y_target,vader_preds))
print("์ ํ๋ : {:.3f} ".format(accuracy_score(y_target,vader_preds)))
print("์ ๋ฐ๋ : {:.3f}".format(precision_score(y_target,vader_preds)))
print("์ฌํ์จ : {:.3f}".format(recall_score(y_target,vader_preds)))
vader_polarity()ํจ์๋ ์ ๋ ฅ ํ๋ผ๋ฏธํฐ๋ก ์ํ ๊ฐ์ํ ํ ์คํธ์ ๊ธ์ /๋ถ์ ์ ๊ฒฐ์ ํ๋ ์๊ณ๊ฐ์ ๊ฐ์ง๋ค.
SentimentIntensityAnalyzer ๊ฐ์ฒด์ polarity_scores()๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ๊ฐ์ฑ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ค.
์ ํ๋๊ฐ SentiWordNet์ผ๋ก ํฅ์๋์์ผ๋ฉฐ ์ฌํ์จ์ 0.851๋ก ๋ง์ด ํฅ์๋์๋ค.
'๐ Machine Learning > ํ ์คํธ ๋ถ์' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Python] ๋ฌธ์ ๊ตฐ์งํ (0) | 2022.02.24 |
---|---|
[Python] ํ ํฝ ๋ชจ๋ธ๋ง (20 ๋ด์ค๊ทธ๋ฃน) (0) | 2022.02.22 |
[Python] ๊ฐ์ฑ๋ถ์ - ๋น์ง๋ ํ์ต (0) | 2022.02.20 |
[Python] ๊ฐ์ฑ ๋ถ์(Sentiment Analysis) - ์ง๋ํ์ต (0) | 2022.02.19 |
[Python] ๋ด์ค ๊ทธ๋ฃน ๋ถ๋ฅ (0) | 2022.02.19 |