텍스트를 단어별, 문장별, 형태소별로 나누기 ➡️ 토큰: 작게 나누어진 하나의 단위
text_to_word_sequence(바꿀문장)

('단어', 단어가 등장한 횟수)로 출력token = Tokenizer()
token.fit_on_texts(바꿀문장)


token.document_count: token에 총 몇개의 문장이 들어있는지 세기
token.word_docs: 단어들이 각 몇개의 문장에 나오는지 세기
token.word_index: 각 단어에 부여된 인덱스 값 출력
단어가 문장의 다른 요소와 어떤 관계를 가지고 있는지 알아봐야 함



Tokenizer()를 불러와 단어 단위로 토큰화하고 각 단어의 인덱스 값 출력해서 확인token = Tokenizer()
token.fit_on_texts([바꾸려는문장])
print(token.word_index)

Tokenizer()의 texts_to_sequences() 함수를 사용해서 앞서 만들어진 토큰의 인덱스로만 채워진 새로운 배열 만들기x = token.texts_to_sequences([text])
print(x)
결과: [[1, 2, 3, 4, 5, 6]]
to_categorical(바꿀대상, 그 대상의 크기)함수를 이용해 1~6의 정수 6개로 인덱스되어있는 것을 0과 1로만 이루어진 배열로 바꾸기from tensorflow.keras.utils import to_categorical
word_size = len(token.word_index) + 1
# 배열 맨 앞에 0이 추가되므로 인덱스 수를 단어 개수보다 하나 더 많게 잡아줌
x = to_categorical(x, num_classes=word_size)
print(x)

원-핫 인코딩의 단점: 벡터의 길이가 너무 길어짐
예: 1만개의 단어 토큰으로 이루어진 말뭉치를 다룰 때, 이 데이터를 원-핫 인코딩으로 벡터화하면 9999개의 0과 하나의 1로 이루어진 단어 벡터를 1만개나 만들어야 함 ➡️ 공간 낭비
단어 임베딩: 주어진 배열을 정해진 길이로 압축시킴
결과적으로 밀집된 정보를 가지고 공간 낭비를 줄이는 결과치를 얻을 수 있음

How? 단어 간의 유사도를 계산하기
예: happy라는 단어는 bad보다 good에 가깝고, cat이라는 단어는 good보다는 dog에 가깝다는 것을 고려해 각 배열을 새로운 수치로 바꾸어 주는 것

단어간의 유사도 계산하는 방법: 적절한 크기로 배열을 바꿔주기 위해 최적의 유사도를 계산하는데 오차 역전파 사용
Embedding(입력될 총 단어 수, 출력될 벡터 크기, input_length(매번 입력할 단어 개수))함수를 사용
Embedding(16, 4, input_length=2) : 입력될 총 단어 개수는 16개이지만 매번 두개씩만 넣을 것임. 임베딩 후 출력되는 벡터의 크기는 4
from tensorflow.keras.layers import Embedding
model = Sequential()
model.add(Embedding(16, 4))
영화를 보고 남긴 리뷰를 딥러닝 모델로 학습해서 각 리뷰가 긍정적인지 부정적인지를 예측하는 것
docs = ["너무 재밌네요", "최고에요", ... "별로에요", "생각보다 지루하네요"]
class = array([1, 1, 1, 1, 1, 0, 0, 0, 0, 0])
fit_on_texts 사용token = Tokenizer()
token.fit_on_texts(docs)
print(token.word_index)

texts_to_sequences()x = token.texts_to_sequences(docs)
print(x)

pad_sequences(패딩할배열, 원하는길이) 는 원하는 길이보다 짧은 부분은 앞부분에 숫자 0을 넣어서 채워주고(예: [1, 2] ➡️ [0, 0, 1, 2]), 긴 데이터는 잘라서 같은 길이로 맞춤padded_x = pad_sequences(x, 4)
print(padded_x)

Embedding(입력될 총 단어 수, 출력될 벡터 크기, input_length(매번 입력할 단어 개수))함수 사용word_size = len(token.word_index) + 1
Embedding(word_size, 8 input_length = 4)
# input_length=4: 앞서 계산한 padding의 원하는 길이를 4로 설정했으므로
# 8은 임의로 정한 값이므로 원한다면 바꿀 수 있음
model = Sequential()
Embedding(word_size, 8 input_length = 4)
model.add(Flatten())
model.add(Dense(1, activation='sigmoid'))
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]))
