我有一个充满短语(80-100个字符)和一些长文档(50-100Kb)的数据库,并且我想要给出一个给定文档的短语排列列表;而不是搜索引擎的通常输出,也就是给定短语的文档列表。反向搜索:每个文档的短语
我以前使用过MYSQL全文索引,并查看了lucene,但从未使用它。 他们都似乎适合比较短的(搜索词)和long(文档)。
你会如何得到这个相反的?
我有一个充满短语(80-100个字符)和一些长文档(50-100Kb)的数据库,并且我想要给出一个给定文档的短语排列列表;而不是搜索引擎的通常输出,也就是给定短语的文档列表。反向搜索:每个文档的短语
我以前使用过MYSQL全文索引,并查看了lucene,但从未使用它。 他们都似乎适合比较短的(搜索词)和long(文档)。
你会如何得到这个相反的?
我做了一些类似于维基百科标题的数据库,并设法减少到每个〜50KB文档的几百毫秒。这对我的需求来说还不够快,但也许它可以为你工作。
基本上这个想法是尽可能地使用哈希函数,只对可能的匹配进行字符串比较,这是非常罕见的。
首先,你把你的数据库,并将其转换成一个散列数组。如果你有几十亿的短语,这可能不适合你。当你计算散列时,一定要通过一个标记器来传递这些短语,它将删除标点符号和空白符号。这部分只需要完成一次。
然后,通过具有相同标记器的文档,保留最后1,2,...,n个标记的运行列表进行散列。在每次迭代中,您都会对哈希数据库进行二分查找。
当您找到匹配项时,您会进行实际的字符串比较以查看是否找到匹配项。
下面是一些代码,给你磨的味道我的意思是,强硬的这个例子实际上并没有做字符串比较:
HashSet<Long> foundHashes = new HashSet<Long>();
LinkedList<String> words = new LinkedList<String>();
for(int i=0; i<params.maxPhrase; i++) words.addLast("");
StandardTokenizer st = new StandardTokenizer(new StringReader(docText));
Token t = new Token();
while(st.next(t) != null) {
String token = new String(t.termBuffer(), 0, t.termLength());
words.addLast(token);
words.removeFirst();
for(int len=params.minPhrase; len<params.maxPhrase; len++) {
String term = Utils.join(new ArrayList<String>(words.subList(params.maxPhrase-len,params.maxPhrase)), " ");
long hash = Utils.longHash(term);
if(params.lexicon.isTermHash(hash)) {
foundHashes.add(hash);
}
}
}
for(long hash : foundHashes) {
if(count.containsKey(hash)) {
count.put(hash, count.get(hash) + 1);
} else {
count.put(hash, 1);
}
}
将每个短语转换为正则表达式并运行文档上的每个短语,计算出现次数是否太慢?
如果这不起作用,也许你可以将所有的短语合并成一个巨大的正则表达式(使用|
),并编译它。然后,从文档中的每个字符开始运行这个巨大的正则表达式。在通过角色时计算匹配数量。
我可以交易时间建立索引,以便查找短语列表(针对给定的文档)尽可能快。 – Tourch 2009-12-31 17:47:47
短语数据库有多大?我认为它非常大。通过在其中的一个关键词
指数短语:
我会做以下。您可以在每个短语中选择最不常用的单词。您可以通过假设该单词至少是例如长度为5个字符,如果长度较短,则将该单词填充为5个字符。填充可以是单词后面的空格,接着是后面的单词,以减少匹配,或者如果单词出现在短语结尾处,则可以使用某个默认字符(例如“XX”)。
通过您的文档,通过填充(如有必要)将每个单词(常见的单词可以丢弃)转换为一个键,检索短语。
通过这些关键字检索相关短语。
使用内存中的文本搜索来查找每个检索到的短语的出现次数。
我假设短语不能跨越句子边界。在这种情况下,可以将文档的每个句子读入数组中的子字符串,并使用子字符串函数来搜索每个短语的每个句子并计算出现次数,并为每个短语保留一个运行总和。
也许读Peter Turney on keyphrase extraction会给你一些想法。总体而言,他的方法与伊塔多克的建议有些相似之处。
几百毫秒是可以接受的。我会给这个方法一个去 – Tourch 2009-12-31 19:21:57