web-dev-qa-db-ja.com

レーベンシュタイン距離によるテキストクラスタリング

小さな文字列(3〜6文字)のセット(2k〜4k)があり、それらをクラスター化します。私は文字列を使用しているので、 クラスタリング(特に文字列クラスタリング)の仕組み に関する以前の回答は、 レーベンシュタイン距離 が文字列の距離関数として使用するのに適していることを教えてくれました。また、クラスターの数が事前にわからないため、 階層的クラスター化 はk-meansではなく進むべき方法です。

問題は抽象的な形で得られますが、実際にそれを行う簡単な方法はわかりません。たとえば、MATLABまたはRは、カスタム関数(レーベンシュタイン距離)を使用した階層クラスタリングの実際の実装に適した選択肢です。両方のソフトウェアについて、レーベンシュタイン距離の実装を簡単に見つけることができます。クラスタリングの部分は難しいようです。たとえば、 MATLABのクラスタリングテキスト はすべての文字列の距離配列を計算しますが、距離配列を使用して実際にクラスタリングを取得する方法を理解できません。指導者のいずれかが、カスタム関数を使用して、MATLABまたはRで階層クラスタリングを実装する方法を教えてくれますか?

30
Alexandros

これは少し単純かもしれませんが、Rのレーベンシュタイン距離に基づいた階層的クラスタリングを使用するコード例です。

_set.seed(1)
rstr <- function(n,k){   # vector of n random char(k) strings
  sapply(1:n,function(i){do.call(paste0,as.list(sample(letters,k,replace=T)))})
}

str<- c(paste0("aa",rstr(10,3)),paste0("bb",rstr(10,3)),paste0("cc",rstr(10,3)))
# Levenshtein Distance
d  <- adist(str)
rownames(d) <- str
hc <- hclust(as.dist(d))
plot(hc)
rect.hclust(hc,k=3)
df <- data.frame(str,cutree(hc,k=3))
_

この例では、3つのグループ( "aa"、 "bb"、および "cc"で始まる)に30個のランダムなchar(5)文字列のセットを人為的に作成します。 adist(...)を使用してレーベンシュタイン距離行列を計算し、hclust(...)を使用して階層クラスタリングを実行します。次に、樹状図をcutree(...)を使用して3つのクラスターにカットし、クラスターIDを元の文字列に追加します。

38
jlhoward

[〜#〜] elki [〜#〜] にはレーベンシュタイン距離が含まれ、たとえば [〜#〜 ] optics [〜#〜] クラスタリング。

テキストクラスタリングのサポートは、Felix Stahlbergによる次の作業の一部として提供されました。

Stahlberg、F.、Schlippe、T.、Vogel、S。、およびSchultz、T。
クロスリンガルの単語と音素のアライメントによる単語のセグメンテーション。
Spoken Language Technology Workshop(SLT)、2012 IEEE。 IEEE、2012。

もちろん、さらなる貢献をお願いします。

4
Erich Schubert

答えは、文字列のmeaningにある程度依存しますが、一般に、問題はシーケンス分析ファミリの手法によって解決されます。より具体的には、Optimal Matching Analysis(OMA)。

ほとんどの場合、OMAは3つのステップで実行されます。最初に、シーケンスを定義します。あなたの説明から、各文字は別々の「状態」、つまり連続したビルディングブロックであると仮定できます。次に、いくつかのアルゴリズムのいずれかを使用して、データセット内のすべてのシーケンス間の距離を計算し、距離行列を取得します。最後に、その距離行列を、クラスターの品質に関する追加情報のために人気を博していると思われる階層的クラスタリングやMedoidsのパーティション分割(PAM)などのクラスタリングアルゴリズムに送ります。後者は、クラスターの数の選択をガイドします。クラスターの数は、シーケンス分析のいくつかの主観的なステップの1つです。

Rでは、多数の機能を備えた最も便利なパッケージはTraMineRです。Webサイトは here にあります。そのユーザーガイドは非常にアクセスしやすく、開発者は多かれ少なかれSO。

クラスタ数の決定を除き、クラスタリングは最も難しい部分ではないことに気付くでしょう。 TraMineRのガイドは、構文が非常に単純であり、視覚的なシーケンスグラフに基づいて結果を簡単に解釈できることを示しています。ユーザーガイドの例を次に示します。

clusterward1 <- agnes(dist.om1, diss = TRUE, method = "ward")

dist.om1はOMAによって取得された距離行列です。クラスターメンバーシップはclusterward1オブジェクトに含まれます。これは、プロット、変数としての再コーディングなど、何でもできます。diss=TRUEオプションは、データオブジェクトが非類似度(または距離)マトリックスであること。簡単ですね最も難しい選択(構文ではなく、方法論)は、特定のアプリケーションに適した適切な距離アルゴリズムを選択することです。それができたら、選択を正当化できるので、残りは非常に簡単です。幸運を!

3
Maxim.K

問題を解決するためにパーティションクラスタリング(確実に高速になる)を使用する方法の明確な説明が必要な場合は、このペーパー「クラスタリングアルゴリズムを使用した効果的なスペルチェック方法」を確認してください。 https://www.researchgate.net/publication/255965260_Effective_Spell_Checking_Methods_Using_Clustering_Algorithms?ev=prf_pub

著者は、iK-Meansの修正(PAMのような)バージョンを使用して辞書をクラスター化する方法を説明します。

幸運を祈ります!

2