菜品文本匹配
數(shù)據(jù)準(zhǔn)備
- 原始數(shù)據(jù):從網(wǎng)上爬蟲得到的菜單數(shù)據(jù),包含菜名,單價(jià),銷售量等
- 目標(biāo):將原始數(shù)據(jù)中的菜名分類,并劃分菜譜類別(如粵菜、川菜、西餐等)
- 輔助:從網(wǎng)上搜索找到菜譜數(shù)據(jù)庫(kù),包含了5000多種菜的標(biāo)準(zhǔn)菜名、菜譜類型、做法等,但是需要修正菜譜類型至我們所規(guī)定的類別。
問題點(diǎn)
原始數(shù)據(jù)中的菜名千奇百怪,需要跟標(biāo)準(zhǔn)菜名進(jìn)行匹配,而且一個(gè)菜名可能對(duì)應(yīng)多個(gè)標(biāo)準(zhǔn)菜名,需要找出最相關(guān)的標(biāo)準(zhǔn)菜名。例如'蝦仁小餛飩'、'大份餛飩'都對(duì)應(yīng)了''餛飩'',但是也有可能對(duì)應(yīng)'蝦仁炒飯'。
<aside>
?? 注意
- 文本匹配的方法,相似性的算法
- 先分詞在做相似性評(píng)價(jià),可能效果更好
- 數(shù)據(jù)量大,匹配算法不能太慢
</aside>
解決思路(基于字符的匹配,忽略語義)
- 精準(zhǔn)匹配+模糊匹配:
- 精準(zhǔn)匹配: 用字符串查找函數(shù)來精確匹配原始數(shù)據(jù)菜名中是否包含標(biāo)準(zhǔn)菜名,只要包含就認(rèn)為匹配成功
- 模糊匹配:調(diào)用fuzzywuzzy庫(kù),結(jié)果jieba中文分詞提高匹配率
fuzzywuzzy的使用
fuzzywuzzy.token_sort_ratio或token_sort_ratio計(jì)算相似度時(shí)在中文字符串里需要用空格分詞才有效
fuzz.ratio("番茄炒蛋","雞蛋拌番茄")#單純匹配文本的編輯距離,考慮總字符數(shù)
44
fuzz.partial_ratio("番茄炒蛋","雞蛋拌番茄")#單純匹配文本的編輯距離,考慮最短文本的字符數(shù)
50
fuzz.token_sort_ratio("番茄炒蛋","雞蛋拌番茄")#忽略分詞順序的相似度,需要空格間隔分詞才有效
44
fuzz.token_set_ratio("番茄炒蛋","雞蛋拌番茄")#忽略分詞重復(fù)的相似度,需要空格間隔分詞才有效
44
fuzz.partial_ratio("番茄 炒 蛋","雞蛋 拌 番茄")
33
fuzz.token_sort_ratio("番茄 炒 蛋","雞蛋 拌 番茄")#加空格分詞后顯著提高相似性
77
fuzz.token_set_ratio("番茄 炒 蛋","雞蛋 拌 番茄")#加空格分詞后顯著提高相似性
77
fuzz.token_set_ratio("番茄 炒 蛋","雞蛋 蛋 拌 番茄")#分詞時(shí)用全匹配的方式似乎可以提高相似性
80
fuzz.token_sort_ratio("番茄 炒 蛋","雞蛋 蛋 拌 番茄")
67
#綜合表現(xiàn)來說,中文分詞后用fuzzywuzzy.token_set_ratio最合適
fuzzywuzzy.extractOne或者extract提取候選集合中相似性最大的一個(gè)或多個(gè)選項(xiàng),輸出(匹配文本,相似度)
matchname = process.extractOne(row['匹配菜名'], choices, scorer=fuzz.token_set_ratio)
#scorer用于指定相似度計(jì)算器,默認(rèn)是Wratio,它的編碼方式是utf-8,不能用于中文,但指定scorer后可用
jieba中文分詞包
jieba.lcut("紫菜蛋花湯")#精確模式,精確分詞不冗余
['紫菜', '蛋花湯']
jieba.lcut("紫菜蛋花湯",cut_all=True)#全模式,所有可能的詞組
['紫菜', '蛋花', '蛋花湯', '花湯']
jieba.lcut_for_search("紫菜蛋花湯")#精確模式的基礎(chǔ)上對(duì)長(zhǎng)文本進(jìn)一步分詞
['紫菜', '蛋花', '花湯', '蛋花湯']
jieba.lcut("豐化芋艿頭")
['豐化', '芋艿', '頭']
jieba.lcut("豐化芋艿頭",cut_all=True)
['豐', '化', '芋艿', '頭']
jieba.lcut_for_search("豐化芋艿頭")
['豐化', '芋艿', '頭']
#lcut分詞過于簡(jiǎn)單,忽略了類似'蛋花湯'中的'蛋花'信息,cut_all又過于細(xì),反而不利于后續(xù)的相似度計(jì)算
#個(gè)人感覺lcut_for_search最合適
實(shí)驗(yàn)結(jié)果
第一階段實(shí)驗(yàn):
-
精確匹配結(jié)果:
匹配成功次數(shù) 225
嘗試匹配次數(shù) 1000
匹配成功率
循環(huán)運(yùn)行時(shí)間: -
模糊匹配結(jié)果:(不包括分詞)
ratio≥0.6
匹配成功次數(shù) 239
嘗試匹配次數(shù) 775
匹配成功率 0.30838709677419357
循環(huán)運(yùn)行時(shí)間:100.00秒 -
模糊匹配結(jié)果:(包括分詞)
ratio≥0.6
匹配成功次數(shù) 503
嘗試匹配次數(shù) 775
匹配成功率 0.6490322580645161
循環(huán)運(yùn)行時(shí)間:106.94秒ratio≥0.8
匹配成功次數(shù) 134
嘗試匹配次數(shù) 775
匹配成功率 0.17290322580645162
循環(huán)運(yùn)行時(shí)間:61.48秒
<aside>
?? 采用分詞后,同樣的模糊匹配模式和ratio閾值,匹配的“門檻”變低,匹配成功率提高,但結(jié)果不夠準(zhǔn)確。 提高ratio閾值,會(huì)降低匹配成功率,但提高準(zhǔn)確性
</aside>