- 浏览: 82860 次
- 来自: 济南
文章分类
最新评论
-
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 1324Lucene在添加或删除文 ... -
19) 第二章 索引:用IndexReader删除文档
2012-04-19 22:17 1826除了IndexWriter外,IndexReader也可 ... -
18) 第二章 索引:锁策略--Lucene自身提供的锁实现
2011-07-08 17:57 2170首先需要清楚一个大前提:在同一个索引文件上,一次只能 ... -
17) 第二章 索引:优化索引(Optimizing)
2011-06-23 13:59 1793索引文件的多个段可以合并成一个或少量几个。这样将节省 ... -
16) 第二章 索引:设置Field的截断
2011-06-14 16:57 1109针对Field我们还有最后一个特性要讨论:截断(tru ... -
15) 第二章 索引:设计用来排序的域
2011-06-14 09:38 868这一节非常非常简单,场景是这样的:我们对Luce ... -
14) 第二章 索引:用Lucene索引数字
2011-06-13 14:28 2236索引数字的场景主要有两种:一是把它们当作字符串一 ... -
13) 第二章 索引:用Lucene索引日期和时间
2011-06-10 17:46 2785对Lucene而言,每个域都是String类型。 ... -
12) 第二章 索引:规则(Norms)
2011-06-10 10:32 1077在索引阶段,文档(Document)中每个被索引 ... -
10) 第二章 索引:Field中含多个值的问题
2011-06-08 17:17 1590假设你的Document中有一个名为" ... -
9) 第二章 索引:Field的设置
2011-06-08 16:25 1245Field也许算是Lucene索引阶段最重要的类 ... -
Hibernate Search常用注解总结
2011-06-08 14:08 65071. @Indexed -> index ... -
8) 第二章 索引:基本索引操作
2011-06-07 15:09 1420先上示例代码,原意看的就看,不愿意看的先略过,回 ... -
7) 第二章 索引:理解Lucene索引过程
2011-06-07 11:32 1211Lucene索引的API非常简单,然而在其 ... -
6) 第二章 索引:Lucene索引的文档模型
2011-06-07 10:57 11021. 文档(Document)和域(Field) ... -
5) 第一章 初识Lucene:理解核心搜索类
2011-05-31 17:22 10731. IndexSearcher Ind ... -
4) 第一章 初识Lucene:理解核心索引类
2011-05-30 17:18 12181. IndexWriter Index ... -
3) 第一章 初识Lucene:一个简单的实例
2011-05-30 16:37 1177还是看代码来的直接: 1. 索引 imp ... -
2) 第一章 初识Lucene:索引和搜索
2011-05-30 15:31 11081. 为什么需要搜索 为什么需要高效的、准确的搜索 ... -
1) 第一章 初识Lucene:简介
2011-05-30 14:05 14161. Lucene是什么 Lucene是一个高性能 ...
相关推荐
Tree boosting is a highly eective and widely used machine learning method. In this paper, we describe a scalable endto- end tree boosting system called XGBoost, which is used widely by data scientists...
GREEDY FUNCTION APPROXIMATION: A GRADIENT BOOSTING MACHINE
XGBoost: A Scalable Tree Boosting System-附件资源
XGBoost is an optimized distributed gradient boosting library designed to be highly efficient, flexible and portable. It implements machine learning algorithms under the Gradient Boosting framework. ...
报告对各种Boosting 集成学习模型进行系统测试 Boosting 集成学习模型将多个弱学习器串行结合,能够很好地兼顾模型的 偏差和方差,该类模型在最近几年获得了长足的发展,主要包括AdaBoost、 GBDT、XGBoost。本篇报告...
Boosting基础与算法,Boosting入门必备书籍!
boosting 算法
D:\Edgedownload\BaiduNetdisk\BaiduNetdiskDownload\stanford machine learning【CSDN]\Supplemental Notes\ 的索引 [上级目录] 名称 大小 修改日期 boosting_example.m 2.1 kB 2023/8/2 10:20:05 boosting.pdf 126...
文档xgboost-eXtreme Gradient Boosting.pdf This is an introductory document of using the xgboost package in R.
集成学习:Boosting算法综述.pdf
Additive logistic regression-a statistical view of boosting.pdf
Boosting Chain
代表:Adaboost(Adaptive boosting)公式推导可见《机器学习》P174优点:泛化错误率低,易编码,可以应用在大部分分类器上,无参数调整缺点
一个简单的boosting算法,里面有图片集和演示demo。
机器学习Boosting Model 的设计, 实验, 数据以及结果
Gradient Boosting Decision Tree
决策树 boosting
boosting算法的PPT课件,比较详细,适合刚学或想学boosting算法的同学
boosting学习算法的课件,适合入门者.