如何在elasticsearch中实现sklearn的tf-idf作为脚本分数

问题描述

我尝试在 elasticsearch 中实现 sklearn TfidfVectorizer 计算 tf-idf 的方法,以便我可以比较两个结果。

sklearn 像这样计算 tf-idf(认情况下):

% Generate dummy 3d array
img = ones(5,4,3);
for ii=1:size(img,3)
    img(:,:,ii)=ii;
end
% Try plotting heatmap with slider
h = heatmap(img(:,1));
uiSlider(h)

与:

tf-idf(t,d) = tf(t,d) * idf(t)

和 tf(t,d) 只是没有缩放/加权的原始词频

elasticsearch(引擎盖下有 lucene)认实现基于 tf-idf 的 BM25,建议实现基本的 tf-idf 作为脚本分数,例如:

idf(t) = log [ (1 + n) / (1 + df(t)) ] + 1

其中详细说明:

"similarity": {
      "scripted_tfidf": {
        "type": "scripted","script": {
          "source": "double tf = Math.sqrt(doc.freq); double idf = Math.log((field.docCount+1.0)/(term.docFreq+1.0)) + 1.0; double norm = 1/Math.sqrt(doc.length); return query.boost * tf * idf * norm;"
        }
      }
    }

与:

tf-idf = query.boost * tf * idf * norm

所以我实现 sklearn 的 tf-idf 的方法是:

tf = Math.sqrt(doc.freq)
idf = Math.log((field.docCount+1.0)/(term.docFreq+1.0)) + 1.0
norm = 1/Math.sqrt(doc.length)

但是通过这个实现,我得到了可怕的搜索结果,这比 sklearn 的要糟糕得多(而 tf-idf 的认弹性搜索实现优于 sklearn)。

所以我的问题是:我的脚本化 tf-idf 实现有什么错误

(我知道 sklearn 建议在计算具有余弦相似度的相似度分数之前对 tf-idf 进行归一化,但是由于 elasticsearch 没有这样做,我认为结果分数和查询搜索结果之前的分数应该相同。)

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)