728x90
◎ NLP이냐 텍스트 분석이냐?¶
- NLP(National Language Processing)는 머신이 인간의 언어를 이해하고 해석하는 데 더 중섬을 두고 기술이 발전
- 텍스트 마이닝이라고도 불리는 텍스트 분석은 비정형 텍스트에서 의미 있는 정보를 추출하는 것에 좀 더 중점을 두고 발전
- 룰 기반 시스템에서 머신러닝의 텍스트 데이터를 기반으로 변경되면서 기술적 발전이 가능해짐
※ 텍스트 분석 집중 기술 영역
- 텍스트 분류 : 문서가 특정 분류 또는 카테고리에 속하는 것을 예측하는 기법을 통칭. 스팸 메일 검출 같은 프로그램으로 지도학습을 적용
- 감성 분석 : 텍스트에서 나타나는 감정/판단/믿음/의견/기분 등의 주관적인 요소를 분석하는 기법을 총칭. 리뷰, 여론조사 등의 다양한 영역에서 활용되는 지도학습과 비지도학습 모두 적용 가능
- 텍스트 요약 : 텍스트 내에서 중요한 주제나 중심 사상을 추출하는 기법. 대표적으로 토픽 모델링(Topic Modeling)이 해당
- 텍스트 군집화와 유사도 측정 : 비슷한 유형의 문서에 대해 군집화를 수행하는 기법. 텍스트 분류를 비지도학습으로 수행하는 방법
01. 텍스트 분석 이해¶
- 텍스트 분석은 비정형 데이터인 텍스트를 분석하는 것
- 비정형 데이터 텍스트를 word 기반의 다수의 피처로 추출하고 이 피처에 단어 빈도수와 같은 숫자 값을 부여하면 텍스트는 단어의 조합인 벡터값으로 표현 가능, 이러한 변환을 피처 벡터화 또는 피처 추출이라고 부름
- 피처 벡터화해서 변환하는 방법에는 BOW(Bag of Words)와 Word2Vec 방법이 존재
- 텍스트를 벡터값을 가지는 피처로 변환하는 것은 머신러닝 모델 적용하기 전에 수행해야할 매우 중요한 요소
◎ 텍스트 분석 수행 프로세스¶
※ 텍스트 분석 프로세스
- 텍스트 사전 준비작업(텍스트 전처리) : 텍스트를 피처로 만들기 전에 미리 클렌징, 대/소문자 변경, 특수문자 삭제 등의 클렌징 작업, 단어(Word) 등의 토큰화 작업, 의미 없는 단어 제거 작업, 어근 추출 등의 텍스트 정규화 작업을 수행하는 것을 통칭
- 피처 벡터화/추출 : 가공된 텍스트에서 피처를 추출하고 여기에 벡터 값을 할당, 대표적으로 BOW와 Word2Vec이 있으며, BOW는 대표적으로 Count 기반과 TF-IDF 기반 벡터화가 있음
- ML 모델 수립 및 학습/예측/평가 : 피처 벡터화된 데이터 세트에 ML 모델을 적용해 학습/예측 및 평가를 수행
◎ 파이썬 기반의 NLP, 텍스트 분석 패키지¶
- NTLK는 오래전부터 대표적인 NLP 패키지였지만, 수행 성능과 정확도, 신기술, 엔터프라이즈한 기능 지원 등의 측면에서 부족하여 이를 보완한 Genism과 SpaCy를 최근 자주 활용
- NLTK : 파이썬의 가장 대표적인 NLP 패키지. 방대한 데이터 세트와 서브 모듈을 가지고 있으며 NLP의 거의 모든 영역을 커버, 수행 속도 측면에서 아쉬운 부분이 있어서 실제 대량의 데이터 기반에서는 제대로 활용되지 못함
- Gensim : 토픽 모델링 분야에서 가장 두각을 나타내는 패키지. 토픽 모델링을 쉽게 구현할 수 있는 기능 제공해 왔으며 Word2Vec 구현 등의 다양한 신기능도 제공
- SpaCy : 뛰어난 수행 성능으로 최근 가장 주목을 받는 NLP패키지
- 사이킷런은 머신러닝 위주의 라이브러리여서 NLP를 위한 다양한 라이브러리는 가지고 있지 않음, 그래서 더 다양한 텍스트 분석이 적용돼야하는 경우 NTLK/Gensim/SpaCy와 같은 NLP 전용 패키지와 함께 결합해 애플리케이션을 적성하는 경우가 많음
02. 텍스트 사전 준비 작업(텍스트 전처리) - 텍스트 정규화¶
- 텍스트를 가공하는 준비 작업이 필요, 정규화는 클렌징, 정제, 토큰화, 어근화 등의 다양한 텍스트 데이터의 사전 작업을 수행하는 것을 의미
◎ 클렌징¶
- 텍스트에서 분석에 방해가 되는 불필요한 문자, 기호 등을 사전에 제거하는 작업
◎ 텍스트 토큰화¶
- 토큰화의 유형은 문서에서 문장을 분리하는 문장 토큰화와 문장에서 단어를 토큰으로 분리하는 단어 토큰화로 나눔-- 단어 토큰화 : 공백, 콤마(,), 마침표(.), 개행문자 등으로 단어를 분리
- -- 문장 토큰화 : 문장의 마침표(.), 개행문자(\n) 등 문장의 마지막을 뜻하는 기호에 따라 분리하는 것
In [1]:
# 문장 토큰화 예제
from nltk import sent_tokenize
import nltk
nltk.download('punkt')
text_sample = 'The Matrix is everywhere its all around us, here even in this room. \
You can see it out your window or on your television. \
You feel it when you go to work, or go to church or pay your taxes.'
sentences = sent_tokenize(text=text_sample)
print(type(sentences),len(sentences))
print(sentences)
<class 'list'> 3
['The Matrix is everywhere its all around us, here even in this room.', 'You can see it out your window or on your television.', 'You feel it when you go to work, or go to church or pay your taxes.']
[nltk_data] Downloading package punkt to
[nltk_data] C:\Users\설위준\AppData\Roaming\nltk_data...
[nltk_data] Package punkt is already up-to-date!
In [2]:
# 단어 토근화 예제
from nltk import word_tokenize
sentence = "The Matrix is everywhere its all around us, here even in this room."
words = word_tokenize(sentence)
print(type(words), len(words))
print(words)
<class 'list'> 15
['The', 'Matrix', 'is', 'everywhere', 'its', 'all', 'around', 'us', ',', 'here', 'even', 'in', 'this', 'room', '.']
In [3]:
from nltk import word_tokenize, sent_tokenize
#여러개의 문장으로 된 입력 데이터를 문장별로 단어 토큰화 만드는 함수 생성
def tokenize_text(text):
# 문장별로 분리 토큰
sentences = sent_tokenize(text)
# 분리된 문장별 단어 토큰화
word_tokens = [word_tokenize(sentence) for sentence in sentences]
return word_tokens
#여러 문장들에 대해 문장별 단어 토큰화 수행.
word_tokens = tokenize_text(text_sample)
print(type(word_tokens),len(word_tokens))
print(word_tokens)
<class 'list'> 3
[['The', 'Matrix', 'is', 'everywhere', 'its', 'all', 'around', 'us', ',', 'here', 'even', 'in', 'this', 'room', '.'], ['You', 'can', 'see', 'it', 'out', 'your', 'window', 'or', 'on', 'your', 'television', '.'], ['You', 'feel', 'it', 'when', 'you', 'go', 'to', 'work', ',', 'or', 'go', 'to', 'church', 'or', 'pay', 'your', 'taxes', '.']]
- 문장을 단어별로 하나씩 토큰화 할 경우 문맥적인 의미가 무시, 이러한 문제를 조금이라도 해결하고자 n-gram을 도입
◎ 스톱 워드 제거¶
- 스톱 워드는 분석에 큰 의미가 없는 단어를 지칭
- 영어에서 is, the, a, will 등 문맥적으로 큰 의미가 없는 단어로 사전에 제거하지 않으면 그 빈번함으로 인해 오히려 중요한 단어로 인지될 수 있기 때문에 이 의미 없는 단어를 제거하는 것이 중요한 전처리 작업
- NTLK의 경우 가장 다양한 언어의 스톱 워드를 제공
In [4]:
# 스톱 워드 예시
import nltk
nltk.download('stopwords')
print('영어 stop words 갯수:',len(nltk.corpus.stopwords.words('english')))
print(nltk.corpus.stopwords.words('english')[:20])
영어 stop words 갯수: 179
['i', 'me', 'my', 'myself', 'we', 'our', 'ours', 'ourselves', 'you', "you're", "you've", "you'll", "you'd", 'your', 'yours', 'yourself', 'yourselves', 'he', 'him', 'his']
[nltk_data] Downloading package stopwords to
[nltk_data] C:\Users\설위준\AppData\Roaming\nltk_data...
[nltk_data] Package stopwords is already up-to-date!
In [5]:
# 스톱워드 제거 쿼리
import nltk
stopwords = nltk.corpus.stopwords.words('english')
all_tokens = []
# 위 예제의 3개의 문장별로 얻은 word_tokens list 에 대해 stop word 제거 Loop
for sentence in word_tokens:
filtered_words=[]
# 개별 문장별로 tokenize된 sentence list에 대해 stop word 제거 Loop
for word in sentence:
#소문자로 모두 변환합니다.
word = word.lower()
# tokenize 된 개별 word가 stop words 들의 단어에 포함되지 않으면 word_tokens에 추가
if word not in stopwords:
filtered_words.append(word)
all_tokens.append(filtered_words)
print(all_tokens)
[['matrix', 'everywhere', 'around', 'us', ',', 'even', 'room', '.'], ['see', 'window', 'television', '.'], ['feel', 'go', 'work', ',', 'go', 'church', 'pay', 'taxes', '.']]
◎ Stemming과 Lemmatization¶
- Stemming과 Lemmatization은 문법적 또는 의미적으로 변환하는 단어의 원형을 찾는 것
- 두 기능 모두 원형 단어를 찾는다는 목적은 유사하지만, Lemmatization이 Stemming보다 정교하며 의미론적인 기반에서 단어의 원형을 찾음
- Stemming은 원형 단어로 변환 시 일반적인 방버블 적용하거나 더 단순화된 방법을 적용해 원래 단어에서 일부 철자가 훼손된 어근 단어를 추출하는 경향이 있음
- Lemmatization은 품사와 같은 문법적인 요소와 더 의미적인 부분을 감안해 정확한 철자로 된 어근 단어를 찾아 Lemmatization이 Stemming보다 변환에 더 오랜 시간이 필요
- NTLK는 Porter, Lancaster, Snowball Stemmer 등 다양한 Stemmer 제공, 그리고 Lemmatization을 위해서는 WordNetLemmatizer를 제공
03. Bag of Words - BOW¶
- Bag of Words 모델은 문서가 가지는 모든 단어(Words)를 문맥이나 순서를 무시하고 일괄적으로 단어에 대해 빈도 값을 부여해 피처 값을 추출하는 모델
- BOW 모델의 장점은 쉽고 빠른 구축이며 단순히 단어의 발생 횟수에 기반하고 있지만, 예상보다 문서의 특징을 잘 나타낼 수 있는 모델이어서 전통적으로 여러 분야에서 활용도가 높음
- But! BOW 기반의 NLP 연구는 여러 가지 제약에 부딪히고 있는데, 대표적인 단점은
-- 문맥 의미 반영 부족 : 단어의 순서를 고려하지 않기 때문에 단어의 문맥적인 의미가 무시, 이를 보완하고자 n_gram 기법을 활용할 수 있지만, 제한적인 부분에 그치므로 문맥적인 해석을 처리하지 못하는 단점이 존재 -- 희소 행렬 문제 : BOW로 피처 벡터화를 수행하면 희소 행렬 형태의 데이터 세트가 만들어지기 쉬움, 많은 문서에서 단어의 총 개수는 수만~수십만 개가 될 수 있는데, 하나의 문서에 있는 단어는 이 중 극히 일부분이므로 대부분의 데이터는 0 값으로 채워짐, 이처럼 대규모의 칼럼으로 구성된 행렬에서 대부분의 값이 0으로 채워지는 행렬을 희소 행렬이라고하고 반대는 밀집 행렬이라고 함, 희소 행렬은 ML 알고리즘의 수행 시간과 예측 성능을 떨어뜨림
◎ BOW 피처 벡터화¶
- 텍스트는 특정 의미를 가지는 숫자형 값인 벡터 값으로 변환해야 하는데, 이러한 변환을 피처 벡터화라고 함
- BOW 모델에서 피처 벡터화를 수행한다는 것은 모든 문서에서 모든 단어를 칼럼 형태로 나열하고 각 문서에서 해당 단어의 횟수나 정규화된 빈도를 값으로 부여하는 데이터 세트 모델로 변경하는 것
- BOW의 피처 벡터화는 카운트 기반의 벡터화와 TF-IDF 기반의 벡터화 두 가지 방식이 있음
- 카운트 벡터화에서는 카운트 값이 높을수록 중요한 단어로 인식, 그러나 카운트만 부여할 경우 그 문서의 특징을 나타내기보다는 언어의 특성상 문장에서 자주 사용될 수밖에 없는 단어까지 높은 값을 부여하게됨
- 이러한 문제를 보완하기 위해 TF-IDF는 개별 문서에서 자주 나타나는 단어에 높은 가중치를 주되, 모든 문서에서 전반적으로 자주 나타나는 단어에 대해서는 페널티를 주는 방식으로 값을 부여
- 문서마다 텍스트가 길고 문서의 개수가 많은 경우 카운트 방식보다는 TF-IDF 방식을 사용하는 것이 더 좋은 예측 성능을 보장
◎ 사이킷런의 Count 및 TF-IDF 벡터화 구현 : CountVectorizer, TfidfVecorizer¶
- 사이킷런의 CountVectorizer 클래스는 단지 피처 벡터화만 수행하지 않으며 소문자 일괄 변환, 토큰화, 스톱 워드 필터링 등의 텍스트 전처리도 함계 수행
※ CountVectorizer의 파라미터
- max_df : 전체 문서에 걸쳐서 너무 높은 빈도수의 단어를 제외하기 위한 파라미터
- min_df : 전체 문서에 걸쳐서 너무 낮은 빈도수의 단어를 제외하기 위한 파라미터
- max_features : 추출하는 피처의 개수를 제한하며 정수로 값을 지정
- stop_words : 'english'로 지정하면 영어의 스톱 워드로 지정된 단어는 추출에서 제외
- n_gram_range : 튜플 형태로 값을 지정
- analyzer : 피처 추출을 수행한 단위를 지정
- token_pattern : 토큰화를 수행하는 정규 표현식 패턴을 지정
- tokenizer : 토큰화를 별도의 ㅋ커스텀 함수로 이용시 적용
◎ BOW 벡터화를 위한 희소 행렬¶
- 사이킷런의 CountVectorizer/TfidfVectorizer를 이용해 텍스트를 피처 단위로 벡터화해 변환하고 CSR 형태의 희소 행렬을 반환
- 희소 행렬은 불필요한 0 값이 메모리 공간에 할당되어 메모리 공간이 많이 필요하며, 행렬의 크기가 커서 연산 시에도 데이터 엑세스를 위한 시간이 많이 소모
- 따라서 이러한 희소 행렬을 변환하는 대표적인 방법으로 COO 형식과 CSR 형식이 존재, CSR을 더 많이 사용
◎ 희소 행렬 - COO 형식¶
- COO(Coordinate : 좌표) 형식은 0이 아닌 데이터만 별도의 데이터 배열에 저장하고, 그 데이터가 가리키는 행과 열의 위치를 별도의 배열로 저장하는 방식
In [6]:
# COO 활용 쿼리
import numpy as np
dense = np.array( [ [ 3, 0, 1 ], [0, 2, 0 ] ] )
from scipy import sparse
from scipy import sparse
# 0 이 아닌 데이터 추출
data = np.array([3,1,2])
# 행 위치와 열 위치를 각각 array로 생성
row_pos = np.array([0,0,1])
col_pos = np.array([0,2,1])
# sparse 패키지의 coo_matrix를 이용하여 COO 형식으로 희소 행렬 생성
sparse_coo = sparse.coo_matrix((data, (row_pos,col_pos)))
sparse_coo.toarray()
Out[6]:
array([[3, 0, 1],
[0, 2, 0]])
In [7]:
from sklearn.datasets import fetch_20newsgroups
news_data = fetch_20newsgroups(subset='all',random_state=156)
# subset='train'으로 학습용(Train) 데이터만 추출, remove=('headers', 'footers', 'quotes')로 내용만 추출
train_news= fetch_20newsgroups(subset='train', remove=('headers', 'footers', 'quotes'), random_state=156)
X_train = train_news.data
y_train = train_news.target
print(type(X_train))
# subset='test'으로 테스트(Test) 데이터만 추출, remove=('headers', 'footers', 'quotes')로 내용만 추출
test_news= fetch_20newsgroups(subset='test',remove=('headers', 'footers','quotes'),random_state=156)
X_test = test_news.data
y_test = test_news.target
print('학습 데이터 크기 {0} , 테스트 데이터 크기 {1}'.format(len(train_news.data) , len(test_news.data)))
<class 'list'>
학습 데이터 크기 11314 , 테스트 데이터 크기 7532
◎ 사이킷런 파이프라인(Pipeline) 사용 및 GridSearchCV와의 결합¶
- Pipeline 방식 적용시 머신러닝 코드를 더 직관적이고 쉽게 작성 가능
In [8]:
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, roc_auc_score
# TfidfVectorizer 객체를 tfidf_vect 객체명으로, LogisticRegression객체를 lr_clf 객체명으로 생성하는 Pipeline생성
pipeline = Pipeline([
('tfidf_vect', TfidfVectorizer(stop_words='english', ngram_range=(1,2), max_df=300)),
('lr_clf', LogisticRegression(C=10))
])
# 별도의 TfidfVectorizer객체의 fit_transform( )과 LogisticRegression의 fit(), predict( )가 필요 없음.
# pipeline의 fit( ) 과 predict( ) 만으로 한꺼번에 Feature Vectorization과 ML 학습/예측이 가능.
pipeline.fit(X_train, y_train)
pred = pipeline.predict(X_test)
print('Pipeline을 통한 Logistic Regression 의 예측 정확도는 {0:.3f}'.format(accuracy_score(y_test ,pred)))
C:\work\envs\datascience\lib\site-packages\sklearn\linear_model\_logistic.py:763: ConvergenceWarning: lbfgs failed to converge (status=1):
STOP: TOTAL NO. of ITERATIONS REACHED LIMIT.
Increase the number of iterations (max_iter) or scale the data as shown in:
https://scikit-learn.org/stable/modules/preprocessing.html
Please also refer to the documentation for alternative solver options:
https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression
n_iter_i = _check_optimize_result(
Pipeline을 통한 Logistic Regression 의 예측 정확도는 0.701
- Pipeline 기반에서도 하이퍼 파라미터 튜닝을 GridSearchCV 방식으로 진행할 수 있게 지원
- 이렇게 하면 피처 벡터화를 위한 파라미터와 ML 알고리즘의 하이퍼 파라미터를 모두 한 번에 GridSearchCV를 이용해 최적화 가능
- 로지스틱 회귀 외에도 서포트 벡터머신(Support Vector Machine)과 나이브 베이즈 알고리즘도 희소 행렬 기반의 텍스트 분류에 자주 사용되는 머신러닝 알고리즘
In [9]:
from sklearn.pipeline import Pipeline
from sklearn.model_selection import GridSearchCV
pipeline = Pipeline([
('tfidf_vect', TfidfVectorizer(stop_words='english')),
('lr_clf', LogisticRegression())
])
# Pipeline에 기술된 각각의 객체 변수에 언더바(_)2개를 연달아 붙여 GridSearchCV에 사용될
# 파라미터/하이퍼 파라미터 이름과 값을 설정. .
params = { 'tfidf_vect__ngram_range': [(1,2)],
'tfidf_vect__max_df': [100],
'lr_clf__C': [1]
}
# GridSearchCV의 생성자에 Estimator가 아닌 Pipeline 객체 입력
grid_cv_pipe = GridSearchCV(pipeline, param_grid=params, cv=3 , scoring='accuracy',verbose=1)
grid_cv_pipe.fit(X_train , y_train)
print(grid_cv_pipe.best_params_ , grid_cv_pipe.best_score_)
pred = grid_cv_pipe.predict(X_test)
print('Pipeline을 통한 Logistic Regression 의 예측 정확도는 {0:.3f}'.format(accuracy_score(y_test ,pred)))
Fitting 3 folds for each of 1 candidates, totalling 3 fits
{'lr_clf__C': 1, 'tfidf_vect__max_df': 100, 'tfidf_vect__ngram_range': (1, 2)} 0.7305993705193182
Pipeline을 통한 Logistic Regression 의 예측 정확도는 0.682
05. 감성 분석¶
◎ 감성 분석 소개¶
- 감성 분석(Sentiment Analysis)은 문서의 주관적인 감성/의견/감정/기분 등을 파악하기 위한 방법으로 다양한 분야에서 활용
- 감성 분석은 긍정 감성 지수와 부정 감성 지수로 구성된 감성 지수를 합산해 긍정 감성 또는 부정 감성을 결정
- 감성 분석은 머신러닝 관점에서 지도학습과 비지도학습 방식으로 나눔-- 비지도학습은 Lexicon이라는 일종의 감성 어휘 사전을 이용해 문서의 긍정적, 부정적 감성 여부를 판단
- -- 지도학습은 학습 데이터와 타깃 레이블 값을 기반으로 감성 분석 학습을 수행한 뒤 이를 기반으로 다른 데이터 감성 분석을 예측하는 방법으로 일반적인 텍스트 기반의 분류와 거의 동일
◎ 지도학습 기반 감성 분석 실습 - IMDB 영화평¶
In [ ]:
# 코드
import re
# <br> html 태그는 replace 함수로 공백으로 변환
review_df['review'] = review_df['review'].str.replace('<br />',' ')
# 파이썬의 정규 표현식 모듈인 re를 이용하여 영어 문자열이 아닌 문자는 모두 공백으로 변환
review_df['review'] = review_df['review'].apply( lambda x : re.sub("[^a-zA-Z]", " ", x) )
from sklearn.model_selection import train_test_split
class_df = review_df['sentiment']
feature_df = review_df.drop(['id','sentiment'], axis=1, inplace=False)
X_train, X_test, y_train, y_test= train_test_split(feature_df, class_df, test_size=0.3, random_state=156)
X_train.shape, X_test.shape
# 스톱 워드는 english, filtering, ngram은 (1,2)로 설정해 TF-IDF 벡터화 수행.
# LogisticRegression의 C는 10으로 설정.
pipeline = Pipeline([
('tfidf_vect', TfidfVectorizer(stop_words='english', ngram_range=(1,2) )),
('lr_clf', LogisticRegression(C=10))])
pipeline.fit(X_train['review'], y_train)
pred = pipeline.predict(X_test['review'])
pred_probs = pipeline.predict_proba(X_test['review'])[:,1]
print('예측 정확도는 {0:.4f}, ROC-AUC는 {1:.4f}'.format(accuracy_score(y_test ,pred),
roc_auc_score(y_test, pred_probs)))
◎ 비지도학습 기반 감정 분석 소개¶
- Lexicon : 비지도 감정 분석 (한글을 지원하는 Lexicon은 없음)
- NLTK 패키지에 있는 감성 사전인 Lexicon은 단어의 위치나 주변 단어, 문맥, POS(Part of Speech) 등을 참고해 결정
- NLP에서 제공하는 WordNet 모듈은 방대한 영어 어휘 사전, WordNet은 단순한 어휘 사전이 아닌 시맨틱 분석을 제공하는 어휘 사전
- 시맨틱(semantic)은 산단히 표현하면 '문맥상 의미'
- NLTK은 감성에 대한 훌륭한 사전 역할을 제공한 장점은 있지만, 아쉽게도 예측 성능은 그리 좋지 못하다는 단점 존재
※ 대표적인 감성 사전
- SentiWordNet : 감성 단어 전용의 WordNet을 구현, WordNet의 Synset 개념을 감성 분석에 적용, WordNet의 Synet별로 긍정 감성 지수, 부정 감성 지수, 객관성 지수 3가지 감성 점수를 할당, 문장별로 단어들의 긍정 감성 지수와 부정 감성 지수를 합산하여 최종 감성 지수를 계산하고 이에 기반해 감성이 긍정인지 부정인지 결정
- VADER : 주로 소셜 미디어의 텍스트에 대한 감성 분석을 제공하기 위한 패키지, 뛰어난 감성 분석 결과를 제공하며, 비교적 빠른 수행 시간을 보장해 대용량 텍스트 데이터에 잘 사용되는 패키지
- Pattern : 예측 성능 측면에서 가장 주목받는 패키지
◎ SentiWordNet을 이용한 감성 분석¶
- SentiWordNet은 WordNet 기반의 synset을 이용, WordNet의 이용을 위해서는 NTLK를 셋업한 후에 WordNet 서브패키지와 데이터 세트를 내려받아야함
- synset은 하나의 단어가 가질 수 있는 여러 가지 시맨틱 정보를 개별 클래스로 나타낸 것
In [12]:
import pandas as pd
import nltk
nltk.download('all')
from nltk.corpus import wordnet as wn
term = 'present'
# 'present'라는 단어로 wordnet의 synsets 생성.
synsets = wn.synsets(term)
print('synsets() 반환 type :', type(synsets))
print('synsets() 반환 값 갯수:', len(synsets))
print('synsets() 반환 값 :', synsets)
# synset 객체를 단어별로 생성합니다.
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')
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
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())
father 긍정감성 지수: 0.0
father 부정감성 지수: 0.0
father 객관성 지수: 1.0
fabulous 긍정감성 지수: 0.875
fabulous 부정감성 지수: 0.125
◎ SentiWordNet을 이용한 영화 감상평 감성 분석¶
- 감성 분석 수행하는 개략적인 순서
1. 문서를 문장 단위로 분해 2. 다시 문장을 단어 단위로 토큰화하고 품사 태킹 3. 품사 태킹된 단어 기반으로 synset 객체와 senti_synset 객체 생성 4. Senti_synset에서 긍정/부정 감성 지수를 구하고 이를 모두 합산해 특정 임계치 값 이상일 때 긍정으로, 그렇지 않을 때는 부정 감성으로 결정
◎ VARDER을 이용한 감성 분석¶
- VARDER는 소셜 미디어의 감성 분석 용도로 만들어진 룰 기반의 Lexicon
- polarity_scores() 메서드는 딕셔너리 형태의 감성 점수를 반환 ('neg'는 부정, 'neu'는 중립, 'pos'는 긍점, 그리고 compound는 neg,neu,pos score를 적절히 조합해 -1에서 1 사이의 감성 지수를 표현한 것으로 보통 0.1 이상이면 긍정 아니면 부정으로 사용)
In [14]:
from IPython.core.display import display, HTML
display(HTML("<style>.container {width:80% !important;}</style>"))
728x90
'Book report > 파이썬 머신러닝 완벽가이드' 카테고리의 다른 글
[파이썬 머신러닝 완벽가이드] 08. 텍스트 분석(2) (1) | 2023.06.06 |
---|---|
[파이썬 머신러닝 완벽가이드] 07. 군집화 (0) | 2022.09.18 |
[파이썬 머신러닝 완벽가이드] 06. 차원 축소 (0) | 2022.09.12 |
[파이썬 머신러닝 완벽가이드] 05. 회귀 (0) | 2022.09.11 |
[파이썬 머신러닝 완벽가이드] 04. 분류 (0) | 2022.04.24 |