我有一組旨在將公司匹配在一起的遺留資料(基于許多不同的因素)。但是,我想僅根據來自不同組態檔的名稱(并且可能存在細微差異)對匹配進行一些 QA。
假設一個資料集如下:
| 比賽編號 | 姓名左 | 姓名權 |
|---|---|---|
| 1 | 檸檬農場 | 檸檬農場公司 |
| 2 | 桃樹 | 桃樹農場 |
| 3 | 番茄林 | 橙色獵豹農場 |
他們是一種演算法或 pythonic 方式來知道例如 1 和 2 可能匹配得很好而 3 匹配得不好?這個,沒有任何 ML 等。
我想我需要以某種方式創造一個分數并淘汰它。但是,如果他們是最佳實踐,我會喜歡一些輸入。
我的一些想法是查看模式,比較集合中的字母等。但是,無法執行它們。
uj5u.com熱心網友回復:
你可以試試fuzzywuzzyscore ,然后你只需要為 cut 設定分數限制
from fuzzywuzzy import fuzz
df['score'] = df[['Name Left','Name Right']].apply(lambda x : fuzz.partial_ratio(*x),axis=1)
df
Out[134]:
Match ID Name Left Name Right score
0 1 LemonFarms Lemon Farms Inc 90
1 2 Peachtree PeachTree Farms 89
2 3 Tomato Grove Orange Cheetah Farm 13
uj5u.com熱心網友回復:
他們是一種演算法或 pythonic 方式來知道例如 1 和 2 可能匹配得很好而 3 匹配得不好?這個,沒有任何 ML 等。
為了計算兩個字串之間的相似性,您可以使用Levenshtein distance,到目前為止我知道它不可用,pandas因此您需要其他庫來完成此任務,如果您想要易于使用,我可能會建議使用pylev,但您可以使用選擇使用另一個一,特別是如果您發現需要為不同的替換使用不同的成本(所謂的加權 Levenshtein 距離)
使用您的樣本資料:
import pandas as pd
import pylev
df = pd.DataFrame({"nameleft":["LemonFarms","Peachtree","Tomato Grove"],"nameright":["Lemon Farms Inc","PeachTree Farms","Orange Cheetah Farm"]})
df["distance"] = df.apply(lambda x:pylev.levenshtein(x.nameleft,x.nameright),axis=1)
print(df)
輸出
nameleft nameright distance
0 LemonFarms Lemon Farms Inc 5
1 Peachtree PeachTree Farms 7
2 Tomato Grove Orange Cheetah Farm 18
您將需要選擇截止值或值,超過該值的名稱將被視為不同。
以上假設您可以根據需要使用外部庫,如果不是這種情況,您可能需要自己實作 Levenshtein 距離計算功能。如果您擔心等價(基本)Levenshtein 距離,這應該不是什么大問題,您可能會python在Rosetta Code中閱讀一些實作。
uj5u.com熱心網友回復:
萊文斯坦距離
無論如何,我不是這方面的專家,但我以前聽說過Levenshtein Distance。
... Levenshtein 距離是用于測量兩個序列之間差異的字串度量。
它將為您提供一個數字,定義兩個字串的相似程度。數字越大,兩個字串的相似度就越高。你可以在 python 中使用它和包fuzzywuzzy。
pip install fuzzywuzzy
例子:
from fuzzywuzzy import fuzz
n1 = "LemonFarms"
n2 = "Lemon Farms Inc"
m1 = "Tomato Grove"
m2 = "Orange Cheetah Farm"
print(fuzz.ratio(n1, n2))
print(fuzz.ratio(m1, m2))
這將為表格的第一行回傳80 ,為第三行回傳6。玩這個,讓我知道你是否找到了讓你滿意的東西。這里還有更多示例。
uj5u.com熱心網友回復:
Levenshtein模塊實作了著名的 Levenshtein 模糊匹配演算法以及其他相關演算法(例如 Jaro、Jaro-Winkler 等)。
Levenshtein.jaro_winkler()是一個字串相似度度量,它賦予公共前綴更多的權重,因為拼寫錯誤更可能發生在單詞的末尾附近。它回傳一個從 0.0 到 1.0 的數值,其中 1.0 最相似。
Levenshtein.distance()計算將一個序列更改為另一個序列所需的最小插入、洗掉和替換次數。
import pandas as pd
import Levenshtein
data = [[1, 'LemonFarms', 'Lemon Farms Inc'],
[2, 'Peachtree', 'PeachTree Farms'],
[3, 'Tomato Grove', 'Orange Cheetah Far']
]
df = pd.DataFrame(data, columns=['Match ID', 'Name Left', 'Name Right'])
df['score'] = df[['Name Left', 'Name Right']].apply(lambda x: Levenshtein.jaro_winkler(*x), axis=1)
df['distance'] = df[['Name Left', 'Name Right']].apply(lambda x: Levenshtein.distance(*x), axis=1)
print(df)
輸出:
Match ID Name Left Name Right score distance
0 1 LemonFarms Lemon Farms Inc 0.933333 5
1 2 Peachtree PeachTree Farms 0.884444 7
2 3 Tomato Grove Orange Cheetah Far 0.431481 17
為了提高分數,您可以在計算相似度分數之前將值轉換為小寫字符,這樣分數不區分大小寫。
df['score'] = df[['Name Left', 'Name Right']].apply(
lambda x: Levenshtein.jaro_winkler(x[0].lower(), x[1].lower()), axis=1)
這將 Peachtree vs PeachTree Farms 的得分從 0.884444 更改為 0.920000。您可以使用截止閾值;例如 score >= 0.9 表示字串匹配良好,< 0.9 表示匹配不良。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/424769.html
