원-핫 인코딩(one-hot encoding)
- 단어 또는 문장을 이진 벡터로 변환하여 각 단어 또는 문장 요소의 존재 여부를 표현
- 각 단어를 모두 0으로 바꾸고 원하는 단어만 1로 바꾸어 주는 것
나는 = [ 0 1 0 0 0 0 0 0 ]
그대만큼 = [ 0 0 1 0 0 0 0 0 ]
사랑스러운 = [ 0 0 0 1 0 0 0 0 ]
사람을 = [ 0 0 0 0 1 0 0 0 ]
본 = [ 0 0 0 0 0 1 0 0 ]
적이 = [ 0 0 0 0 0 0 1 0 ]
없다 =[ 0 0 0 0 0 0 0 1 ]
※ 맨 첫 번째는 0 인덱스 자리
1. 토큰화 및 인덱스 값 출력
text = '나는 그대만큼 사랑스러운 사람을 본 적이 없다'
token = Tokenizer()
token.fit_on_texts([text])
print(token.word_index)
{'나는': 1, '그대만큼': 2, '사랑스러운': 3, '사람을': 4, '본': 5, '적이': 6, '없다': 7}
2. 토큰 인덱스 배열 생성
- texts_to_sequences()
: 텍스트를 단어 단위로 분리하고, 각 단어를 해당하는 정수 인덱스로 변환하여 배열 생성
: Tokenizer에 존재
x = token.texts_to_sequences([text])
print(x)
[[1, 2, 3, 4, 5, 6, 7]]
3. 원-핫 인코딩
- 배열 맨 앞에 0이 추가되므로 단어 수보다 1이 더 많게 인덱스 숫자 잡아줘야 함
- to_categorical()
: 정수로 인덱스된 배열을 0과 1로만 이루어진 배열로 바꾸어 줌
: keras에 존재
from tensorflow.keras.utils import to_categorical
#인덱스 수에 하나를 추가해서 원-핫 인코딩 배열 만들기
word_size = len(token.word_index) + 1
x = to_categorical(x, num_classes=word_size)
print(x)
[[[0. 1. 0. 0. 0. 0. 0. 0.]
[0. 0. 1. 0. 0. 0. 0. 0.]
[0. 0. 0. 1. 0. 0. 0. 0.]
[0. 0. 0. 0. 1. 0. 0. 0.]
[0. 0. 0. 0. 0. 1. 0. 0.]
[0. 0. 0. 0. 0. 0. 1. 0.]
[0. 0. 0. 0. 0. 0. 0. 1.]]]
단어 임베딩(word embedding)
- 단어들 간의 의미적 유사성과 관계를 반영하도록 단어를 저차원의 밀집 벡터로 매핑
- 차원이 매우 크고, 단어 간의 의미적인 유사성을 고려하지 않은 원-핫 인코딩의 문제점 해결
- Embedding(input_dim, output_dim, input_length=n)
: 단어를 밀집된 벡터로 표현
: keras에 존재
- input_dim : 입력될 총 단어 수
- output_dim : 임베딩 후 출력되는 벡터 크기
- input_length : 입력되는 배열의 길이
from tensorflow.keras.layers import Embedding
model = Sequential()
model.add(Embedding(16, 4, input_length=2))
긍정 부정 예측 코드
- 영화 리뷰를 딥러닝 모델로 학습해서 각 리뷰가 긍정적인지 부정적인지 예측
1. 리뷰 클래스 지정
from numpy import array
# 텍스트 리뷰 자료 지정
docs = ["너무 재밌네요","최고예요","참 잘 만든 영화예요","추천하고 싶은 영화입니다","한번 더 보고싶네요","글쎄요","별로예요","생각보다 지루하네요","연기가 어색해요","재미없어요"]
# 긍정 리뷰는 1, 부정 리뷰는 0으로 클래스 지정
classes = array([1,1,1,1,1,0,0,0,0,0])
2. 토큰화
token = Tokenizer()
token.fit_on_texts(docs)
print(token.word_index)
{'너무': 1, '재밌네요': 2, '최고예요': 3, '참': 4, '잘': 5, '만든': 6, '영화예요': 7, '추천하고': 8,
'싶은': 9, '영화입니다': 10, '한번': 11, '더': 12, '보고': 13, '싶네요': 14, '글쎄요': 15,
'별로예요': 16, '생각보다': 17, '지루하네요': 18, '연기가': 19, '어색해요': 20, '재미없어요': 21}
3. 토큰 인덱스 배열 생성
x = token.texts_to_sequences(docs)
print("리뷰 텍스트, 토큰화 결과:\n", x)
리뷰 텍스트, 토큰화 결과:
[[1, 2], [3], [4, 5, 6, 7], [8, 9, 10], [11, 12, 13, 14], [15], [16], [17, 18], [19, 20], [21]]
4. 패딩(padding)
- 학습 데이터의 길이를 똑같이 맞추어 주는 작업
- pad_sequences()
: 원하는 길이보다 짧은 부분은 숫자 0을 넣어서 채워 주고, 긴 데이터는 잘라서 같은 길이로 맞춤
: keras에 존재
from tensorflow.keras.preprocessing.sequence import pad_sequences
# 패딩. 서로 다른 길이의 데이터를 4로 맞추어 줌
padded_x = pad_sequences(x, 4)
print("패딩 결과:\n", padded_x)
패딩 결과:
[[ 0 0 1 2]
[ 0 0 0 3]
[ 4 5 6 7]
[ 0 8 9 10]
[11 12 13 14]
[ 0 0 0 15]
[ 0 0 0 16]
[ 0 0 17 18]
[ 0 0 19 20]
[ 0 0 0 21]]
5. 모델 설정 - 단어 임베딩 포함
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense,Flatten,Embedding
# 단어 임베딩 함수의 입력 인덱스 수
word_size = len(token.word_index) + 1
model = Sequential()
model.add(Embedding(word_size, 8, input_length=4))
model.add(Flatten())
model.add(Dense(1, activation='sigmoid'))
model.summary()
6. 모델 실행
model.compile(optimizer='adam',loss='binary_crossentropy', metrics=['accuracy'])
model.fit(padded_x, classes, epochs=20)
print("\nAccuracy : %.4f" % (model.evaluate(padded_x, classes)[1]))
'모두의 딥러닝 개정 3판'의 내용과 https://github.com/taehojo/deeplearning의 코드 참고
'AI > 모두의 딥러닝' 카테고리의 다른 글
[모두의 딥러닝] 24. 순환 신경망(RNN), LSTM(Long Short Term Memory) - 로이터 뉴스 카테고리 분류 데이터 (0) | 2023.06.05 |
---|---|
[모두의 딥러닝] 22. 텍스트 전처리 - 토큰화(tokenization), 빈도 수 세기 (0) | 2023.06.02 |
[모두의 딥러닝] 21. 컨볼루션 신경망(CNN), 풀링(Pooling), 드롭아웃(drop out), 플래튼(flatten) - MNIST 데이터 (0) | 2023.06.02 |
[모두의 딥러닝] 20. 이미지 인식, 데이터 전처리 - MNIST 데이터 (2) | 2023.05.29 |
[모두의 딥러닝] 19. 결측치 처리, 속성별 관련도 추출 - 부동산 가격 예측 데이터 (0) | 2023.05.29 |