我在尝试编写一个搜索引擎时遇到了麻烦,该搜索引擎将一个单词的所有变形视为相同的基本单词。
虚拟语气( 例如 可能;关键 已完成;我希望< EM>是)
例如,使用“ enable ”,我不希望将“启用”和“启用”打印为单独的条目。所有这三个都应该算作相同的基本单词,动词 enable 。
我可以使用类似的哈希来阻止打印重复项:
unless ($seenmatches{ $headmatches[$l] }++)
有人可以解释一下吗?在下面的评论中解释。
这并不能阻止复数/过去继续。有没有办法做到这一点,或者一些完全不同的方法,也许一个涉及正则表达式和/或替换,然后是一个unub?
我不能用替换修改单词,因为那时打印不能正确打印出来。虽然我还没有进入舞台,但最终我还想包括不规则的过去时期[ᴇᴅɪᴛᴏʀɴᴏᴛᴇand:和不规则的名词,以及]以及
我不确定你还需要什么来回答我的问题,所以请让我知道任何我无意中遗漏的内容,并且我会填写任何遗漏的内容以帮助更清楚。
答案 0 :(得分:5)
典型搜索引擎的工作方式如下:
Lingua::Stem
(或更好,Lingua::Stem::Snowball
)这些是Porter词干分析器的略微更新版本现在,当一个查询到达时,它也被标记化并且每个标记都被阻止,但这次我们并不关心这些位置。我们查找每个令牌与我们索引的那些令牌,以找到帖子(匹配文档标识符)。我们现在可以检索存储的开始/结束偏移以确定术语在原始文本中的位置。
因此,您确实丢失了索引的后缀(这是用于查找匹配文档的内容),但您保留了原始文本和这些文档的偏移量,因此您可以执行查询突出显示和你应该需要很好的显示东西。
绝对是这项工作的正确工具。主要技巧是确保以相同的方式处理查询和文档。您可以修改原始文档,但实际上,您希望将其转换为类似书籍索引的内容,而不是将其转换为使用正则表达式的字符串 - 如果您确实在使用搜索引擎,那就是。如果您愿意,请查看CPAN上的优秀KinoSearch
模块,或查看最初派生自的Apache Lucene项目。
答案 1 :(得分:1)
Text::English模块包含一个Porter词干分析器,这是将相同单词的不同形式视为相同用于匹配目的的常用方法。
答案 2 :(得分:1)
查看verbTenseChanger.pl(http://cogcomp.cs.illinois.edu/page/tools_view/1) 这是自述文件:
##codes for the various tenses are:
#0 - Base Form
#1 - Past Simple
#2 - Past Participle
#3 - 3rd Person Singular
#4 - Present Participle
##Example use:
##my $newTense = changeVerbForm("see",0,4);
##changes tense from base form to the present participle
我通过创建不同的形式来使用它(我猜这包括一个词干分析器):
my @changeverbforms = map changeVerbForm( $search_key, 0, $_ ), 1..4;
my @verbforms;
push (@verbforms, $changeverbforms[0]) unless ($changeverbforms[0] eq "");
push (@verbforms, $changeverbforms[1]) unless ($changeverbforms[1] eq "");
push (@verbforms, $changeverbforms[2]) unless ($changeverbforms[2] eq "");
push (@verbforms, $changeverbforms[3]) unless ($changeverbforms[3] eq "");
然后循环遍历@verbforms
(围绕整个搜索引擎perl代码)和我$search_key
的所有地方,我也放了or $verbform
。还有一些额外的事情要解决,但这是一般的实施(尽管根据我的具体情况)
有关错误在线代码的一些调试,请参阅:https://stackoverflow.com/questions/6459085/need-help-understanding-this-verb-tense-changing-code-please
答案 3 :(得分:0)
我尝试过Lingua :: Stem,Lingua :: Stem :: Snowball和WordNet :: stem,它们都无法阻止最常见的单词。要获得这些简单的单词,您可以在之后运行这个简单的词干分析器,它使用WordNet的.exc(例外?)文件:
1. Download and install WordNet.
2. export WNHOME='/usr/lib/wnres' (if that is the directory containing the dict directory; that's where Cygwin puts it. You'll need that to install Wordnet::QueryData.)
3. cat $WNHOME/dict/*.exc > wordnet.exc (combine all the .exc files)
4. Make this perl file:
$ cat > stem.pl
use strict;
use warnings;
# Read in WordNet exception files
my $ExcFile = "wordnet.exc";
my %Stems;
open(my $FILE, "<$ExcFile") or die "Could not read $ExcFile: $!";
while (my $line = <$FILE>) {
chomp($line);
my ($word, $stem) = split(/\s+/, $line);
$Stems{$word} = $stem;
}
close($FILE);
while (defined(my $in = <>)) {
chomp($in); $in =~ s/\r$//;
$in =~ s/^\s+//;
$in =~ s/\s+$//;
next if $in eq '';
my @words = split(/\s+/, $in);
foreach my $w (@words) {
$w = $Stems{$w} if $Stems{$w};
}
print "@words\n";
}
<ctrl-D>
然后你可以用
来阻止foo.txtperl stem.pl < foo.txt
你可能想要在此之前而不是在这一步之后运行其他词干分析器,因为如果他们聪明并且使用词语上下文来阻止(虽然我怀疑他们这样做),他们需要完整的不受限制的行使用,而stem.pl逐字工作。