![]() |
ノート/テキストマイニング/WordNethttps://pepper.is.sci.toho-u.ac.jp:443/pepper/index.php?%A5%CE%A1%BC%A5%C8%2F%A5%C6%A5%AD%A5%B9%A5%C8%A5%DE%A5%A4%A5%CB%A5%F3%A5%B0%2FWordNet |
![]() |
ノート/テキストマイニング
3453 2017-07-21 (金) 17:23:02
nltk (Natural Language Took Kit)を使う。日本語対応のためには新しいバージョンが必要。
>>> import nltk >>> nltk.download()コマンドプロンプトが出るので、"all" を選んで全データをインストール。
実際に使っている様子は、HowToの中にあるサンプルを見るとよい。
>>> from nltk.corpus import wordnet as wn >>> wn.synsets('dog')
NLTK/corpus/wordnet.pyの中に含まれているデモプログラムを抜き出して、単独で走るようにimportなどを追加したもの。
細かい説明は 『入門 自然言語処理』2章 テキストコーパスと語彙資源へのアクセス (3)
###################################################################### # Demo ###################################################################### from nltk.corpus import wordnet from nltk.corpus.reader import WordNetCorpusReader, WordNetICCorpusReader def demo(): import nltk print('loading wordnet') wn = WordNetCorpusReader(nltk.data.find('corpora/wordnet'), None) print('done loading') S = wn.synset L = wn.lemma print('getting a synset for go') move_synset = S('go.v.21') print(move_synset.name(), move_synset.pos(), move_synset.lexname()) print(move_synset.lemma_names()) print(move_synset.definition()) print(move_synset.examples()) zap_n = ['zap.n.01'] zap_v = ['zap.v.01', 'zap.v.02', 'nuke.v.01', 'microwave.v.01'] def _get_synsets(synset_strings): return [S(synset) for synset in synset_strings] zap_n_synsets = _get_synsets(zap_n) zap_v_synsets = _get_synsets(zap_v) print(zap_n_synsets) print(zap_v_synsets) print("Navigations:") print(S('travel.v.01').hypernyms()) print(S('travel.v.02').hypernyms()) print(S('travel.v.03').hypernyms()) print(L('zap.v.03.nuke').derivationally_related_forms()) print(L('zap.v.03.atomize').derivationally_related_forms()) print(L('zap.v.03.atomise').derivationally_related_forms()) print(L('zap.v.03.zap').derivationally_related_forms()) print(S('dog.n.01').member_holonyms()) print(S('dog.n.01').part_meronyms()) print(S('breakfast.n.1').hypernyms()) print(S('meal.n.1').hyponyms()) print(S('Austen.n.1').instance_hypernyms()) print(S('composer.n.1').instance_hyponyms()) print(S('faculty.n.2').member_meronyms()) print(S('copilot.n.1').member_holonyms()) print(S('table.n.2').part_meronyms()) print(S('course.n.7').part_holonyms()) print(S('water.n.1').substance_meronyms()) print(S('gin.n.1').substance_holonyms()) # 以下3行は、エラーが出る # print(L('leader.n.1.leader')) # Have some error possibly in data? # print(L('leader.n.1.leader').antonyms()) # print(L('increase.v.1.increase').antonyms()) print(S('snore.v.1').entailments()) print(S('heavy.a.1').similar_tos()) print(S('light.a.1').attributes()) print(S('heavy.a.1').attributes()) # print(L('English.a.1.English').pertainyms()) # Same error as above print(S('person.n.01').root_hypernyms()) print(S('sail.v.01').root_hypernyms()) print(S('fall.v.12').root_hypernyms()) print(S('person.n.01').lowest_common_hypernyms(S('dog.n.01'))) print(S('woman.n.01').lowest_common_hypernyms(S('girlfriend.n.02'))) print(S('dog.n.01').path_similarity(S('cat.n.01'))) print(S('dog.n.01').lch_similarity(S('cat.n.01'))) print(S('dog.n.01').wup_similarity(S('cat.n.01'))) wnic = WordNetICCorpusReader(nltk.data.find('corpora/wordnet_ic'), '.*\.dat') ic = wnic.ic('ic-brown.dat') print(S('dog.n.01').jcn_similarity(S('cat.n.01'), ic)) ic = wnic.ic('ic-semcor.dat') print(S('dog.n.01').lin_similarity(S('cat.n.01'), ic)) print(S('code.n.03').topic_domains()) print(S('pukka.a.01').region_domains()) print(S('freaky.a.01').usage_domains()) if __name__ == '__main__': demo()
実行結果は、
loading wordnet done loading getting a synset for go move.v.15 v verb.competition ['move', 'go'] have a turn; make one's move in a game ['Can I go now?'] [Synset('zap.n.01')] [Synset('zap.v.01'), Synset('zap.v.02'), Synset('nuke.v.01'), Synset('microwave.v.01')] Navigations: [] [Synset('travel.v.03')] [] [Lemma('atomic_warhead.n.01.nuke')] [Lemma('atomization.n.02.atomization')] [Lemma('atomization.n.02.atomisation')] [] [Synset('canis.n.01'), Synset('pack.n.06')] [Synset('flag.n.07')] [Synset('meal.n.01')] [Synset('banquet.n.02'), Synset('bite.n.04'), Synset('breakfast.n.01'), Synset('brunch.n.01'), Synset('buffet.n.02'), Synset('dinner.n.01'), Synset('lunch.n.01'), Synset('mess.n.04'), Synset('nosh-up.n.01'), Synset('picnic.n.03'), Synset('ploughman's_lunch.n.01'), Synset('potluck.n.01'), Synset('refection.n.01'), Synset('square_meal.n.01'), Synset('supper.n.01'), Synset('tea.n.02')] [Synset('writer.n.01')] [Synset('ambrose.n.01'), Synset('bach.n.01'), Synset('barber.n.01'), Synset('bartok.n.01'), Synset('beethoven.n.01'), Synset('bellini.n.01'), Synset('berg.n.02'), Synset('berlioz.n.01'), Synset('bernstein.n.01'), Synset('bizet.n.01'), Synset('blitzstein.n.01'), Synset('bloch.n.01'), Synset('borodin.n.01'), Synset('boulez.n.01'), Synset('brahms.n.01'), Synset('britten.n.01'), Synset('bruch.n.01'), Synset('bruckner.n.01'), Synset('byrd.n.01'), Synset('cage.n.03'), Synset('chavez.n.01'), Synset('cherubini.n.01'), Synset('chopin.n.03'), Synset('copland.n.01'), Synset('corelli.n.01'), Synset('couperin.n.01'), Synset('coward.n.02'), Synset('czerny.n.01'), Synset('debussy.n.01'), Synset('delibes.n.01'), Synset('delius.n.01'), Synset('donizetti.n.01'), Synset('dowland.n.01'), Synset('dukas.n.01'), Synset('dvorak.n.01'), Synset('elgar.n.01'), Synset('enesco.n.01'), Synset('falla.n.01'), Synset('franck.n.01'), Synset('gershwin.n.02'), Synset('glinka.n.01'), Synset('gluck.n.01'), Synset('gounod.n.01'), Synset('grainger.n.01'), Synset('grieg.n.01'), Synset('halevy.n.01'), Synset('handel.n.01'), Synset('handy.n.01'), Synset('haydn.n.01'), Synset('hindemith.n.01'), Synset('honegger.n.01'), Synset('humperdinck.n.01'), Synset('ibert.n.01'), Synset('ives.n.01'), Synset('joachim.n.01'), Synset('joplin.n.02'), Synset('kachaturian.n.01'), Synset('kern.n.01'), Synset('khachaturian.n.01'), Synset('lambert.n.02'), Synset('lasso.n.01'), Synset('ledbetter.n.01'), Synset('lehar.n.01'), Synset('liszt.n.01'), Synset('lloyd_webber.n.01'), Synset('loewe.n.01'), Synset('lully.n.02'), Synset('macdowell.n.01'), Synset('mahler.n.01'), Synset('massenet.n.01'), Synset('mendelssohn.n.01'), Synset('menotti.n.01'), Synset('meyerbeer.n.01'), Synset('milhaud.n.01'), Synset('monteverdi.n.01'), Synset('moore.n.01'), Synset('mozart.n.01'), Synset('mussorgsky.n.01'), Synset('nielsen.n.01'), Synset('offenbach.n.01'), Synset('orbison.n.01'), Synset('palestrina.n.01'), Synset('piston.n.01'), Synset('porter.n.04'), Synset('poulenc.n.01'), Synset('prokofiev.n.01'), Synset('puccini.n.01'), Synset('purcell.n.01'), Synset('rachmaninoff.n.01'), Synset('rameau.n.01'), Synset('ravel.n.01'), Synset('reich.n.03'), Synset('respighi.n.01'), Synset('rimsky-korsakov.n.01'), Synset('rodgers.n.01'), Synset('romberg.n.01'), Synset('rossini.n.01'), Synset('rubinstein.n.02'), Synset('saint-saens.n.01'), Synset('satie.n.01'), Synset('schnabel.n.01'), Synset('schonberg.n.01'), Synset('schubert.n.01'), Synset('schumann.n.01'), Synset('schumann.n.02'), Synset('scriabin.n.01'), Synset('segovia.n.01'), Synset('sessions.n.01'), Synset('shostakovich.n.01'), Synset('sibelius.n.01'), Synset('smetana.n.01'), Synset('sondheim.n.01'), Synset('sousa.n.01'), Synset('strauss.n.01'), Synset('strauss.n.02'), Synset('strauss.n.03'), Synset('stravinsky.n.01'), Synset('sullivan.n.05'), Synset('tallis.n.01'), Synset('taylor.n.01'), Synset('tchaikovsky.n.01'), Synset('telemann.n.01'), Synset('thomson.n.01'), Synset('varese.n.01'), Synset('vaughan_williams.n.01'), Synset('verdi.n.01'), Synset('villa-lobos.n.01'), Synset('vivaldi.n.01'), Synset('wagner.n.02'), Synset('walton.n.01'), Synset('weber.n.05'), Synset('weill.n.01'), Synset('wolf.n.02')] [Synset('professor.n.01')] [Synset('crew.n.01')] [Synset('leg.n.03'), Synset('tabletop.n.01'), Synset('tableware.n.01')] [Synset('meal.n.01')] [Synset('hydrogen.n.01'), Synset('oxygen.n.01')] [Synset('gin_and_it.n.01'), Synset('gin_and_tonic.n.01'), Synset('martini.n.01'), Synset('pink_lady.n.01')] [Synset('sleep.v.01')] [Synset('dense.s.03'), Synset('doughy.s.01'), Synset('heavier-than-air.s.01'), Synset('hefty.s.02'), Synset('massive.s.04'), Synset('non-buoyant.s.01'), Synset('ponderous.s.02')] [Synset('weight.n.01')] [Synset('weight.n.01')] [Synset('entity.n.01')] [Synset('travel.v.01')] [Synset('act.v.01'), Synset('fall.v.17')] [Synset('organism.n.01')] [Synset('woman.n.01')] 0.2 2.0281482472922856 0.8571428571428571 0.4497755285516739 0.8863288628086228 [Synset('computer_science.n.01')] [Synset('india.n.01')] [Synset('slang.n.02')]
いろいろとあったが、新しい目のバージョンのNLTKでは多言語サポートが入っている。
参照ページはBond先生らの Open Multilingual Wordnet で、日本語WordNetの研究の延長で多言語(からのリンク)にしたものらしい。
このページに記述されているようなデータやインターフェースは、NLTK(少なくとも3.2.4には)に入っているようだ。
使い方は、
>>> from nltk.corpus import wordnet as wn >>> wn.synsets('鯨', lang='jpn') [Synset('whale.n.02')] >>> wn.synset('spy.n.01').lemma_names('jpn') ['いぬ', 'スパイ', '回者', '回し者', '密偵', '工作員', '廻者', '廻し者', '探', '探り', '犬', '秘密捜査員', 'まわし者', '諜報員', '諜者', '間者', '間諜', '隠密']
というところ。
使い方の説明は NLTKのHOWTOsの wordnet HOWTO に例が出ている。曰く
The WordNet corpus reader gives access to the Open Multilingual WordNet, using ISO-639 language codes. >>> sorted(wn.langs()) ['als', 'arb', 'cat', 'cmn', 'dan', 'eng', 'eus', 'fas', 'fin', 'fra', 'fre', 'glg', 'heb', 'ind', 'ita', 'jpn', 'nno', 'nob', 'pol', 'por', 'spa', 'tha', 'zsm'] >>> wn.synsets(b'\xe7\x8a\xac'.decode('utf-8'), lang='jpn') [Synset('dog.n.01'), Synset('spy.n.01')] (以下略)
日本語WordNetを使ってみた例
>>> wp.synsets('リンゴ', lang='jpn') [Synset('apple.n.01'), Synset('apple.n.02')] >>> wp.synset('リンゴ', lang='jpn') <-- synsetSではなくsynsetの場合はダメ TypeError: synset() got an unexpected keyword argument 'lang' >>> wp.synsets('りんご', lang='jpn') [] <-- ひらがなの'りんご'では登録されていない >>> wn.synsets('ミカン', lang='jpn')[0] Synset('orange.n.01') <-- 'ミカン'は1つだけ >>> wn.synsets('リンゴ', lang='jpn')[0].path_similarity(wn.synsets('ミカン', lang='jpn')[0]) 0.25 <-- 経路距離メソッド path_simlarityを使ってみる。どちらも[0]の単一要素にして問うた >>> wn.synsets('リンゴ', lang='jpn')[1].path_similarity(wn.synsets('ミカン', lang='jpn')[0]) 0.05263157894736842 <-- 'リンゴ'の2要素目を試してみた >>> orange = wn.synsets('ミカン', lang='jpn')[0] >>> orange.hypernyms() <-- [Synset('citrus.n.01')] >>> orange.hyponyms() [Synset('bitter_orange.n.02'), Synset('sweet_orange.n.01'), Synset('temple_orange.n.02')] >>> orange.member_holonyms() [] >>> orange.root_hypernyms() <-- [Synset('entity.n.01')] >>> apple = wn.synsets('リンゴ', lang='jpn')[0] >>> orange.lowest_common_hypernyms(apple) <-- [Synset('edible_fruit.n.01')] >>> wn.synset('orange.n.01').lowest_common_hypernyms(wn.synset('apple.n.01')) [Synset('edible_fruit.n.01')]
>>> wn.lemmas('dog', lang='jpn') [] >>> wn.lemmas('犬', lang='jpn') [Lemma('dog.n.01.犬'), Lemma('spy.n.01.犬')] >>> wn.synset('dog.n.01').lemmas('jpn') [Lemma('dog.n.01.イヌ'), Lemma('dog.n.01.ドッグ'), Lemma('dog.n.01.洋犬'), Lemma('dog.n.01.犬'), Lemma('dog.n.01.飼犬'), Lemma('dog.n.01.飼い犬')] >>> [u.lemma_names('jpn') for u in list(wn.synsets('犬', lang='jpn'))] [['イヌ', 'ドッグ', '洋犬', '犬', '飼犬', '飼い犬'], ['いぬ', 'スパイ', '回者', '回し者', '密偵', '工作員', '廻者', '廻し者', '探', '探り', '犬', '秘密捜査員', 'まわし者', '諜報員', '諜者', '間者', '間諜', '隠密']]
裏は、corpus readerの
class nltk.corpus.reader.wordnet.WordNetCorpusReader(root, omw_reader)
のところに、omw_reader (omw=open multilingual wordnet) が追加されていること。 (これが新し目のバージョンが必要な理由)
「歴史的には」もともとBond先生らを中心にした研究の成果として日本語WordNet として公開されていたものがあり、 ダウンロードページも整備されていた。
また、本 Steven Bird, Ewan Klein, Edward Loper: Natural Language Processing with Python の翻訳「入門 自然言語処理」(2010年)に当たって、訳者の萩原正人氏らが第12章「Python による日本語自然言語処理」を追加した(この章はWebでも公開されている。Python による日本語自然言語処理)が、その中で日本語WordNetの使い方を取り上げている。この時はNLTKのWordNetリーダーの外側に自前のリーダーを作っていた(Example II.1 (12_1_5_jpwordnet.py))ため、それなりの手順が必要であった。 (ちなみに、このコードは、NLTKのWordNetCorpusReaderの__init__に(このomw対応の改変のために)パラメタ(まさにomw_reader)が追加されたため、そのままでは動かないようだ。) その後、NLTK側にインターフェースを追加したようで、現在の簡単な形になっているようだ。