搜索引擎查询扩展
查询扩展
查询扩展的动机:提高召回率
问题:考虑查询q: [aircraft],某篇文档d包含“plane”, 但是不包含“aircraft”,显然对于查询q,一个简单的IR系统不会返回文档d,即使d是和q最相关的文档。我们试图改变这种做法:也就是说,我们会返回不包含查询词项的相关文档。
方法:不考虑查询(即与查询无关)及其返回文档情况下对初始查询进行扩展和重构,即进行一次性的全局分析(比如分析整个文档集)来产生同/近义词词典。(对于查询q: [aircraft],查询扩展为[aircraft、plane])。
注:对于查询中的每个查询词项t,可以通过在词典中找出t 的同义词或者相关词对查询进行自动扩展。同义词词典的使用可以与词项的权重计算相结合,比如对增加的查询词项赋予一个低于原始查询词项的权重。
词典生成方法
人工构建的同(近)义词词典(人工编辑人员维护的词典)
自动导出的同(近)义词词典(比如,基于词语的共现统计信息)
基于查询日志挖掘出的查询等价类(Web上很普遍)
同义词词典的自动构建
人工构建同义词词典的代价很大,一种取代思路是通过分析文档集来自动构造这种词典,让机器来构造词典。
通过分析文档集中的词项分布来自动生成同(近)义词词典,基本的想法是计算词语之间的相似度。
基于词的共现信息: 如果两个词各自的上下文共现词类似,那么它们类似
例子:“car” ≈ “motorcycle” ,因为它们都与“road”、“gas” 及“license”之类的词共现,因此它们类似。
基于语法关系: 两个词,如果它们同某些一样的词具有某种给定的语法关系的话,那么它们类似
比如,我们可以认为可生长、可烹调、可取食和可消化的实体很可能是食品, 因此苹果和梨肯定彼此类似
简单地采用词共现信息更具鲁棒性(它不可能会产生语法分析器出错所导致的错误),但是采用语法关系有可能会更精确。
搜索引擎中的查询扩展
搜索引擎进行查询扩展主要依赖的资源:查询日志(query log)
例1: 提交查询[herbs] (草药)后,用户常常搜索[herbal remedies] (草本疗法) → “herbal remedies” 是“herb”的潜在扩展查询
例2: 用户搜索[flower pix] 时常常点击URL photobucket.com/flower,而用户搜索[flower clipart]常常点击同样的URL→ “flower clipart”和“flower pix” 可能互为扩展查询
Lucene中同义词分析器的简单实现
回顾Lucene的分析过程,自定义同义词分析器主要注意两点:
1. 构建自定义的分析器链(analyzer chain)
2. PositionIncrementAttribute设置为0,0增量表示词项与前一词项之间是同义词
代码实现
SynonymAnalyzer
//自定义同义词Analyzer
public class SynonymAnalyzer extends Analyzer {
private SynonymEngine engine ;
public SynonymAnalyzer(SynonymEngine engine) {
this.engine = engine;
}
@Override
//LetterTokenizer->LowerCaseFilter->StopFilter->SynonymFilter分析器链
public TokenStream tokenStream(String fieldName, Reader reader) {
TokenStream result = new SynonymFilter(
new StopFilter(Version.LUCENE_36,
new LowerCaseFilter(Version.LUCENE_36,
new LetterTokenizer(Version.LUCENE_36, reader)),
StopAnalyzer. ENGLISH_STOP_WORDS_SET), engine );
return result;
}
}
SynonymEngine
//获得同义词列表接口 public interface SynonymEngine { String[] getSynonyms(String s) throws IOException; }
SimpleSynonymEngine
//硬编码同义词列表
public class SimpleSynonymEngine implements SynonymEngine {
private static HashMap<String, String[]> map = new HashMap<String, String[]>();
static {
map.put( "quick", new String[] {"fast", "speedy"});
map.put( "jumps", new String[] {"leaps", "hops"});
map.put( "over", new String[] {"above"});
map.put( "lazy", new String[] {"apathetic", "sluggish"});
map.put( "dog", new String[] {"canine", "pooch"});
}
public String[] getSynonyms(String s) {
return map.get(s);
}
}
SynonymFilter
//自定义同义词TokenFilter
public class SynonymFilter extends TokenFilter {
public static final String TOKEN_TYPE_SYNONYM = "SYNONYM";
private Stack<String> synonymStack ;
private SynonymEngine engine ;
private AttributeSource.State current;
private final CharTermAttribute termAtt;
private final PositionIncrementAttribute posIncrAtt;
public SynonymFilter(TokenStream in, SynonymEngine engine) {
super(in);
synonymStack = new Stack<String>();
this.engine = engine;
this.termAtt = addAttribute(CharTermAttribute.class);
this.posIncrAtt = addAttribute(PositionIncrementAttribute.class);
}
public boolean incrementToken() throws IOException {
if (synonymStack .size() > 0) {
char[] syn = synonymStack .pop().toCharArray();
termAtt.copyBuffer(syn, 0, syn.length );
//同义词位置增量设为0
posIncrAtt.setPositionIncrement(0);
return true ;
}
if (!input .incrementToken())
return false ;
addAliasesToStack();
return true ;
}
private String getTerm(CharTermAttribute term) {
return new String(term.buffer(), 0, term.length());
}
private boolean addAliasesToStack() throws IOException {
String[] synonyms = engine.getSynonyms(getTerm(termAtt ));
if (synonyms == null) {
return false ;
}
for (String synonym : synonyms) {
synonymStack.push(synonym);
}
return true ;
}
}
SynonymAnalyzer测试
public static void main(String[] args) throws IOException {
SynonymEngine engine = new SimpleSynonymEngine();
AnalyzerUtils. displayTokensWithFullDetails(new SynonymAnalyzer(engine),
"The quick brown fox jumps over the lazy dog" );
}
结果输出
2: [quick:4->9:word] [speedy:4->9:word] [fast:4->9:word]
3: [brown:10->15:word]
4: [fox:16->19:word]
5: [jumps:20->25:word] [hops:20->25:word] [leaps:20->25:word]
6: [over:26->30:word] [above:26->30:word]
8: [lazy:35->39:word] [sluggish:35->39:word] [apathetic:35->39:word]
9: [dog:40->43:word] [pooch:40->43:word] [canine:40->43:word]
posted on 2012-09-24 15:00 God bless you 阅读(5234) 评论(0) 编辑 收藏 举报