【问题标题】:string matching of synoymns in different columns不同列中同义词的字符串匹配
【发布时间】:2018-12-31 06:46:00
【问题描述】:

我有一个看起来像这样的数据集

  name      col1            col2                      col13 
  company1  Banking         Finance                   B&F
  company2  Utilities       Utilities                 NaN
  company3  Transportation  Pipeline Transportation   Utilities
  company4  Consulting      Tech                      Insurance

等等…………

所以我需要做的是将每一列相互比较,并标记那些完全不相似(或同义)的列。例如 - 公司 4 没有类似的东西,所以我想标记它。公司 3 看起来有些相似,所以我想将其标记为几乎相似(黄色标志),并且匹配的绿色是绿色。

The output somewhat needs to look like this :
  name      col1            col2                      col13       flag 
  company1  Banking         Finance                   B&F          green
  company2  Utilities       Utilities                 NaN          green
  company3  Transportation  Pipeline Transportation   Utilities   yellow
  company4  Consulting      Tech                      Insurance    red

我知道这似乎是一个非常大的问题,但有人可以为我提供一个开始 - 比如如何解决这个问题。我可以在这里使用哪些字符串匹配算法?

谢谢

【问题讨论】:

  • 您是否希望仅在同一行上跨列进行比较?
  • 是的,我正在寻找那个
  • 查看fuzzywuzzy 模块
  • 我想这就是你在问题中想要弄清楚的,但如果你能明确定义你正在寻找什么样的相似之处,它肯定会帮助你更快地得到答案对于
  • 我正在寻找同义词的相似之处 - 比如银行和金融是同义词,但金融和技术并不接近。

标签: python string pandas scikit-learn nltk


【解决方案1】:

首先,您可以使用fuzzywuzzy 中的ratiopartial_ratio 来获取同一行单元格之间的字符串相似度。接下来,您还可以使用WordNetnltk)之类的词法数据库来比较同一行的每个单元格是否是彼此的同义词。需要注意的是,每个单词的建议同义词是详尽的,可能不是包罗万象的——我们可以在使用 WordNet 时看到这一点,但 BankingFinanceB&F 被标记为红色。但是,这两种方法可能有助于您开始。

先安装依赖:

pip install nltk fuzzywuzzy

下载 WordNet:

python
>>> nltk.download('wordnet')
[nltk_data] Downloading package wordnet to
[nltk_data]     C:\Users\user\AppData\Roaming\nltk_data...
[nltk_data]   Unzipping corpora\wordnet.zip.
True

执行脚本:

import pandas as pd

from nltk.corpus import wordnet as wn
from fuzzywuzzy import fuzz

df = pd.DataFrame({
'name': ['company 1', 'company 2', 'company 3', 'company 4'],
'col1': ['Banking', 'Utilities', 'Transportation', 'Consulting'],
'col2': ['Finance', 'Utilities', 'Pipeline Transportation', 'Utilities'],
'col3': ['B&F', 'NaN', 'Utilities', 'Insurance'],
})

def get_synonyms(word):
    synonym_list = []
    for synset in wn.synsets(word):
        for lemma in synset.lemmas():
            if not lemma.name() in synonym_list:
                synonym_list.append(lemma.name().replace('_',' '))
    return synonym_list

def check_flag(row):

    col1_data = row['col1']
    col2_data = row['col2']
    col3_data = row['col3']

    green_flag_threshold = 80

    # Get Fuzzy Ratio
    fuzz_ratio_1 = fuzz.ratio(col1_data,col2_data)
    fuzz_ratio_2 = fuzz.ratio(col2_data,col3_data)
    fuzz_ratio_3 = fuzz.ratio(col3_data,col1_data)

    if col1_data == col2_data or col2_data == col3_data or col3_data == col1_data or green_flag_threshold < (fuzz_ratio_1 or fuzz_ratio_2 or fuzz_ratio_3):
        return 'green'

    # Check synonyms using Wordnet (nltk)
    col1_syn_list = get_synonyms(col1_data)
    col2_syn_list = get_synonyms(col2_data)
    col3_syn_list = get_synonyms(col3_data)

    all_data = [col1_data, col2_data, col3_data]

    for col_data in all_data:
        for word in col_data.split():
            if word in (col1_syn_list or col2_syn_list or col3_syn_list):
                return 'yellow'

    return 'red'

df['flag'] = df.apply(check_flag, axis=1)

print(df)

结果:

             col1                     col2       col3       name    flag
0         Banking                  Finance        B&F  company 1     red
1       Utilities                Utilities        NaN  company 2   green
2  Transportation  Pipeline Transportation  Utilities  company 3  yellow
3      Consulting                Utilities  Insurance  company 4     red

Process finished with exit code 0

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-01
    • 2020-07-07
    • 2023-03-10
    • 2017-12-15
    • 1970-01-01
    • 2017-01-01
    • 1970-01-01
    • 2021-06-02
    相关资源
    最近更新 更多