日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

jaccard相似度_如何计算两个字符串之间的文本相似度?

發布時間:2025/3/11 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 jaccard相似度_如何计算两个字符串之间的文本相似度? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

推薦閱讀:

  • 面試BAT 卻被小小字符串秒殺?這13道題幫你一舉擊敗字符串算法題
  • 字節跳動秋招面經:后端開發工程師,已拿意向書

前言

平時的編碼中,我們經常需要判斷兩個文本的相似性,不管是用來做文本糾錯或者去重等等,那么我們應該以什么維度來判斷相似性呢?這些算法又怎么實現呢?這篇文章對常見的計算方式做一個記錄。

Jaccard 相似度

首先是 Jaccard 相似度系數,下面是它在維基百科上的一個定義及計算公式。

The Jaccard index, also known as Intersection over Union and the Jaccard similarity coefficient (originally given the French name coefficient de communauté by Paul Jaccard), is a statistic used for gauging the similarity and diversity of sample sets. The Jaccard coefficient measures similarity between finite sample sets, and is defined as the size of the intersection divided by the size of the union of the sample sets:

其實總結就是一句話:集合的交集與集合的并集的比例.

java 代碼實現如下:

public static float jaccard(String a, String b) { if (a == null && b == null) { return 1f; } // 都為空相似度為 1 if (a == null || b == null) { return 0f; } Set aChar = a.chars().boxed().collect(Collectors.toSet()); Set bChar = b.chars().boxed().collect(Collectors.toSet()); // 交集數量 int intersection = SetUtils.intersection(aChar, bChar).size(); if (intersection == 0) return 0; // 并集數量 int union = SetUtils.union(aChar, bChar).size(); return ((float) intersection) / (float)union; }

Sorensen Dice 相似度系數

與 Jaccard 類似,Dice 系數也是一種計算簡單集合之間相似度的一種計算方式。與 Jaccard 不同的是,計算方式略有不同。下面是它的定義。

The S?rensen–Dice coefficient (see below for other names) is a statistic used to gauge the similarity of two samples. It was independently developed by the botanists Thorvald S?rensen[1] and Lee Raymond Dice,[2] who published in 1948 and 1945 respectively.

需要注意的是,他是:集合交集的 2 倍除以兩個集合相加。并不是并集.

java 代碼實現如下:

public static float SorensenDice(String a, String b) { if (a == null && b == null) { return 1f; } if (a == null || b == null) { return 0F; } Set aChars = a.chars().boxed().collect(Collectors.toSet()); Set bChars = b.chars().boxed().collect(Collectors.toSet()); // 求交集數量 int intersect = SetUtils.intersection(aChars, bChars).size(); if (intersect == 0) { return 0F; } // 全集,兩個集合直接加起來 int aSize = aChars.size(); int bSize = bChars.size(); return (2 * (float) intersect) / ((float) (aSize + bSize)); }

Levenshtein

萊文斯坦距離,又稱 Levenshtein 距離,是編輯距離的一種。指兩個字串之間,由一個轉成另一個所需的最少編輯操作次數。

簡單的說,就是用編輯距離表示字符串相似度, 編輯距離越小,字符串越相似。

java 實現代碼如下:

public static float Levenshtein(String a, String b) { if (a == null && b == null) { return 1f; } if (a == null || b == null) { return 0F; } int editDistance = editDis(a, b); return 1 - ((float) editDistance / Math.max(a.length(), b.length())); } private static int editDis(String a, String b) { int aLen = a.length(); int bLen = b.length(); if (aLen == 0) return aLen; if (bLen == 0) return bLen; int[][] v = new int[aLen + 1][bLen + 1]; for (int i = 0; i <= aLen; ++i) { for (int j = 0; j <= bLen; ++j) { if (i == 0) { v[i][j] = j; } else if (j == 0) { v[i][j] = i; } else if (a.charAt(i - 1) == b.charAt(j - 1)) { v[i][j] = v[i - 1][j - 1]; } else { v[i][j] = 1 + Math.min(v[i - 1][j - 1], Math.min(v[i][j - 1], v[i - 1][j])); } } } return v[aLen][bLen]; }

代碼中的編輯距離求解使用了經典的動態規劃求解法。

我們使用了** 1 - ( 編輯距離 / 兩個字符串的最大長度) ** 來表示相似度,這樣可以得到符合我們語義的相似度。

漢明距離

漢明距離是編輯距離中的一個特殊情況,僅用來計算兩個等長字符串中不一致的字符個數。

因此漢明距離不用考慮添加及刪除,只需要對比不同即可,所以實現比較簡單。

我們可以用similarity=漢明距離/長度來表示兩個字符串的相似度。

java 代碼如下:

public static float hamming(String a, String b) { if (a == null || b == null) { return 0f; } if (a.length() != b.length()) { return 0f; } int disCount = 0; for (int i = 0; i < a.length(); i++) { if (a.charAt(i) != b.charAt(i)) { disCount++; } } return (float) disCount / (float) a.length(); }

下面是測試用例:

Assert.assertEquals(0.0f, StringSimilarity.hamming("java 開發

總結

以上是生活随笔為你收集整理的jaccard相似度_如何计算两个字符串之间的文本相似度?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。