[이론] 자연어처리 intro
- Word Embedding
- NLP with Deep Learning(RNN)
- Sentiment Analysis
- Subword Segmentation
- Overfitting and Transfer Learning
- Text generation
- 기계번역
- 전이학습을 통한 Seq2Seq Text Generation
- Encoder-Decoder Model
- Attention Model
- Text Summarization
- Transformers
- BERT(Bidirectional Encoder Representational from Transformers)
- GPT/T5
<NLP의 기본 사전 지식>
1. Corpus(말뭉치, collection of texts) : 자연어 분석 작업을 위해 만든 샘플 문서 집합.
2. Token : 자연어 문서를 분석하기 위해 긴 문자열을 작은 단위로 나눈 것
3. Tokenize : 문자열을 여러개의 조각 즉 여러 토큰으로 쪼개는 것
Tokenization
입력 text를 가진 덩어리 (단어, 문장, 구, 절)로 분할 하는 작업.
Python split() 메소드 사용
nltk.sent_tokenize : 문장 분리
nltk.word_tokenize : 단어 분리
tensorflow 제공의 Tokenizer : 단순히 구둣점이나 space로 단어를 분리한다.
Hugging Face Tokenizer : BPE, WordPiece, SentencePiece 등을 제공한다.
BOW
Bag of Words
- 모든 문장을 토큰화 하고 각 문장에 토큰이 몇 번 등장하는지 셈.
- 각 토큰을 feature 화 => Text Vetorization
- Scikit-learn의 nltk.CountVectorizer 메소드 이용
<CountVectorizer>
min_df : vocabulary 에 포함할 최소 발생 빈도
ngram_range : (1, 1) - unigram only, (1, 2) - unigram + bigram
max_features : top max_features 만으로 vocabulary 구성
token_pattern = (?u)\b\w\w+\b : unocode 영수자 2 글자 이상만 포함
문제점 :
1. 단어들 간 순서를 유지할 수 없음.
=> n-gram로 일부 해결
=> bigrams 인접 단어의 쌍으로 구성
=> trigrams 인접 세개의 단어로 구성
2. 카운터가 normalize 되어있지 않음. 단어간 중요도를 모름 (a, the 같은 거 필요없으니까)
=> TF-IDF 로 해결
=> Scikit-learn의 TfidfVectorizer 메소드 사용
TF-IDF(Term Frequency - Inverse Document Frequency)
- TF : 단어 빈도 term frequency
특정 단어가 문서 내에 얼마나 자주 등장하는지 나타내는 값.
높을 수록 특정 문서에서 중요하다고 간주
- DF : 문서 빈도 document frequency
단어 자체가 전체 문서 집단 내에서 사용되는 빈도
DF가 높으면 그 단어가 흔하게 등장함을 의미(조사같은거)
- IDF(역문서 빈도, inverse document frequency) => DF의 역수
- TF-IDF = TF * IDF
low TF-IDF : 전체 문서에서 공통으로 사용되는 단어임을 의미
high TF-IDF : 모든 문서가 아닌, 특정 문서에서 자주 사용되는 단어임을 의미
One-hot Encoding
문제점 :
단어를 단순히 index 번호에 따라 one-hot-encoding 으로 vectorize 하므로 단어 간 유사성을 파악하지 못함
=> Word Embedding 으로 해결 : 단어/문장 간 관련도 계산, 의미적/문법적 정보 함축, 전이학습 가능
Word Embedding
- 숫자화된 단어의 나열로부터 sentiment 추출
- 연관성 있는 단어들을 군집화 하여 multi-dimension 공간에 vector로 표시
=> 단어나 문장을 vector space로 끼워넣음(embedding)
- Projection Matrix 라고도 명칭
<Word2Vec>
- 2013년 구글 개발
- One-Hidden layer의 shallow network => 최초의 neural embedding model
- 매우 큰 Corpus에서 자동학습
훈련방법 :
- 중심 단어로 주변 단어를 (skip-gram), 주변 단어로 중심단어를 (CBOW)예측하는 과정에서 단어를 벡터로 임베딩 하는 두 가지 방법.
- 임베딩 된 단어의 내적(innor product)이 코사인 유사도가 되도록 함
- 유사도 측정(Cosine Similarity) 진행
<GloVe (Global Vectors for Word Representation)>
- 미국 스탠포드 대학 개발
- Word2Vec은 사용자가 지정한 window(주변 단어 몇 개)내에서만 학습/분석이 이루어 지기 때문에 전체 Corpus 에서 co-occurrence(통계적 동시 등장 확률)가 반영되기 어려운 단점 보완.
- Co-occurrence(context window 내 두 개의 단어가 동시 등장)가 있는 두 단어의 word vector를 이용해 co-occurrence 값을 예측하는 regression 문제 풀이
<FastText>
-2016년 facebook이 발표
- Word2Vec은 언어의 형태학적 특성을 반영하지 못하고, 희소한 단어가 embedding 되지 않는 단점이 있음
- 단어를 Bag-of-Characters로 보고, 단어가 아닌 n-gram character를 embedding
- n-gram character를 embedding 하게 되면 OOV를 처리할 수 있는 장점이 있음(다양한 용언을 가진 한국어에 잘 맞음)
Word encoding - 토큰 분리, word index 작성
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.preprocessing.text import Tokenizer
import pandas as pd
sentences = ['I love my dog', 'I love my cat', 'you love my dog!']
tokenizer = Tokenizer(num_words = 100) #문장에서 상위 100개 단어 가져오기
tokenizer.fit_on_texts(sentences)
word_index = tokenizer.word_index
print(word_index)
: {'love' : 1, 'my' : 2, 'i' : 3, 'dog' : 4, 'cat' : 5, 'you' : 6}
Text to sequence - 수열반환
sentences = ['I love my dog.',
'I love my cat.',
'you love my dog!',
'Do you think my dog is amazing?',
]
tokenizer = Tokenizer(num_words = 100) #100개
tokenizer.fit_on_texts(sentences)
work_index = tokenizer.word_index
sequences = tokenizer.texts_to_sequnces(sentences)
print(word_index)
: {'my':1,'love':2,'dog':3,'i':4,'you':5,'cat':6,'do':7,'think':8,'is':9,'amazing':10}
print(sequences)
: [[4,2,1,3], [4,2,1,6], [5,2,1,3], [7,5,8,1,3,9,10]]
padding - 입력 text를 동일한 길이로 맞추기
from tensorflow.keras.preprocessing.sequence import pad_sequences
sentences = ['I love my dog.',
'I love my cat.',
'you love my dog!',
'Do you think my dog is amazing?',
]
tokenizer = Tokenizer(num_work=100, oov_token='<OOV>')
word_index = tokenizer.word_index
sequences = tokenizer.text_to_sequences(sentences)
padded = pad_sequences(sequences)
one-hot encoding
sentence = ["I really think is amazingi. honest."]
sequence = tokenizer.text_to_sequences(sentence)