자연어(Natural Language)
- 우리가 평소에 말하는 음성이나 텍스트를 의미
자연어 처리(Natural Language Processing)
- 음성이나 텍스트를 컴퓨터가 인식하고 처리
텍스트의 토큰화
토큰(token)
- 분석할 텍스트를 단어별, 문장별, 형태소 별로 나눈 것
# 전처리 과정 연습
# 케라스의 텍스트 전처리와 관련한 함수 중 text_to_word_sequence 함수를 불러옵니다.
from tensorflow.keras.preprocessing.text import text_to_word_sequence
text = '해보지 않으면 해낼 수 없다'
result = text_to_word_sequence(text)
print('원문 :', text)
print('토큰화된 결과 :', result)
text = '한글 분석을 시작합니다. 잘 되겠죠?'
result = text_to_word_sequence(text)
print('원문 :', text)
print('토큰화된 결과 :', result)
단어의 빈도수 파악
Tokenizer( )를 사용하면 단어의 빈도수를 쉽게 계산
from tensorflow.keras.preprocessing.text import Tokenizer
#전처리하려는 세 개의 문서(document)을 docs라는 리스트에 저장
docs = [
'먼저 텍스트의 각 단어를 나누어 토큰화합니다.',
'텍스트의 단어로 토큰화해야 딥러닝에서 인식됩니다.',
'토큰화한 결과는 딥러닝에서 사용할 수 있습니다.'
]
# Tokenizer() : 전처리 과정(토큰화)을 수행할 객체 반환
token = Tokenizer()
token.fit_on_texts(docs) # 문서(들)을 토큰화함.
# token.word_counts는 각 단어(token)가
# "전체 문서(document)"에서 몇 번 나타나는지 빈도 정보를 담고 있음
print('단어 카운트')
token.word_counts
docs = [
'난 난 꿈이 있었죠. 버려지고 찢겨 남루하여도 내 가슴 깊숙이 보물과 같이 간직했던 꿈. 혹 때론 누군가가 뜻 모를 비웃음 내 등뒤에 흘릴때도 난 참아야 했죠.',
'참을 수 있었죠. 그 날을 위해 늘 걱정하듯 말하죠. 헛된 꿈은 독이라고 세상은 끝이 정해진 책처럼 이미 돌이킬 수 없는 현실이라고 그래요 난 난 꿈이 있어요.',
'그 꿈을 믿어요. 나를 지켜봐요. 저 차갑게 서 있는 운명이란 벽앞에 당당히 마주칠 수 있어요.',
'언젠가 난 그 벽을 넘고서 저 하늘을 높이 날을 수 있어요. 이 무거운 세상도 나를 묶을 순 없죠.',
'내 삶의 끝에서 나 웃을 그 날을 함께해요.',
'늘 걱정하듯 말하죠. 헛된 꿈은 독이라고. 세상은 끝이 정해진 책처럼 이미 돌이킬 수 없는 현실이라고.',
'그래요. 난 난 꿈이 있어요. 그 꿈을 믿어요 나를 지켜봐요. 저 차갑게 서 있는 운명이란 벽앞에 당당히 마주칠 수 있어요.',
'언젠가 난 그 벽을 넘고서 저 하늘을 높이 날을 수 있어요. 이 무거운 세상도 나를 묶을 순 없죠. 내 삶의 끝에서 나 웃을 그 날을 함께해요.',
'난 난 꿈이 있어요. 그 꿈을 믿어요 나를 지켜봐요'
]
# Tokenizer()를 이용해 전처리 하는 과정
token = Tokenizer()
token.fit_on_texts(docs) # 문서(들)을 토큰화
# document_count 속성에서 총 몇 개의 문서가 들어 있는지 알 수 있음.
print('문서 카운트:\n', token.document_count, '\n' )
print('단어 카운트')
token.word_counts
word_docs 속성 : 각 단어가 몇 개의 문서에 등장하는지 파악
# token.word_docs를 통해 각 단어들이 몇 개의 문서에 등장하는지 나타냄
# 출력 되는 단어의 순서는 랜덤
print('각 단어가 몇 개의 문서에 포함되어 있는가')
token.word_docs
word_index : 각 단어의 인덱스 속성 확인
# 각 단어에 매겨진 인덱스 값을 출력하려면 word_index 속성에서 확인
print('각 단어에 매겨진 인덱스 값:\n', token.word_index)
token = Tokenizer( )
token의 여러 속성
단어의 원-핫 인코딩
텍스트를 숫자로 표현하는 방법
1. 원-핫 인코딩(One-hot encoding)
- 각 단어를 “one-hot”으로 인코딩!
- 예, 텍스트 : “the cat sat on the mat”
2. 고유 번호로 각 단어 인코딩
- 고유 번호를 사용하여 각 단어를 인코딩
- 예, “the”에 1에, “cat”에 2, “mat”에 3를 할당하는 식으로
- The cat sat on the mat” à [1, 2, 4, 5, 3]의 밀집 벡터로 인코딩
3. 단어 임베딩(word embedding)
text = '오랫동안 꿈꾸는 이는 그 꿈을 닮아간다'
token = Tokenizer()
token.fit_on_texts([text])
token.word_index
x = token.texts_to_sequences([text])
print(x)
from tensorflow.keras.utils import to_categorical
word_size = len(token.word_index) + 1
x = to_categorical(x, num_classes = word_size)
print(x)
원-핫 인코딩의 단점
- 단어들 간의 유사성, 관계 정보가 없음
- 인코딩된 코의 길이가 너무 길어짐
- 예를 들어 텍스트가 1만 개의 토큰(단어)로 구성되어다면 한 단어를 원-핫 인코딩하면 9,999개의 0과 1 개의 1로 구성된 희소벡터가 만들어짐. 이는 메모리 낭비외 여러 가지 문제를 초래할 수 있음
- 이러한 메모리 공간적 낭비를 줄이기 위해 등장한 것이 '단어 임베딩'임
단어 임베딩이란
- 단어를 숫자로 표현하는 기법 중 하나
- 각 단어 간의 유사도를 계산하여 각 단어를 N차원 벡터(요소의 개수가 N개인 데이터)로 변경시키는 것
희소 벡터(Sparse vector)
- 원-핫 인코딩은 표현하고자 하는 단어에 해당 하는 위치 값만 ‘핫(1)’이고 나머지는 0인 형태의 벡터를 생성
- 희소 벡터를 생성하는 원-핫 인코딩의 문제는 전체 데이터에서 단어의 개수가 늘어나면 벡터의 차원이 한 없이 증가
-
메모리 공간의 낭비 등 여러 가지 아쉬운 점이 발생할 것임
밀집 벡터(Dense vector)
- 희소 벡터과 상반되는 개념의 벡터
- 희소하지 않고 밀집한 벡터를 갖게 할 수 있음
워드 임베딩(Word Embedding)
- 적절한 방법을 통해 밀집 벡터 출력 : 훈련 데이터로부터 학습 함
from tensorflow.keras.preprocessing.text import Tokenizer
text = '매운맛 단맛 짠맛 꿀맛'
token = Tokenizer()
token.fit_on_texts([text])
print(token.word_index)
x = token.texts_to_sequences([text]) # 토큰(단어)의 인텍스를 요소로 하는 배열을 생성
print(type(x))
print(x)
x = token.texts_to_sequences(['단맛 짠맛 꿀맛 매운맛']) # 토큰(단어)의 인텍스를 요소로 하는 배열을 생성
print(type(x))
print(x)
x = token.texts_to_sequences(['단맛 짠맛 꿀맛']) # 토큰(단어)의 인텍스를 요소로 하는 배열을 생성
print(type(x))
print(x)
text = '조직의 뜨거운 맛을 보여주겠어'
token = Tokenizer()
token.fit_on_texts([text])
x = token.texts_to_sequences([text])
print(type(x))
print(x)
x = token.texts_to_sequences(['뜨거운 맛을 보여주겠어'])
print(type(x))
print(x)
x = token.texts_to_sequences(['뜨거운 뜨거운 맛을 보여주겠어'])
print(type(x))
print(x)
docs = [
'조직의 뜨거운 맛을 보여주겠어',
'아 벌써 10시 반이다'
]
token = Tokenizer()
token.fit_on_texts(docs) # docs를 토큰화
x = token.texts_to_sequences(docs)
print(x)
token.texts_to_sequences(['아 조직의 맛을 벌써?'])
from tensorflow.keras.utils import to_categorical
x = to_categorical(x, 4) # 여기서 4의 의미는?
print( type(x) )
print(x)
from tensorflow.keras.layers import Embedding
model = Sequential()
model.add(Embedding(16, 4))
model.add(Embedding(16, 4, input_length=2))
- 첫 번째 매개변수 : 처리하려는 전 데이터에 총 16개의 단어(토큰)가 있음을 알림
- 두 번째 매개변수 : 입력 벡터를 워드 임베딩을 해서 4차원 벡터로 출력
- 세 번째 매개변수 : 입력 벡터는 2차원(한 번에 입력되는 요소의 개수는 2개)
텍스트를 읽고 긍정, 부정 예측하기
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten, Embedding
from tensorflow.keras.utils import to_categorical
import numpy as np
10개의 리뷰를 보고 긍정적이면 1, 부정적이면 0으로 클래스(라벨) 생성
docs = ['너무 재밌네요',
'최고예요',
'참 잘 만든 영화예요',
'추천하고 싶은 영화에요',
'한 번 더 보고 싶네요',
'글세요',
'별로예요',
'생각보다 지루하네요',
'연기가 어색해요',
'재미없어요']
classes = np.array([1,1,1,1,1,0,0,0,0,0])
토큰화
# 토큰화
token = Tokenizer() # 토큰 처리 객체 생성
token.fit_on_texts(docs) # docs에 있는 텍스트를 토큰화함
token.word_index # 각 토큰(단어)와 해당 토큰(단어)에 대한 인덱스 정
입력 데이터 생성
x = token.texts_to_sequences(docs)
print(len(x))
x
x = token.texts_to_sequences(['너무 너무 재밌네요']) # 토큰(단어)의 인텍스를 요소로 하는 배열을 생성
print(x)
x = token.texts_to_sequences(['보고 싶은', '너무 너무 최고예요']) # 토큰(단어)의 인텍스를 요소로 하는 배열을 생성
print(x)
패딩
- 학습 데이터(벡터)의 길이가 같아야 함
- 패딩은 각 리뷰 데이터에 대한 토큰의 수를 동일하게 만드는 것을 말함
padded_x = pad_sequences(x, 4)
padded_x
모델 구조 설계
model.add(Embedding(T, N, input_length=M))
word_size = len(token.word_index) + 1
print(word_size) #23
model.add(Embedding(word_size, 8, input_length=4))
token = Tokenizer()
token.word_index #1
x = token.texts_to_sequences(docs) #2
padded_x = pad_sequences(x, 4) #3
word_size = len(token.word_index) +1
model = Sequential()
model.add(Embedding(word_size, 8, input_length=4))
로지스틱 회귀
model = Sequential()
model.add(Embedding(word_size, 8, input_length=4)
model.add(Flatten())
model.add(Dense(1, activation='sigmoid’))
model.summary()
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
model.fit(padded_x, classes, epochs=20)
print("\n Accuracy: %.4f" % (model.evaluate(padded_x, classes)[1]))
'빅데이터 분석가 양성과정 > Python - 딥러닝' 카테고리의 다른 글
딥러닝 사전지식 ( Pre-knowledge ) (1) | 2024.07.17 |
---|---|
순환 신경망(Recurrent Neural Network, RNN) (0) | 2024.07.17 |
이미지 인식 - CNN (0) | 2024.07.17 |
실습 (0) | 2024.07.17 |
모델 성능 향상 (1) | 2024.07.17 |