임베딩이란?
언어는 특정 개념을 표현하기 위한 약속의 집합
=> 글자를 컴퓨터에 입력으로 넣어주기 위해서는 컴퓨터가 이해할 수 있는 형태로 변경해야 함
컴퓨터는 특정 단어를 숫자의 형태(벡터)로 받아들임.
따라서 단어를 숫자의 형태로 변형하는 과정이 필요 => 임베딩
임베딩, Embedding
: 텍스트 데이터를 벡터로 변환하는 기술
-> 이는 텍스트 마이닝을 비롯해 자연어 처리에서 매우 기본적인 과정
데이터 준비 -> 전처리 -> 임베딩 -> 시각화
- 데이터 준비 : 원문 데이터 혹은 다른 소스로부터 데이터를 수집
- 전처리 : 불용어, 오타 등의 데이터를 제외
- 임베딩 : 목적에 맞는 임베딩 알고리즘을 적용
- 시각화 : 필요시 임베딩 결과를 그려보고 이를 확인
1) 단어 임베딩 : 하나의 단어를 벡터로 변환
2) 문장 임베딩 : 문장 자체를 벡터로 변환
임베딩과 벡터 공간
임베딩의 결과는 벡터이므로, 벡터가 존재하는 벡터 공간에 표현 가능
ex. [1, 2] 벡터는 2차원 공간에 표현 가능
단어는 고차원으로 표현됨 -> 그래야 다양한 종류의 단어 포괄 가능
원핫 인코딩(One-hot encoding)
특정 단어를 표현하는 위치만 1이고 나머지 위치는 0으로 구성 (전통적인 방법)
=> 단어의 수만큼의 크기를 갖는 벡터 생성
-> 직관적으로 쉽게 단어를 벡터로 변환 가능
원핫인코딩의 한계
- 차원의 저주
: 하나의 단어를 표현하는 벡터의 크기는 전체 단어 수와 같음 => 효율성과 계산 복잡도 증가
- 의미 부재
: 의미적으로 비슷한 단어끼리 비슷한 공간에 존재하지 않음
ex. 축구-농구 관계와 축구-비행기 관계의 차이가 없음
- 정보의 희소성
: 특정 단어의 위치만 1이므로 중요한 정보가 매우 희소. 대부분 0이 많음
인코딩과 임베딩
인코딩과 임베딩 모두 데이터를 새로운 형태로 변환하는 과정
인코딩
: 데이터를 표준화된 형식으로 변환
-> 이미 변환 과정은 정의되어있고, 그 정의에 맞춰 변환 진행 => 본질적으로 의미가 변하지 않음
==> 데이터의 형식을 변환하는데 중점
임베딩
: 머신러닝 모델이 처리하기 쉬운 형태로 변환.
=> 데이터의 의미적, 문맥적 특성을 모델이 이해할 수 있는 형태로 변환
분산 표현 (Distribution Representation)
: 원핫인코딩의 한계를 극복하기 위해 제안된 개념
정수가 아닌 실수(연속적인 값)로 이루어진 벡터로 임베딩 진행
(원핫인코딩은 0과 1 값으로만 임베딩 진행)
- 연속적인 실수의 값으로 단어를 변경하면서
데이터의 의미를 여러 특성(feature)에 걸쳐 분산시켜 표현
ex. [0.2, -1.1, 2.6, 0.5]
=> 단어나 개체의 의미가 하나의 차원 혹은 공간에 집중되어 표현되는 것이 아니라,
여러 요소에 걸쳐 분산되어 표현됨
==> 다양한 의미 & 문맥적 특성을 풍부하게 포함 가능
==> 분산표현으로 잘 임베딩이 된다면, 비슷한 의미를 갖는 단어들은 비슷한 분포를 갖게 됨
+ 비슷한 공간에 표현 가능
단어 임베딩
원핫 인코딩(One-hot encoding)
: 특정 단어를 표현하는 위치만 1, 나머지는 0
=> 문장을 단어의 형태로 분해 필요 : tokenize
- 고유한 단어 집합 생성 ('사과는', '바나나는', '맛있다')
-> 고유 단어에 독립된 인덱스 부여 (사과는 = 0, 바나나는 = 1, 맛있다 = 2)
-> 벡터 생성 : 각 단어의 인덱스에 1 부여 ( 사과는 = [1, 0, 0] / 바나나는 = [0, 1, 0] / 맛있다 = [0, 0, 1] )
원핫 인코딩 실습
from sklearn.preprocessing import OneHotEncoder
# OneHotEncoder 객체 생성
# sparse_output=False : 0과 1로 이루어진 행렬의 형태로 변환
encoder = OneHotEncoder(sparse_output=False)
one_hot_encoded = encoder.fit_transform("사과는 맛있다 바나나는 맛있다")
# [[0. 0. 1.]
# [1. 0. 0.]
# [0. 1. 0.]
# [1. 0. 0.]]
encoder.get_feature_names_out() # 각 열이 어떤 단어를 나타내는지를 표시
# array(['x0_맛있다', 'x0_바나나는', 'x0_사과는'], dtype=object)
함수화해보기
# 함수화
def one_hot_encode_words(sentence):
words = sentence.split()
words_array = np.array(words).reshape(-1, 1)
encoder = OneHotEncoder(sparse_output=False)
one_hot_encoded = encoder.fit_transform(words_array)
return one_hot_encoded, encoder.get_feature_names_out()
학습 기반 임베딩
분산 가설 (Distribution Hypothesis)
: 분산 표현의 이론적 기반
: 1950년대 제안된 언어학 이론으로 "단어의 의미는 그 단어가 나타나는 문맥에 의해서 결정된다"는 아이디어를 중심으로 함
=> 최신 임베딩 기법은 분포 가설을 기반으로 연구됨
-> 특정 단어의 의미를 숫자 벡터로 표현하기 위해 문맥과 주변 단어를 이용해 학습 진행
Word2Vec
: 2013년 구글 연구진에 의해 개발된 알고리즘
: 윈도우가 이동하며 동일한 개수의 단어 인식 -> 이들 사이의 연산을 진행해 각 단어들 임베딩
<두 가지 방법으로 단어를 벡터로 변환>
- CBOW : 이웃한 단어들을 바탕으로 가운데 단어가 무엇인지 예측하는 과정에서 임베딩 진행
- Skip-gram : 가운데 단어로 이웃한 단어들을 예측하는 과정으로 임베딩 진행
Word2Vec 실습
: Gensim 패키지 이용
: 내장 함수 모델 사용 -> 기본 모델을 다운받는데 시간 소요 & 학습에 사용되지 않은 단어는 활용 불가
- 기본 word2vec 모델은 특정 단어를 300개의 실수 값을 이용해 표현
-> 이를 이용해 유사도 관련 어플리케이션 적용 가능
- 유사도 계산 (Cos similarity)
- 가장 유사한 단어 찾기
from gensim.models import KeyedVectors
from gensim.downloader import load
def use_word2vec(word, model):
try:
word_vector = model[word]
return word_vector
except KeyError:
return "단어가 모델의 어휘에 없습니다."
# word2vec-google-news-300 : 기본 Word2Vec 모델, 구글의 뉴스 데이터로 하나의 단어를 300차원으로 변경
word2vec_model = load('word2vec-google-news-300')
use_word2vec('apple', word2vec_model)
# [-0.06445312 -0.16015625 -0.01208496 0.13476562 -0.22949219 0.16210938
# 0.3046875 -0.1796875 -0.12109375 0.25390625 -0.01428223 -0.06396484
# -0.08056641 -0.05688477 -0.19628906 0.2890625 -0.05151367 0 .........]
## 학습 당시 존재하지 않는 단어는 임베딩 불가
from scipy.spatial.distance import cosine
def word_similarity(word1, word2, model):
try:
vector1 = model[word1]
vector2 = model[word2]
similarity = 1 - cosine(vector1, vector2) # 코사인 유사도 계산
return similarity
except KeyError as e:
return str(e)
def most_similar(word, model, topn=5):
try:
similar_words = model.most_similar(word, topn=topn) # 가장 유사한 단어 찾기
return similar_words
except KeyError as e:
return str(e)
# 두 단어 사이의 유사도 확인
print('football & basketball 유사도 : ' , word_similarity('football', 'basketball', word2vec_model))
print('football & airplane 유사도 : ' , word_similarity('football', 'airplane', word2vec_model))
# football & basketball 유사도 : 0.668246865272522
# football & airplane 유사도 : 0.1512438803911209
# 특정 단어와 가장 유사한 단어 보여주기
print('football과 가장 유사한 단어 5개는 : ' , most_similar('football', word2vec_model, topn=5))
# football과 가장 유사한 단어 5개는 : [('soccer', 0.731354832649231), ('fooball', 0.7139959335327148), ('Football', 0.7124834060668945), ('basketball', 0.668246865272522), ('footbal', 0.6649289727210999)]
GloVe (Global Vectors for Word Representation)
: 2014년 스탠포드 대학에서 연구된 알고리즘
: 전체 글에 단어간 공동 출현 통계를 이용해 각 단어의 의미를 벡터로 표현, '공동출현행렬'
=> 공동으로 자주 출현하는 단어들을 벡터 공간 내 비슷한 위치에 존재하도록 임베딩
GloVe 실습
: Gensim 패키지 이용
def use_glove(word):
# 기본 GloVe 모델
model = load('glove-wiki-gigaword-300')
word_vector = model[word]
return word_vector
print(use_glove('airpods') # 역시 학습 당시에 없던 단어는 임베딩 불가
# [-0.20842 -0.019668 0.063981 -0.71403 -0.21181 -0.59283
# -0.15316 0.044217 0.63289 -0.84821 -0.21129 -0.19763
# ...........
# 두 단어 사이의 유사도 확인 (GloVe)
print('football & basketball 유사도 : ' , word_similarity('football', 'basketball', glove_model))
print('football & airplane 유사도 : ' , word_similarity('football', 'airplane', glove_model))
# football & basketball 유사도 : 0.7341024279594421
# football & airplane 유사도 : 0.002223522402346134
## -> 전체 문맥 안의 유사도를 보기 때문에 Word2Vec 보다 성능이 좋다
딥러닝을 활용한 학습 기반 단어 임베딩
- BERT : 2018년 구글, 문장 내적 & 외적 관계를 바탕으로 임베딩
- CLIP : 2021년 OpenAI, 이미지와 텍스트의 공동 의미를 임베딩에 활용
- 등
문장 임베딩
: 문장 자체를 숫자의 형태로 변환
-> 단어를 넘어 문장 자체가 갖고 있는 의미를 벡터로 표현
단어 임베딩과 문장 임베딩의 차이점
문장 임베딩과 단어 임베딩은 서로 다른 목적과 사용 사례를 기반으로 개발
=> 즉, 문제를 해결하는 서로 다른 도구임!
단어 임베딩은..
단어의 의미, 문맥적 유사성, 동의어 등과 같이 단어 수준에서 의미를 활용하는 경우에 사용
문장 임베딩은..
전반적인 글의 이해, 문맥 파악, 글 생성 등과 같이 문장 단위에서 정보를 포착하는 경우에 사용
원핫 인코딩
: 단어 인코딩과 마찬가지로 각 단어에 독립된 인덱싱 진행
=> 단어의 인덱스 위치에 1 부여
원핫 인코딩 실습
- CountVectorizer 활용
- 각 문장에 나온 단어를 독립적인 인덱스로 바꿔주는 과정과
- 또한, 해당 인덱스에 1의 값을 넣어주는 과정 지원
- binary=True 라는 값을 넣어주면 중복된 단어가 나와도 1로 표현
- 만약 Flase라면 BoW의 형태의 코드가 됨
from sklearn.feature_extraction.text import CountVectorizer
# CountVectorizer를 생성
# CountVectorizer : 텍스트 데이터를 단어 빈도(count)로 변환하는 객체
# binary=True : 빈도가 2 이상이어도 1로 표현
# binary=False : BoW 코드로 사용 가능
vectorizer = CountVectorizer(binary=True)
vectorizer.fit(sentences)
vectorizer.vocabulary_
# {'사과는': 6, '맛있다': 3, '바나나는': 5, '딸기는': 2, '김치는': 0, '맵다': 4, ..}
vectorizer.transform("소고기는 맛있다").toarray()
# [0 0 0 1 0 0 0 1 0 0]
다양한 문장 임베딩 기법
문장은 단어를 기반으로 만들어지는 개념
=> 따라서 각 단어들의 임베딩을 이용해 문장의 임베딩 생성
- 각 단어의 임베딩의 평균을 활용
: 가장 직관적인 방법, 그러나 다른 의미의 문장이 서로 비슷한 임베딩 값을 가질 수 있음
ex. "고양이가 강아지를 쫒는다", "강아지가 고양이를 쫒는다"는 다른 의미지만 평균 임베딩은 동일
- TF-IDF를 활용한 단어 가중치를 적용해 문장 임베딩을 생성
: TF-IDF란 문장 내 단어의 중요도를 나타내는 척도
-> 이를 이용해 각 단어 임베딩에 가중치를 주고, 가중된 값들을 활용해 평균 값 활용
딥러닝을 활용한 학습 기반 문장 임베딩
: 딥러닝 모델이 단어를 임베딩하는 과정에서 전체 문장의 의미를 담는 벡터 생성
=> 문장을 구성하는 각 단어에서 정보를 공급받아 임베딩 벡터를 생성
즉, 단어 임베딩을 진행하고 이를 이용하는 문장 임베딩 진행!
'STUDY > DevCourse' 카테고리의 다른 글
[데브코스][데이터 분석] 토픽 모델링과 워드 클라우드 (1) | 2024.05.15 |
---|---|
[데브코스][데이터 분석] 감정 분석 (0) | 2024.05.14 |
[데브코스][데이터 분석] 텍스트 마이닝 개요 (0) | 2024.05.13 |
[데브코스][데이터 분석] SageMaker 소개 및 실습 (0) | 2024.05.03 |
[데브코스][데이터 분석] ML 모델 개발 절차 및 프레임워크 (0) | 2024.05.02 |