Lucene 8 巴西葡萄牙语分析器中的奇怪标记化
Strange tokenization in Lucene 8 Brazilian Portuguese analyzers
我在 Windows 10 上使用带有 AdoptOpenJDK 11 的 Lucene 8.6.2(目前最新可用),我遇到了葡萄牙语和巴西葡萄牙语分析器破坏标记化的奇怪问题。
举个简单的例子:Jorge Aragão 的著名桑巴歌曲“Já É”的副歌的第一行,首先使用 org.apache.lucene.analysis.standard.StandardAnalyzer
作为参考。
Pra onde você for
String text = "Pra onde você for";
try (Analyzer analyzer = new StandardAnalyzer()) {
try (final TokenStream tokenStream = analyzer.tokenStream("text", text)) {
CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);
tokenStream.reset();
while(tokenStream.incrementToken()) {
System.out.println("term: charTermAttribute.toString());
}
tokenStream.end();
}
}
这给了我以下条款(为了便于阅读而折叠成一行):
pra onde você for
好的,这几乎是我对任何分析仪的期望。但是如果我使用 org.apache.lucene.analysis.pt.PortugueseAnalyzer
代替,使用无参数构造函数,我得到的是:
pra onde
嗯?也许它认为“você”(“你”)和“for”(“可能去”)是停用词并删除了它们。
但现在让我们尝试 org.apache.lucene.analysis.br.BrazilianAnalyzer
,再次使用无参数构造函数:
pra ond voc for
现在它已经坏掉了。它将“onde”(“where”)改为“ond”,据我所知这甚至不是葡萄牙语单词。对于“você”,它只是去掉了“ê”。
其他线路同样糟糕或更糟:
- 文本:“A saudade é dor, volta meu amor”
StandardAnalyzer
: a saudade é dor volta meu amor
PortugueseAnalyzer
: saudad é dor volt amor
BrazilianAnalyzer
: saudad é dor volt amor
在这里你可以看到葡萄牙语和巴西葡萄牙语分析器产生了相同的输出——但它是相同的错误输出,因为如果我我很想让我的爱回到我身边。
我是否在使用 Lucene 核心库和语言分析器时犯了一些严重错误?输出毫无意义,我很惊讶这种通用语言的分析器会像那样破坏标记。
查看 PortugueseAnalyzer
和 BrazilianAnalyzer
的代码,看起来这些分析器正在执行词干提取。 (我对编写 Lucene 有点陌生,所以这不是我所期望的。)所以对于索引,也许这就是作者的意图。也许“você”是“você”和“vocês”的词干。我猜“volt”是动词(不定式)“voltar”的词干。 (但是“saudad”并不是我所期望的“saudade”的词干,但同样,文本分析的这一方面对我来说有点新鲜。)
对于我的特定用例,我只想标记词并跳过停用词。我找不到关闭 PortugueseAnalyzer
和 BrazilianAnalyzer
的词干提取的方法,所以我想我将只使用 StandardAnalyzer
,但使用 [=42] 中的停用词=] 分析器,像这样:
final Analyzer analyzer;
try (BrazilianAnalyzer ptBRAnalyzer = new BrazilianAnalyzer()) {
analyzer = new StandardAnalyzer(ptBRAnalyzer.getStopwordSet());
}
这有点迂回,但至少这给了我更多我想要的东西:
- 文本:“A saudade é dor, volta meu amor”
StandardAnalyzer
: a saudade é dor volta meu amor
StandardAnalyzer
和 PortugueseAnalyzer
停用词:saudade é dor volta amor
StandardAnalyzer
和 BrazilianAnalyzer
停用词:saudade é dor volta meu amor
这样更好。但显然,葡萄牙语分析器认为“meu”是停用词,尽管巴西语分析器并非如此。我猜想“我的”这个词在葡萄牙葡萄牙语和巴西葡萄牙语中的意思差不多;奇怪的是,这两个分析器在默认情况下是否应该将其作为停用词存在分歧。
我在 Windows 10 上使用带有 AdoptOpenJDK 11 的 Lucene 8.6.2(目前最新可用),我遇到了葡萄牙语和巴西葡萄牙语分析器破坏标记化的奇怪问题。
举个简单的例子:Jorge Aragão 的著名桑巴歌曲“Já É”的副歌的第一行,首先使用 org.apache.lucene.analysis.standard.StandardAnalyzer
作为参考。
Pra onde você for
String text = "Pra onde você for";
try (Analyzer analyzer = new StandardAnalyzer()) {
try (final TokenStream tokenStream = analyzer.tokenStream("text", text)) {
CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);
tokenStream.reset();
while(tokenStream.incrementToken()) {
System.out.println("term: charTermAttribute.toString());
}
tokenStream.end();
}
}
这给了我以下条款(为了便于阅读而折叠成一行):
pra onde você for
好的,这几乎是我对任何分析仪的期望。但是如果我使用 org.apache.lucene.analysis.pt.PortugueseAnalyzer
代替,使用无参数构造函数,我得到的是:
pra onde
嗯?也许它认为“você”(“你”)和“for”(“可能去”)是停用词并删除了它们。
但现在让我们尝试 org.apache.lucene.analysis.br.BrazilianAnalyzer
,再次使用无参数构造函数:
pra ond voc for
现在它已经坏掉了。它将“onde”(“where”)改为“ond”,据我所知这甚至不是葡萄牙语单词。对于“você”,它只是去掉了“ê”。
其他线路同样糟糕或更糟:
- 文本:“A saudade é dor, volta meu amor”
StandardAnalyzer
:a saudade é dor volta meu amor
PortugueseAnalyzer
:saudad é dor volt amor
BrazilianAnalyzer
:saudad é dor volt amor
在这里你可以看到葡萄牙语和巴西葡萄牙语分析器产生了相同的输出——但它是相同的错误输出,因为如果我我很想让我的爱回到我身边。
我是否在使用 Lucene 核心库和语言分析器时犯了一些严重错误?输出毫无意义,我很惊讶这种通用语言的分析器会像那样破坏标记。
查看 PortugueseAnalyzer
和 BrazilianAnalyzer
的代码,看起来这些分析器正在执行词干提取。 (我对编写 Lucene 有点陌生,所以这不是我所期望的。)所以对于索引,也许这就是作者的意图。也许“você”是“você”和“vocês”的词干。我猜“volt”是动词(不定式)“voltar”的词干。 (但是“saudad”并不是我所期望的“saudade”的词干,但同样,文本分析的这一方面对我来说有点新鲜。)
对于我的特定用例,我只想标记词并跳过停用词。我找不到关闭 PortugueseAnalyzer
和 BrazilianAnalyzer
的词干提取的方法,所以我想我将只使用 StandardAnalyzer
,但使用 [=42] 中的停用词=] 分析器,像这样:
final Analyzer analyzer;
try (BrazilianAnalyzer ptBRAnalyzer = new BrazilianAnalyzer()) {
analyzer = new StandardAnalyzer(ptBRAnalyzer.getStopwordSet());
}
这有点迂回,但至少这给了我更多我想要的东西:
- 文本:“A saudade é dor, volta meu amor”
StandardAnalyzer
:a saudade é dor volta meu amor
StandardAnalyzer
和PortugueseAnalyzer
停用词:saudade é dor volta amor
StandardAnalyzer
和BrazilianAnalyzer
停用词:saudade é dor volta meu amor
这样更好。但显然,葡萄牙语分析器认为“meu”是停用词,尽管巴西语分析器并非如此。我猜想“我的”这个词在葡萄牙葡萄牙语和巴西葡萄牙语中的意思差不多;奇怪的是,这两个分析器在默认情况下是否应该将其作为停用词存在分歧。