Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database 使用歌曲标题列表比较两个文件的最简单方法_Database_List_Comparison_Recordset_Fuzzy Comparison - Fatal编程技术网

Database 使用歌曲标题列表比较两个文件的最简单方法

Database 使用歌曲标题列表比较两个文件的最简单方法,database,list,comparison,recordset,fuzzy-comparison,Database,List,Comparison,Recordset,Fuzzy Comparison,我有两个歌曲标题列表,每个都在一个纯文本文件中,这是许可歌词文件的文件名-我想检查短列表标题(针)是否在长列表(草堆)中。脚本/应用程序应该返回不在大海捞针中的标题列表 我更喜欢使用Python或shell脚本(BASH),或者只使用能够处理所需模糊性的VisualDiff程序 主要的问题是,标题需要模糊匹配,以考虑数据输入错误以及可能的单词顺序 Haystack示例(注意一些重复和接近重复的线,突出显示匹配项): 针样: You Are Good (I Want To Scream It Ou

我有两个歌曲标题列表,每个都在一个纯文本文件中,这是许可歌词文件的文件名-我想检查短列表标题(针)是否在长列表(草堆)中。脚本/应用程序应该返回不在大海捞针中的标题列表

我更喜欢使用Python或shell脚本(BASH),或者只使用能够处理所需模糊性的VisualDiff程序

主要的问题是,标题需要模糊匹配,以考虑数据输入错误以及可能的单词顺序

Haystack示例(注意一些重复和接近重复的线,突出显示匹配项):

针样:

You Are Good (I Want To Scream It Out)
You Are My Strength (In The Fullness)
You Are My Vision O King Of My Heart
You Are The King Of Glory (Hosanna To The Son)
**You Chose The Cross (Lost In Wonder)**
**Your Grace Is Enough (This Is Our God)**
**Your Love Is Amazing Steady And Unchanging**
**Your Love Shining Like The Sun**
请注意,针的标题“你的爱像太阳一样闪耀”只可能与“你的爱”匹配。最好是不匹配,因此任何不确定的标题匹配都应该出现在输出中

comm -1 -3 <(sort haystack.txt) <(sort needle.txt)

comm-1-3您可能想看看fuzzyfuzzy()


提取函数的有用参数是limit、scorer和processor。

我在MySQL中做了类似的操作。我使用以下代码来定义Levenshtein距离和比率函数(我从答案中得到):

然后,您可以使用如下查询来比较这两个表

SELECT title, best_match,
    levenshtein_ratio(TRIM(LOWER(title)), TRIM(LOWER(best_match))) AS ratio
FROM (
    SELECT n.title AS title, (
                SELECT h.title
                FROM haystack h
                ORDER BY levenshtein_ratio(TRIM(LOWER(n.title)), TRIM(LOWER(h.title))) DESC
                LIMIT 1
           ) AS best_match
    FROM needle n
) x
ORDER BY ratio DESC
选择一个截止值,低于该值的所有行都没有良好的匹配。如果要直接使用编辑距离,可以使用levenshtein()而不是levenshtein_ratio(),在本例中,使用ORDER BY to ASC


请注意,这并没有针对词序差异的任何特殊规定。此外,如果你的列表很大,比较可能会很慢。

模糊模糊可以让你的梦想成真:

import csv
from fuzzywuzzy import fuzz

# Grab CSV data: 
with open('needles.csv', 'U') as z:
    reader = csv.reader(z)
    needles = list(reader)

with open('haystack.csv', 'U') as w:
    reader = csv.reader(w)
    haystack = list(reader)

# Calculate matches and append to list
NeedlesNotInHaystack = []

Fuzziness = 80 # ADJUST THIS VALUE TO FINE-TUNE RESULTS 
for x in needle:
    for y in haystack:
        if fuzz.ratio(x,y) > Fuzziness: 
            NeedlesNotInHaystack.append(x)

#Export results to CSV:
with open('Results', 'wb') as csvfile:
    temp = csv.writer(csvfile)
    temp.writerows(NeedlesNotInHaystack)
与fuzz.ratio不同,您可以使用以下方法获得更好的结果:

fuzz.token_sort_ratio OR fuzz.token_set_ratio

IMO是Python中模糊匹配的最佳+最简明概述

如果您想采用OpenRefine的方式,最好是设置一个本地对帐服务器-我建议

将haystack加载到对账服务器中,让OpenRefine处理您的针头文件并将其发送到对账服务

对账服务器会在每个提案中返回一个分数,这样您就可以(我只是以这些分数为例,不要认为它们是理所当然的):

  • 批量接受超过0.9的所有内容
  • 手动查看0.8和0.9之间的所有内容
  • 丢弃0.8以下的所有内容

可能听起来很愚蠢。。。但是我们可以将这两个文件加载到表中,并通过简单的连接来完成。有一些库消除了对90%代码的需要,无需重新发明轮子。你真的成功地让csv工作了吗?我已经在一些测试数据上尝试过了,它会将所有内容与CSV文件的第一行进行匹配。。。
needle (title VARCHAR)
haystack (title VARCHAR)
SELECT title, best_match,
    levenshtein_ratio(TRIM(LOWER(title)), TRIM(LOWER(best_match))) AS ratio
FROM (
    SELECT n.title AS title, (
                SELECT h.title
                FROM haystack h
                ORDER BY levenshtein_ratio(TRIM(LOWER(n.title)), TRIM(LOWER(h.title))) DESC
                LIMIT 1
           ) AS best_match
    FROM needle n
) x
ORDER BY ratio DESC
import csv
from fuzzywuzzy import fuzz

# Grab CSV data: 
with open('needles.csv', 'U') as z:
    reader = csv.reader(z)
    needles = list(reader)

with open('haystack.csv', 'U') as w:
    reader = csv.reader(w)
    haystack = list(reader)

# Calculate matches and append to list
NeedlesNotInHaystack = []

Fuzziness = 80 # ADJUST THIS VALUE TO FINE-TUNE RESULTS 
for x in needle:
    for y in haystack:
        if fuzz.ratio(x,y) > Fuzziness: 
            NeedlesNotInHaystack.append(x)

#Export results to CSV:
with open('Results', 'wb') as csvfile:
    temp = csv.writer(csvfile)
    temp.writerows(NeedlesNotInHaystack)
fuzz.token_sort_ratio OR fuzz.token_set_ratio