文字比较中的值有误

如何解决文字比较中的值有误

在下面的数据集中查找文本匹配时遇到了一些困难(请注意Sim是我当前的输出,它是通过运行下面的代码生成的。它显示错误的匹配)。

    ID      Text                                                   Sim
13  fsad    amazing  ...                                           fsd
14  fdsdf   best sport everand the gane of the year❤️❤️❤️❤️...     fdsfdgte3e
18  gsd     wonderful                                              fast 
21  dfsfs   i love this its incredible ...                         reds
23  gwe     wonderful end ever seen you ...                        add
... ... ... ...
261 add     wonderful                                              gwe
261 add     wonderful                                              gsd
261 add     wonderful                                              fdsdf
267 fdsfdgte3e  best match ever its a masterpiece                  fdsdf
277 hgdfgre terrible destroys everything ...                       tm28

如上所示,Sim不会给写出匹配文本的ID。 例如,add应该与gsd匹配,反之亦然。但是我的输出显示addgwe匹配,这是不正确的。

我正在使用的代码如下:

    from fuzzywuzzy import fuzz
    
        def sim (nm,df): # this function finds matches between texts based on a threshold,which is 100. The logic is fuzzywuzzy,specifically partial ratio. The output should be IDs whether texts match,based on the threshold.
            matches = dataset.apply(lambda row: ((fuzz.partial_ratio(row['Text'],nm)) = 100),axis=1)
            return [df.ID[i] for i,x in enumerate(matches) if x]
    
    df['L_Text']=df['Text'].str.lower() 
    df['Sim']=df.apply(lambda row: sim(row['L_Text'],df),axis=1)
    df=df.assign(
        Sim = df.apply(lambda x: [s for s in x['Sim'] if s != x['ID']],axis=1)
    )

def tr (row): # this function assign a similarity score for each text applying partial_ratio similarity
    return (df.loc[:row.name-1,'L_Text']
                    .apply(lambda name: fuzz.partial_ratio(name,row['L_Text'])))

t = (df.loc[1:].apply(tr,axis=1)
         .reindex(index=df.index,columns=df.index)
         .fillna(0)
         .add_prefix('txt')
     )
t += t.to_numpy().T + np.diag(np.ones(t.shape[0]))

能否请您帮助我理解代码中的错误?不幸的是我看不到它。

我的预期输出如下:

ID      Text                                                   Sim
13  fsad    amazing  ...                                          
14  fdsdf   best sport everand the gane of the year❤️❤️❤️❤️...    
18  gsd     wonderful                                              add 
21  dfsfs   i love this its incredible ...                         
23  gwe     wonderful end ever seen you ...                       
... ... ... ...
261 add     wonderful                                              gsd
261 add     wonderful                                              gsd
261 add     wonderful                                              gsd
267 fdsfdgte3e  best match ever its a masterpiece                 
277 hgdfgre terrible destroys everything ... 

                 

sim函数中将其设置为完全匹配(= 1)。

解决方法

初始假设

首先,由于您的问题对我来说还不清楚,我假设您希望对所有行进行成对比较,并且如果匹配分数> 100,则需要添加匹配的行。如果不是这种情况,请纠正我。

语法问题

因此,上面的代码存在多个问题。首先,如果只复制并粘贴它,则从语法上讲不可能运行它。 sim()函数应如下所示:

def sim (nm,df): 
    matches = df.apply(lambda row: fuzz.partial_ratio(row['Text'],nm) == 100),axis=1)
    return [df.ID[i] for i,x in enumerate(matches) if x]

请注意,df代替了dataset以及==代替了=。我还删除了多余的括号以提高可读性。

语义问题

如果我随后运行您的代码并打印t(这似乎不是最终结果),则会得到以下信息:

   txt0  txt1   txt2  txt3   txt4   txt5   txt6   txt7  txt8  txt9
0   1.0  27.0   12.0  45.0   45.0   12.0   12.0   12.0  27.0  64.0
1  27.0   1.0   33.0  33.0   42.0   33.0   33.0   33.0  52.0  44.0
2  12.0  33.0    1.0  22.0  100.0  100.0  100.0  100.0  22.0  33.0
3  45.0  33.0   22.0   1.0   41.0   22.0   22.0   22.0  40.0  30.0
4  45.0  42.0  100.0  41.0    1.0  100.0  100.0  100.0  35.0  47.0
5  12.0  33.0  100.0  22.0  100.0    1.0  100.0  100.0  22.0  33.0
6  12.0  33.0  100.0  22.0  100.0  100.0    1.0  100.0  22.0  33.0
7  12.0  33.0  100.0  22.0  100.0  100.0  100.0    1.0  22.0  33.0
8  27.0  52.0   22.0  40.0   35.0   22.0   22.0   22.0   1.0  34.0
9  64.0  44.0   33.0  30.0   47.0   33.0   33.0   33.0  34.0   1.0

对我来说似乎是正确的,因为fuzz.partial_ratio("wonderful end ever seen you","wonderful")返回100(因为部分比赛已经被认为是100分)。 出于一致性原因,您可以更改

t += t.to_numpy().T + np.diag(np.ones(t.shape[0]))

t += t.to_numpy().T + np.diag(np.ones(t.shape[0])) * 100

,因为所有元素都应该完全匹配。所以当你说

但是我的输出显示add与gwe匹配,这是不正确的。

fuzz.partial_ratio()的意义上,这是正确的,您可能要考虑使用fuzz.ratio()。另外,将t转换为新的Sim列时可能会出错,但是在提供的示例中似乎没有代码。

替代实现

而且,正如一些评论所建议的那样,有时对重组代码很有帮助,以便人们更轻松地为您提供帮助。这是一个看起来像这样的示例:

import re

import pandas as pd
from fuzzywuzzy import fuzz

data = """
13   fsad        amazing ...                                           fsd
14   fdsdf       best sport everand the gane of the year❤️❤️❤️❤️...    fdsfdgte3e
18   gsd         wonderful                                             fast 
21   dfsfs       i love this its incredible ...                        reds
23   gwe         wonderful end ever seen you ...                       add
261  add         wonderful                                             gwe
261  add         wonderful                                             gsd
261  add         wonderful                                             fdsdf
267  fdsfdgte3e  best match ever its a masterpiece                     fdsdf
277  hgdfgre     terrible destroys everything ...                      tm28
"""

rows = data.strip().split('\n')
records = [[element for element in re.split(r' {2,}',row) if element != ''] for row in rows]

df = pd.DataFrame.from_records(records,columns=['RowNumber','ID','Text','IncorrectSim'],index='RowNumber')
df = df.drop('IncorrectSim',axis=1)
df = df.drop_duplicates(subset=["ID","Text"])  # Assuming that there is no point in keeping duplicate rows
df = df.set_index('ID')  # Assuming that the "ID" column holds a unique ID

comparison_df = df.copy()
comparison_df['Text'] = comparison_df["Text"].str.lower()
comparison_df['Tmp'] = 1
# This gives us all possible row combinations
comparison_df = comparison_df.reset_index().merge(comparison_df.reset_index(),on='Tmp').drop('Tmp',axis=1)
comparison_df = comparison_df[comparison_df['ID_x'] != comparison_df['ID_y']]  # We only want rows that do not match itself
comparison_df['matchScore'] = comparison_df.apply(lambda row: fuzz.partial_ratio(row['Text_x'],row['Text_y']),axis=1)
comparison_df = comparison_df[comparison_df['matchScore'] == 100]  # only keep perfect matches
comparison_df = comparison_df[['ID_x','ID_y']].rename(columns={'ID_x': 'ID','ID_y': 'Sim'}).set_index('ID')  # Cleanup

result = df.join(comparison_df,how='left').fillna('')
print(result.to_string())

给予:

                                                         Text  Sim
ID                                                                
add                                                 wonderful  gsd
add                                                 wonderful  gwe
dfsfs                          i love this its incredible ...     
fdsdf       best sport everand the gane of the year❤️❤️❤️❤...     
fdsfdgte3e                  best match ever its a masterpiece     
fsad                                              amazing ...     
gsd                                                 wonderful  gwe
gsd                                                 wonderful  add
gwe                           wonderful end ever seen you ...  gsd
gwe                           wonderful end ever seen you ...  add
hgdfgre                      terrible destroys everything ...     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?