python - 如何构建一个使用多个属性的基于内容的推荐系统?

标签 python pandas machine-learning scikit-learn recommendation-engine

我想用 Python 构建一个基于内容的推荐系统,该系统使用多个属性来确定两个项目是否相似。在我的例子中,“项目”是由 C# 包管理器 ( example ) 托管的包,它们具有各种属性,例如名称、描述、有助于识别类似包的标签。

我有一个原型(prototype)推荐系统 here目前只使用一个属性,描述,来决定包是否相似。它计算描述的 TF-IDF 排名,并打印出基于此的前 10 个推荐:

# Code mostly stolen from http://blog.untrod.com/2016/06/simple-similar-products-recommendation-engine-in-python.html
def train(dataframe):
    tfidf = TfidfVectorizer(analyzer='word',
                            ngram_range=(1, 3),
                            min_df=0,
                            stop_words='english')
    tfidf_matrix = tfidf.fit_transform(dataframe['description'])
    cosine_similarities = linear_kernel(tfidf_matrix, tfidf_matrix)
    for idx, row in dataframe.iterrows():
        similar_indices = cosine_similarities[idx].argsort()[:-10:-1]
        similar_items = [(dataframe['id'][i], cosine_similarities[idx][i])
                        for i in similar_indices]

        id = row['id']
        similar_items = [it for it in similar_items if it[0] != id]
        # This 'sum' is turns a list of tuples into a single tuple:
        # [(1,2), (3,4)] -> (1,2,3,4)
        flattened = sum(similar_items, ())
        try_print("Top 10 recommendations for %s: %s" % (id, flattened))

如何将 cosine_similarities 与其他相似性度量(基于同一作者、相似名称、共享标签等)相结合,为我的推荐提供更多背景信息?

最佳答案

在某些情况下,我与基于内容的推荐系统的合作主要围绕原始文本和分类数据/特征展开。这是我采用的一种高级方法,效果很好,而且实现起来非常简单。

假设我有三个可以用来提出建议的特征列:description , name , 和 tags .对我来说,阻力最小的路径需要以有用的方式组合这三个功能集。

您有了一个良好的开端,使用 TF-IDF 对 description 进行编码.那么为什么不治疗 nametags以类似的方式创建由 description 组成的特征“语料库” , name , 和 tags ?从字面上看,这意味着将三列中每一列的内容连接成一个长文本列。

不过,请明智地处理串联,因为在像 name 这样的特征的情况下,保留给定单词来自哪一列 可能对您有利。和 tag ,假定其基数比 description 低得多.更明确地说:而不是像这样创建你的语料库列:

df['corpus'] = (pd.Series(df[['description', 'name', 'tags']]
                .fillna('')
                .values.tolist()
                ).str.join(' ')

您可以尝试保留有关特定数据点在 name 中的位置的信息和 tags来自。像这样:

df['name_feature'] = ['name_{}'.format(x) for x in df['name']]
df['tags_feature'] = ['tags_{}'.format(x) for x in df['tags']]

在你这样做之后,我会更进一步,考虑默认分词器(你在上面使用的)如何在 TfidfVectorizer 中工作。 .假设您有给定包作者的姓名:“Johnny 'Lightning' Thundersmith”。如果您只是连接该文字字符串,标记器会将其拆分并将“Johnny”、“Lightning”和“Thundersmith”中的每一个滚动到单独的特征中,这可能会减少由此添加的信息name 的行值.我认为最好尝试保留该信息。因此,我会对每个较低基数的文本列(例如 nametags)执行类似的操作:

def raw_text_to_feature(s, sep=' ', join_sep='x', to_include=string.ascii_lowercase):
    def filter_word(word):
        return ''.join([c for c in word if c in to_include])
    return join_sep.join([filter_word(word) for word in text.split(sep)])

def['name_feature'] = df['name'].apply(raw_text_to_feature)

同样的批判性思维应该应用于 tags .如果您有一个以逗号分隔的标签“列表”,您可能必须单独解析这些标签并找出使用它们的正确方法。

最终,一旦您获得所有 <x>_feature创建列,然后您可以创建最终的“语料库”并将其作为输入插入推荐系统。

可以肯定的是,整个系统需要一些工程,但我发现这是从具有不同基数的其他列引入新信息的最简单方法。

关于python - 如何构建一个使用多个属性的基于内容的推荐系统?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48245809/

相关文章:

python-3.x - 基于不同数据框条件的新数据框列

python-3.x - 如何检查嵌套列表是否存在以及如果存在则取消嵌套?

machine-learning - 在mxnet错误中定义一个简单的神经网络

python - 使用 NumPy 快速进行 token 到索引的转换

python - 使用python打开目录中的文件,编码有问题

pandas - 在 'groupby()' 和 'value_counts() 函数之后选择每组的第一行

apache-spark - Spark 机器学习 AST 比较

Python Pandas : remove entries based on the number of occurrences

python - 'M'在scipy文档中意味着什么?

python - 缺失的分类数据应使用全零单热向量进行编码