텍스트 데이터를 단순화하여 알고리즘이 이해하고 처리할 수 있도록 관리하기 쉽게 만드는 것
텍스트 정규화 : 소문자 변환, 불필요한 구두점과 공백 제거
구분자 사용 : 공백이나 구두점을 기준으로 텍스트 분해
고급 토큰화 기법 : 언어의 문법적, 의미적 구조를 고려하여 토큰 생성
형태소 분석
단어를 구성하는 최소 의미 단위인 형태소 분석
ex) "cats"는 "cat"과 복수형 접미사 "s"로 분해
어간 추출
어간을 추출하여 형태를 단순화
ex) "running", "runs", "ran" → "run"
어근 추출
단어의 어근을 추출하여 형태를 표준화
ex) "better"는 어근 "good"으로 변환
BPE
자주 등장하는 바이트 쌍을 병합하여 점진적으로 단어를 분해
ex) "lowest"가 "l", "o", "w", "e", "s", "t"로 분해되고, 자주 등장하는 "lo", "we"가 결합되어 "low", "est"로 변환
WordPiece
BPE와 유사하지만, 서브워드(subword) 단위로 토큰을 생성
ex) "unhappiness" → ["un", "##happiness"]
트랜스포머 모델(BERT 등)에서 사용
SentencePiece
언어에 중립적인 방식으로 텍스트를 서브워드 단위로 분해합니다.
BPE와 유사하지만, 문장을 토큰화하는 과정에서 공백을 고려하지 않음
ex) "unhappiness" → ["un", "ha", "ppiness"]
Google의 T5, ALBERT 모델에서 사용
=================================================
** from tensorflow.keras.preprocessing.text
text_to_word_sequence
주어진 텍스트를 단어 단위로 분할하여 리스트로 변환
Tokenizer() #토큰화 함수 지정
-> 텍스트를 정수 시퀀스로 변환하도록 설계
token = Tokenizer()
token.fit_on_texts(docs) #토큰화 함수에 문장 적용
word_counts : 순서를 기억하여 단어 카운트
document_count : 문장 카운트
word_docs : 각 단어가 몇 개의 문장에 포함되어 있는지
word_index : 각 단어에 매겨진 인덱스 값
=> 단어의 빈도에 따라 가장 빈번한 단어부터 / 동일 빈도일 경우 먼저 등장한 단어가 더 낮은 인덱스 할당
================================================
Okt 형태소 분석기
** from konlpy.tag import Okt
from collections import Counter
okt = Okt()
okt.morphs(sentence) -> 형태소 분석
Counter(tokens) -> 형태소 빈도 계산
================================================
word_size:
고유 단어의 총 개수에 1을 더한 값
이는 NLP에서 일반적인 관행으로, "0" 인덱스를 포함하기 위해 사용
-> "0" 인덱스는 패딩(padding)에 사용되거나, 구현에 따라 알 수 없는 단어를 나타낼 우려
num_classes :
총 클래스 수를 지정
이 경우 어휘 크기(word_size)로 설정되어, One-Hot Encoding에 어휘의 모든 단어에 대한 슬롯과 추가 "0" 인덱스가 있는지 확인
One-Hot Encoding :
to_categorical 함수는 클래스 벡터(정수 인덱스)를 바이너리 클래스 행렬로 변환
===================================================
Embedding 레이어 :
자연어 처리나 시퀀스 데이터를 다루는 모델에서 자주 사용되는 레이어로, 입력 데이터를 고정된 크기의 고차원 벡터로 변환해주는 역할
고차원 공간(예: 원-핫 인코딩된 벡터)의 단어를 저차원의 연속 벡터 공간으로 매핑하며 이는 표현을 더욱 효율적으로 만들고 계산 복잡성을 줄인다
ex) model.add(Embedding(word_size, 8, input_length=4))
word_size: 입력 차원의 크기, 즉 어휘 크기
데이터 세트에 있는 총 고유 단어 수에 1을 더한 값
8: 임베딩 벡터의 크기. 각 단어는 8차원 벡터로 표현
input_length=4: 입력 시퀀스의 길이
이 모델은 각 입력 시퀀스의 길이가 4일 것으로 예상(예: 입력당 4개의 단어)
_embedding을 사용한 모델 생성 후 평가_
from keras.datasets import imdb
from keras.preprocessing.sequence import pad_sequences
from keras.models import Sequential
from keras.layers import Embedding, Flatten, Dense
(X_train, y_train),(X_test, y_test) = imdb.load_data(num_words=10000)
** num_words 훈련 데이터에서 가장 자주 나타나는 상위 만개의 단어만 사용하겠다는 의미
X_train = pad_sequences(X_train, maxlen=100)
X_test = pad_sequences(X_test, maxlen=100)
** pad_sequences 서로 다른 길이의 데이터를 맞춰준다
여기서는 100으로
padding = 'pre'면 앞에 0을 채워서 맞춤(뒤는 post)
model = Sequential()
model.add(Input(shape=(100,))) # 모든 입력 데이터를 동일한 길이로 맞춰야 하기 때문에 패딩 사용 후 100으로 맞춤
model.add(Embedding(10000,8)) # 입력 차원은 단어 인덱스의 최대값 +1, 출력 차원은 임베딩 후 벡터 크기
#임베딩 레이어는 모델이 학습할 수 있는 단어 인덱스의 총 개수를 설정
model.add(Flatten()) # 임베딩된 시퀀스를 평탄화
model.add(Dense(1, activation='sigmoid')) # 긍정과 부정을 분류하므로 시그모이드 활성화 함수 사용
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
model.summary()
history = model.fit(X_train, y_train, epochs=10, batch_size=32, validation_split=0.2)
loss, accuracy = model.evaluate(X_test, y_test)
print(f"Test Accracy: {accuracy}")