spaCy(2)로 힌디어 텍스트 처리: 동의어 찾기

11358 단어 machinelearningpython
이 게시물에서는 단어 임베딩을 살펴보고 이를 사용하여 단어, 문장 및 문서의 유사성을 결정하는 방법을 알아봅니다.

따라서 spacy를 사용하여 원시 텍스트를 spaCy 문서/토큰으로 변환하고 벡터 임베딩을 살펴보겠습니다.

from spacy.lang.hi import Hindi 
nlp = Hindi()
sent1 = 'मुझे भोजन पसंद है।'
doc = nlp(sent1)
doc[0].vector
# array([], dtype=float32)


이런! 토큰에 해당하는 벡터가 없습니다. 보시다시피 힌디어 단어에 사용할 수 있는 단어 임베딩이 없습니다. 다행스럽게도 페이스북의 fasttext 프로젝트에서 온라인으로 사용할 수 있는 단어 임베딩이 있습니다. 따라서 다운로드하여 spaCy에 로드합니다.

import requests 
url = "https://dl.fbaipublicfiles.com/fasttext/vectors-crawl/cc.hi.300.vec.gz"
r = requests.get(url, allow_redirects=True)
fpath = url.split("/")[-1]
with open(fpath, "wb") as fw:
  fw.write(r.content)

단어 벡터 파일의 크기는 약 1GB입니다. 그래서 다운로드하는데 시간이 좀 걸립니다.
spaCy에서 외부 단어 임베딩을 사용하는 방법을 살펴보겠습니다.
다음은 이 작업을 수행하는 방법에 대한 spaCy 설명서 링크입니다https://spacy.io/usage/vectors-similarity#converting.

단어 벡터가 다운로드되면 명령줄에서 spaCy 모델에 로드해 보겠습니다.

python -m spacy init-model hi ./hi_vectors_wiki_lg --vectors-loc cc.hi.300.vec.gz

몇 가지 작업을 수행하기 위해 이제 모델을 spacy에 로드해 보겠습니다.
수입 공간

nlp_hi = spacy.load("./hi_vectors_wiki_lg")
doc = nlp_hi(sent1)
doc[0].vector

이제 spaCy에서 벡터를 사용할 수 있음을 알 수 있습니다. 이 임베딩을 사용하여 두 문장의 유사성을 결정해 봅시다. 이 벡터를 사용하여 두 개의 매우 유사한 문장을 비교합시다.

sent2 = 'मैं ऐसे भोजन की सराहना करता हूं जिसका स्वाद अच्छा हो।'
doc1 = nlp_hi(sent1)
doc2 = nlp_hi(sent2)

# Both the sent1 and sent2 are very similar, so, we expect their similarity score to be high
doc1.similarity(doc2) # prints 0.86

이제 이러한 임베딩을 사용하여 단어의 동의어를 찾아보겠습니다.

def get_similar_words(word):
  vector = word.vector
  results = nlp_hi.vocab.vectors.most_similar(vector.reshape(1, 300))

  ret = []
  for result in results:    
    try:
      candidate = nlp_hi.vocab[result[0][0]]
      ret.append(candidate.text)
    except KeyError:
      pass
    return ret
get_similar_words(doc[1]) # prints ['भोजन']

그다지 유용하지 않습니다.
아마도 단어 벡터는 매우 희박하고 아주 작은 어휘에 대해 훈련될 것입니다.
nltk 라이브러리를 살펴보고 Hindi WordNet을 사용하여 유사한 단어를 찾을 수 있는지 알아보겠습니다. 그러나 NLTK 설명서에는 아직 지원하지 않는 언어hin가 언급되어 있습니다. 그래서 검색이 계속됩니다.

약간의 인터넷 검색 끝에 IITB의 연구 그룹이 꽤 오랫동안 인도 언어를 위한 WordNet을 개발하고 있음을 알게 되었습니다.
자세한 내용은 Checkout 링크를 참조하세요.
쉽게 접근할 수 있도록 Python 라이브러리pyiwn를 게시했습니다. 힌디어 synset의 적용 범위가 아직 NLTK에 통합되기에 충분하지 않기 때문에 아직 nltk에 넣지 않았습니다.
그것으로 이 라이브러리를 설치하자

pip install pyiwn 



import pyiwn 
iwn = pyiwn.IndoWordNet(lang=pyiwn.Language.HINDI)
aam_all_synsets = iwn.synsets('आम') # Mango
aam_all_synsets

# [Synset('कच्चा.adjective.2283'),
# Synset('अधपका.adjective.2697'),
# Synset('आम.noun.3462'),
# Synset('आम.noun.3463'),
# Synset('सामान्य.adjective.3468'),
# Synset('सामूहिक.adjective.3469'),
# Synset('आँव.noun.6253'),
# Synset('आँव.noun.8446'),
# Synset('आम.adjective.39736')]

단어의 synsets에 Mango와 common이라는 단어의 두 가지 의미가 모두 포함되어 있다는 것은 매우 흥미로운 일입니다. synset에서 하나의 synset과 다른 동의어를 선택합시다

aam = aam_all_synsets[2]

# Let's took at the definition 
aam.gloss()
# prints 'एक फल जो खाया या चूसा जाता है'

# This will print examples where the word is being used
aam.examples()
# ['तोता पेड़ पर बैठकर आम खा रहा है ।',
# 'शास्त्रों ने आम को इंद्रासनी फल की संज्ञा दी है ।']

# Now, let's look at the synonyms for the word 
aam.lemma_names()
# ['आम',
# 'आम्र',
# 'अंब',
# 'अम्ब',
# 'आँब',
# 'आंब',
# 'रसाल',
# 'च्यूत',
# 'प्रियांबु',
# 'प्रियाम्बु',
# 'केशवायुध',
# 'कामायुध',
# 'कामशर',
# 'कामांग']

synset에 대한 일부 Hyponyms를 인쇄해 보겠습니다.
A가 B의 유형이면 A는 B의 하위입니다. 예를 들어 pigeon은 새이므로 pigeon은 Bird의 하위입니다.

iwn.synset_relation(aam, pyiwn.SynsetRelations.HYPONYMY)[:5]
# [Synset('सफेदा.noun.1294'),
# Synset('अंबिया.noun.2888'),
# Synset('सिंदूरिया.noun.8636'),
# Synset('जरदालू.noun.4724'),
# Synset('तोतापरी.noun.6892')]

결론



이제 한동안 워드넷을 가지고 놀았습니다. WordNet이 무엇인지 요약해 보겠습니다. WordNet은 단어 간의 관계와 함께 단어의 의미를 저장하는 것을 목표로 합니다. 따라서 어떤 의미에서 Wordnet = 언어 사전 + 동의어 사전 + 명사에 대한 계층적 IS-A 관계 + 기타.

참고: 노트북을 가지고 놀고 싶다면 아래 링크를 클릭하십시오.



좋은 웹페이지 즐겨찾기