HAZEL

[ NLP : CH5. 유사성과 모호성 ] 단어의 의미, 원핫 인코딩, 시소러스, 특징, TF-IDF 본문

DATA ANALYSIS/NLP

[ NLP : CH5. 유사성과 모호성 ] 단어의 의미, 원핫 인코딩, 시소러스, 특징, TF-IDF

Rmsid01 2020. 12. 27. 16:11

5장. 유사성과 모호성

5-1. 단어의 의미 

5.1.1. 단어와 의미의 관계 

표제어 : 겉으로 보이는 단어의 형태 

- 같은 형태이지만, 다른 의미로 쓰이는 단어가 존재. 사람들은 주변정보에 따라 의미를 파악함

- 주변정보가 부족하여 모호성이 증가하면, 사람이여도 해석이 실패함.

 

중의성 문제 : 한가지 형태의 단어에 여러 의미가 포함되어 생기는 문제.

- 기계 번역에서 단어의 의미에 따라 해당 번역 단어의 형태가 완전히 바뀌기 때문에 중요

 

-> 겉으로 보이는 형태의 매개체를 이해하고 내부의 다양한 의미로 변환하여 사용하여야 함

 

5.1.2. 동형어와 다의어

동형어 : 형태는 같으나 뜻이 다른 단어, 아예 어원이 다른 의미들이 같은 형태를 띄고 있는 것 

다의어 : 한 형태의 단어가 여러의미를 가지지만, 그 의미들이 서로 연관되어 있음  

-> 동형어나 다의어는 '단어 중의성 해소(WSD)라는 방법을 통해 단어의 의미를 명확히 하는 과정이 필요

 

5.1.3. 동의어

동의어 : 다른 현태이지만 의미가 같은 단어

동의어의 집합 : 동의어가 여러 개 존재 할 때, 이들의 집합

 

5.1.4. 상위어와 하위어

상위어 : 개념들을 포함하는 상위 개념 EX, 동물

하위어 : 하위 개념을 표현하는 단어 EX, 포유류

- 어휘 분류에 따라 단어간 관계 구조를 계층화 할 수 있음 

 

5.1.5. 모호성 해소 

: 단어의 겉 형태인 텍스트만으로는 모호성이 매우 높음. 모호성 제거로 자연어 처리 성능을 높일 수 있음

-> 단어가 가지는 모호성 제거하는 과정을 '단어 중의성 해소(WSD)'라고 함

 


5-2. 원핫 인코딩 

5.1.1. 원핫 인코딩이란?

: 단어를 학습시키기 위해 벡터로 변환하는 작업 중에서 가장 간단한 방법으로, 단 하나의 1과 나머지 수많은 0으로 표현된 인코딩 방식

 

- 원핫 인코딩의 벡터의 차원은 보통 전체 어휘의 개수가 됨.

 

5.1.2. 원핫 인코딩 구현

1) 각 단어에 고유한 인덱스를 부여함 ( 정수 인코딩 )

from konlpy.tag import Okt
okt = Okt()
token = okt.morphs("나는 사과를 좋아한다")

# 각 토큰에 대한 고유한 인텍스 부여 ( 빈도수대로 정렬하기도 함 )
word2index = {}
for i in token :
    if i not in word2index.keys():
        word2index[i] = len(word2index)
print(word2index) # {'나': 0, '는': 1, '사과': 2, '를': 3, '좋아한다': 4} 

 

2) 표현하고 싶은 단어의 인덱스 위치에 1을 부여하고 나머지엔 0을 부여함

# 원핫 인코딩 함수
def one_hot_encoding(word, word2index):
    one_hot_vector = [0]*(len(word2index))
    index  = word2index[word]
    one_hot_vector[index] = 1
    return one_hot_vector
    
one_hot_encoding('사과', word2index) # [0, 0, 1, 0, 0]

* 케라스로도 더 쉽게 구현할 수 있음

 

 

5.1.3. 원핫 인코딩의 문제점

1) 단어간의 유사도를 파악할 수 없다

2) 모든 벡터가 수직이므로 cosine similarity = 0, 3개의 단어는 3차원의 벡터가 되므로 차원이 너무 커진다.

 


5-3. 시소러스 

: 원핫 벡터로는 단어간의 계층적 구조라는 특징을 잘 반영할 수 없기 때문에, 잘 구축되어진 데이터 베이스를 이용한다. 그것을 '시소러스(어휘분류사전)이라고 부르는데 그 중 대표적인 것이 '워드넷'이 있다.

 

5.1.1. 워드넷

 : 단어에 대한 상위어와 하위어 정보를 구축함으로써, 유향 비순환 그래프를 이루게 됨.

 

5.1.2. 워드넷 코드 구현

import nltk
nltk.download('wordnet')

# wn.sysets을 하면 하나의 노드의 경로만 나타나게 된다.
wn.synsets('pen')

# 최상단 노드까지 구하기 위해서 코드를 작성함 for 구문으로 해서 얻을 수 있음
from nltk.corpus import wordnet as wn

def hypernyms(word):
    current_node = wn.synsets(word)[0]
    yield current_node
    
    while True :
        try :
            current_node = current_node.hypernyms()[0]
            yield current_node
            
        except IndexError :
            break
            
for h in hypernyms('pen'):
    print(h)

"""
Synset('pen.n.01')
Synset('writing_implement.n.01')
Synset('implement.n.01')
Synset('instrumentality.n.03')
Synset('artifact.n.01')
Synset('whole.n.02')
Synset('object.n.01')
Synset('physical_entity.n.01')
Synset('entity.n.01')
"""

[h for h in hypernyms('pen')]

 

- 두개 단어의 거리를 구하기 

# 두개 단어의 거리를 구할 수 있다. 
def distance(word1, word2):
    word1_hypernyms = [h for h in hypernyms(word1)]

    for i, word2_hypernym in enumerate(hypernyms(word2)):
        try:            
            return i + word1_hypernyms.index(word2_hypernym)
        
        except ValueError:
            continue

print('책과 개의 거리 :' , distance('book', 'dog') ) # 책과 개의 거리 : 16
print( '고양이와 개의 거리 :' ,distance('dog', 'cat') ) # 고양이와 개의 거리 : 4

 

- 각 최하단 노드 간의 최단거리를 유사도로 치환하여 활용할 수 있음 

  > 멀수록 단어간의 유사도는 떨어짐

# 최하단 노드 간의 최단 거리를 알 수 있고, 이것을 유사도로 치환하여 활용할 수 있음
# 거리가 멀수록 단어간의 유사도는 떨어짐. 

import numpy as np

def similarity(word1, word2):
    return -np.log(distance(word1, word2))

print('개와 책의 유사도 : ' , similarity('dog', 'book')) # 개와 책의 유사도 :  -2.772588722239781
print('개와 고양이의 유사도 : ' , similarity('dog', 'cat')) # 개와 고양이의 유사도 :  -1.3862943611198906

5-4. 특징 ( feature vector )

: 효과적으로 단어의 정보를 추출하고 배우려면 '특징'을 잘 표현해야함

- 특징은 수치로 표현

- 최대한 많은 샘플을 설명할 수 있어야함

 

>> 특징별 수치들을 모아 벡터로 표현한 것을 '특징 벡터 ( feature vector ) ' 라고 함 

 


5-5 특징 추출하기 : TF - IDF 

: 출현 빈도를 사용하여 어떤 단어 w 가 문서 d 내에서 얼마나 중요한지 나타내는 수치

 

a . IDF ( Inverse Document frequency ) ; 그 단어가 출현한 문서의 숫자의 역수 

     - IDF 를 구해 TF에 곱해줌으로써 ‘a’ ‘the’같은 단어에 패널티를 줌

b. TF ( Term Frequency ) ; 단어 문서 내에 출현 횟수

c. DF ( Document Frequency ) ; 해당 단어가 출현한 문서의 수

 

- 계산을 할 때, log를 취해줘야 한다.

구할 떄, log를 취해줘야 한다

       - log 를 취해줘야 idf가 기하급수적으로 커지는 것을 방지해줌

 

DF 의 역수에 1을 더해줘야한다.

       - 특정단어가 전체 문서에 등장하지 않을 경우 분모가 0이 되는 것을 방지

 


** 본 게시글은 아래 자연어 책을 공부하면서 작성하였습니다.

출처 : 김기현의 자연어 처리 딥러닝 캠프 _ 파이 토치 편

wikidocs.net/31698