`
shingo7
  • 浏览: 19317 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

全文检索中近义词、关联词的解决方案

阅读更多

         一直想找到一个好的同义词解决方案,在百度和google查找,大家对于这个问题都只是寥寥数语,不愿讲清,我在javaeye搜此类信息也求不到,后来发了个提问贴也只有浏览数而无回复,不知道这是什么原因,无奈之下我只有自己研究。

         因为没有其它的解决方案可以借鉴,以下纯为我个人的见解。

 

我认为所谓近义词、关联词检索不外乎以下三种形式:

1.类似google suggest,用户输入关键字后自动提示功能。

2.假如“奥运会”的关联词是“北京”,用户输入“奥运会”搜索时,将“奥运会”的搜索结果以及“北京”的搜索结果都搜出来。

3.用户输入“奥运会”搜索,只显示“奥运会”的结果,它的关联词在结果集的底端用“相关搜索”的形式提示给用户。

 

 

这三种方式中看似2和3是类似的,其实还是有些很大区别的,我个人认为在实际的应用中,第3种方式是最多见的。

 

先说说第1种方式

google suggest的在网上可以搜到完整的解决方案,跟我此前想的一样。

建一个用来存储关键字的表

例如:  

create table  KEYS(    
   ITEM_ID varcha2(50) not null,    
   SEARCH_KEY varchar2(100),        
);  

SEARCH_KEY里存储一些检索的关键字,如“奥运”,“奥运会”,“北京奥运会”等.

当用户在文本框敲入时,使用AJAX将当前文本框的内容发到Action,进行下面类似的操作

String key = request.getParameter("inputValue");
String sql = "select * from KEYS as k where k.SEARCH_KEY like '%key%'";

这个办法也就是把当前文本框中的字放到数据库中做模糊查询,比如用户输入“奥”这个字,会从搜出所有包含“奥”字的词,然后将这些词包装好,发回至页面,页面上用JS画出下拉框,将这些包含“奥”字的词填入就可以了。

google做的是右边匹配,即是用的 like 'key%' ,输入“奥”字,会出现所有以“奥”字开头的词的提示。

大家应该注意到google suggest的提示词的最后面都写有“约XXXXX条记录”,我现在唯一能想到的解决方案是,当我们在Action中拿到匹配的词之后,将匹配的词搜索一次即可得出具体记录的条数,其实这样也不耗多少资源。

 

第2种方式

将关键词和关键词所联的词的结果都搜出来

我个人认为这个功能在实际的应用中只需用到其5%就可以了,因为在用户体验方面考虑,我们必须保障搜索结果的质量。关键词的近义词可以在结果页的底端提示给用户,也就是我上边说到的第3种方式。

我所说的只需用到5%的意思是只需为少数的、必须转义的词实现这样的功能

比如搜索“China”,那么“中国”这个词的结果肯定得出现在结果集里,还有比如搜索“08”,那么“2008”的结果也得出现在结果集里,这些都是一些特定情况,其它的词没必要做成这样,只需做提示即可。

现在中文检索一般都是基于词库的检索,实现第2种方式这个功能必须将之前的词库以及分词算法进行修改。

一般的方法是在词库中把同义词写成一行,如将“中国 China”写在同一行,然后修改Token算法(这个大家可以去研究一下,我现在使用的Analyzer包是公司商业上的伙伴提供的测试包,这个测试包已经可以满足很大一部分需求了,我还不知道能不能共享)

其实原理是在索引时将原词和原词的近义词一起索引

具体给大家个例子

有这样一句话  ---- “中国是世界上人口最多的国家”

如果没有为其做同义词,大家可能会索引成这样

[中国][世界][人口][最多][国家]

如果做了同义词,会索引成

[中国][China][世界][人口][最多][国家]

即是说在索引时就已经将“中国”这个词存成[中国][China]了,搜索时无论搜“中国”或是“China”都可以搜到这句话。

其实这个功能相当大一部分是依赖第三方的jar包,说来说去也没多大意思,并且大多数情况下我们需要的并不同这种功能,而是更人性化的查询提示的功能,也就是第3种方式。

 

第3种方式

这种方式是我在原有的系统上改进完成的

原有的系统是 compass + paoding + lucene

由于我不太熟compass的搜索,所以我还是采用的lucene搜索。相信大家对这种搭配的全文检索已经非常熟悉了,paoding的词库是可以自己配置的。

那么怎样在原有的基础实现关键词提示功能呢???

我的做法是这样的,我按照paoding词库的特点新建了一个mydictionary.dic文件放在classpath下,里面的内容大致如下。

第1行:奥运会  北京  2008  第29届奥运会

第2行:中国 China 中华人民共和国 中国电信 中国人民银行

........

 

然后在服务器启动时,将mydictionary.dic这个文件中的文字一行行读入,分别做索引

    	InputStream fi = this.getClass().getClassLoader().getResourceAsStream("mydictionary.dic");    	
    	File indexDir = new File("d:\\tong");
    	Analyzer luceneAnalyzer = new StandardAnalyzer();    
        	IndexWriter indexWriter = new IndexWriter(indexDir, luceneAnalyzer,true);    	
	BufferedReader reader = new BufferedReader(new InputStreamReader(fi, "UTF-8"));   
	String line = new String();    	   
	while ((line = reader.readLine()) != null) 
	{   
		Document document = new Document();
		Field FieldName = new Field("line", line,Field.Store.YES, Field.Index.TOKENIZED);
		document.add(FieldName);
		indexWriter.addDocument(document);
	}   
	indexWriter.optimize();
        	indexWriter.close();
	reader.close();    

 

 在搜索时,对用户输入的关键字正常搜索出结果后,对关键字进行第二次搜索,搜的是同义词的索引,得到的结果按空格分开,即可得到所有同义词,然后将同义词发送至页面即可。

	public List getTongYi(String searchword) throws Exception
	{
		List list = new ArrayList();
		Hits hits = null;    
		String queryString = searchword;    
		Query query = null;    
		String result = "";
		IndexSearcher searcher = new IndexSearcher("d:\\tong");    		   
		Analyzer analyzer = new StandardAnalyzer();    
		QueryParser qp = new QueryParser("line", analyzer);    
		query = qp.parse(queryString);    	        
		if (searcher != null)
		{    
		    hits = searcher.search(query);      
		    for(int i=0;i<hits.length();i++)
		    {
		    	Document doc = hits.doc(i);
		    	System.out.println((i+1)+"."+doc.get("line"));
		    	result = doc.get("line");
		    }          
		}
		if(result!=null && !result.equals(""))
		{
			String [] manyresult = result.split(" ");
			for(int i=0;i<manyresult.length;i++)
			{
				if(manyresult[i]!=null && !manyresult[i].trim().equals(""))
				{
					list.add(manyresult[i]);
				}
			}
		}
		return list;    
	}	

  我觉得做同义词索引和搜索的时候最好用StandardAnalyzer,切成单字是最符合的。

 

  写了这么多,如果各位有更好的想法不妨发出来一起研究一下。

  

分享到:
评论
18 楼 shingo7 2009-01-22  
mikel 写道
为什么不用lucene?


你在说什么?
17 楼 mikel 2009-01-16  
为什么不用lucene?
16 楼 sdh5724 2008-12-28  
euler13 写道
可参考trie, btree。 我们做的应用, 对上百万的热门搜索词语中,毫秒级的时间内给出前缀关联词。


如果是trie实现的, 应该跟词汇的数量关系不大。
15 楼 euler13 2008-12-27  
可参考trie, btree。 我们做的应用, 对上百万的热门搜索词语中,毫秒级的时间内给出前缀关联词。
14 楼 lcllcl987 2008-12-25  
可以看看wordnet
斯坦福搞的
13 楼 shingo7 2008-12-25  
sdh5724 写道
楼上的回答很精确。
关于trie, 你去看我的blog吧。 paoding的算法完全可以通过我提供的的代码取代掉。  算法密集的应用, 如果仅仅是访问不高的网站, 其实lucence就足够了。lucence做个比较大规模的论坛还是没有问题的, 但是中文分词,相关性比较困难。

不知道你的网站的访问量高不高, 如果很多高的话, 你的办法还真是行不通。



感谢你的分享,其实我所说的三种方式解决方案是针对一般的全文检索应用得出的,由于不是做特别专业的检索,大数据量的情况还没有考虑到。我现在采用的是第3种法做关键词提示,我觉得一般的应用这种方式应该能够支持
12 楼 whaosoft 2008-12-25  
支持你 不过做这个真的很麻烦~
11 楼 卡拉阿风 2008-12-24  
<p>支持3<img src='/images/smiles/icon_smile.gif' alt=''/><img src='/images/smiles/icon_smile.gif' alt=''/></p>
<p> </p>
10 楼 xuyao 2008-12-24  
确实,中文分词,不是那么简单的,这个和社会发展对语言的认识也有关系。不过,一般够用就行
9 楼 imjl 2008-12-24  
其实看你做什么了。

如果做垂直专业类搜索,那么其特点专业用语,简写,拼写准确这些为主,建议人工为主(当然有现有资源那就充分利用)

如果做类似谷歌百度类海量搜索,我觉得必须要考虑分词的智能性,也就是自动识别新鲜词语,靠字典+算法+人工修正来完成,应该能达到比较好的分词。当然说起来容易做起来难。

我认为baidu和google都还在研究怎么才能更加精确,用户在最短时间能快速获得最想要的信息。所以我不相信使用现有任何一种算法就能完成很精确的分词。

好的分词不是几个算法,一个程序就能搞定的,它需要不断研究分析,尤其是中文。

以上为我个人观点,呵呵,有点打击一些人积极性了。
8 楼 hanfeng870223 2008-12-24  
这个Google suggest每输入几个字,到数据库查询一下,而且还用 ‘like’,这样效率不是很低啊,有没有更好的办法啊
7 楼 john2007 2008-12-23  
哪有免费的同义词词典可以下载啊?
6 楼 sdh5724 2008-12-23  
整个中文search体系是非常复杂的, 如果很简单, 也不知道跑出来几个baidu类似的公司了。 别跟我说其他的几个, 好多都是麒麟操作系统的来源。
5 楼 kiki 2008-12-23  
lucene提供同义词的处理方法。
4 楼 sdh5724 2008-12-23  
楼上的回答很精确。
关于trie, 你去看我的blog吧。 paoding的算法完全可以通过我提供的的代码取代掉。  算法密集的应用, 如果仅仅是访问不高的网站, 其实lucence就足够了。lucence做个比较大规模的论坛还是没有问题的, 但是中文分词,相关性比较困难。

不知道你的网站的访问量高不高, 如果很多高的话, 你的办法还真是行不通。
3 楼 baseworld 2008-12-23  
你提的方案除了3可以尝试外 其他的方案在大数据量下其实是不可行的

一般的做法是:
1. 算。通过一些规则结合自然语言的一些算法算出哪些是重要性相关的,也就是同义的、近意的。
2. 一个好的搜索结构,一般情况下,不使用lucene等等,而是自己实现一个比如trie的紧凑高效的数据结构。

特别是suggestion,suggest的ajax一般是用户输入的时候定时发送请求 一般一个用户输入一个词,会向服务器发送若干个请求,这样的搜索量还是比较大的。数据库肯定顶不住,更别提like了。

这种东西应该是算法密集型的。
2 楼 JohnnyJian 2008-12-23  
好像应该用贝叶斯方法的说
1 楼 sorphi 2008-12-23  
提点意见,以供讨论

可以将搜索关键词及其命中数量,进行索引存储,这样就不走数据库了

另外,相关词/近义词库的积累,可否优先调用通用搜索引擎(比如google)的suggest接口获取并积累呢?



相关推荐

    MySQL实现中文全文检索的解决方案.pdf

    在这个解决方案中,我们可以使用一个拼音转换程序将中文转换为拼音,然后将拼音存储到数据库中。当用户输入中文检索词时,我们可以将其转换为拼音,然后与数据库中的拼音进行匹配。这种解决方案的优点是可以实现中文...

    基于Lucene的全文检索框架

    它提供了一个可扩展的、高效的文本搜索解决方案,适用于各种应用场景,包括网站搜索、文档检索、数据挖掘等。这个开源项目,OSChina开源社区基于Lucene构建的全文检索框架,旨在简化开发人员在实际项目中实现全文...

    oracle text全文检索的开发和相关文档

    Oracle Text 是 Oracle 数据库提供的一种强大的全文检索解决方案,它自 Oracle 7.3 版本开始引入,并在后续版本中不断演进和完善。Oracle Text 旨在帮助用户高效地搜索和管理文本数据,无论这些数据存储在本地文件、...

    elastisearch 全文检索

    总结来说,Elasticsearch 是一款强大的全文检索工具,它通过其独特的分布式架构、实时搜索、高效索引以及丰富的查询和分析功能,为大数据搜索提供了高效、灵活的解决方案。无论是在网站搜索、日志分析还是其他大数据...

    oracle全文检索使用说明

    总的来说,Oracle Text是Oracle数据库中一个强大而灵活的文本搜索解决方案,尤其适用于需要快速高效搜索大量文本数据的应用场景,如文档管理系统、搜索引擎或XML应用。通过其丰富的特性和配置选项,用户可以根据需求...

    精品资料(2021-2022收藏)Lucene:基于Java的全文检索引擎简介22173.doc

    通过对Lucene的深入理解和使用,我们可以学习到如何设计和实现高性能的文本搜索解决方案,以及如何针对不同语言,尤其是中文,进行定制化处理。无论是在Web应用、内容管理系统还是其他任何需要全文搜索功能的Java...

    Lucene:基于Java的全文检索引擎简介

    【Lucene:基于Java的全文检索引擎简介】 Lucene是一个由Apache Jakarta项目开发的全文检索引擎工具包,它采用Java语言编写,旨在...通过理解和利用Lucene提供的功能,开发者可以创建出高效、用户友好的搜索解决方案。

    基于PHP的Sphinx全文检索引擎php版forWindows源码.zip

    这意味着开发者可以在Windows平台上下载、编译并使用这些源代码,以实现自定义的全文检索解决方案。 标签“PHP”进一步强调了这个项目与PHP语言的关联,这意味着所有与之相关的代码、配置和接口设计都是针对PHP的。...

    Elasticsearch in Action 全文检索

    10. **生态系统**:Elasticsearch是Elastic Stack(以前称为ELK Stack)的一部分,与Logstash(日志收集)和Kibana(数据可视化)紧密集成,共同构建了一个强大的日志管理和分析解决方案。 在《Elasticsearch in ...

    支持拼音、代码、中文快速检索的字典demo

    这个名为“支持拼音、代码、中文快速检索的字典demo”的项目提供了一个高效、便捷的解决方案,它结合了JavaScript编程语言,针对中文字符、拼音和代码进行快速查找。下面我们将深入探讨这个项目的相关知识点。 首先...

    EngTxt_IR_1.6.rar_信息检索_文本 检索 visual_文本检索_文档检索_检索软件

    总的来说,EngTxt_IR_1.6是一款针对本地文本文件的信息检索工具,它通过构建索引、提供可视化的查询界面和处理多种文本格式,为用户提供了便捷、高效的文本检索解决方案。在日常工作中,无论是研究、写作还是资料...

    移动互联网跨媒体信息检索技术

    1. **基于“词袋”模型建立多媒体对象知识库**:该方法通过对多媒体对象进行人工标注,利用“词袋”模型等手段建立多媒体信息知识库,以实现跨媒体检索。但由于依赖人工标注,耗时耗力且难以保证一致性,检索准确性...

    sphinx+php检索引擎

    此时,引入Sphinx作为全文检索解决方案是一个明智的选择。Sphinx是一款专门用于处理大量文本数据的高性能全文搜索工具,能够显著提高搜索速度和准确性。 #### 二、Sphinx简介 Sphinx是由俄罗斯开发者Andrew ...

    基于PHP的similar.js-WP博客搜索框下拉关联词插件.zip

    在WordPress博客平台上,提高用户体验和互动性是每个网站管理员关注的重点。"基于PHP的similar.js-WP博客搜索框下拉关联词插件"是一个旨在优化博客...对于希望提升网站互动性的博主来说,这是一个值得考虑的解决方案。

    图像文本检索+图像预训练

    传统的解决方案通常采用双流编码器来将图像和文本转化为稠密表示,但这种方法在大规模检索中效率低下,检索速度受限。香港浸会大学和微软的研究团队针对这一问题,提出了名为“词汇瓶颈语言-图像预训练”(Lexicon-...

    电信设备-基于疑问词扩展的信息检索方法.zip

    在基于疑问词扩展的信息检索中,这些疑问词被用作提示,用于挖掘用户的潜在需求和信息上下文。例如,一个简单的查询“电信设备故障”可能通过添加疑问词“如何诊断”或“怎样解决”扩展为“如何快速诊断电信设备故障...

    lucene 检索

    **Lucene 检索** Lucene 是一个高性能、全文本搜索库,由 Apache 软件基金会开发并维护。这个强大的工具集为开发者提供了在各种...无论是简单的网站搜索还是复杂的商业应用,Lucene 都能提供稳定、可扩展的解决方案。

    2022年数字档案管理系统解决方案.pdf

    【2022年数字档案管理系统解决方案】 在数字化时代,高效、安全的档案管理系统成为企业和组织不可或缺的一部分。本文将详细解析2022年数字档案管理系统解决方案,涵盖系统的特点、需求以及主要功能。 首先,该解决...

Global site tag (gtag.js) - Google Analytics