在没有 SnowBall Analyzer 或自定义分析器的情况下 Lucene.NET 中的英语词干提取或词形还原
English stemming or lemmatization in Lucene.NET without SnowBall Analyzer or a custom analyzer
是否有可以进行英语词干提取或词形还原的非过时 Lucene.NET 分析器,或者我是否需要编写自定义分析器?
我似乎找不到在源代码中包含 PorterStemFilter
或 EnglishMinimalStemFilter
的分析器。我可以编写自己的分析器,但感觉不需要那样做,而且我会重新发明错误的轮子。
我正在尝试对 Lucene.NET 中的英语单词进行词干提取。据我所知,这不是开箱即用的。我试过像这样使用 EnglishAnalizer:
[TestFixture]
public class TestAnalyzers
{
private const string FieldName = "CustomFieldName";
public Directory CreateDirectory(IEnumerable<string> documents, Analyzer analyzer)
{
var directory = new RAMDirectory();
var iwc = new IndexWriterConfig(LuceneVersion.LUCENE_48, analyzer)
{
OpenMode = OpenMode.CREATE_OR_APPEND,
};
var writer = new IndexWriter(directory, iwc);
writer.Commit();
foreach(var doc in documents) {
var document = new Document();
document.AddTextField(FieldName, doc, StoredField.Store.YES);
writer.AddDocument(document);
}
writer.Flush(true, true);
writer.Commit();
return directory;
}
private QueryParser CreateQueryParser(Analyzer analyzer)
=> new MultiFieldQueryParser(
LuceneVersion.LUCENE_48,
GetSearchFields(),
analyzer);
private string[] GetSearchFields() => new [] { FieldName };
[TestCase("for", "for")]
[TestCase("for", "forward")]
[TestCase("forward", "for")]
//[TestCase("retire", "retirement")]
[TestCase("retirement", "retire")]
[Test]
public void TestPartialWordsStandard(string fieldValue, string query)
{
var analyzer = new EnglishAnalyzer(LuceneVersion.LUCENE_48);
var directory = CreateDirectory(new [] { fieldValue }, analyzer);
var indexReader = DirectoryReader.Open(directory);
Assert.AreEqual(1, indexReader.NumDocs);
var doc = indexReader.Document(0);
Assert.NotNull(doc);
Assert.AreEqual(fieldValue, doc.GetField(FieldName).GetStringValue());
var searcher = new IndexSearcher(indexReader);
var queryObj = CreateQueryParser(analyzer).Parse(query);
var results = searcher.Search(queryObj, 2);
Assert.AreEqual(1, results.TotalHits);
doc = indexReader.Document(results.ScoreDocs.First().Doc);
Assert.AreEqual(fieldValue, doc.GetField(FieldName).GetStringValue());
}
}
它没有词干。通过阅读代码,它使用所有格过滤器删除 s 和 s, but not the english stemming filter or the
PorterStemFilter`。
我能够使用 var analyzer = new SnowballAnalyzer(LuceneVersion.LUCENE_48, "English");.
进行一些词干提取,它的词干提取量足够,但是 class 已经过时了。
Lucene.Net EnglishAnalyzer
确实包括波特词干提取。在 class 的 source code 的第 117 行是这一行:
result = new PorterStemFilter(result);
我还 运行 使用 EnglishAnalyzer
在我的系统中进行了测试,并确认它确实是词干提取。因此,例如,我的索引文本包含单词 "walking",当我在 "walked" 上搜索时,我得到了记录。
是否有可以进行英语词干提取或词形还原的非过时 Lucene.NET 分析器,或者我是否需要编写自定义分析器?
我似乎找不到在源代码中包含 PorterStemFilter
或 EnglishMinimalStemFilter
的分析器。我可以编写自己的分析器,但感觉不需要那样做,而且我会重新发明错误的轮子。
我正在尝试对 Lucene.NET 中的英语单词进行词干提取。据我所知,这不是开箱即用的。我试过像这样使用 EnglishAnalizer:
[TestFixture]
public class TestAnalyzers
{
private const string FieldName = "CustomFieldName";
public Directory CreateDirectory(IEnumerable<string> documents, Analyzer analyzer)
{
var directory = new RAMDirectory();
var iwc = new IndexWriterConfig(LuceneVersion.LUCENE_48, analyzer)
{
OpenMode = OpenMode.CREATE_OR_APPEND,
};
var writer = new IndexWriter(directory, iwc);
writer.Commit();
foreach(var doc in documents) {
var document = new Document();
document.AddTextField(FieldName, doc, StoredField.Store.YES);
writer.AddDocument(document);
}
writer.Flush(true, true);
writer.Commit();
return directory;
}
private QueryParser CreateQueryParser(Analyzer analyzer)
=> new MultiFieldQueryParser(
LuceneVersion.LUCENE_48,
GetSearchFields(),
analyzer);
private string[] GetSearchFields() => new [] { FieldName };
[TestCase("for", "for")]
[TestCase("for", "forward")]
[TestCase("forward", "for")]
//[TestCase("retire", "retirement")]
[TestCase("retirement", "retire")]
[Test]
public void TestPartialWordsStandard(string fieldValue, string query)
{
var analyzer = new EnglishAnalyzer(LuceneVersion.LUCENE_48);
var directory = CreateDirectory(new [] { fieldValue }, analyzer);
var indexReader = DirectoryReader.Open(directory);
Assert.AreEqual(1, indexReader.NumDocs);
var doc = indexReader.Document(0);
Assert.NotNull(doc);
Assert.AreEqual(fieldValue, doc.GetField(FieldName).GetStringValue());
var searcher = new IndexSearcher(indexReader);
var queryObj = CreateQueryParser(analyzer).Parse(query);
var results = searcher.Search(queryObj, 2);
Assert.AreEqual(1, results.TotalHits);
doc = indexReader.Document(results.ScoreDocs.First().Doc);
Assert.AreEqual(fieldValue, doc.GetField(FieldName).GetStringValue());
}
}
它没有词干。通过阅读代码,它使用所有格过滤器删除 s 和 s, but not the english stemming filter or the
PorterStemFilter`。
我能够使用 var analyzer = new SnowballAnalyzer(LuceneVersion.LUCENE_48, "English");.
进行一些词干提取,它的词干提取量足够,但是 class 已经过时了。
Lucene.Net EnglishAnalyzer
确实包括波特词干提取。在 class 的 source code 的第 117 行是这一行:
result = new PorterStemFilter(result);
我还 运行 使用 EnglishAnalyzer
在我的系统中进行了测试,并确认它确实是词干提取。因此,例如,我的索引文本包含单词 "walking",当我在 "walked" 上搜索时,我得到了记录。