推荐系统——前言

来源:互联网 发布:node服务器和appache 编辑:程序博客网 时间:2024/05/19 00:38

用户数据的获取
一般是日志Log , 网页的浏览以及反馈。

用户行为的分析
用户的行为符合:“长尾分布”。

推荐算法
基于用户的协同过滤算法
基于物品的协同过滤算法

数据集
GroupLens提供的MovieLens数据集。
数据集中参数的定义:

    def __init__(self):        self.trainset = {}        self.testset = {}        self.n_sim_user = 20        self.n_rec_movie = 10        self.user_sim_mat = {}        self.movie_popular = {}        self.movie_count = 0        print ('Similar user number = %d' % self.n_sim_user, file=sys.stderr)        print ('recommended movie number = %d' %               self.n_rec_movie, file=sys.stderr)

实验
离线的实验设计一般如下:
将用户行为数据均匀分为M份,挑选一份作为测试集,剩下的M-1作为训练集。在训练集中建立用户的兴趣模型,并在测试机上对用户进行预测,统计相应的指标。为了保证评测指标不是过拟合的结果,需要进行M次试验,取M次的平均值作为最终的指标。

分割代码

@staticmethod    def loadfile(filename):        ''' load a file, return a generator. '''        fp = open(filename, 'r')        for i, line in enumerate(fp):            yield line.strip('\r\n')            if i % 100000 == 0:                print ('loading %s(%s)' % (filename, i), file=sys.stderr)        fp.close()        print ('load %s succ' % filename, file=sys.stderr)    def generate_dataset(self, filename, pivot=0.7):        ''' load rating data and split it to training set and test set '''        trainset_len = 0        testset_len = 0        for line in self.loadfile(filename):            user, movie, rating, _ = line.split('::')            # split the data by pivot            if random.random() < pivot:                self.trainset.setdefault(user, {})                self.trainset[user][movie] = int(rating)                trainset_len += 1            else:                self.testset.setdefault(user, {})                self.testset[user][movie] = int(rating)                testset_len += 1        print ('split training set and test set succ', file=sys.stderr)        print ('train set = %s' % trainset_len, file=sys.stderr)        print ('test set = %s' % testset_len, file=sys.stderr)

评测指标
召回率:recall 多少比例的用户记录包含在推荐列表中

准确率:precision 推荐列表中多少比例是发生记录的

覆盖率:推荐物品中包含多大比例的物品

    def evaluate(self):        ''' print evaluation result: precision, recall, coverage and popularity '''        print ('Evaluation start...', file=sys.stderr)        N = self.n_rec_movie        #  varables for precision and recall        hit = 0        rec_count = 0        test_count = 0        # varables for coverage        all_rec_movies = set()        # varables for popularity        popular_sum = 0        for i, user in enumerate(self.trainset):            if i % 500 == 0:                print ('recommended for %d users' % i, file=sys.stderr)            test_movies = self.testset.get(user, {})            rec_movies = self.recommend(user)            for movie, _ in rec_movies:                if movie in test_movies:                    hit += 1                all_rec_movies.add(movie)                popular_sum += math.log(1 + self.movie_popular[movie])            rec_count += N            test_count += len(test_movies)        precision = hit / (1.0 * rec_count)        recall = hit / (1.0 * test_count)        coverage = len(all_rec_movies) / (1.0 * self.movie_count)        popularity = popular_sum / (1.0 * rec_count)        print ('precision=%.4f\trecall=%.4f\tcoverage=%.4f\tpopularity=%.4f' %               (precision, recall, coverage, popularity), file=sys.stderr)

下一章
下一章我们会给出基于邻域的算法(基于用户和基于物品)

原创粉丝点击