語義曖昧解消NLPプロジェクト実験
17694 ワード
語義曖昧解消NLPプロジェクト実験
本プロジェクトの主な使用https://github.com/alvations/pywsdのpywsdライブラリで意味の曖昧さを解消
現在、ライブラリの一部はnltkに移植されており、
NLTK
モジュールpywsd
ライブラリではなく、より良いパフォーマンスWSDを得るために使用されています.一般的に、pywsd
のsimple_lesk()
からNLTK
のlesk
より良い.暇なときは、できるだけNLTK
モジュールを更新します.このドキュメントでは、元のpywsdライブラリの使用について主に説明します.一、使用する技術:
LeskアルゴリズムOriginal Lesk (Lesk, 1986)
Adapted/Extended Lesk (Banerjee and Pederson, 2002/2003)
Simple Lesk (with definition, example(s) and hyper+hyponyms)
Cosine Lesk (use cosines to calculate overlaps instead of using raw counts)
最大化類似度(see also,Pedersen et al.(2003))Path similarity (Wu-Palmer, 1994; Leacock and Chodorow, 1998)
Information Content (Resnik, 1995; Jiang and Corath, 1997; Lin, 1998)
ベースラインRandom sense
First NLTK sense
Highest lemma counts
二、使用方法:
インストール:
pip install -U nltk
python -m nltk.downloader 'popular'
pip install -U pywsd
次の操作を行います.
from pywsd.lesk import simple_lesk # pywsd
sent = 'I went to the bank to deposit my money' #
ambiguous = 'bank' #
answer = simple_lesk(sent, ambiguous, pos='n') # answer ,
print (answer.definition()) #
三、原理
語義曖昧解消、英語名Word Sense Disambiguation、英語略称WSD、LESKアルゴリズムは語義曖昧解消の主なアルゴリズムである.
LESKアルゴリズムはTF-IDFを重みとする周波数判別アルゴリズムであり、主な流れは以下のように簡単に述べることができる.
ストップワードを削除
この語以外のTF-IDF値を集計する.
加算すると、複数の意味の下でこの値の大きさを比較し、値が大きいほどその文の意味であることを示す.
NBAロケットチームを例にleskアルゴリズムを簡単に実装します.
import os
import jieba
from math import log2
#
def read_file(path):
with open(path, 'r', encoding='utf-8') as f:
lines = [_.strip() for _ in f.readlines()]
return lines
#
sent = ' , 。'
wsd_word = ' '
jieba.add_word(wsd_word)
sent_words = list(jieba.cut(sent, cut_all=False))
#
stopwords = [wsd_word, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',' ',\
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '。', ',', '!', '?']
sent_cut = []
for word in sent_words:
if word not in stopwords:
sent_cut.append(word)
print(sent_cut)
# TF-IDF
wsd_dict = {}
for file in os.listdir('.'):
if wsd_word in file:
wsd_dict[file.replace('.txt', '')] = read_file(file)
#
tf_dict = {}
for meaning, sents in wsd_dict.items():
tf_dict[meaning] = []
for word in sent_cut:
word_count = 0
for sent in sents:
example = list(jieba.cut(sent, cut_all=False))
word_count += example.count(word)
if word_count:
tf_dict[meaning].append((word, word_count))
idf_dict = {}
for word in sent_cut:
document_count = 0
for meaning, sents in wsd_dict.items():
for sent in sents:
if word in sent:
document_count += 1
idf_dict[word] = document_count
#
total_document = 0
for meaning, sents in wsd_dict.items():
total_document += len(sents)
# tf_idf
mean_tf_idf = []
for k, v in tf_dict.items():
print(k+':')
tf_idf_sum = 0
for item in v:
word = item[0]
tf = item[1]
tf_idf = item[1]*log2(total_document/(1+idf_dict[word]))
tf_idf_sum += tf_idf
print('%s, : %s, TF-IDF : %s'% (word, tf, tf_idf))
mean_tf_idf.append((k, tf_idf_sum))
sort_array = sorted(mean_tf_idf, key=lambda x:x[1], reverse=True)
true_meaning = sort_array[0][0].split('_')[1]
print('
,%s %s .' % (wsd_word, true_meaning))
結果は次のとおりです.
[' ', ' ', ' ', ' ', ' ', ' ', ' ']
_ :
, : 2, TF-IDF : 12.49585502688717
_NBA :
, : 63, TF-IDF : 204.6194333469459
, : 1, TF-IDF : 6.247927513443585
, : 1, TF-IDF : 8.055282435501189
, : 16, TF-IDF : 80.88451896801904
, : 7, TF-IDF : 33.13348038429679
, : 40, TF-IDF : 158.712783770034
, NBA .
次のようになります.
三十数年前、戦士たちはゴビ砂漠で素手で起業し、わが国のロケット発射基地を建てた.
[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']
_ :
, : 2, TF-IDF : 9.063440958888354
, : 1, TF-IDF : 6.05528243550119
, : 3, TF-IDF : 22.410959804340102
, : 89, TF-IDF : 253.27878721862933
, : 7, TF-IDF : 42.38697704850833
_NBA :
, : 3, TF-IDF : 13.59516143833253
, : 1, TF-IDF : 6.05528243550119
, .
概要:入力された文セグメントまたは文は,その後,分割されたその語の意味を分割し,いくつかの語を形成する.そして,各文節や文において分割された語の個数を計算し,TF−IDFの値を算出し,どのTF−IDFの値が最大となるかを計算し,その解釈により適したものとする.
四、改善
コード自体に対して、少し進歩的な最適化を行うことができ、アルゴリズム上の最適化はより大きな飛躍を遂げることができます.http://www.doc88.com/p-9959426974439.htmlこの文章で述べたleskアルゴリズムの改善.
leskアルゴリズムの欠点に対して,意味の判断は同じTF−IDFの値,すなわち重み値が同じ場合に容易に誤魔化される.