目前計算句子類似性有不少不一樣的方案,好比基於語義詞典的方法、基於相同詞彙的方法、基於統計的方法和基於編輯距離的方法。這篇文章先介紹編輯距離的基礎。java
編輯距離其實就是指把一個字符串轉換爲另一個字符串所須要的最小編輯操做的代價數。包括插入字符、替換字符和刪除字符。編輯距離越小,類似度越大。git
好比咱們要將what
轉換成where
,多是將 a -> e,接着 t -> r ,變爲wher
,最後添加 e,完成。由於每一步均可以插入、刪除或替換,那麼如何才能在最終獲得一個最小的代價,這是就會用到動態規劃來求解。github
假設咱們有長度分別爲i、j
的兩個字符串,設編輯距離爲edit(i,j)
。接着咱們看下,若是它們最後的字符相等,則編輯距離其實等於edit(i-1,j-1)
。而若是最後的字符不相等,那麼咱們能夠經過插入或替換來使其相等,可是不一樣的操做對應的代價不相同,若是插入則爲edit(i,j-1)+1
或 eidit(i-1,j)+1
,替換則爲edit(i-1,j-1)+1
。bash
用如下動態方程來表示:併發
其中舉個前面的例子,what 到 where,假設兩個字符分別爲空時對應的代價數以下,機器學習
編輯距離 | 空 | w | h | a | t |
空 | 0 | 1 | 2 | 3 | 4 |
w | 1 | ||||
h | 2 | ||||
e | 3 | ||||
r | 4 | ||||
e | 5 |
動態規劃後爲:分佈式
編輯距離 | 空 | w | h | a | t |
空 | 0 | 1 | 2 | 3 | 4 |
w | 1 | 0 | 1 | 2 | 3 |
h | 2 | 1 | 0 | 1 | 2 |
e | 3 | 2 | 1 | 1 | 2 |
r | 4 | 3 | 2 | 2 | 2 |
e | 5 | 4 | 3 | 3 | 3 |
在整個動態規劃過程當中一直都是選擇最小的代價數,因此最終的3便是這兩個字符串的最小代價數,即編輯距離。學習
https://github.com/sea-boat/TextAnalyzer/blob/master/src/main/java/com/seaboat/text/analyzer/distance/CharEditDistance.javaui
public class EditDistance {
public static int getEditDistance(String s, String t) {
int d[][];
int n;
int m;
int i;
int j;
char s_i;
char t_j;
int cost;
n = s.length();
m = t.length();
if (n == 0) {
return m;
}
if (m == 0) {
return n;
}
d = new int[n + 1][m + 1];
for (i = 0; i <= n; i++) {
d[i][0] = i;
}
for (j = 0; j <= m; j++) {
d[0][j] = j;
}
for (i = 1; i <= n; i++) {
s_i = s.charAt(i - 1);
for (j = 1; j <= m; j++) {
t_j = t.charAt(j - 1);
cost = (s_i == t_j) ? 0 : 1;
d[i][j] = Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1);
d[i][j] = Math.min(d[i][j], d[i - 1][j - 1] + cost);
}
}
return d[n][m];
}
public static void main(String[] args) {
EditDistance ed = new EditDistance();
System.out.println(ed.getEditDistance("what", "where"));
}
}
複製代碼
-------------推薦閱讀------------spa
跟我交流,向我提問:
公衆號的菜單已分爲「讀書總結」、「分佈式」、「機器學習」、「深度學習」、「NLP」、「Java深度」、「Java併發核心」、「JDK源碼」、「Tomcat內核」等,可能有一款適合你的胃口。
歡迎關注: