RS推荐系统-实例之基于内容相似度的酒店推荐

在推荐系统中,有一个环节是基于物品的推荐。它是基于物品的相似度,即物品的静态属性,如物品内容描述、物品特征向量等属性。这次我们会用到TFIDF和相似度计算的方法,对用户进行酒店推荐。本次使用的酒店数据会放到github中,需要自取:https://github.com/Vihagle/AI/tree/main/data.

下面的代码中,会提到余弦相似度,那我们也顺便提一嘴:
所谓余弦相似度,就是通过测量个向量的夹角的余弦值来度量它们之间的相似度。判断两个向量大致方向是否相同,

  • 方向相同时,余弦相似度为1;
  • 两个向量夹角为90°时,余弦相似度的值为0;
  • 方向完全相反时,余弦相似度的值为-1
  • 两个向量之间夹角的余弦值为[-1,1]
  • 给定属性向量A和B,A和B之间的夹角θ余弦值可以通过点积和向量长度计算得出:
    s i m i l a r i t y = c o s ( θ ) = A ⋅ B ∣ A ∣ ∣ B ∣ = ∑ i = 1 n A i ∗ B i ∑ i = 1 n ( A i ) 2 ∗ ∑ i = 1 n ( B i ) 2 similarity = cos(\theta) = \frac{A\cdot B}{|A||B|} = \frac{\sum^n_{i=1}A_i*B_i}{\sqrt{\sum^n_{i=1}(A_i)^2}*\sqrt{\sum^n_{i=1}(B_i)^2}} similarity=cos(θ)=ABAB=i=1n(Ai)2 i=1n(Bi)2 i=1nAiBi

除此之外,再了解一下什么是N-Gram(N元语法)

  • 基于一个假设:第n个词的出现与前n-1个词相关,而与其他词无关
  • N=1时为unigram,N=2为bigram,N=3为trigram
  • N-Gram指的是给定一个文本,其中的N个item的序列
  • 比如文本:ABCDE,对应的Bi-Gram为AB,BC,CD,DE
  • 当一阶特征不够用时,可以用N-Gram作为新的特征。比如处理文本特征时,一个关键词是一个,但有些情况不太够用,需要提取更多的特征,需要提取更多特征,采用N-Gram=》可以理解是相邻两个关键词的特征组合。

代码展示:

import numpy as np
import pandas as pd
from nltk.corpus import stopwords
from sklearn.metrics.pairwise import linear_kernel
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.decomposition import LatentDirichletAllocation
import re
import random

#加载数据集
data = pd.read_table('./Seattle_Hotels.txt',encoding="latin-1",sep = ',')
data

在这里插入图片描述

#得到酒店描述中n-gram特征中Top10个
def get_top_n_words(corpus,n=1,k=10):
    #统计ngram词频矩阵
    vec = CountVectorizer(ngram_range=(n,n),stop_words='english').fit(corpus)
    bag_of_words = vec.transform(corpus)
    sum_words = bag_of_words.sum(axis=0)
    words_freq = [(word, sum_words[0, idx]) for word, idx in vec.vocabulary_.items()]
    #按照词频从大到小排序
    words_freq = sorted(words_freq,key = lambda x:x[1],reverse = True)
    return words_freq[:k]

common_words = get_top_n_words(data['desc'], 1, 10)

#对高频词进行可视化展示
import matplotlib.pyplot as plt
plt.figure(figsize = (10,8))
plt.barh([i[0] for i in common_words[::-1]],[i[1] for i in common_words[::-1]])

在这里插入图片描述

#文本预处理
REPLACE_BY_SPACE_RE = re.compile('[/(){}\|@,;]')
BAD_SYMBOLS_RE = re.compile('[^0-9a-z #+_]')

#加载停用词
STOPWORDS = set(stopwords.words('english'))

#对酒店描述进行文本清洗
def clean_text(text):
    #全部文本转换成小写
    text = text.lower()
    #用空格替代标点符号
    text = REPLACE_BY_SPACE_RE.sub(' ',text)
    #移除BAD_SYMBOLS_RE
    text = BAD_SYMBOLS_RE.sub(' ',text)
    #去除停用词
    text = ' '.join(word for word in text.split() if word not in STOPWORDS)
    return text

#对'desc'字段进行文本清洗
data['clean_desc'] = data['desc'].apply(clean_text)
data

在这里插入图片描述

#将酒店名字作为索引
data.set_index('name',inplace = True)

#利用TF-IDF提取文本特征,min_df代表最小词频的百分比
tf = TfidfVectorizer(analyzer='word',ngram_range=(1,3),min_df = 0.01,stop_words = 'english')
#获取TF-IDF结果
res = tf.fit_transform(data['clean_desc'])
#获取TF-IDF矩阵
res_matrix = res.toarray()
#获取TF-IDF词名称
res_name = tf.get_feature_names()

#查看矩阵大小
res_matrix.shape #(152, 3245)

#计算酒店之间的相似度(基于余弦相似度)
cosine_similarities = linear_kernel(res,res)
#打印相似度矩阵
sim_hotel = pd.DataFrame(cosine_similarities,columns = data.index.tolist(),index = data.index.tolist())
sim_hotel

在这里插入图片描述

#基于相似度矩阵和指定酒店名称,推荐TOP10酒店
def recommandation(metrix,hotel):
    rec_index = np.argsort(-metrix[hotel])[1:11] #这里从第二个索引开始取的原因是,相似度最高的肯定是指定酒店自身
    rec = []
    for index,i in enumerate(rec_index):
        print(f'酒店推荐排行第{index+1}名:{metrix.index[i]}')

#打印推荐结果
recommandation(sim_hotel,'Hilton Seattle Airport & Conference Center')

在这里插入图片描述

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.Wiggles

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值