我需要对2+个因子进行加权排序,按"相关性"排序.然而,这些因素并非完全孤立,因为我希望一个或多个因素影响其他因素的"紧迫性"(权重).
示例:贡献的内容(文章)可以上/下投票,因此具有评级; 他们有一个发布日期,他们也被标记为类别.用户撰写文章并可以投票,并且可能有也可能没有自己的某种排名(专家等).可能与StackOverflow类似,对吧?
我想为每个用户提供按标签分组但按"相关性"排序的文章列表,其中相关性是根据文章的评级和年龄计算的,并且可能受作者排名的影响.IE是几年前写的一篇排名很高的文章可能不一定像昨天写的中等文章一样重要.也许如果一篇文章是由专家撰写的,那么它将被视为比"Joe Schmoe"所写的文章更具相关性.
另一个很好的例子是为酒店分配一个由价格,评级和景点组成的"元评分".
我的问题是,多因素排序的最佳算法是什么?这可能是该问题的重复,但我对任意数量因素的通用算法感兴趣(更合理的期望是2 - 4个因素),最好是我不需要的"全自动"功能调整或要求用户输入,我无法解析线性代数和特征向量古怪.
到目前为止我找到的可能性:
注意:S是"排序分数"
我想为我的用户提供最相关和最好的结果.例如,我奖励具有大标题,描述,附加照片等的记录.对于上下文:记录是自行车路线,具有路线点(坐标)和元数据,如照片,评论等.
现在,我使用了索引这些记录Hibernate,然后使用Lucenein 在索引中搜索Hibernate Search.为了对我的结果进行评分,我根据文档属性构建查询并在以下文件中提升它们(使用boostedTo())should BooleanJunction clause:
bj.should(qb.range().onField("descriptionLength").above(3000).createQuery()).boostedTo(3.0f);
bj.should(qb.range().onField("views.views").above(5000).createQuery()).boostedTo(3.0f);
bj.should(qb.range().onField("nameLength").above(20).createQuery()).boostedTo(1.0f);
bj.should(qb.range().onField("picturesLength").above(0).createQuery()).boostedTo(5.0f);
bj.should(qb.keyword().onField("routePoints.poi.participant").matching("true").createQuery()).boostedTo(10.0f);
Run Code Online (Sandbox Code Playgroud)
要尝试禁用Lucene的评分,我已经覆盖了DefaultSimilarity该类,将所有比较设置为1.0f得分并通过Hibernate配置启用它:
public class IgnoreScoringSimilarity extends DefaultSimilarity {
@Override
public float idf(long docFreq, long numDocs) {
return 1.0f;
}
@Override
public float tf(float freq) {
return 1.0f;
}
@Override
public float coord(int overlap, int maxOverlap) {
return 1.0f;
}
@Override
public float lengthNorm(FieldInvertState state) {
return 1.0f;
}
@Override
public float queryNorm(float sumOfSquaredWeights) {
return 1.0f;
}
} …Run Code Online (Sandbox Code Playgroud) 默认情况下,Lucene按相关性(得分)的顺序返回查询结果.您可以传递排序字段(或多个),然后结果按该字段排序.
我现在正在寻找一个很好的解决方案,以随机顺序获取搜索结果.
糟糕的方法:
当然我可以采取所有结果,然后洗牌收集,但在5 Mio搜索结果的情况下,这表现不佳.
优雅的分页方法:
通过这种方法,您可以告诉Lucene以下内容:
a)给我结果1到10个5Mio结果是随机顺序
b)然后给我11到20(基于相同的随机序列用于一个).
c)只是澄清:如果你打电话给a)两次,你会得到相同的随机元素.
你怎么能实现这种方法?
2012年7月27日更新:请注意,此处针对Lucene 2.9.x 所述的解决方案无法正常运行.使用RandomOrderScoreDocComparator将导致在结果列表中两次具有某些结果.