You are on page 1of 16

Kumoh National Institute of Technology

딥러닝 (Deep Learning)


자연어 처리 : 텍스트 분류

컴퓨터공학과 황준하
Contents

1. 텍스트 데이터와 딥러닝

2. 텍스트의 토큰화

3. 단어의 one-hot 인코딩

4. 단어 임베딩

5. 텍스트의 긍정 / 부정 예측하기

2/15
자연어 처리 : 텍스트 분류
1. 텍스트 데이터와 딥러닝

텍스트 데이터 학습 문제의 예


 다음과 같은 문제가 있다면 어떻게 딥러닝을 적용할 수
있을까 ? x y
◦ 1 : 긍정 , 0 : 부정 1
“ 너무 재밌네요”
 문제점숫자가 필요해 “ 참 잘 만든 영화예요” 1
◦ 숫자가 필요해 0
“ 별로예요”
 one-hot 인코딩 ?
“ 연기가 어색해요” 숫자가 필요해 ! 0 0 과 1 사이면 좋아
 단어 개수가 10,000 개면 ?
◦ x 데이터마다 x y

 단어 개수가 [[1,0,0,0,0,0,0,0,0], [0,1,0,0,0,0,0,0,0]] 1

다름 ? [[0,0,1,0,0,0,0,0,0], [0,0,0,1,0,0,0,0,0], ..] 1

[[0,0,0,0,0,0,1,0,0]] 0

[[0,0,0,0,0,0,0,1,0], [0,0,0,0,0,0,0,0,1]] 0
RNN 데이터와 유사  Flatten 학습 가능
 RNN 학습 가능 3/15
자연어 처리 : 텍스트 분류
1. 텍스트 데이터와 딥러닝

텍스트 데이터의 벡터화


 텍스트 데이터의 벡터화 과정
◦ 표준화 참 ♡ 잘 만든 영화예요 !!!
 불필요한 문자 제거 표준화

 어간화 등
참 잘 만든 영화다
◦ 토큰화 토큰화
 단어 단위로 분리
“ 참” , “ 잘” , “ 만든” , “ 영화다”
◦ 인덱스 생성 토큰 인덱스 생성 ( 숫자와 매치 )
 숫자와 매치시킴
2, 8, 15, 22
◦ 0~1 사이로 변환 one-hot 인코딩 또는 임베딩
 one-hot 인코딩
[[0, 0, 1, 0, 0, 0, 0, 0],
 단어 임베딩 [0, 0, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 0],
◦ x 데이터마다 다른 길이 [0, 0, 0, 0, 0, 0, 0, 1]]
 패딩 (0)  길이 동일하게 조정
4/15
자연어 처리 : 텍스트 분류
2. 텍스트의 토큰화

“ 텍스트의 토큰화”의 의미
 keras.preprocessing.text 모듈
◦ text_to_word_sequence() 함수
from tensorflow.keras.preprocessing.text import
text_to_word_sequence

text = " 해보지 않으면 해낼 수 없다 "


result = text_to_word_sequence(text) # 토큰화

print(f" 원문 : {text}")
print(f" 토큰화 : {result}")
원문 : 해보지 않으면 해낼 수 없다
토큰화 : [' 해보지 ', ' 않으면 ', ' 해낼 ', ' 수 ', ' 없다 ']

5/15
자연어 처리 : 텍스트 분류
2. 텍스트의 토큰화

keras : Tokenizer 클래스 (1)


 텍스트 처리를 위해 토큰화 이후 다양한 기능 필요
◦ BOW(Bag-of-Words) : 각 단어의 빈도수
◦ 각 단어가 몇 개의 문장에 등장했는가 ? 등
from tensorflow.keras.preprocessing.text import Tokenizer

docs = [' 먼저 텍스트의 각 단어를 나누어 토큰화 합니다 .',


' 텍스트의 단어로 토큰화 해야 딥러닝에서 인식됩니다 .',
' 토큰화 한 결과는 딥러닝에서 사용 할 수 있습니다 .']
단어 인덱스 : 빈도수가 높은
tokenizer = Tokenizer() 것부터 1, 2, 3, ...
# 토큰화 객체 생성
tokenizer.fit_on_texts(docs) # 문장 적용 => 단어 인덱스 구축
print(f" 단어 인덱스 :\n {tokenizer.word_index}") # 간 단어별 인덱스

단어 인덱스 :
{' 토큰화 ': 1, ' 텍스트의 ': 2, ' 딥러닝에서 ': 3, ' 먼저 ': 4, ' 각 ': 5,
' 단어를 ': 6, ' 나누어 ': 7, ' 합니다 ': 8, ' 단어로 ': 9, ' 해야 ': 10, '
인식됩니다 ': 11, ' 한 ': 12, ' 결과는 ': 13, ' 사용 ': 14, ' 할 ': 1
6/15
5, ': 수
자연어 처리 ': 분류
텍스트 16, ' 있습니다 ': 17}
2. 텍스트의 토큰화

keras : Tokenizer 클래스 (2)


print(f" 단어 카운트 :\n {tokenizer.word_counts}") # 단어별 빈도수
딕셔너리
print(f" 문장 카운트 :\n {tokenizer.document_count}") # 문장 개수
print(f" 단어별 등장 문장 카운트 :\n {tokenizer.word_docs}")
단어 카운트 :
OrderedDict([(' 먼저 ', 1), (' 텍스트의 ', 2), (' 각 ', 1), (' 단어를 ',
1), (' 나누어 ', 1), (' 토큰화 ', 3), (' 합니다 ', 1), (' 단어로 ', 1),
(' 해야 ', 1), (' 딥러닝에서 ', 2), (' 인식됩니다 ', 1), (' 한 ', 1), ('
결과는 ', 1), (' 사용 ', 1), (' 할 ', 1), (' 수 ', 1), (' 있습니다 ', 1)])
문장 카운트 :
3
단어별 등장 문장 카운트 :
defaultdict(<class 'int'>, {' 나누어 ': 1, ' 토큰화 ': 3, ' 먼저 ': 1,
' 텍스트의 ': 2, ' 합니다 ': 1, ' 각 ': 1, ' 단어를 ': 1, ' 해야 ': 1, '
인식됩니다 ': 1, ' 단어로 ': 1, ' 딥러닝에서 ': 2, ' 할 ': 1, ' 결과는 ': 1,
' 수 ': 1, ' 있습니다 ': 1, ' 한 ': 1, ' 사용 ': 1})

Tokenizer(num_words=10) : 본 자료의 딥러닝에서는 Tokenizer 의


빈도수가 높은 것부터 10 개만 사용 인덱싱 , 토큰화 기능만 사용
7/15
자연어 처리 : 텍스트 분류
2. 텍스트의 토큰화

텍스트 데이터  인덱싱 데이터 변환


 텍스트 데이터  인덱싱 데이터 변환
◦ tokenizer.texts_to_sequences(doc) 함수
 각 예제 (x) 별로 단어 개수 일치시키기 ( 패딩 )
◦ 최대 길이가 되도록 앞에 0 추가
◦ keras.preprocessing.sequence.pad_sequences 함수
[[1, 2], [3], [4, 5, 6, 7], [8, 9, 10],
[11, 12, 13], [14], [15], [16, 17], [18,
tokenizer = Tokenizer() 19], [20]]
패딩 결과 :
tokenizer.fit_on_texts(doc)
[[ 0 0 1 2]
x = tokenizer.texts_to_sequences(doc) [ 0 0 0 3]
max_word_count = max(map(len, x)) [ 4 5 6 7]
[ 0 8 9 10]
padded_x = pad_sequences(x,
[ 0 11 12 13]
max_word_count) [ 0 0 0 14]
pad_sequences(..., padding=“post”)
[ 0 0 0 15]
=> 0 이 뒤에 추가됨 [ 0 0 16 17]
[ 0 0 18 19]
[ 0 0 0 20]] 8/15
자연어 처리 : 텍스트 분류
3. 단어의 one-hot 인코딩

단어의 one-hot 인코딩 표현


 어휘 사전
◦ 현재 텍스트 데이터에 등장하는 단어와 인덱스 정보
 one-hot 인코딩
◦ n 개의 단어가 어휘 사전에 있다면
◦ 하나의 단어는 (n + 1) 개의 0 벡터로 표현
 해당 단어의 인덱스 위치만 1 로 변경

단어 인덱스는 1 부터 시작하므로 one-


hot 인코딩의 첫 번째 값은 모두 0 으로
동일 (0 인덱스 - 패딩 (0) 위치 ), 이후로
단어 인덱스에 맞는 위치만 1 로 설정
즉 , 0  [1 0 0 0 0 0 0]

9/15
자연어 처리 : 텍스트 분류
3. 단어의 one-hot 인코딩

tokenizer.texts_to_sequences(doc) 함수
import tensorflow as tf
 텍스트
from 데이터를
tensorflow 인덱스
import keras데이터로 변환
from tensorflow.keras.preprocessing.text import Tokenizer
◦ x = tokenizer.texts_to_sequences(doc)
doc = [" 오랫동안 꿈꾸는 이는 그 꿈을 닮아간다 "]
 one-hot 인코딩으로 변환
tokenizer = Tokenizer()
◦ keras.utils.to_categorical(x, num_classes= 단어수 +1)
tokenizer.fit_on_texts(doc)
print(tokenizer.word_index)

x = tokenizer.texts_to_sequences(doc) # 인덱스로 변환
print(x)

word_size = len(tokenizer.word_index) + 1
x = keras.utils.to_categorical(x, num_classes=word_size) # one-
hot 인코딩으로 변환
{' 오랫동안 ': 1, ' 꿈꾸는 ': 2, ' 이는 ': 3, ' 그 ': 4, ' 꿈을 ': 5, '
print(x) 닮아간다 ': 6}
[[1, 2, 3, 4, 5, 6]]
[[[0. 1. 0. 0. 0. 0. 0.]
[0. 0. 1. 0. 0. 0. 0.]
[0. 0. 0. 1. 0. 0. 0.]
[0. 0. 0. 0. 1. 0. 0.]
[0. 0. 0. 0. 0. 1. 0.] 10/15
자연어 처리 : 텍스트 분류
3. 단어의 one-hot 인코딩

one-hot 인코딩의 문제점


 벡터의 길이가 너무 길어질 수 있음
◦ 예 , 어휘 사전에 1 만 개의 단어가 있다면
 하나의 단어 : 10,000 개의 0 과 하나의 1 로 이루어짐
 단어들 사이의 관계를 파악할 수 없음
◦ 주어진 문제 ( 데이터 ) 에서 유사어 , 반의어 등
 좋다 - 환상적이다 , 나쁘다 - 형편없다
 벡터 사이에도 가깝게 나타난다면 학습에 유리 ?!
 학습을 통해 가까움 정도를 스스로 학습하도록 함
 단어 임베딩

11/15
자연어 처리 : 텍스트 분류
4. 단어 임베딩

단어 임베딩
 one-hot 인코딩 표현을 짧은 벡터로 표현
◦ 예 , 15 개 단어의 one-hot 벡터 . 즉 , 16 개 0/1
 4 개의 값으로 표현한다면 ? 단어 임베딩

단어 임베딩 값들은 어떻게


결정 ?
학습을 통해 문제 ( 데이터 ) 에
맞는 값 결정
- 유사 단어 : 가까운 값

12/15
자연어 처리 : 텍스트 분류
4. 단어 임베딩

단어 임베딩 레이어
 Embedding 레이어
x = layers.Embedding(word_size, 8, input_length=4)
(inputs)
◦ word_size : 단어 개수 + 1 (one-hot 인코딩 비트 개수 )
◦ 8 : 8 개의 실수로 표현
◦ input_length=4 : 한 예제 (example) 의 최대 단어 개수
◦ 참고 : 가중치 개수
 word_size * 8
 one-hot 인코딩 (word_size) 을 8 개의 값으로 매핑시키는 작업

13/15
자연어 처리 : 텍스트 분류
5. 텍스트의 긍정 / 부정 예측하기

텍스트의 긍정 / 부정 예측하기
 프로그램
◦ 09_1_1_ 영화 리뷰 긍정 _ 부정 예측하기 .ipynb
◦ 가상의 데이터 대상
docs = [" 너무 재밌네요 ", " 최고예요 ", " 참 잘 만든 영화예요 ",
" 추천하고 싶은 영화입니다 ", " 한번 더 보고싶네요 ",
" 글쎄요 ", " 별로예요 ", " 생각보다 지루하네요 ",
" 연기가 어색해요 ", " 재미있어요 "]

y_train = np.array([1, 1, 1, 1, 1, 0, 0, 0, 0, 0])

14/15
자연어 처리 : 텍스트 분류
연습 문제

네이버 영화 리뷰 감성 분석 ( 긍정 / 부정 )
 데이터 : 네이버 영화 리뷰 전처리 후 데이터
◦ 원본 : https://github.com/e9t/nsmc/
◦ 제공 데이터 : 전처리 후 데이터
 학습 데이터 : preprocessed_ratings_train.csv
 열 : preprocessed_document, label
 preprcessed_document : 리뷰 내용
 label : 1( 긍정 ), 0( 부정 )
 145393 개
 검증 데이터 : preprocessed_ratings_test.csv
 48852 개
 실험 : 학습 데이터로 학습하고 검증 데이터로 검증하면서
검증 데이터의 accuracy 의 추세를 분석하라 .
15/15
자연어 처리 : 텍스트 분류
연습 문제

[ 참고 ] 네이버 영화 리뷰 감성 분석
 데이터 읽기 (x_train(docs), y_train 만들기 )
preprocessed_train_data =
pd.read_csv("preprocessed_ratings_train.csv")
preprocessed_test_data =
pd.read_csv("preprocessed_ratings_test.csv")
docs =
preprocessed_train_data["preprocessed_document"].values
print(docs[:10]) # 확인

y_train = preprocessed_train_data["label"].values
tokenizer.texts_to_sequence(docs) 에서 에러 발생 시
- 에러 : IOPub data rate exceeded. ...
 JupyterLab 실행 시 다음 옵션을 추가하여 실행
jupyter lab “ 폴더” --NotebookApp.iopub_data_rate_limit=1.0e10

16/15
자연어 처리 : 텍스트 분류

You might also like