0

我有大量的文本,分成句子。我有每个句子的两个版本,一个版本有 POS 标记的标记。我想对版本 1 中的所有内容进行 POS 标记。我想通过将版本 1 中的单词替换为版本 2 中带有 POS 标记的对应词来做到这一点。

这有一些并发症:

  1. 同一个词的拼写在两个版本之间可能不同(例如'cafe'vs. 'café')。

  2. 带有 POS 标记的版本中的间距并不总是与另一个中的间距相匹配(例如"did", "n't"vs. "didn't")。

  3. 一个版本经常使用符号,而另一个版本则拼出完整的单词(例如'&'vs. 'and')。

文本的语言不是英语,所以上面的例子只是对正在发生的事情的粗略估计。以下是实际文本中的几个示例。我希望很容易看出版本 2 中带有 POS 标记的文本如何与版本 1 中的文本紧密匹配,但不完全匹配;有些单词丢失了,有些单词拼写不同,有些单词乱了,等等。

Example 1.
Version 1: ".o. omi adov-ztu jo znóyod sotfico pru & bra"
Version 2: [['omi', '<DET>'], ['adov', '<NOUN>'], ['ztu', '<PRON>'], ['znóyod', '<VERB>'],
           ['sotfico', '<ADJ>'], ['uont', '<CCONJ>'], ['jo', '<ADP>']]

Example 2.
Version 1: "vomoyj zíy"
Version 2: [['vó', '<SCONJ>'], ['ṁo', '<PART>'], ['yj', '<PRON>'], ['zíy', '<ADJ>']]

Example 3.
Version 1: ".o. fa-tistyjogot"
Version 2: [['fa', '<PP>'], ['t', '<IP>'], ['is', '<UU>'], ['fatistyjogot', '<VERB>']] 

在示例 1'&'中映射到'uont'. 版本 1 中的单词'pru''bra'不映射到版本 2 中的任何内容。单词 ,'jo'在版本 2 中的位置也错误,需要遵循版本 1 的词序。

在示例 2'vó''ṁo', 和'yj'all 都映射到'vomoyj',即使某些字符不同,并且它被拆分在两个位置。

在示例 3 中,只有一个单词,但部分重复。'fa', 't', 和'is'都出现在 中'fatisyjogot',所以我可以忽略除'fatisyjogot'版本 2 之外的所有内容。

在版本 2 中标记了单词的地方,我想用版本 2 中的形式和 POS-tag 替换版本 1 中的对应词。这样我就可以保持版本 1 的词序。如果版本 2 中不存在带标签的表单,我想保留版本 1 中的单词并添加占位符标签'<X>'. 如果版本 2 中的任何内容像示例 3 一样重复,我还需要省略它。因此,从上面的示例中,我想创建以下列表:

Example 1: [['.o.', '<X>'], ['omi', '<DET>'], ['adov', '<NOUN>'], ['ztu', '<PRON>'], ['jo', '<ADP>'],
           ['znóyod', '<VERB>'], ['sotfico', '<ADJ>'], ['pru', '<X>'], ['uont', '<CCONJ>'], ['bra', '<X>']]
Example 2: [['vó', '<SCONJ>'], ['ṁo', '<PART>'], ['yj', '<PRON>'], ['zíy', '<ADJ>']]
Example 3: [['.o.', '<X>'], ['fatistyjogot', '<VERB>']]

我尝试使用 RegEx 和nltk模块中的编辑距离方法编写一个函数来识别相似的字符串。它适用于较长的字符串,但由于某些字符串很短,就像'vó'上面一样,它有时会遇到困难。我还查看了序列比对库,但发现自己在尝试应用它们时感到困惑。

有没有办法比较这些字符串并将版本 2 中的每个字符串与版本 1 中的某个子字符串进行高精度匹配?我可以自己整理 POS 标签,我只需要一种方法来找到所有相应的令牌。

例如,我可以编写一个函数,给它两个版本作为参数,并让它返回所有相关的字符串(以及它们在句子中的索引/位置)吗?

v1 = "vomoyj zíy"
v2 = [['vó', '<SCONJ>'], ['ṁo', '<PART>'], ['yj', '<PRON>'], ['zíy', '<ADJ>']]

def some_func(v1, v2):
    *do something*
    return comparison_list

print(some_func(v1, v2))

Output:
[['vó', 'vomoyj', 0], ['ṁo', 'vomoyj', 1], ['yj', 'vomoyj', 2], ['zíy', 'zíy', 3]]
*OR*
[['vó', 'vo'], ['ṁo', 'mo'], ['yj', 'yj'], ['zíy', 'zíy']]

编辑:将其翻译成英文以简化问题是不可行的。我真的需要比较字符串。

4

1 回答 1

0

您可以将标记转换为英文标记,然后可以用于查找类似标记,并且它位于字符串中(这里是 v1)

v1 = 'vomoyj ziy'
v2 = [['vó', '<SCONJ>'], ['ṁo', '<PART>'], ['yj', '<PRON>'], ['zíy', '<ADJ>']]

import unidecode
def comparison_func(v1,v2):
   output_ = []
   for token in v2:
      converted_token =   unidecode.unidecode(token[0])
      position =  v1.find(converted_token)         
      output_.append([token[0],v1[position:position+len(converted_token)],position])
   return output_

comparison_func(v1,v2)
#op
[['vó', 'vo', 0], ['ṁo', 'mo', 2], ['yj', 'yj', 4], ['zíy', 'ziy', 7]]
于 2020-02-12T09:21:13.340 回答