基线(Baseline)

在计算机术语中,基线(Baseline)是软件文档或源码(或其它产出物)的一个稳定版本,它是进一步开发的基础。

关于基线可以从以下两个方面来理解:

1)代表多个源代码文件的一组稳定版本。 比如有三个文件,aaa.c、bbb.c和ccc.h。可以对这三个文件做一个基线,取aaa.c的版本1.1,取bbb.c的版本1.3,取ccc.h的版本1.0。(1.1,1.3,1.0)就是一个基线。

2)代表文档的一个稳定状态。 比如有一个项目设计文档,当设计基本完成,开发即将开始的时候,需要把这个文档固定下来,内容不能再频繁改变,否则开发人员就无所适从了,可能导致每个人所参照的文档并不是同一个文档。 一个文档如果经过讨论被通过了,被固定了,就可以说这个文档被“基线化”了,然后所有人就可以在这个“基线”的基础上工作。

基线是项目储存库中每个工件版本在特定时期的一个“快照”。它提供一个正式标准,随后的工作基于此标准,并且只有经过授权后才能变更这个标准。建立一个初始基线后,以后每次对其进行的变更都将记录为一个差值,直到建成下一个基线。

KNNBaseline的官方说明

class surprise.prediction_algorithms.knns.KNNBaseline

KNNBaseline算法在电影推荐的应用例子

1
2
3
4
5
6
7
from __future__ import (absolute_import, division, print_function, unicode_literals)
import os
import io
from surprise import KNNBaseline
from surprise import Dataset,Reader

import logging
1
2
3
logging.basicConfig(level=logging.INFO,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
datefmt='%a, %d %b %Y %H:%M:%S')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
def getSimModle():
# Load the movielens‐100k dataset
file_path = os.path.expanduser('./u.data')
# 告诉文本阅读器,文本的格式是怎么样的
#定义一个Reader对象来解析文件或数据框
reader = Reader(line_format='user item rating timestamp', sep='\t')
#从用户文件加载数据文件
data = Dataset.load_from_file(file_path, reader)
#获取训练集,这里取数据集全部数据
trainset = data.build_full_trainset()
#使用pearson_baseline方式计算相似度 False以item为基准计算相似度 本例为电影之间的相似度
# Surprise中基于近邻的方法(协同过滤)可以设定不同的度量准则。具体如下:
# 1:cosine 用户(items)之间的cosine相似度
# 2:msd 用户(items)之间的均方差误差
# 3:pearson 用户(items)之间的皮尔逊相关系数
# 4:pearson_baseline 计算用户(item)之间的(缩小的)皮尔逊相关系数,使用基准值进行居中而不是平均值。
sim_options = {'name': 'pearson_baseline', 'user_based': False}
bsl_options = {'method': 'als', #sgd 随机梯度下降法 #als交替最小二乘法
'n_epochs': 20,
}
#使用KNNBaseline算法
#一种基本的协同过滤算法
# k(int):要考虑的(最大)邻居数聚合。默认为40个
# min_k(int):他要考虑的邻居的最少数量聚合,如果没有足够的邻居聚合,设置为零(因此预测结果相当于基线)。默认值为“1”。
# sim_options:相似性度量的选项字典
# bsl_options:基线估计的选项字典计算
algo = KNNBaseline(40,1,sim_options=sim_options,bsl_options=bsl_options)
#训练模型
algo.fit(trainset)
return algo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 获取id到name的互相映射  步骤:2
def read_item_names():
"""
获取电影名到电影id 和 电影id到电影名的映射
"""
#os.path.expanduser(path) 把path中包含的"~"和"~user"转换成用户目录
file_name = (os.path.expanduser('.') +'/u.item')
rid_to_name = {}
name_to_rid = {}
with io.open(file_name, 'r', encoding='ISO-8859-1') as f:
for line in f:
line = line.split('|')
rid_to_name[line[0]] = line[1]
name_to_rid[line[1]] = line[0]
return rid_to_name, name_to_rid
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 基于之前训练的模型 进行相关电影的推荐  步骤:3
def showSimilarMovies(algo, rid_to_name, name_to_rid):
# 获得电影Toy Story (1995)的raw_id
toy_story_raw_id = name_to_rid['Beauty and the Beast (1991)'] #Beauty and the Beast(1991) 或 Toy Story (1995)
logging.debug('raw_id=' + toy_story_raw_id)
#把电影的raw_id转换为模型的内部id
toy_story_inner_id = algo.trainset.to_inner_iid(toy_story_raw_id)
#将信息打印到控制台上
logging.debug('inner_id=' + str(toy_story_inner_id))
#通过模型获取推荐电影 这里设置的是10部
toy_story_neighbors = algo.get_neighbors(toy_story_inner_id, 10)
logging.debug('neighbors_ids=' + str(toy_story_neighbors))
#模型内部id转换为实际电影id
#列表表达式
neighbors_raw_ids = [algo.trainset.to_raw_iid(inner_id) for inner_id in toy_story_neighbors]
#通过电影id列表 或得电影推荐列表
neighbors_movies = [rid_to_name[raw_id] for raw_id in neighbors_raw_ids]
print('The 10 nearest neighbors of Toy Story are:')
for movie in neighbors_movies:
print(movie)
if __name__=="__main__":
# 获取id到name的互相映射
rid_to_name, name_to_rid = read_item_names()

# 训练推荐模型
algo = getSimModle()

##显示相关电影
showSimilarMovies(algo, rid_to_name, name_to_rid)

运行结果:

Estimating biases using als...
Computing the pearson_baseline similarity matrix...
Done computing similarity matrix.
The 10 nearest neighbors of Toy Story are:
Lion King, The (1994)
Toy Story (1995)
Cinderella (1950)
Hunchback of Notre Dame, The (1996)
Sound of Music, The (1965)
Clueless (1995)
Aladdin (1992)
E.T. the Extra-Terrestrial (1982)
Winnie the Pooh and the Blustery Day (1968)
Ghost (1990)

参考文章:
Surprise库使用KNNBaseline算法进行电影推荐