m0_56062032 2024-03-13 21:32 采纳率: 68%
浏览 1
已结题

推荐算法的评估怎样得出

基于协同过滤的电影推荐研究,用协同过滤做出了算法得到了结果,但是评估是怎样得出的呢?准确率,召回率,F1是怎样得到的数据呢?


import pandas as pd 
import numpy as np
import warnings
warnings.filterwarnings('ignore')#控制警告
#读入数据
df = pd.read_csv('D:/Datamovies/ml-100k/u.data', sep='\t',names=['user_id','item_id','rating','titmestamp'])
# df = pd.read_csv('u.data', sep='\t',names=['用户id','电影id','评价','时间戳'])
df.head()
#读入电影数据 主要是想要其电影标题
movie_titles = pd.read_csv('D:/Datamovies/ml-100k/u.item',sep='|',encoding='ISO-8859-1',header=None)
movie_titles.rename(columns = {0: "item_id", 1:"title"},  inplace=True)
movie_titles.head()
df1 = pd.merge(df, movie_titles[['item_id','title']], on='item_id')
df1.head()
# 将df转为user_matrix

#数据的离差标准化(把数据映射到[0,1]),df1['rating']进行标准化
def MinMaxScale(data):
    data = (data-data.min())/(data.max()-data.min())
    return data

def df_to_userma(df):
    user_matrix1 = df.pivot_table(index='user_id', columns='title', values='rating')
    return user_matrix1

def userma_to_num(df):
    m = df['user_id'].max() #用户最大数量,考虑id从0开始,所有+1
    n=df['item_id'].max() #电影最大数量
    df.sort_values(by=['user_id', 'item_id'],inplace=True)
    user_matrix_num = np.zeros((m, n))#创建一个数值矩阵,其大小为用户数乘以电影数
    for line in df.itertuples():
        user_matrix_num[int(line[1])-1, int(line[2])-1] = line[3]
    return user_matrix_num

# 返回用户数组
def userid_num(user_matrix):
    user= user_matrix.index
    return user

#返回电影标题数组
def title_num(user_matrix):
    title= user_matrix.columns
    return title

#创建评分记录矩阵record,含有评分记录为1,否则为0
def record_num(user_matrix_num):
    record = user_matrix_num>0 # 出来为布尔值
    record  = np.array(record,dtype=int) #布尔值转为整型
    return record

# 1.相关度计算(皮尔逊)并对缺失值进行填充和将其转换为numpy数组
def data_handling(user_matrix):
    user_pearson= user_matrix.T.corr(method='pearson')
    user_pearson = user_pearson.fillna(0)
    user_pearson_num=user_pearson.to_numpy()
    return user_pearson_num

# 2.预测推荐分
def predict(ratings, similarity):
    record = record_num(ratings)
    m,n = ratings.shape #m代表电影数量,n代表用户数量
    mean_user_rating = np.zeros((m,1)) #用户每部电影的平均得分
    for i in range(m):
        idx = record[i,:]!=0  #每部电影的评分,[i,:]表示每一行的所有列
        mean_user_rating[i] = np.mean(ratings[i,idx]) #第i行,评价分idx的平均得分
    ratings_diff = (ratings - mean_user_rating)# 列中每一个元素减去平均数0
    pred = mean_user_rating + similarity.dot(ratings_diff) / np.array([np.abs(similarity).sum(axis=0)]).T
    return pred
import heapq
def main():
    df1['rating'] = MinMaxScale(df1['rating'])
    user_matrix1 = df_to_userma(df1)
    user_matrix_num = userma_to_num(df1)
    # print(user_matrix_num)
    title = title_num(user_matrix1)
    # user_matrix_num = fillna_numpy(user_matrix)
    user_pearson_num = data_handling(pd.DataFrame(user_matrix_num))
    user_prediction = predict(user_matrix_num, user_pearson_num)
    # print(user_prediction)
    while True:
        userid = int(input("请输入用户id(如:3):"))
        while userid not in range(0,944):
            userid = int(input("抱歉您输入的用户id不存在:"))
        if userid == 0:
            print("感谢使用")
            break
        n = 10
        a = user_prediction[:,userid]
        max_indexs = heapq.nlargest(n, range(len(a)), a.take)
        print('已为用户id为{}用户推荐以下十部电影:'.format(userid))
        k=0
        for i in max_indexs:
            k=k+1
            print('{}.{},推荐值为:{}'.format(k,title[i],user_prediction[:,userid][i]))
        print()
    
main()
# print(f"a={a}")#皮尔逊衡量向量相似度
  • 写回答

3条回答 默认 最新

  • GISer Liu 2024-03-13 22:13
    关注

    该回答引用自GPT-3.5,由博主GISer Liu编写:

    首先,要评估基于协同过滤的电影推荐算法的性能,常用的指标包括准确率、召回率和F1值。这些指标可以通过对算法进行交叉验证或者在测试集上进行评估来得到。
    在你的代码中,似乎并没有明确的评估部分。我将为你添加一个简单的评估函数,以计算准确率、召回率和F1值。首先,我们需要一个测试集,可以从你的数据中分割出一部分作为测试集。然后,我们使用推荐算法生成推荐列表,并将推荐结果与测试集中的实际用户喜好进行比较,从而计算评估指标。
    以下是代码的修改部分,用于添加评估函数:
    pythonCopy code

    def evaluate_recommendations(test_set, user_matrix_num, user_pearson_num, user_prediction, k=10):
    TP = 0  # True Positives
    FP = 0  # False Positives
    FN = 0  # False Negatives
    for user_id in test_set.index:
    # Generate recommendations
    recommendations = recommend_movies(user_id, user_matrix_num, user_pearson_num, user_prediction, k)
    # Get actual liked movies from test set
    actual_liked_movies = test_set.loc[user_id][test_set.loc[user_id] > 0].index.tolist()
    for movie_id in recommendations:
    if movie_id in actual_liked_movies:
    TP += 1
    else:
    FP += 1
    for movie_id in actual_liked_movies:
    if movie_id not in recommendations:
    FN += 1
    precision = TP / (TP + FP)
    recall = TP / (TP + FN)
    f1_score = 2 * (precision * recall) / (precision + recall)
    return precision, recall, f1_score
    def recommend_movies(user_id, user_matrix_num, user_pearson_num, user_prediction, k=10):
    a = user_prediction[:, user_id]
    max_indexs = heapq.nlargest(k, range(len(a)), a.take)
    return max_indexs
    def main():
    # Your existing code here...
    # Splitting data into training and testing sets (80% train, 20% test)
    train_set = df1.sample(frac=0.8, random_state=42)
    test_set = df1.drop(train_set.index)
    # Preprocessing...
    # Training the model...
    # Generate recommendations and evaluate
    precision, recall, f1_score = evaluate_recommendations(test_set, user_matrix_num, user_pearson_num, user_prediction)
    print("Precision:", precision)
    print("Recall:", recall)
    print("F1 Score:", f1_score)
    if __name__ == "__main__":
    main()
    

    在上述代码中,我添加了evaluate_recommendations函数,用于评估推荐结果的准确率、召回率和F1值。然后在main函数中,将数据分为训练集和测试集,并调用evaluate_recommendations函数进行评估。
    需要注意的是,recommend_movies函数用于生成推荐列表,这里直接使用了你已经编写的推荐逻辑。评估函数evaluate_recommendations则会根据生成的推荐列表和测试集中的实际用户喜好来计算评估指标。

    如果该回答解决了您的问题,请采纳!如果没有,请参考以下方案进行修订

    用户答题指南

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 3月21日
  • 已采纳回答 3月13日
  • 创建了问题 3月13日