python - 如何计算 pandas/sklearn 中一列中不同子类别之间的余弦相似度?(基于知识的推荐)
问题描述
我正在尝试创建一个根据用户输入推荐护肤品的程序。
期望的结果:
我想遍历 data['category'] 列下的每个子类别,并返回得分最高的产品名称(data['name'])。我确信解决方案相对简单,但我对 pandas 很陌生,并且已经研究了几天。
问题:
目前,当我在运行推荐函数(这一行print(data['name'].iloc[indices]
)后返回数据时,它只返回子类别“清洁剂”中的项目。理想情况下,它将返回所有具有最高相似性的产品,但即使我编辑此行score = score[0:15]
以显示所有结果,它也只显示清洁剂。这可能是我如何计算相似度的问题
可能的解决方案:
我认为这个解决方案非常接近我想要的。但是,我似乎无法弄清楚如何用我的程序来实现它。以示例的方式通过 cosine_similarity 运行输入,会返回错误“您需要使用 a.reshape(-1, 1) 进行整形”,但重新整形输入也不起作用,因为它是字符串列表。
我想我在问,我如何达到我想要的结果。那 ^ 解决方案接近吗?我离基地很远吗?
如果您想自己运行它来测试结果,这也是我的 csv 文件(别担心,它的压缩版本非常小)https://pastebin.com/5iz8nxat
import numpy as np
import pandas as pd
from ast import literal_eval
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.feature_extraction.text import CountVectorizer
data = pd.read_csv('skin_recs.csv')
data = data[['category','skin_types','concern','sensitive','name','details']]
data['skin_types'] = data['skin_types'].fillna('[]')
data['concern'] = data['concern'].fillna('[]')
#convert to python dict
data['skin_types'] = data['skin_types'].apply(literal_eval)
data['concern'] = data['concern'].apply(literal_eval)
#grab all skin types & concerns
data['skin_types'] = data['skin_types'].apply(lambda x: [i['name'].lower() for i in x] if isinstance(x, list) else [])
data['concern'] = data['concern'].apply(lambda x: [i['name'].lower() for i in x] if isinstance(x, list) else [])
#remove spaces
data['skin_types'] = data['skin_types'].apply(lambda x: [i.replace(' ', '') for i in x])
data['concern'] = data['concern'].apply(lambda x: [i.replace(' ', '') for i in x])
s = data.apply(lambda x: pd.Series(x['skin_types']), axis=1).stack().reset_index(level=1,drop=True)
s.name = 'type'
data = data.drop('skin_types', axis=1).join(s)
s = data.apply(lambda x: pd.Series(x['concern']), axis=1).stack().reset_index(level=1,drop=True)
s.name = 'goal'
data = data.drop('concern', axis=1).join(s)
data['metadata'] = data.apply(lambda x : ''.join(x['type']) + ', ' + ''.join(x['goal']), axis = 1)
vectorizer = CountVectorizer(stop_words='english')
vect_matrix = vectorizer.fit_transform(data['name'])
similarity = cosine_similarity(vect_matrix, vect_matrix)
mapping = pd.Series(data.index,index = data['metadata'])
def recommender(input, category):
index = mapping[input]
score = list(enumerate(similarity[index]))
score = sorted(score, key=lambda x: x[0], reverse=True)
score = score[0:15]
indices = [i[0] for i in score]
print(data['name'].iloc[indices])
recommender('dry, acne', 'cleanser')
解决方案
推荐阅读
- ggfortify - 使用自动绘图为线性模型上使用的 ggfortify 对象生成交互式绘图
- javascript - 如何在带有 Google 地图 API 的 asp.net MVC 中使用两个地图?
- python - 如何将 keras cnn 模型转换为 pytorch 版本
- python - 在错误处理中获取文件路径 - python
- python - Django 项目运行 manage.py 导致没有名为 django 的模块
- browser - 设置可见性后更改元素的宽度是否会导致重排:隐藏?
- python-3.x - 使用 python pt.2 下载 pdf
- sql - 大表上的函数 to_date 和 BETWEEN 慢查询
- javascript - 用于解析复杂 JSON 对象/数组的 JavaScript 递归函数
- cobol - 如何解决 Cobol 程序中的排序问题?