분석doc.mindscale.kr/ngv/nlp03_02.pdf · 2020. 11. 10. · 단어 문서 행렬 만들기...
TRANSCRIPT
-
감성 분석
1
-
데이터 열기import pandas as pd df = pd.read_csv('imdb.zip')
데이터의 초반 5개를 확인합니다.
df.head()
.shape 로 데이터의 크기를 확인합니다.
df.shape
2
-
단어 문서 행렬 만들기CountVectorizer 를 사용하여 단어 문서 행렬을 만듭니다.
from sklearn.feature_extraction.text import CountVectorizer
max_features=1000 : 피처의 개수는 1000개로 설정합니다.
영어 데이터이므로 stop_words='english' 를 통해 관사 등을 제거합니다.
cv = CountVectorizer(max_features=1000, stop_words='english')
tdm = cv.fit_transform(df['review'])
3
-
데이터 분할 (1)review 로 만든 단어 문서 행렬을 x 로 sentiment 를 y 에 할당한다.
x = tdm y = df['sentiment']
4
-
데이터 분할 (2)x 와 y 를 훈련용과 테스트용으로 분할한다.
test_size=0.2 : 20%를 무작위로 테스트용 데이터로 할당한다.
random_state : 데이터를 할당할 때 생성할 난수의 씨앗값을 정한다. 재현가능한 결과를 위하여 하나의 숫자(예: 42)로 고정한다.
from sklearn.model_selection import train_test_split x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42)
5
-
데이터 분할 (3)x_train 은 x 의 훈련용 데이터이다.
x_train
x_test 는 x 의 테스트용 데이터이다.
x_test
y_train 은 y 의 훈련용 데이터이다.
y_train
y_test 는 y 의 테스트용 데이터이다.
y_test 6
-
로지스틱 회귀분석import tensorflow as tf
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Dense( 1, # 출력은 긍정(1)/부정(0) 하나 input_shape=(1000,), # 입력은 단어 수 activation='sigmoid'))
7
-
모형 요약model.summary()
8
-
학습 설정학습 알고리즘( optimizer )는 경사하강법의 일종인 adam
손실함수( loss )는 교차 엔트로피( binary_crossentropy )보조적인 지표로 정확도( accurary )를 사용한다. 정확도란 전체 사례 중 맞은 사례의비율이다.
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
9
-
모형 학습batch_size 는 한 번에 데이터를 입력하는 크기로 여기서는 한 번에 32개의 데이터를 입력한다.
모든 데이터를 한 번 입력하는 것을 1 에포크(epoch)라고 한다. 아래는 epochs=10 이므로 총 10 에포크를 진행한다.
10
-
학습
model.fit(x_train.toarray(), y_train.values, batch_size=32, epochs=10)
각 에포크마다 손실( loss )가 감소하고, 그에 따라 정확도( accuracy )가 증가하는 것을볼 수 있다.
ValueError: A Scipy sparse matrix was passed to a model that expects dense inputs.
Please densify your inputs first, such as calling x.toarray() 와 같은 에러가 발생할수 있다. 이때는 x_train 을 x_train.toarray() 로 바꿔준다.
11
-
모형 평가테스트용 데이터로 모형을 평가한다.
model.evaluate(x_test.toarray(), y_test.values, verbose=0)
훈련 때보다 테스트에서 손실은 높고, 정확도는 낮다. 이를 통해 과적합이 발생하였음을알 수 있다.
12
-
모형 저장model.save('imdb-sentiment.krs')
13
-
모형 불러오기import tensorflow as tf model = tf.keras.models.load_model('imdb-sentiment.krs')
14
-
파라미터
모형의 파라미터는 각 단어에 대한 가중치( weight )와 y 절편( bias )이다.
weight, bias = model.trainable_weights
15
-
단어와 가중치를 표로 정리단어와 가중치의 쌍을 표로 정리한다.
import pandas as pd
word_weight = pd.DataFrame({ '단어': cv.get_feature_names(), '가중치': weight.numpy().flat })
16
-
부정 단어음의 가중치를 가지는 단어가 많으면, 리뷰가 부정(0)으로 분류된다. 따라서 이들 단어는부정 단어라고 할 수 있다.
word_weight.sort_values('가중치').head()
나쁜(bad), 끔찍한(awful), 낭비(waste) 등이 강한 음의 가중치를 가진다.
17
-
긍정 단어양의 가중치를 가지는 단어가 많으면, 리뷰가 긍정(1)으로 분류된다. 따라서 이들 단어는긍정 단어라고 할 수 있다.
word_weight.sort_values('가중치').tail()
좋은(fine), 유쾌한(hilarious), 흥미로운(interesting) 등이 강한 양의 가중치를 가진다.
18
-
준단어 토큰화
19
-
tokenizers 설치!pip install tokenizers
20
-
데이터 열기import pandas as pd nsmc = pd.read_csv('ratings_train.txt', sep='\t')
21
-
텍스트만 저장토큰화를 위해 데이터에서 텍스트만 추출하여 텍스트 파일로 저장한다.
with open('sample.txt', 'w', encoding='utf8') as f: for row in nsmc.itertuples(): try: f.write(row.document) f.write('\n') except TypeError: pass
!head sample.txt
22
-
BPEfrom tokenizers import CharBPETokenizer
bpe = CharBPETokenizer(lowercase=True)
bpe.train(files='sample.txt', min_frequency=1, vocab_size=5000)
23
-
BPEenc = bpe.encode( '자연어 처리는 재밌다!')
enc.ids
enc.tokens
24
-
풀어쓰기
한글을 풀어쓰기하여 텍스트를 저장한다.
import unicodedata
with open('decomposed.txt', 'w', encoding='utf8') as f: for row in nsmc.itertuples(): try: q = unicodedata.normalize('NFD', row.document) f.write(q) f.write('\n') except TypeError: pass
25
-
풀어쓰기 BPEbpe = CharBPETokenizer(lowercase=True)
bpe.train(files='decomposed.txt', min_frequency=1, vocab_size=5000)
26
-
풀어쓰기 BPE텍스트를 토큰화 전에 풀어쓰기 한다.
text = unicodedata.normalize('NFD', '자연어 처리는 재밌다!') enc = bpe.encode(text)
enc.ids
enc.tokens
27
-
Byte-level BPEfrom tokenizers import ByteLevelBPETokenizer
byte = ByteLevelBPETokenizer(lowercase=True)
byte.train(files='sample.txt', min_frequency=1, vocab_size=5000)
28
-
Byte-level BPEenc = byte.encode('자연어 처리는 재밌다!')
enc.ids
enc.tokens
29
-
WordPiece modelfrom tokenizers import BertWordPieceTokenizer
wp = BertWordPieceTokenizer(lowercase=True)
wp.train(files='sample.txt', min_frequency=1, vocab_size=5000)
30
-
WordPiece modelenc = wp.encode('자연어 처리는 재밌다!')
enc.ids
enc.tokens
31
-
SentencePiece modelfrom tokenizers import SentencePieceBPETokenizer
sp = SentencePieceBPETokenizer()
sp.train(files='sample.txt', min_frequency=1, vocab_size=5000)
32
-
SentencePiece modelenc = sp.encode('자연어 처리는 재밌다!')
enc.ids
enc.tokens
33
-
저장
저장할 폴더를 만든다
import os
os.mkdir('nsmc-sp')
폴더에 저장
sp.save('nsmc-sp')
34
-
토크나이저 불러오기from tokenizers import SentencePieceBPETokenizer
sp = SentencePieceBPETokenizer( vocab_file='nsmc-sp/vocab.json', merges_file='nsmc-sp/merges.txt')
35
-
준단어 토큰화 함수def tokenizer(text): return sp.encode(text).tokens
tokenizer('좋은 아침입니다.')
36
-
단어 문서 행렬from sklearn.feature_extraction.text import CountVectorizer
cv = CountVectorizer(max_features=1000, tokenizer=tokenizer)
tdm = cv.fit_transform(nsmc.loc[0:3999, 'document'])
37
-
데이터 분할from sklearn.model_selection import train_test_split
y = nsmc.loc[0:3999, 'label']
x_train, x_test, y_train, y_test = train_test_split(tdm, y, test_size=0.2, random_state=42)
x_train.shape
38
-
모형
import tensorflow as tf
kernel_regularizer 에는 정규화를 위한 페널티 항을 추가한다. l1 , l2 그리고 l1_l2를 사용할 수 있다.
model = tf.keras.models.Sequential() model.add( tf.keras.layers.Dense( 1, input_shape=(1000,), activation='sigmoid', kernel_regularizer=tf.keras.regularizers.l2(0.001)))
39
-
요약
model.summary()
40
-
설정
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
41
-
학습
model.fit(x_train.toarray(), y_train.values, epochs=100, validation_split=0.1, callbacks=[tf.keras.callbacks.EarlyStopping()])
42
-
모형 평가model.evaluate(x_test.toarray(), y_test.values, verbose=0)
43
-
가중치
weights, _ = model.trainable_weights
import pandas as pd token_weight = pd.DataFrame({ '토큰': cv.get_feature_names(), '가중치': weights.numpy().flat })
44
-
부정단어
부정단어를 확인한다.
token_weight.sort_values('가중치').head()
45
-
긍정단어
긍정단어를 확인한다.
token_weight.sort_values('가중치').tail()
46
-
새로운 데이터에 적용새로운 데이터
new_data = ['뽀로로는 정말 재미있는 영화다.', '이런 영화를 만들다니 감독은 무슨 생각이냐?']
47
-
TDM 변환새로운 데이터를 TDM으로 변환한다. 이미 TDM의 형식이 정해져 있으므로fit_transform 대신 transform 을 사용한다.
x_new = cv.transform(new_data)
48
-
예측
새로운 데이터에서 각 리뷰가 긍정( 1 )일 확률을 예측한다.
model.predict(x_new.toarray())
49