스터디/AI

[이론] 자연어처리 intro

_leezoee_ 2023. 3. 17. 16:49

- 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)