我有一个项目,其中有一个项目目录,每个项目都有一组标签。我想根据这些标签展示相似的项目。
像这样的东西(但数据集更大):
{
"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 编写所有代码,使用主干和下划线。然而,语言并不是那么重要——只是好奇什么样的技术或算法可能会产生更好的结果。