【问题标题】:Detecting word boundaries and the language for each word from UTF8 buffer从 UTF8 缓冲区中检测每个单词的单词边界和语言
【发布时间】:2012-05-09 12:30:16
【问题描述】:

我正在开发一个自定义搜索引擎,我需要将每个单词传递给适当的语言特定词干分析器。

我最近发现了紧凑型语言检测器 (CLD) http://blog.mikemccandless.com/2011/10/language-detection-with-googles-compact.html,它为 UTF8 缓冲区提供了令人印象深刻的语言检测。

虽然 CLD 非常适合检测给定缓冲区的语言,但我需要从缓冲区中提取单词边界,并为这些单词检测每个单词的语言。

有什么想法吗?

【问题讨论】:

  • 带有\b特殊字符的正则表达式。

标签: encoding utf-8 internationalization icu


【解决方案1】:

祝你好运:)

老实说,这是高级 NLP 主题,很难可靠地做到。

首先,您无法像这样检测许多语言中的单词边界。尤其是在表意语言(中文、日文……)中,您需要训练有素的学习算法来进行标记化。
有传言说有人这样做了(请参阅基础技术),但这仅对您有能力支付许可费有用。

顺便说一句。许多单词可以用几种语言完全一样地写出来,你不会得到可靠的语言检测。更糟糕的是,算法(通常是一些基于 n-gram 的检测器)将需要几个八位字节来检测任何东西(对或错)。

正如我所说,祝你好运。如果我是你,我会重新考虑我的策略;)

【讨论】:

  • Dyda:你有使用 Lucene 的经验吗?我注意到 Lucene 有一个内置的用于多语言文本的中断迭代器,称为 CompositeBreakIterator。靠谱吗?
  • @Manoj:老实说,我自己没有玩过 Apache Lucene。我所知道的只是你需要规范化你输入的文本,否则你会得到不可预知的结果。此外,我们的一个团队提出了对搜索可靠性的担忧,但我不能说它是否有效 - 需要进行一些认真的研究。
  • @PawełDyda 我为天城体脚本编写了一个简单的语言检测器。这个想法是只接受UTF8 编码数据,遍历每个字符并对其进行解码以获得代码点。将代码点与 unicode 字符范围匹配,并确定它属于哪个语言范围。在迭代时,我忽略了加入者和非加入者。如果所有字符都在同一语言范围内,则报告该语言。当我们得到一个在不同范围内的代码点时,迭代停止。到目前为止,这运作良好。我想知道,这种方法可以用于所有非梵文语言吗?
  • @Appu:我看到两个问题: 1. 如果你有混合脚本环境,那就是你有例如。用梵文写的句子中的英文单词(拉丁文)?我相信它一直在发生。 2. 某些代码范围恰好用于不止一种语言,例如。波兰语和立陶宛语可以使用字母“ą”(a 和 ogonek);大多数西里尔字符都可以用在俄语、白俄罗斯语、乌克兰语、保加利亚语、马其顿语、塞尔维亚语甚至蒙古语中(还有其他的)。没有统计语言配置文件 = n-grams,无法匹配语言。
【解决方案2】:

我使用 ICU 开发了一个语言检测引擎,它基本上执行以下操作:

  1. 使用 ICU BreakIterator 和英语 (Locale::getEnglish()) 规则发现基本“单词”
  2. 将 #1 中的单词输入到我的引擎中,这反过来又为我提供了按分数排序的“真实”语言

由于您的输入是 UTF-8,因此出于您的目的,您可以使用 setText() 方法采用 UText*(请注意此处链接的示例,这几乎正是您所需要的——不过,您可能想要使用C++ API),可以设置为遍历 UTF-8。

【讨论】:

  • BreakIterator 的问题是,它不能在亚洲语言中正常工作,这在其文档中有明确说明。此外,ICU 的语言检测可靠性比预期的要差一些(来自我的研究,遗憾的是我无法分享)。
  • 我想念你的帖子。我在上面发布的答案非常适合作为“单词”提取以馈送到语言检测器的预处理步骤(在我的情况下,我使用 n-gram 引擎)。至于解析 CJK 的边界,它非常非常复杂:)
猜你喜欢
  • 1970-01-01
  • 2019-07-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-03
  • 2014-12-11
  • 2017-06-14
  • 1970-01-01
相关资源
最近更新 更多