人気ブログランキング | 話題のタグを見る
文字列の類似度の尺度について試してみた
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>

by mima_ita | 2013-06-13 17:10 | python
<< テキストを類似度毎に階層的クラ... R言語でTwitterを操作する >>



実験ですお

by mima_ita
検索
カテゴリ
最新の記事
.NET4.5におけるasy..
at 2014-07-02 00:46
.NETでTwitterを検..
at 2014-06-29 00:49
Redmineのプラグインで..
at 2014-06-28 03:29
IO.popenのwrite..
at 2014-06-28 03:25
RedmineのWikiでU..
at 2014-06-28 03:16
以前の記事
最新のトラックバック
その他のジャンル
ブログパーツ