《推荐系统笔记(十六)》tf-idf与基于内容的推荐(简单的酒店推荐)

基于内容的推荐,仅仅依赖于物品的信息,对于系统冷启动和物品冷启动,可以有效解决。拿到物品的信息之后,对物品信息进行处理,生成特征向量,然后就可以定义物品相似度,对物品进行推荐。

通常,基于内容的推荐遵循下面三个步骤:

  • 物品表达(item representation),即从物品信息中抽出特征向量
  • 用户侧写(user profile),即根据用户过去行为中,学习到用户喜欢哪些物品特征,讨厌哪些物品特征
  • 生成推荐,即通过物品表达和用户侧写,来给用户推荐最相关的物品

我们用一份西雅图的酒店数据(seatleHotels.txt,已经上传,可以免费下载)作为数据集,里面包含三个特征,分别是 酒店名称、酒店地址和酒店描述。

我们接下来简单介绍下tf-idf。

实际上,tf指的是词频,即一个单词在文档中出现的概率。一般来说,单词出现的越频繁,可能会越能代表这篇文档。举一个计算的例子, doc=‘america is mygod country but it is a shit’,这里,我们分别计算每个单词出现的频率
t f = 该 单 词 出 现 次 数 文 档 总 单 词 数 tf=\frac{该单词出现次数}{文档总单词数} tf=如下

americaismygodcountrybutitashit
1/92/91/91/91/91/91/91/9

而idf则是指逆文档率。如上所示,出现很多的字可能只是介词之类的无意义的词,这类词在绝大多数文档中都会出现,为了降低这类词的权重,我们给出一个逆文档率的概念,也就是说,当这个词在越多文档中出现,那么这个词的权重越低,
i d f = l o g 总 文 档 数 1 + 出 现 该 单 词 的 文 档 数 idf=log\frac{总文档数}{1+出现该单词的文档数} idf=log1+

当我们综合考虑,我们希望在众多文档中,挑选出来最能代表这个文档的词,我们给这个词以最大的权重,也就是说,

  • 在该文档中,一个词的频率 t f tf tf越大,权重越大
  • 在所有文档中,一个词独属于这个文档的概率越大, i d f idf idf越大,则权重越大

因此,我们用 t f ⋅ i d f tf\cdot idf tfidf作为衡量某文档中一个词的重要程度, t f ⋅ i d f tf\cdot idf tfidf越大,越能说明这个词重要,能代表该文档的程度也越高。

我们可以用酒店描述部分,生成酒店的特征信息,具体的,

  • 用tf-idf对酒店文字描述部分进行处理,生成特征向量
  • 根据酒店的特征向量,计算不同酒店的相似度
  • 假设用户喜欢某个酒店,那么给用户推荐相似酒店
# 第三方库
import pandas as pd
import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer
# 载入数据
data = pd.read_csv(r'D:\myfile\开课吧\推荐系统\第七节\seatleHotels.txt', sep=',')
data.head()
# 将desc中的大写都改成小写
data['desc'] = data['desc'].apply(str.lower)
data.head()
# 计算tf-idf矩阵
tfidf = TfidfVectorizer(ngram_range=(1, 2), stop_words='english')
tfidf_array = tfidf.fit_transform(data['desc']).toarray()
# 创建tf-idf的dataframe
tfidf_dataframe = pd.DataFrame(tfidf_array, columns=tfidf.get_feature_names(), index=data.name)
tfidf_dataframe.head()
# 计算不同酒店之间的余弦相似度
cos_similarity = tfidf_array.dot(tfidf_array.T)
cos_similarity.shape
# 创建相似度pandas
similarity = pd.DataFrame(cos_similarity, columns=data['name'], index=data['name'])
similarity.head()
# 根据相似度进行推荐
def topN(hotel, N=4):
    neighbors = similarity.loc[hotel, :].sort_values(ascending=False)[1: N+1]
    return neighbors.index.tolist()
 
# 测试   
topN('Hilton Garden Seattle Downtown')  
# 结果
['Staybridge Suites Seattle Downtown - Lake Union',
 'Silver Cloud Inn - Seattle Lake Union',
 'Residence Inn by Marriott Seattle Downtown/Lake Union',
 'The Loyal Inn']
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值