MeCabで形態素解析したものをnltkを使用して距離を取得する。
今回実験した内容は次の機能
・編集距離
nltk.metrics.distance.edit_distance
・Nグラム類似度
nltk.bigramsによるバイグラムの取得。
・Jaccard距離
nltk.metrics.distance.jaccard_distance
・MASI距離
nltk.metrics.distance.masi_distance
■コード
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
import MeCab
import nltk
mecab = MeCab.Tagger("")
def get_tokens(text):
node = mecab.parseToNode(text)
words = []
while node:
if (node.surface is not None) and node.surface != "":
words.append(node.surface)
node = node.next
return words
print "単語の編集距離===================================================="
print "片方の文字がもう片方の文字列に変換するには、挿入、削除、置換を何回やらなければならないかを計算する。小さいほど類似"
s = u"まりさ"
tests = [u"まりさ",u"まりざ",u"まりちゃ",u"まり",u"まいしゃ",u"まっけんろー",u"れいむ",u"れいみゅ"]
for t in tests:
print t + str( nltk.metrics.distance.edit_distance(s,t) )
print "Nグラム類似度===================================================="
print "2つの文に共通するバイグラムがいくつあるか調べる。大きいほど類似"
s = u"ここはまりさのゆっくりプレイスだよ!"
tests = [u"ここはまりさのゆっくりプレイスだよ!",
u"ここはまりさのゆっくりプレイスだよ!ここからさっさとでっていってね!",
u"ゆっくりしていってね!ここはまりさのゆっくりプレイスだよ!",
u"ここはまりさのゆっくりプレイスなのぜ!",
u"きょきょはまりちゃのゆっくちプレイちゅなのじぇ!",
u"ここはれいむのゆっくりプレイスだよ!",
u"むーしゃむーしゃするよ!しあわせー!",
u"ぷくー!"
]
ceo_bigrams = nltk.bigrams( get_tokens(s.encode('utf-8')),pad_right=True,pad_left=True)
print "元文章のバイグラムの数:" + str(len(set(ceo_bigrams)))
for t in tests:
cto_bigrams = nltk.bigrams( get_tokens(t.encode('utf-8')),pad_right=True,pad_left=True)
print " " + t +":"+ str(len(set(ceo_bigrams).intersection(set(cto_bigrams))))
print "Jaccard距離===================================================="
print "2つの集合の類似度を |set1 ∩ set2| / |set1 ∪ set2|であらわした。小さいほど類似"
for t in tests:
r = nltk.metrics.distance.jaccard_distance(set(get_tokens(s.encode('utf-8'))),set(get_tokens(t.encode('utf-8'))))
print " " + t + ":" + str(r)
print "MASI距離===================================================="
print "Jaccard距離の改造重複があったら距離が短くなる。小さいほど類似"
for t in tests:
r = nltk.metrics.distance.masi_distance(set(get_tokens(s.encode('utf-8'))),set(get_tokens(t.encode('utf-8'))))
print " " + t + ":" + str(r)
■実行結果
C:\dev\python\nltk>python distance.py
単語の編集距離====================================================
片方の文字がもう片方の文字列に変換するには、挿入、削除、置換を何回やらなければならないかを計算する。小さいほど類似
まりさ0
まりざ1
まりちゃ2
まり1
まいしゃ3
まっけんろー5
れいむ3
れいみゅ4
Nグラム類似度====================================================
2つの文に共通するバイグラムがいくつあるか調べる。大きいほど類似
元文章のバイグラムの数:9
ここはまりさのゆっくりプレイスだよ!:9
ここはまりさのゆっくりプレイスだよ!ここからさっさとでっていってね!:9
ゆっくりしていってね!ここはまりさのゆっくりプレイスだよ!:8
ここはまりさのゆっくりプレイスなのぜ!:6
きょきょはまりちゃのゆっくちプレイちゅなのじぇ!:1
ここはれいむのゆっくりプレイスだよ!:7
むーしゃむーしゃするよ!しあわせー!:2
ぷくー!:0
Jaccard距離====================================================
2つの集合の類似度を |set1 ∩ set2| / |set1 ∪ set2|であらわした。小さいほど類似
ここはまりさのゆっくりプレイスだよ!:0.0
ここはまりさのゆっくりプレイスだよ!ここからさっさとでっていってね!:0.428571428571
ゆっくりしていってね!ここはまりさのゆっくりプレイスだよ!:0.111111111111
ここはまりさのゆっくりプレイスなのぜ!:0.4
きょきょはまりちゃのゆっくちプレイちゅなのじぇ!:0.923076923077
ここはれいむのゆっくりプレイスだよ!:0.222222222222
むーしゃむーしゃするよ!しあわせー!:0.833333333333
ぷくー!:1.0
MASI距離====================================================
Jaccard距離の改造重複があったら距離が短くなる。小さいほど類似
ここはまりさのゆっくりプレイスだよ!:0.0
ここはまりさのゆっくりプレイスだよ!ここからさっさとでっていってね!:0.617142857143
ゆっくりしていってね!ここはまりさのゆっくりプレイスだよ!:0.404444444444
ここはまりさのゆっくりプレイスなのぜ!:0.802
きょきょはまりちゃのゆっくちプレイちゅなのじぇ!:0.974615384615
ここはれいむのゆっくりプレイスだよ!:0.743333333333
むーしゃむーしゃするよ!しあわせー!:0.945
ぷくー!:1.0
C:\dev\python\nltk>