【发布时间】:2013-11-02 23:10:19
【问题描述】:
我有一个项目,其中有一个项目目录,每个项目都有一个标签数组。我想根据这些标签展示相似的项目。
类似这样(但数据集更大):
{
"item": {
"description":"thing",
"tags": ["a","b","c","e","f"]
},
"item": {
"description":"thing",
"tags": ["a","b"]
},
"item": {
"description":"thing",
"tags": ["a","c"]
},
"item": {
"description":"thing",
"tags": ["b","c"]
}
}
到目前为止我尝试过的两件事:
首先是单个项目上的标签与具有一个或多个相同标签的其他项目之间的直接交叉点。这很好用,但在标签有点通用的情况下(想想,用“音乐”之类的东西标记,它们都是音乐项目),返回项目的数量是巨大的。
第二个想法有点疯狂,我将标签数组变成了一个字符串,并计算了 levenshtein 差异。这适用于长度大致相同或更大但笨重的项目。尽管如此,它确实减少了第一种方法返回的大量脂肪。这不是正确的方法,但想展示我的目标。像这样实现它:
// snip: this is inside a BB collection
getSimilarByTag: function(tags, ignore){
var hits = [];
if (tags) {
this.filter(function(item){
if (item.get('cat') === ignore){
return; // no need to include
};
var itemTags = item.get('tags');
var result = _.intersection(tags, itemTags);
if (result.length) {
// calc levenshtein distance between the intersection and the search array
var dist = _.str.levenshtein(result.join(' '), tags.join(' '));
if (Math.log(dist) < 1.5) { // this value needs tuning?
hits.push(item.toJSON());
} else {
// based on our magic number above, ignore this
}
};
});
}
return hits;
}
我正在使用 javascript 编写所有代码,使用主干和下划线。然而,语言并不是那么重要——只是好奇什么样的技术或算法可能会产生更好的结果。
【问题讨论】:
-
有没有可能使用分类和标签?所以“音乐”是一个类别,标签可以是“古典”、“朋克”……这样你就可以简单地忽略不属于同一类别的任何东西,然后根据(变量最小值数量)标签。
-
不幸的是不是——实际上类别可以被视为某种“主标签”,这并没有让我走得更远。感谢您的意见!
-
如果返回的数据集可能很大,我们通常(您必须清楚地知道)以块的形式返回集合,即 sql 限制。为什么不考虑实施这样的技术?似乎您要求的是不可能的事情,无论是什么语言,大量数据都是大量数据。
-
我试图找出最适用的数据是什么,而不仅仅是如何处理它,超越交叉路口。
-
您的真正问题是什么?您只是在问在两个字符串数组之间创建相似度分数的最佳方法是什么?
标签: javascript backbone.js search-suggestion