Natural Language Processing with PyTorch
  • 소개글
  • 서문
  • Index
  • 딥러닝을 활용한 자연어 처리 개요
    • 자연어 처리란 무엇일까?
    • 딥러닝 소개
    • 왜 자연어 처리는 어려울까?
    • 무엇이 한국어 자연어 처리를 더욱 어렵게 만들까?
    • 자연어 처리의 최근 추세
  • 기초 수학
    • 서문
    • 랜덤 변수와 확률 분포
    • 쉬어가기: 몬티 홀 문제
    • 기대값과 샘플링
    • Maximum Likelihood Estimation
    • 정보 이론
    • 쉬어가기: MSE 손실 함수와 확률 분포 함수
    • 마치며
  • Hello 파이토치
    • 딥러닝을 시작하기 전에
    • 설치 방법
    • 짧은 튜토리얼
    • 쉬어가기: 윈도우즈 개발 환경 구축
  • 전처리
    • 전처리란
    • 코퍼스 수집
    • 코퍼스 정제
    • 분절
    • 병렬 코퍼스 정렬
    • 서브워드 분절
    • 분절 복원
    • 토치텍스트
  • 유사성과 모호성
    • 단어의 의미
    • One-hot 인코딩
    • 시소러스를 활용한 단어 의미 파악
    • 특징
    • 특징 추출하기: TF-IDF
    • 특징 벡터 만들기
    • 특징 유사도 구하기
    • 단어 중의성 해소
    • Selectional Preference
    • 마치며
  • 단어 임베딩
    • 들어가며
    • 차원 축소
    • 흔한 오해 1
    • Word2Vec
    • GloVe
    • Word2Vec 예제
    • 마치며
  • 시퀀스 모델링
    • 들어가며
    • Recurrent Neural Network
    • Long Short Term Memory
    • Gated Recurrent Unit
    • 그래디언트 클리핑
    • 마치며
  • 텍스트 분류
    • 들어가기
    • 나이브 베이즈를 활용하기
    • 흔한 오해 2
    • RNN을 활용하기
    • CNN을 활용하기
    • 쉬어가기: 멀티 레이블 분류
    • 마치며
  • 언어 모델링
    • 들어가며
    • n-gram
    • 언어 모델의 평가 방법
    • SRILM을 활용한 n-gram 실습
    • NNLM
    • 언어 모델의 활용
    • 마치며
  • 신경망 기계번역
    • 들어가며
    • Sequence-to-Sequence
    • Attention
    • Input Feeding
    • 자기회귀 속성과 Teacher Forcing 훈련 방법
    • 탐색(추론)
    • 성능 평가
    • 마치며
  • 신경망 기계번역 심화 주제
    • 다국어 신경망 번역
    • 단일 언어 코퍼스를 활용하기
    • 트랜스포머
    • 마치며
  • 강화학습을 활용한 자연어 생성
    • 들어가며
    • 강화학습 기초
    • 정책 기반 강화학습
    • 자연어 생성에 강화학습 적용하기
    • 강화학습을 활용한 지도학습
    • 강화학습을 활용한 비지도학습
    • 마치며
  • 듀얼리티 활용
    • 들어가며
    • 듀얼리티를 활용한 지도학습
    • 듀얼리티를 활용한 비지도학습
    • 쉬어가기: Back-translation을 재해석하기
    • 마치며
  • NMT 시스템 구축
    • 파이프라인
    • 구글의 NMT
    • 에딘버러 대학의 NMT
    • MS의 NMT
  • 전이학습
    • 전이학습이란?
    • 기존의 사전 훈련 방식
    • ELMo
    • BERT
    • GPT-2
    • XLNet
    • 마치며
  • 이 책을 마치며
  • 참고문헌
Powered by GitBook
On this page
  • 워드넷
  • 한국어 워드넷
  • 워드넷을 활용한 단어간 유사도 비교
  1. 유사성과 모호성

시소러스를 활용한 단어 의미 파악

PreviousOne-hot 인코딩Next특징

Last updated 5 years ago

단어는 내부에 의미를 지니며, 그 의미는 개념과 같아서 계층적 구조를 가진다고 했습니다. 아쉽게도 원핫 벡터로는 그런 단어 의미의 특징을 잘 반영할 수 없었습니다. 만약 그러한 계층 구조를 잘 분석하고 분류하여 데이터베이스로 구축한다면 자연어 처리를 할 때 매우 큰 도움이 될 것입니다. 이런 용도로 구축된 데이터베이스를 시소러스(어휘분류사전)thesaurus라고 부릅니다. 이번 절에서는 시소러스의 대표인 워드넷WordNet에 대해 다루어보겠습니다.

워드넷

은 1985년부터 심리학 교수인 조지 아미티지 밀러George Armitage Miller 교수의 지도 아래 프린스턴 대학교에서 만드는 프로그램입니다. 처음에는 주로 기계번역을 돕기 위한 목적으로 만들어졌으며, 따라서 '동의어 집합' 또는 '상위어'나 '하위어'에 관한 정보가 특히 잘 구축되어 있다는 장점이 있습니다. 단어에 대한 상위어와 하위어 정보를 구축함으로써, 유향 비순환 그래프directed acyclic graph(DAG)를 이루게 됩니다. 트리 구조가 아닌 이유는 하나의 노드가 여러 상위 노드를 가질 수 있기 때문입니다.

워드넷은 프로그램으로 제공되므로 내려받아 설치할 수도 있고, 워드넷 웹사이트(http:// wordnetweb.princeton.edu/perl/webwn)에서 바로 이용할 수도 있습니다. 또한 NLTK에 랩핑wrapping되어 포함되므로 임포트하여 사용 가능합니다. 다음은 워드넷 웹사이트에서 'bank' 를 검색한 결과입니다.

그림을 보면 'bank'라는 단어에 대해 명사noun일 때의 의미 10개, 동사verb일 때의 의미 8개를 정의했습니다. 명사 'bank#2'의 경우에는 여러 다른 표현(depository finaancial institution#1, banking concern#1)들도 같이 게시되어 있는데, 이것이 동의어 집합입니다.

이처럼 워드넷은 단어별 여러 가지 가능한 의미를 미리 정의하고 번호를 매겨 놓았습니다. 또한 의미별로 비슷한 뜻의 동의어를 링크해 동의어 집합을 제공합니다. 이것은 단어 중의성 해소에 매우 좋은 레이블 데이터가 될 수 있습니다. 만약 워드넷이 없다면 단어별 의미가 전부 몇 개나 되는지조차 알 수 없을 것입니다. 즉, 워드넷이 제공하는 이들 데이터를 바탕으로 지도학습supervised learning을 통해 단어 중의성 해소 문제를 풀 수 있습니다.

한국어 워드넷

다행히 영어 워드넷처럼 한국어를 위한 워드넷도 존재합니다. 다만 아직까지 표준이라고 할 만큼 정해진 것은 없고, 몇 개의 워드넷이 존재하는 정도입니다. 지속적으로 발전하고 있는 만큼, 작업에 따라 필요한 한국어 워드넷을 이용하면 좋습니다.

이름

기관

웹사이트

KorLex

부산대학교

Korean WordNet(KWN)

KAIST

워드넷을 활용한 단어간 유사도 비교

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

앞의 코드를 사용하면 워드넷에서 특정 단어의 최상위 부모 노드까지의 경로를 구할 수 있습니다. 다음과 같이 'policeman'은 'firefighter', 'sheriff'와 매우 비슷한 경로를 가짐을 알 수 있 습니다. 'student'와도 매우 비슷하지만 'mailman'과 더욱 비슷함을 알 수 있습니다.

>>> get_hypernyms(wn.synsets('policeman')[0])
Synset('policeman.n.01')
Synset('lawman.n.01')
Synset('defender.n.01')
Synset('preserver.n.03')
Synset('person.n.01')
Synset('causal_agent.n.01')
Synset('physical_entity.n.01')
Synset('entity.n.01')
>>> get_hypernyms(wn.synsets('firefighter')[0])
Synset('fireman.n.04')
Synset('defender.n.01')
Synset('preserver.n.03')
Synset('person.n.01')
Synset('causal_agent.n.01')
Synset('physical_entity.n.01')
Synset('entity.n.01')
>>> get_hypernyms(wn.synsets('sheriff')[0])
Synset('sheriff.n.01')
Synset('lawman.n.01')
Synset('defender.n.01')
Synset('preserver.n.03')
Synset('person.n.01')
Synset('causal_agent.n.01')
Synset('physical_entity.n.01')
Synset('entity.n.01')
>>> get_hypernyms(wn.synsets('mailman')[0])
Synset('mailman.n.01')
Synset('deliveryman.n.01')
Synset('employee.n.01')
Synset('worker.n.01')
Synset('person.n.01')
Synset('causal_agent.n.01')
Synset('physical_entity.n.01')
Synset('entity.n.01')
>>> get_hypernyms(wn.synsets('student')[0])
Synset('student.n.01')
Synset('enrollee.n.01')
Synset('person.n.01')
Synset('causal_agent.n.01')
Synset('physical_entity.n.01')
Synset('entity.n.01')

이로부터 얻어낸 정보들을 취합하여 그래프로 나타내면 다음과 같습니다. 그림에서 각 최하단 노드들은 코드에서 쿼리로 주어진 단어들입니다.

이때 각 노드 간 거리를 구할 수 있습니다. 다음 그림에 따르면 'student'에서 'fireman'으로 가는 최단 거리에는 'enrollee', 'person', 'preserver', 'defender' 노드들이 위치합니다. 따라서 'student'와 'fireman'의 거리는 5임을 알 수 있습니다.

이처럼 우리는 각 최하단 노드 간의 최단 거리를 알 수 있고, 이것을 유사도로 치환하여 활용할 수 있습니다. 당연히 거리가 멀수록 단어간의 유사도는 떨어질 테니, 다음과 같은 공식을 적용해 볼 수 있습니다.

similarity(w,w′)=−log⁡distance(w,w′)\text{similarity}(w, w')=-\log{\text{distance}(w, w')}similarity(w,w′)=−logdistance(w,w′)

이처럼 시소러스 기반의 정보를 활용하여 단어 간 유사도를 구할 수 있습니다. 하지만 사전을 구축하는 데는 너무 큰 비용과 시간이 소요됩니다. 또한 상위어와 하위어가 잘 반영된 사전이어야만 할 것입니다. 이와 같이 사전에 기반한 유사도를 구하는 방식은 비교적 정확한 값을 구할 수 있으나 그 한계가 뚜렷합니다.

http://korlex.pusan.ac.kr/
http://wordnet.kaist.ac.kr/
워드넷(WordNet)
각 단어별 top-1 의미의 top-1 상위어만 선택하여 트리 구조로 나타낸 경우
[워드넷 웹사이트](http://wordnetweb.princeton.edu/perl/webwn)에서 단어 'bank'를 검색 한 결과
각 단어들의 쿼리 결과 구조도
'student'와 'fireman' 사이에 위치한 노드들(점선)