电影推荐排名搜索算法

项目的方案:

1、搜集电影的特征,包含(年代,主演,内容,剧情等等)

2、对给定的电影特征进行向量化,用了tensorflow(one-hot)

3、调用faiss进行制定索引和相似话查找,采用欧氏距离

4、给定目标向量,搜索向量集合,查找最近的目标

5、展示结果

python3

安装faiss
pip install faiss-cpu -i https://pypi.tuna.tsinghua.edu.cn/simple/

数据集地址:

https://download.csdn.net/download/chehec2010/89036813

实现的代码DEMO:

import pandas as pd
import numpy as np
import json
import faiss
from tensorflow.python.keras.layers.embeddings import Embedding
from keras.preprocessing.sequence import pad_sequences
from keras.preprocessing.text import one_hot

#数据预处理,向量化

def dataProcess():
    df = pd.read_csv('../movies.csv')
    # 俩列合并为一列
    df["ht"] = df["title"] + df["genres"]
    #保存mivied \ ht
    df.to_csv('../Httmovie.csv', index=False)
    htt = df["ht"].tolist()
    print(htt[:4])

    vocab_size = 1000  # 将词汇表设置为1000
    # one_hot
    encode = [one_hot(d, vocab_size) for d in htt]

    # 用padding进行填充,保证长度一直,设立都设置为4
    max_length = 10
    # padding填充最大的词汇长度,0向后填充(padding=post)
    padding_docs = pad_sequences(encode, maxlen=max_length, padding='post')
    print(padding_docs.shape)
    print(padding_docs[:10])
    # 转换为字符串存入csv
    bet = [json.dumps(lu.tolist()) for lu in padding_docs]
    # 将向量保存到csv
    test = pd.DataFrame(bet, columns=['features'])
    # 创建一列为id列
    test['id'] = range(1, len(test) + 1)
    # 调换列'id'和列'features'的位置
    test = test[['id', 'features']]
    # # 转换csv
    test.to_csv('../movie.csv', sep=',', encoding='utf-8', index=True)

# dataProcess()
#读取影评信息
df = pd.read_csv('../movie.csv')
#查看信息
df.head()

#构建ids
ids = df['id'].values.astype(np.int64)

#特征数据格式转换
datas = []

for x in df['features']:
    #str专为json
    datas.append(json.loads(x))

#json转为array
datas = np.array(datas).astype(np.float32)
print(datas.shape,type(datas))

print(datas[0]) #打印第一条数据看看

#建立索引
index = faiss.IndexFlatL2(datas.shape[1]) #基于欧式距离建立索引
index2 = faiss.IndexIDMap(index)  #基于第一个索引去建立第二个索引

#制定ids为datas的索引
index2.add_with_ids(datas,ids)
#查看电影索引
print(index2.ntotal)

#加载电影向量 (根据id是第一个的寻找其相似的5个)
item_embedding = np.array(json.loads(df[df['id']==1]['features'].iloc[0]))

#添加维度,就是[] 变为[[]]
item_embedding = np.expand_dims(item_embedding,axis=0).astype(np.float32)
print(item_embedding)

print(item_embedding.dtype)

#neighbor num=5 定义紧邻检索的数量
topn =5
#dis and idx(D表示各个邻居之间的距离列表,I是最近各个邻居的下标)
D,I = index2.search(item_embedding,topn)

#查看索引的下标
print(I)
print(I.shape)

#生成推荐列表
target_ids = pd.Series(I[0],name="movieId")
#读取原来的列表
df_movies = pd.read_csv('../Httmovie.csv')
# 删除title和genres
df_movies = df_movies.drop(columns=["title" + "genres"])

#进行合并
df_result = pd.merge(target_ids,df_movies)

print(df_result)

正确的帮你检索出最靠近的5个:

 

部分代码解释:

import pandas as pd
import numpy as np
import json
import faiss
from tensorflow.python.keras.layers.embeddings import Embedding
from keras.preprocessing.sequence import pad_sequences
from keras.preprocessing.text import one_hot

df = pd.read_csv('../movie.csv')
test=df[df['id']==1]['features']
print(test)
#0    [137, 92, 518, 382, 607, 883, 89, 650, 0, 0]
test = test.iloc[0] #第0行的元素
print(test)
#     [137, 92, 518, 382, 607, 883, 89, 650, 0, 0]
item_embedding = np.expand_dims(json.loads(test),axis=0).astype(np.float32)
#json.loads(test)是将'[137, 92, 518, 382, 607, 883, 89, 650, 0, 0]' 转化为[137, 92, 518, 382, 607, 883, 89, 650, 0, 0]
print(item_embedding)   #[[137.  92. 518. 382. 607. 883.  89. 650.   0.   0.]]
print(item_embedding.shape) #(1, 10)

'''
执行程序后注意观察中括号[ ]的位置和数量

np.expand_dims(a, axis=0)表示在axis=0维度处扩展维度,加一层中括号[ ];

np.expand_dims(a, axis=1)表示在axis=1维度处扩展维度,加一层中括号[ ];

np.expand_dims(a, axis=2)表示在axis=2维度处扩展维度,加一层中括号[ ];

np.expand_dims(a, axis=-1)表示在axis=-1(最后)维度处扩展维度,加一层中括号[ ];

'''

faiss测试:

import numpy as np
import faiss

np.random.seed(42)

num_vectors = 1000
dim = 64

# 创建1000个向量,每个向量的维度是64
vectors = np.random.rand(num_vectors, dim)
# 创建基于L2的索引
index = faiss.IndexFlatL2(dim)
# 将向量入库
index.add(vectors)

# 创建5个查询向量
queries = np.random.rand(5, dim)
# 要检索的近邻数量
k = 3
# D是距离数组,I是索引数组
D, I = index.search(queries, k)

print("查询结果:")
print("距离:\n", D)
print("索引:\n", I)

'''
默认情况下,每个向量的索引是按照它们入库的顺序进行分配的。但有些时候,我们希望自己给这些向量分配ID,这时候就需要用上 IndexIDMap
具体来讲,IndexIDMap 是一个包装器(wrapper),它在任何 FAISS 索引的基础上工作。首先创建一个基础索引(例如,IndexFlatL2 用于 L2 距离),
然后使用 IndexIDMap 将这个索引包装起来。这样,基础索引负责计算向量间的相似性,而 IndexIDMap 负责处理与这些向量相关联的 ID。
然后我们使用 add_with_ids 来手动为要入库的向量分配索引



'''

参考地址:https://blog.csdn.net/raelum/article/details/135047797

出现一个bug记录一下

index = faiss.IndexFlatL2(dim)
AttributeError: partially initialized module 'faiss' has no attribute 'IndexFlatL2' (most likely due to a circular import)

主要是测试过程中faiss.py文件导致问题,删除掉就好了

 

  • 10
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
推荐系统是基于用户的偏好和历史行为来预测用户可能喜欢的物品或内容。在电影推荐系统中,常见的算法包括协同过滤、内容过滤和混合推荐。下面是一些常用的电影推荐算法: 1. 协同过滤算法:基于用户或物品之间的相似性进行推荐。其中,用户协同过滤(User-based Collaborative Filtering)根据用户之间的相似度来为用户推荐喜欢的电影;物品协同过滤(Item-based Collaborative Filtering)根据电影之间的相似度来为用户推荐类似的电影。常见的相似度度量方法有余弦相似度和皮尔逊相关系数。 2. 内容过滤算法:基于电影的内容特征进行推荐。这些特征可以包括电影的类型、导演、演员、评分等。通过计算用户对这些特征的偏好,来为用户推荐相似的电影。 3. 混合推荐算法:结合协同过滤和内容过滤算法,综合考虑多个因素进行推荐。例如,可以将协同过滤和内容过滤的结果加权融合,或者利用机器学习模型进行综合推荐。 在Python中,可以使用一些开源库来实现电影推荐系统的算法,例如: 1. Surprise:Surprise是一个用于构建和评估推荐系统的Python库,提供了多种经典的协同过滤算法实现,如基于邻域的方法和矩阵分解方法。 2. LightFM:LightFM是一个用于构建混合推荐系统的Python库,支持协同过滤和内容过滤的组合。它提供了一种训练灵活的模型,可以同时考虑用户和物品的特征。 3. scikit-learn:scikit-learn是一个通用的机器学习库,其中包含了各种机器学习算法和工具。可以使用scikit-learn来构建和评估电影推荐系统的机器学习模型。 以上是一些常见的电影推荐系统算法和对应的Python库,你可以根据具体需求选择合适的算法和工具进行实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值