根据标签数组创建有意义的建议

时间:2013-11-02 23:10:20

标签: javascript backbone.js search-suggestion

我有一个项目,其中有一个项目目录,每个项目都有一个标签数组。我想基于这些标签呈现相似的项目。

像这样(但有更大的数据集):

{
    "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中完成所有代码。然而,语言并不那么重要 - 只是好奇什么样的技术或算法可以提供更好的结果。

1 个答案:

答案 0 :(得分:1)

大多数适用数据的简单例程可以是,按照标签交叉点大小的顺序返回匹配,返回计数有限。如果您可以将某些标签加权为更重要,那么您可以使用它来调整返回的订单。例如,如果用户之前已从目录中购买了商品,则与其购买相关联的商品可能会在订单算法中获得更高的分数。