使用ES的快速实现内容相似性推荐

问答系统:通过用户给出的一段描述性文本,通过相似度计算查找与用户输入接近的问题
相似推荐:用户在浏览当前文章时,基于内容相似性推荐与本篇文章相似的文章

more_like_this顾名思义就是帮我找到更多像这个文档的数据,为了便于讲解,这里先构建一个索引库,该索引库包含title和desc两个字段:

 PUT /search_data
{
    "mappings": {
        "properties": {
            "title": {
                "type": "text",
                "term_vector": "yes"
            },
            "desc": {
                "type": "text"
            }
        }
    }
}

  • term_vector
    term_vector为yes时会索引terms向量,加快相似度计算的速度;这里desc字段没有配置term_vector也是可以进行more_like_this查询的,但会有性能损耗,这里不配置是为了更好的说明问题,到线上应用需要都设置为yes。

基于一段短文本或一个问题描述语句进行推荐

GET /_search
{
    "query": {
        "more_like_this" : {
            "fields" : ["title", "desc"],
            "like" : "清明节春游踏青春季旅游学校春游亲子游企业郊游活动",
            "min_term_freq" : 1,
            "max_query_terms" : 12
        }
    }
}

  • fields
    要执行查询的字段,目前只支持text和term
  • like
    要查询相似的文本,可以是文档id或者一个查询字句
  • min_term_freq
    最小词频率,低于该频率的词将被忽略
  • max_query_terms
    根据max_query_terms配置的数,提取like中文本term的tfidf值最大的几个,其余的词将被忽略

另外如果文本太长,也可以基于文章Id进行相似推荐

GET /_search
{
    "query": {
        "more_like_this" : {
            "fields" : ["title", "desc"],
            "like" : [
            {
                "_index" : "search_data",
                "_id" : "1"
            } 
            ],
            "min_term_freq" : 1,
            "max_query_terms" : 12
        }
    }
}

like后面是数组可以跟多篇文章,另外_index对应的索引库也可以不是当前查询的索引库。

结果微调

  • unlike
    如果对推荐的结果不是很满意,也可以通过unlike参数进行微调,使用方式和like一致,不同的是这里传入的是你不喜欢的一些内容,在进行相似性计算时进行降权,需要注意的是,这里如果降权的是头部推荐的话不是很明显。
GET search_data/_search
{
  "size": 112, 
  "_source": ["desc","title"], 
  "query": {
    "more_like_this" : {
            "fields" : ["title", "desc"],
            "unlike":[
              {
                "_index" : "search_data",
                "_id" : "1270715"
              },
              {
                "_index" : "search_data",
                "_id" : "1238991"
              },
              {
                "_index" : "search_data",
                "_id" : "506680"
              },
              "我要把不喜欢的内容屏蔽掉"
              ],
             "like" : [
             {
                "_index" : "search_data",
                "_id" : "986604"
             }  
            ], 
            
            "min_term_freq" : 1 
        }
  }
}

其它可选参数

  • min_doc_freq:最小的文档频率,默认为5。
  • max_doc_freq:最大文档频率。
  • min_word_length:单词的最小长度。
  • max_word_length:单词的最大长度。
  • stop_words:停用词列表。
  • analyzer:分词器。
  • minimum_should_match:文档应该匹配的最小单词数量,默认为query分词后词项的30%。
  • boost_terms:词项的权重。
  • include:是否把输入文档作为结果返回。
  • boost:整个query的权重,默认为1.0。

推荐阅读更多精彩内容

  • 搜索机制 搜索的流程图如下: 1,文档写入ES的时候,ES中会存储两份数据。一份是文档的原始数据,即_source...
    吃火龙果吐芝麻阅读 1,184评论 0 1
  • 我需要一个空间 一个自由的空间 在这个空间我能够面对真实的自己 我曾试着去融入外界 可那些玩笑与冷漠却让我感到危险...
    The_warrior_X阅读 40评论 0 0
  • 时间过的飞快,不知不觉的孩子们迎来了第二个周末。在老师的教导下孩子们也慢慢的学习了很多,成长了很多,比如自己记作业...
    2021级张鑫泽妈妈阅读 149评论 0 4
  • 一个幸福的家,除了要有一个勤劳善良,阳光坚韧的女主人,更要有一个稳重踏实,体贴睿智的男主人。 臭坏蛋先生亲自下厨,...
    新月娟娟从容阅读 1,240评论 19 35
  • 最近,拜读了何炅老师5年前出版的一本书《来得及》。 在办公室的书柜里,专门陈列了一层除专业技术以外的书。打开书柜,...
    宛若熙熙阅读 161评论 1 2