NLP教程:用Fuzzywuzzy进行字符串模糊匹配

编译:yxy

在计算机科学中,字符串模糊匹配( fuzzy string matching)是一种近似地(而不是精确地)查找与模式匹配的字符串的技术。换句话说,字符串模糊匹配是一种搜索,即使用户拼错单词或只输入部分单词进行搜索,也能够找到匹配项。因此,它也被称为字符串近似匹配。

字符串模糊搜索可用于各种应用程序,例如:

  • 拼写检查和拼写错误,拼写错误纠正程序。例如,用户在Google中键入“Missisaga”,将返回文字为“Showing results for mississauga”的点击列表。也就是说,即使用户输入缺少字符、有多余的字符或者有其他类型的拼写错误,搜索查询也会返回结果。
  • 可以使用软件检查重复的记录。例如,如果客户由于他们的名称拼写不同(例如Abigail Martin和Abigail Martinez)(也可能由于错误输入电话号码)在数据库中被多次列出了不同的购买行为,那么就会出现一个新地址。

重复数据删除技术,它可不像听起来那么容易,尤其是如果你有数十万条记录的话。即便是Expedia也没法100%正确:

这篇文章将解释字符串模糊匹配及其用例,并使用Python中Fuzzywuzzy库给出示例。

每个酒店都有自己的命名方法来命名它的房间,在线旅行社(OTA)也是如此。例如,同一家酒店的一间客房Expedia将之称为“Studio, 1 King Bed with Sofa Bed, Corner”,Booking.com(缤客)则简单地将其显示为“Corner King Studio”。

不能说有谁错了,但是当我们想要比较OTA之间的房价时,或者一个OTA希望确保另一个OTA遵循费率平价协议时(rate parity agreement),这可能会导致混乱。换句话说,为了能够比较价格,我们必须确保我们进行比较的东西是同一类型的。

对于价格比较网站和应用程序来说,最令人头条的问题之一就是试图弄清楚两个项目(比如酒店房间)是否是同一事物。

FuzzyWuzzy

Fuzzywuzzy是一个Python库,使用编辑距离(Levenshtein Distance)来计算序列之间的差异。

为了演示,我创建了自己的数据集,也就是说,对于同一酒店物业,我从Expedia拿一个房间类型,比如说“Suite, 1 King Bed (Parlor)”,然后我将它与Booking.com中的同类型房间匹配,即“King Parlor Suite”。只要有一点经验,大多数人都会知道他们是一样的。按照这种方法,我创建了一个包含100多对房间类型的小数据集,可以访问Github下载。

GitHub:https://github.com/susanli2016/NLP-with-Python/blob/master/room_type.csv

我们使用这个数据集测试Fuzzywuzzy的做法。换句话说,我们使用Fuzzywuzzy来匹配两个数据源之间的记录。

import pandas as pd
df= pd.read_csv('room_type.csv')
df.head(10)

数据集是我自己创建的,非常干净无需清理。

有几种方法可以比较Fuzzywuzzy中的两个字符串,让我们一个一个地进行尝试。

  • ratio ,按顺序比较整个字符串的相似度。
from fuzzywuzzyimport fuzz
fuzz.ratio('Deluxe Room, 1 King Bed','Deluxe King Room')

62

它告诉我们“Deluxe Room, 1 King Bed”和“Deluxe King Room”的相似度约62%。

fuzz.ratio('Traditional Double Room, 2 Double Beds','Double Room with Two Double Beds')

69

“Traditional Double Room, 2 Double Beds”和“Double Room with Two Double Beds”的相似度约69%。

fuzz.ratio('Room, 2 Double Beds (19th to 25th Floors)','Two Double Beds - Location Room (19th to 25th Floors)')

74

“Room, 2 Double Beds (19th to 25th Floors)”和“Two Double Beds — Location Room (19th to 25th Floors)”相似度约74%。

显然效果不怎么样。事实证明,简单的方法对于词序,缺失或多余词语以及其他类似问题的微小差异太过敏感。

  • partial_ratio,比较部分字符串的相似度。

我们仍在使用相同的数据对。

fuzz.partial_ratio('Deluxe Room, 1 King Bed','Deluxe King Room')

69

fuzz.partial_ratio('Traditional Double Room, 2 Double Beds','Double Room with Two Double Beds')

83

fuzz.partial_ratio('Room, 2 Double Beds (19th to 25th Floors)','Two Double Beds - Location Room (19th to 25th Floors)')

63

对于我的数据集来说,比较部分字符串并不能带来更好的整体效果。让我们尝试下一个。

token_sort_ratio,忽略单词顺序。

fuzz.token_sort_ratio('Deluxe Room, 1 King Bed','Deluxe King Room')

84

fuzz.token_sort_ratio('Traditional Double Room, 2 Double Beds','Double Room with Two Double Beds')

78

fuzz.token_sort_ratio('Room, 2 Double Beds (19th to 25th Floors)','Two Double Beds - Location Room (19th to 25th Floors)')

83

这是迄今为止最好的。

token_set_ratio,忽略重复的单词。它与token_sort_ratio类似,但更加灵活。

fuzz.token_set_ratio('Deluxe Room, 1 King Bed','Deluxe King Room')

100

fuzz.token_set_ratio('Traditional Double Room, 2 Double Beds','Double Room with Two Double Beds')

78

fuzz.token_set_ratio('Room, 2 Double Beds (19th to 25th Floors)','Two Double Beds - Location Room (19th to 25th Floors)')

97

看来token_set_ratio最适合我的数据。根据这一发现,我决定将token_set_ratio应用到我的整个数据集。

def get_ratio(row):
    name= row['Expedia']
    name1= row['Booking.com']
    return fuzz.token_set_ratio(name, name1)
len(df[df.apply(get_ratio, axis=1) >70])/ len(df)

0.9029126213592233

当设定相似度> 70时,超过90%的房间对超过这个匹配分数。还很不错!

Github:https://github.com/susanli2016/NLP-with-Python/blob/master/Fuzzy%20String%20Matching.ipynb

原文发布于微信公众号 - ATYUN订阅号(atyun_com)

原文发表时间:2018-10-20

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏james大数据架构

算法系列

  算法对程序员来说是熟悉的陌生人,编过大量代码后突然被哪个问到算法是什么也有时不知从何说起,简单来说是没有好好总结过仔细分析过。大学里面导师整天苦口婆心的教导...

243100
来自专栏take time, save time

你所能用到的数据结构(三)

三、对于效率提高的初次尝试     对于最自然的几种排序算法,数学家们开始思考如何提高排序算法的效率,可以通过数学证明出来如果想达到这个目的,必须想办法将相距...

29870
来自专栏行者常至

golang string、int、int64 float 互相转换

20430
来自专栏机器学习算法与Python学习

长文 | 手把手教你如何使用python进行数据分析(最好将文章代码自己码一遍)

关键字全网搜索最新排名 【机器学习算法】:排名第一 【机器学习】:排名第二 【Python】:排名第三 【算法】:排名第四 原文 http://www.cnbl...

40950
来自专栏专知

【 关关的刷题日记50】 Leetcode 345. Reverse Vowels of a String

关关的刷题日记50 – Leetcode 345. Reverse Vowels of a String 题目 Write a function that ta...

27930
来自专栏ml

nyoj------擅长排列的小明

擅长排列的小明 时间限制:1000 ms  |           内存限制:65535 KB 难度:4 描述小明十分聪明,而且十分擅长排列计算。比如给小明一个...

35190
来自专栏python3

python 面向对象之继承实例讲解

        --- info of Student:ChenRonghua ---

12420
来自专栏ACM算法日常

水果(STL+排序)- HDU 1263

夏天来了~~好开心啊,呵呵,好多好多水果~~ Joe经营着一个不大的水果店.他认为生存之道就是经营最受顾客欢迎的水果.现在他想要一份水果销售情况的明细表,这样J...

10810
来自专栏CodeSheep的技术分享

函数式编程思维在三行代码情书中的应用

25650
来自专栏专知

【LeetCode 290】 关关的刷题日记28 Word Pattern

关关的刷题日记28 – Leetcode 290. Word Pattern 题目 Given a pattern and a string str, find...

35480

扫码关注云+社区

领取腾讯云代金券