- 浏览: 85486 次
- 来自: 济南
文章分类
最新评论
-
lib:
速度很快啊!下手很早啊。
在Raspberry Pi上安装Nodejs环境 -
qalong:
如此好文,哪能不顶
Canvas入门实例08:三次方贝塞尔曲线 -
johnnycmj:
膜拜啊....
简单模拟Google的大马跑啊跑的Doodle -
BuN_Ny:
zeng1990 写道BuN_Ny 写道feizhang666 ...
17) 第二章 索引:优化索引(Optimizing) -
zeng1990:
BuN_Ny 写道feizhang666 写道现在已经是luc ...
17) 第二章 索引:优化索引(Optimizing)
请先确认一句话:“并非人人生而平等!”。对于Document和Field也是如此。
假设你现在需要索引一些邮件。要求是,搜索结果中,船长发出的邮件要排在船员的前面!如何实现?
还好Lucene为你提供了它的实现,而且非常简单:boosting. 每个文档都拥有一个优先权重因数,默认情况下它的值是1.0, 你可以通过改变此值来实现上面的要求。重要的文档(此例中为船长的邮件),我们可以让这个数大于1.0, 比如2.0如何?次要的文档(此例中为船员的邮件),我们可以让这个数小于1.0, 比如0.5。 当然,也可以让重要的为3.0,次要的为2.0,怎么设计随你。
那么怎么改变这个因数呢? Lucene API提供了一个独立的方法:setBoost(float); 就是这么简单!
import java.io.IOException; import java.util.ArrayList; import java.util.List; import junit.framework.TestCase; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.Term; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.TopDocs; import org.apache.lucene.store.Directory; import org.apache.lucene.store.RAMDirectory; import org.apache.lucene.util.Version; public class IndexBoostingTest extends TestCase{ private Directory directory; protected void setUp() throws Exception { directory = new RAMDirectory(); IndexWriter writer = getWriter(); List<Email> mails = makeSomeEmails(); for(Email e : mails){ Document doc = new Document(); doc.add(new Field("senderEmail", e.getSenderEmail(), Field.Store.YES, Field.Index.NOT_ANALYZED)); doc.add(new Field("senderName", e.getSenderName(), Field.Store.YES, Field.Index.ANALYZED)); doc.add(new Field("subject", e.getSubject(), Field.Store.YES, Field.Index.ANALYZED)); doc.add(new Field("body", e.getBody(), Field.Store.NO, Field.Index.ANALYZED)); // 关键代码:设置文档的优先权重因数 if(Email.IMPORTANT.equals(e.getSenderDomain())){ doc.setBoost(1.5F); }else if(Email.UNIMPORTANT.equals(e.getSenderDomain())){ doc.setBoost(0.5F); }else{ //此处写不写都一样,默认的优先权重因数是1.0 doc.setBoost(1F); } writer.addDocument(doc); } writer.close(); } //事实上不能这么写测试用例,因为这种测试很不严格。 //排序的结果除了受boost影响还取决于文档与查询词的匹配度等 public void testBoostResult() throws IOException { IndexSearcher is = new IndexSearcher(directory); Query query = new TermQuery(new Term("body", "团")); TopDocs topDocs = is.search(query, 3); ScoreDoc[] docs = topDocs.scoreDocs; //我们期望的排序结果是:Luffy、Sanji、Zoro String luffy = is.doc(docs[0].doc).get("senderName"); String sanji = is.doc(docs[1].doc).get("senderName"); String zoro = is.doc(docs[2].doc).get("senderName"); assertEquals("Luffy", luffy); //路飞排第一啦~~他的boost是1.5 assertEquals("Sanji", sanji); //香吉士采用了默认的boost是1.0 assertEquals("Zoro", zoro); //容易迷路的家伙boost是0.5 } private IndexWriter getWriter() throws IOException { return new IndexWriter(directory, new StandardAnalyzer(Version.LUCENE_30), IndexWriter.MaxFieldLength.UNLIMITED); } //模拟测试数据 private List<Email> makeSomeEmails(){ ArrayList<Email> testData = new ArrayList<Email>(); //测试数据1 不设置boost Email mail1 = new Email(); mail1.setSenderEmail("Sanji@iteye.com"); mail1.setSenderName("Sanji"); mail1.setSenderDomain("普通的~~"); mail1.setSubject("海贼"); mail1.setBody("草帽海贼团厨师,金发,有着卷曲眉毛,永远遮住半边脸的家伙,其左眼是个迷,香烟不离口,海贼中的绅士"); testData.add(mail1); //测试数据2 设置较高的boost Email mail2 = new Email(); mail2.setSenderEmail("Monkey·D·Luffy@iteye.com"); mail2.setSenderName("Luffy"); mail2.setSenderDomain(Email.IMPORTANT); mail2.setSubject("海贼"); mail2.setBody("草帽海贼团船长,特征是头戴草帽,顽强,坚定,喜欢探险,最爱吃肉"); testData.add(mail2); //测试数据3 设置较低的boost(喜欢索隆的别喷我,我也喜欢...举个例子而已) Email mail3 = new Email(); mail3.setSenderEmail("RoronoaZoro@iteye.com"); mail3.setSenderName("Zoro"); mail3.setSenderDomain(Email.UNIMPORTANT); mail3.setSubject("海贼"); mail3.setBody("草帽海贼团剑士,绿色头发,左耳戴三只黄色露珠耳环"); testData.add(mail3); return testData; } } class Email{ public static String IMPORTANT = "important"; public static String UNIMPORTANT = "unimportant"; private String senderEmail; private String senderName; private String senderDomain; private String subject; private String body; public String getSenderEmail() { return senderEmail; } public void setSenderEmail(String senderEmail) { this.senderEmail = senderEmail; } public String getSenderName() { return senderName; } public void setSenderName(String senderName) { this.senderName = senderName; } public String getSenderDomain() { return senderDomain; } public void setSenderDomain(String senderDomain) { this.senderDomain = senderDomain; } public String getSubject() { return subject; } public void setSubject(String subject) { this.subject = subject; } public String getBody() { return body; } public void setBody(String body) { this.body = body; } }
问题又来了,如果我们认为邮件的标题中出现的关键词比正文中更重要呢?也就是说要使名为"subject"的Field优先于"body"的。
哈哈,其实也很简单,只要针对这个域调用 setBoost(float); 即可:
Field subjectField = new Field("subject", subject, Field.Store.YES, Field.Index.ANALYZED); subjectField.setBoost(1.2F);
事实上,之前的例子中对document设置boost值,相当于对该document下的所有Field设置了相同的boost值。理所当然,你也可以为单个Field设置boost值!
必须要指出,如果需要更改已经设置的boost值,那么只能重新索引整个document,然后为它设置另一个boost值。这看起来很糟糕,毕竟客户的需求总是在变化的。放心,我们还可以通过在搜索阶段自定义排序来实现此效果,那将更具动态性,更加灵活。现在,你可以为那些永远要排在前面的文档设置一个无比大的boost值了!
发表评论
-
20) 第二章 索引:缓冲
2012-04-20 22:38 1401Lucene在添加或删除文 ... -
19) 第二章 索引:用IndexReader删除文档
2012-04-19 22:17 1879除了IndexWriter外,IndexReader也可 ... -
18) 第二章 索引:锁策略--Lucene自身提供的锁实现
2011-07-08 17:57 2214首先需要清楚一个大前提:在同一个索引文件上,一次只能 ... -
17) 第二章 索引:优化索引(Optimizing)
2011-06-23 13:59 1861索引文件的多个段可以合并成一个或少量几个。这样将节省 ... -
16) 第二章 索引:设置Field的截断
2011-06-14 16:57 1150针对Field我们还有最后一个特性要讨论:截断(tru ... -
15) 第二章 索引:设计用来排序的域
2011-06-14 09:38 897这一节非常非常简单,场景是这样的:我们对Luce ... -
14) 第二章 索引:用Lucene索引数字
2011-06-13 14:28 2275索引数字的场景主要有两种:一是把它们当作字符串一 ... -
13) 第二章 索引:用Lucene索引日期和时间
2011-06-10 17:46 2830对Lucene而言,每个域都是String类型。 ... -
12) 第二章 索引:规则(Norms)
2011-06-10 10:32 1117在索引阶段,文档(Document)中每个被索引 ... -
10) 第二章 索引:Field中含多个值的问题
2011-06-08 17:17 1643假设你的Document中有一个名为" ... -
9) 第二章 索引:Field的设置
2011-06-08 16:25 1310Field也许算是Lucene索引阶段最重要的类 ... -
Hibernate Search常用注解总结
2011-06-08 14:08 65511. @Indexed -> index ... -
8) 第二章 索引:基本索引操作
2011-06-07 15:09 1462先上示例代码,原意看的就看,不愿意看的先略过,回 ... -
7) 第二章 索引:理解Lucene索引过程
2011-06-07 11:32 1239Lucene索引的API非常简单,然而在其 ... -
6) 第二章 索引:Lucene索引的文档模型
2011-06-07 10:57 11331. 文档(Document)和域(Field) ... -
5) 第一章 初识Lucene:理解核心搜索类
2011-05-31 17:22 11021. IndexSearcher Ind ... -
4) 第一章 初识Lucene:理解核心索引类
2011-05-30 17:18 12551. IndexWriter Index ... -
3) 第一章 初识Lucene:一个简单的实例
2011-05-30 16:37 1212还是看代码来的直接: 1. 索引 imp ... -
2) 第一章 初识Lucene:索引和搜索
2011-05-30 15:31 11451. 为什么需要搜索 为什么需要高效的、准确的搜索 ... -
1) 第一章 初识Lucene:简介
2011-05-30 14:05 14571. Lucene是什么 Lucene是一个高性能 ...
相关推荐
### XGBoost: A Scalable Tree Boosting System #### 概述 《XGBoost: A Scalable Tree Boosting System》是由陈天奇与Carlos Guestrin共同撰写的学术论文,该论文介绍了一种高效的端到端树提升系统——XGBoost。...
人工智能和机器学习之回归算法:LightGBM回归:集成学习与Boosting技术.docx
机器学习经典论文中英文合集:NGBoost Natural Gradient Boosting for ProbabilistiNGBoost 用于概率预测的自然梯度提升技术。 含有中文翻译的论文。
机器学习经典论文中英文合集: CatBoost unbiased boosting with categorical features .zip 采用分类特征的 CatBoost 无偏助推技术 。包含中文论文翻译。
### GREEDY FUNCTION APPROXIMATION: A GRADIENT BOOSTING MACHINE #### 1. 引言与背景 本文探讨了一种新的函数逼近方法——贪心函数逼近法(Greedy Function Approximation, GFA),该方法特别关注梯度提升机...
XGBoost: A Scalable Tree Boosting System-附件资源
陈天奇的论文:XGBoost A Scalable Tree Boosting System 的讲解PPT,全英文!
1. 梯度提升决策树(Gradient Boosting Decision Tree, GBDT): 该部分内容在文档中被提及,它指的是一种集成学习算法,属于机器学习和数据挖掘领域中的高级算法。GBDT通过迭代建立多个决策树,每一棵树都是在上一次...
Boosting是一种集成学习方法,它通过组合多个弱分类器形成一个强分类器,显著提高了预测模型的性能。在这个压缩包中,我们有四份关于Boosting相关算法的PDF文献,分别是《BoostedTree》、《gbdt》、《gradient_...
报告对各种Boosting 集成学习模型进行系统测试 Boosting 集成学习模型将多个弱学习器串行结合,能够很好地兼顾模型的 偏差和方差,该类模型在最近几年获得了长足的发展,主要包括AdaBoost、 GBDT、XGBoost。本篇报告...
1. 分类问题:Boosting 算法可以用于解决二分类、多分类问题,提高分类的准确性。 2. 回归问题:Boosting 算法可以用于解决回归问题,提高预测的准确性。 3. 异常检测:Boosting 算法可以用于检测异常数据,提高检测...
这本书名为《Boosting: Foundations and Algorithms》,是属于“Adaptive Computation and Machine Learning”系列的一部分,由麻省理工学院出版社出版。本书的作者是Robert E. Schapire和Yoav Freund,出版时间为...
内容概要:本文深入探讨了集成学习的概念及其主要组成部分,bagging和boosting。通过对两种主流技术方法的介绍,解释了各自的原理,包括bagging方法的无放回抽样以及boosting针对不同权重训练的例子,并进一步讨论了...
Boosting 算法综述 Boosting 算法是一种常用的集成学习方法,它通过组合多个弱学习器来提高预测精度和稳定性。以下是 Boosting 算法的主要知识点: 1. 基本理论:Boosting 算法的基本思想是通过多个弱学习器的组合...
【标题】"gentle_boosting_demo" 是一个与机器学习相关的项目,主要涉及Boosting算法的应用,特别是Gentle Boosting。Boosting是一种集成学习方法,通过组合多个弱分类器形成一个强分类器,其中Gentle Boosting是...