酒店推荐系统代码详细解读

发布于:2025-08-12 ⋅ 阅读:(18) ⋅ 点赞:(0)

酒店推荐系统代码详细解读

AI大模型应用开发者 2025年08月07日 19:50 北京

图片

这个酒店推荐系统使用了以下关键技术:
1. **文本预处理**:将原始文本转换为标准化、清洗后的格式
2. **特征提取**:使用TF-IDF将文本转换为数值特征向量
3. **相似度计算**:使用余弦相似度衡量酒店描述之间的相似程度4. **推荐算法**:基于相似度为用户推荐最相似的酒店这种基于内容的推荐系统不需要用户交互数据,只依赖于酒店描述的文本内容,适合冷启动场景或数据稀疏的情况。

import pandas as pdfrom sklearn.metrics.pairwise import linear_kernelfrom sklearn.feature_extraction.text import CountVectorizerfrom sklearn.feature_extraction.text import TfidfVectorizerimport repd.options.display.max_columns = 30import matplotlib.pyplot as plt# 支持中文plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签df = pd.read_csv('hotel_recommendation/Seattle_Hotels.csv', encoding="latin-1")# 数据探索print(df.head())print('数据集中的酒店个数:', len(df))# 创建英文停用词列表ENGLISH_STOPWORDS = {    'i', 'me', 'my', 'myself', 'we', 'our', 'ours', 'ourselves', 'you', "you're", "you've", "you'll", "you'd", 'your',     'yours', 'yourself', 'yourselves', 'he', 'him', 'his', 'himself', 'she', "she's", 'her', 'hers', 'herself', 'it',     "it's", 'its', 'itself', 'they', 'them', 'their', 'theirs', 'themselves', 'what', 'which', 'who', 'whom', 'this',     'that', "that'll", 'these', 'those', 'am', 'is', 'are', 'was', 'were', 'be', 'been', 'being', 'have', 'has', 'had',     'having', 'do', 'does', 'did', 'doing', 'a', 'an', 'the', 'and', 'but', 'if', 'or', 'because', 'as', 'until', 'while',     'of', 'at', 'by', 'for', 'with', 'about', 'against', 'between', 'into', 'through', 'during', 'before', 'after', 'above',     'below', 'to', 'from', 'up', 'down', 'in', 'out', 'on', 'off', 'over', 'under', 'again', 'further', 'then', 'once',     'here', 'there', 'when', 'where', 'why', 'how', 'all', 'any', 'both', 'each', 'few', 'more', 'most', 'other', 'some',     'such', 'no', 'nor', 'not', 'only', 'own', 'same', 'so', 'than', 'too', 'very', 's', 't', 'can', 'will', 'just', 'don',     "don't", 'should', "should've", 'now', 'd', 'll', 'm', 'o', 're', 've', 'y', 'ain', 'aren', "aren't", 'couldn',     "couldn't", 'didn', "didn't", 'doesn', "doesn't", 'hadn', "hadn't", 'hasn', "hasn't", 'haven', "haven't", 'isn',     "isn't", 'ma', 'mightn', "mightn't", 'mustn', "mustn't", 'needn', "needn't", 'shan', "shan't", 'shouldn', "shouldn't",     'wasn', "wasn't", 'weren', "weren't", 'won', "won't", 'wouldn', "wouldn't"}def print_description(index):    example = df[df.index == index][['desc', 'name']].values[0]    if len(example) > 0:        print(example[0])        print('Name:', example[1])print('第10个酒店的描述:')print_description(10)# 得到酒店描述中n-gram特征中的TopK个def get_top_n_words(corpus, n=1, k=None):    # 统计ngram词频矩阵,使用自定义停用词列表    vec = CountVectorizer(ngram_range=(n, n), stop_words=list(ENGLISH_STOPWORDS)).fit(corpus)    bag_of_words = vec.transform(corpus)    """    print('feature names:')    print(vec.get_feature_names())    print('bag of words:')    print(bag_of_words.toarray())    """    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(df['desc'], n=3, k=20)#print(common_words)df1 = pd.DataFrame(common_words, columns = ['desc' , 'count'])df1.groupby('desc').sum()['count'].sort_values().plot(kind='barh', title='去掉停用词后,酒店描述中的Top20单词')plt.show()# 文本预处理REPLACE_BY_SPACE_RE = re.compile('[/(){}\[\]\|@,;]')BAD_SYMBOLS_RE = re.compile('[^0-9a-z #+_]')# 使用自定义的英文停用词列表替代nltk的stopwordsSTOPWORDS = ENGLISH_STOPWORDS# 对文本进行清洗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字段进行清理,apply针对某列df['desc_clean'] = df['desc'].apply(clean_text)#print(df['desc_clean'])# 建模df.set_index('name', inplace = True)# 使用TF-IDF提取文本特征,使用自定义停用词列表tf = TfidfVectorizer(analyzer='word', ngram_range=(1, 3), min_df=0.01, stop_words=list(ENGLISH_STOPWORDS))# 针对desc_clean提取tfidftfidf_matrix = tf.fit_transform(df['desc_clean'])print('TFIDF feature names:')#print(tf.get_feature_names_out())print(len(tf.get_feature_names_out()))#print('tfidf_matrix:')#print(tfidf_matrix)#print(tfidf_matrix.shape)# 计算酒店之间的余弦相似度(线性核函数)cosine_similarities = linear_kernel(tfidf_matrix, tfidf_matrix)#print(cosine_similarities)print(cosine_similarities.shape)indices = pd.Series(df.index) #df.index是酒店名称# 基于相似度矩阵和指定的酒店name,推荐TOP10酒店def recommendations(name, cosine_similarities = cosine_similarities):    recommended_hotels = []    # 找到想要查询酒店名称的idx    idx = indices[indices == name].index[0]    print('idx=', idx)    # 对于idx酒店的余弦相似度向量按照从大到小进行排序    score_series = pd.Series(cosine_similarities[idx]).sort_values(ascending = False)    # 取相似度最大的前10个(除了自己以外)    top_10_indexes = list(score_series.iloc[1:11].index)    # 放到推荐列表中    for i in top_10_indexes:        recommended_hotels.append(list(df.index)[i])    return recommended_hotelsprint(recommendations('Hilton Seattle Airport & Conference Center'))print(recommendations('The Bacon Mansion Bed and Breakfast'))#print(result)
# 酒店推荐系统代码详细解读这个代码实现了一个基于文本相似度的酒店推荐系统,使用了自然语言处理和机器学习技术。下面是对代码的详细解读:## 导入必要的库```pythonimport pandas as pd```这行导入了pandas库,并将其简写为pd。pandas是Python中用于数据分析和处理的核心库,提供了DataFrame等数据结构,可以高效地处理和分析结构化数据。```pythonfrom sklearn.metrics.pairwise import linear_kernel```从scikit-learn库中导入linear_kernel函数,用于计算向量之间的线性核(本质上是计算余弦相似度),这在后面用于计算酒店描述之间的相似度。```pythonfrom sklearn.feature_extraction.text import CountVectorizer```导入CountVectorizer类,用于将文本数据转换为词频矩阵,即计算文本中每个词出现的次数。```pythonfrom sklearn.feature_extraction.text import TfidfVectorizer```导入TfidfVectorizer类,用于将文本转换为TF-IDF特征矩阵,这是一种常用的文本特征提取方法,可以反映词语在文档中的重要性。```pythonimport re```导入正则表达式库,用于文本清洗和处理。```pythonpd.options.display.max_columns = 30```设置pandas显示的最大列数为30,这样可以在打印DataFrame时显示更多的列。```pythonimport matplotlib.pyplot as plt```导入matplotlib的pyplot模块,用于数据可视化。```python# 支持中文plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签```设置matplotlib的字体为SimHei,以支持显示中文字符,避免中文显示为乱码。## 数据加载与探索```pythondf = pd.read_csv('hotel_recommendation/Seattle_Hotels.csv', encoding="latin-1")```从指定路径读取CSV文件到DataFrame中,使用latin-1编码(这对于处理包含特殊字符的文件很有用)。```python# 数据探索print(df.head())```打印DataFrame的前几行数据,用于初步了解数据结构。```pythonprint('数据集中的酒店个数:', len(df))```打印数据集中酒店的总数量。## 停用词处理```python# 创建英文停用词列表ENGLISH_STOPWORDS = {    'i', 'me', 'my', 'myself', 'we', 'our', 'ours', 'ourselves', 'you', "you're", "you've", "you'll", "you'd", 'your',     # ... 更多停用词 ...}```创建一个包含英文常见停用词的集合。停用词是在文本分析中通常被过滤掉的常见词(如"the"、"a"、"an"等),因为它们出现频率高但不携带重要信息。## 酒店描述查看函数```pythondef print_description(index):    example = df[df.index == index][['desc', 'name']].values[0]    if len(example) > 0:        print(example[0])        print('Name:', example[1])```定义一个函数,用于打印指定索引的酒店描述和名称。这个函数首先根据索引筛选出对应的酒店记录,然后打印其描述和名称。```pythonprint('第10个酒店的描述:')print_description(10)```打印索引为10的酒店的描述信息。## 文本特征提取```python# 得到酒店描述中n-gram特征中的TopK个def get_top_n_words(corpus, n=1, k=None):    # 统计ngram词频矩阵,使用自定义停用词列表    vec = CountVectorizer(ngram_range=(n, n), stop_words=list(ENGLISH_STOPWORDS)).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]```定义一个函数,用于获取文本语料库中出现频率最高的n-gram特征。n-gram是指连续的n个词组成的序列。这个函数:1. 使用CountVectorizer将文本转换为n-gram词频矩阵2. 计算每个n-gram在所有文档中的总出现次数3. 创建(词, 频率)对的列表4. 按频率降序排序5. 返回前k个最常见的n-gram```pythoncommon_words = get_top_n_words(df['desc'], n=3, k=20)```获取酒店描述中出现频率最高的20个三元词组(trigrams)。```pythondf1 = pd.DataFrame(common_words, columns = ['desc' , 'count'])df1.groupby('desc').sum()['count'].sort_values().plot(kind='barh', title='去掉停用词后,酒店描述中的Top20单词')plt.show()```将常见词及其频率转换为DataFrame,然后创建一个水平条形图来可视化Top20的词频分布。## 文本预处理```python# 文本预处理REPLACE_BY_SPACE_RE = re.compile('[/(){}\[\]\|@,;]')BAD_SYMBOLS_RE = re.compile('[^0-9a-z #+_]')```定义两个正则表达式模式:1. REPLACE_BY_SPACE_RE:匹配需要被空格替换的特殊符号2. BAD_SYMBOLS_RE:匹配需要被删除的不需要的符号```python# 使用自定义的英文停用词列表替代nltk的stopwordsSTOPWORDS = ENGLISH_STOPWORDS```将之前定义的停用词集合赋值给STOPWORDS变量。```python# 对文本进行清洗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```定义一个文本清洗函数,包括以下步骤:1. 将文本转换为小写2. 用空格替换特定的标点符号3. 删除不需要的符号4. 移除停用词```python# 对desc字段进行清理,apply针对某列df['desc_clean'] = df['desc'].apply(clean_text)```对DataFrame中的'desc'列应用clean_text函数,创建一个新的清洗后的描述列'desc_clean'。## 建立推荐模型```python# 建模df.set_index('name', inplace = True)```将DataFrame的索引设置为酒店名称,这样可以直接通过酒店名称来访问数据。```python# 使用TF-IDF提取文本特征,使用自定义停用词列表tf = TfidfVectorizer(analyzer='word', ngram_range=(1, 3), min_df=0.01, stop_words=list(ENGLISH_STOPWORDS))```创建TF-IDF向量化器,用于将文本转换为TF-IDF特征:- analyzer='word':以单词为单位进行分析- ngram_range=(1, 3):考虑1-gram到3-gram的特征- min_df=0.01:忽略在少于1%文档中出现的词- stop_words=list(ENGLISH_STOPWORDS):使用自定义停用词列表```python# 针对desc_clean提取tfidftfidf_matrix = tf.fit_transform(df['desc_clean'])```将清洗后的酒店描述转换为TF-IDF特征矩阵。```pythonprint('TFIDF feature names:')print(len(tf.get_feature_names_out()))```打印TF-IDF特征的数量,即提取出的独特词汇或n-gram的数量。```python# 计算酒店之间的余弦相似度(线性核函数)cosine_similarities = linear_kernel(tfidf_matrix, tfidf_matrix)```使用线性核函数计算TF-IDF矩阵中每对酒店描述之间的余弦相似度,得到一个相似度矩阵。```pythonprint(cosine_similarities.shape)```打印相似度矩阵的形状,应该是(酒店数量, 酒店数量)。```pythonindices = pd.Series(df.index) #df.index是酒店名称```创建一个Series,包含所有酒店名称,用于后续通过名称查找索引。## 推荐函数```python# 基于相似度矩阵和指定的酒店name,推荐TOP10酒店def recommendations(name, cosine_similarities = cosine_similarities):    recommended_hotels = []    # 找到想要查询酒店名称的idx    idx = indices[indices == name].index[0]    print('idx=', idx)    # 对于idx酒店的余弦相似度向量按照从大到小进行排序    score_series = pd.Series(cosine_similarities[idx]).sort_values(ascending = False)    # 取相似度最大的前10个(除了自己以外)    top_10_indexes = list(score_series.iloc[1:11].index)    # 放到推荐列表中    for i in top_10_indexes:        recommended_hotels.append(list(df.index)[i])    return recommended_hotels```定义一个推荐函数,基于酒店名称和相似度矩阵推荐最相似的10个酒店:1. 通过酒店名称找到对应的索引2. 获取该酒店与所有其他酒店的相似度向量3. 按相似度降序排序4. 选取相似度最高的10个酒店(排除自身)5. 返回这10个酒店的名称列表```pythonprint(recommendations('Hilton Seattle Airport & Conference Center'))print(recommendations('The Bacon Mansion Bed and Breakfast'))```分别打印对"Hilton Seattle Airport & Conference Center"和"The Bacon Mansion Bed and Breakfast"这两个酒店的推荐结果。## 总结这个酒店推荐系统使用了以下关键技术:1. **文本预处理**:将原始文本转换为标准化、清洗后的格式2. **特征提取**:使用TF-IDF将文本转换为数值特征向量3. **相似度计算**:使用余弦相似度衡量酒店描述之间的相似程度4. **推荐算法**:基于相似度为用户推荐最相似的酒店这种基于内容的推荐系统不需要用户交互数据,只依赖于酒店描述的文本内容,适合冷启动场景或