更新、更全的《机器学习》的更新网站,更有python、go、数据结构与算法、爬虫、人工智能教学等着你:https://www.cnblogs.com/nickchen121/p/11686958.html

推荐系统

目前推荐系统被应用于各个领域,例如淘宝的商品推荐、b站的视频推荐、网易云音乐的每日推荐等等,这些都是基于用于往日在平台的行为模式给用户推荐他们可能喜欢的商品、视频、音乐。

下面我们将以电影推荐系统举例,一步一步通过Python实现一个简单的电影推荐系统。

由于数据量的原因,我们可能无法做到精度较高的推荐系统,但是做一个差不多能实现推荐功能的电影推荐系统是完全没有问题的。

一、导入模块

import io
import os
import sys
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
from sklearn.impute import SimpleImputer
from sklearn.metrics.pairwise import cosine_similarity
%matplotlib inline
font = FontProperties(fname='/Library/Fonts/Heiti.ttc')

二、收集数据

早期讲构造机器学习系统的时候说到,我们第一步往往是需要收集数据。

由于本次要做的推荐系统是和电影有关的,而为了给用户推荐他喜欢的电影,一般会收集每个用户对自己看过的电影的评分。这里我们假设用户看完电影一定会给电影评分,并且评分范围为\(\{1,2,3,4,5\}\),即评分最低为1分,最高为5分。如果用户没有评分则意味着用户没有看过该电影。

如果是大型的推荐系统,往往需要通过很多途径获得各种数据,如爬虫、平台合作,并且可能还会考虑用户本身的各种信息,如身高、体重、年龄、兴趣爱好……和电影的各种信息,如篇名、导演、演员阵容、上映时间……,通常这种大型系统针对的数据维度往往都是上万,上十万的。由于数据限制,因此这里只假设用户喜欢看的电影和他对电影的评分有关。

由于这是一个简单的推荐系统版本,所以我们假设我们已经获取了用户对自己看过的电影的评分,即数据在movie.xlsx表格中。

# 收集数据
# 没有表格文件时自定义数据
csv_data = '''
《肖申克的救赎》,《控方证人》,《这个杀手不太冷》,《霸王别姬》,《美丽人生》,《阿甘正传》,《辛德勒的名单》,姓名
,4.0,,4.0,,5.0,,'刘一'
4.0,,5.0,3.0,5.0,,,'陈二'
3.0,4.0,,3.0,2.0,3.0,3.0,'张三'
2.0,3.0,,3.0,,,,'李四'
3.0,4.0,,5.0,3.0,3.0,,'王五'
,,4.0,,4.0,2.0,,'赵六'
3.0,,1.0,5.0,3.0,3.0,2.0,'孙七'
2.0,,2.0,,1.0,,,'周八'
1.0,2.0,,,,2.0,,'吴九'
,5.0,,4.0,,3.0,3.0,'郑十'
'''
if not os.path.exists('datasets/movie.xlsx'):
# 将文件读入内存
csv_data = io.StringIO(csv_data)
df = pd.read_csv(csv_data, header=0)
df.index = df['姓名'].tolist()
else:
# 从表格中获取数据
df = pd.read_excel('datasets/movie.xlsx', header=0)
df.index = df['姓名'].tolist()
df

.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
vertical-align: top;
} .dataframe thead th {
text-align: right;
}
《肖申克的救赎》 《控方证人》 《这个杀手不太冷》 《霸王别姬》 《美丽人生》 《阿甘正传》 《辛德勒的名单》 姓名
刘一 NaN 4.0 NaN 4.0 NaN 5.0 NaN 刘一
陈二 4.0 NaN 5.0 3.0 5.0 NaN NaN 陈二
张三 3.0 4.0 NaN 3.0 2.0 3.0 3.0 张三
李四 2.0 3.0 NaN 3.0 3.0 2.0 NaN 李四
王五 3.0 4.0 NaN 5.0 3.0 3.0 NaN 王五
赵六 NaN NaN 4.0 NaN 4.0 2.0 NaN 赵六
孙七 3.0 NaN 1.0 5.0 3.0 3.0 2.0 孙七
周八 2.0 NaN 2.0 NaN 1.0 NaN 2.0 周八
吴九 1.0 2.0 2.0 NaN 1.0 1.0 NaN 吴九
郑十 NaN 5.0 NaN 4.0 NaN 3.0 3.0 郑十

三、数据预处理

3.1 无评分电影处理

从上述表格中可以看到很多用户有些电影是没有看过的,这相当于数据里的缺失值,《数据预处理》那一篇详细讲到了缺失值的处理,这里不再赘述,在此处可能使用中位数、平均数、众数恐怕都不行。

这种情况的缺失值为用户没有看过此电影,而我们以后推荐电影也定是推荐用户没有看过的电影,如果你把他没有看过的电影就这样轻易只依据大家对电影的平均评分,你就给他推荐电影,这可能并不合理。因此我在这里统一用\(0\)替换所有的没有打分的电影,即\(0\)表示用户没有看过这部电影,然后使用其他算法给用户推荐电影。

# 数据缺失值处理
def imputer_data(np_arr):
# 中位数strategy=median,平均数strategy=mean,众数strategy=most_frequent
imputer = SimpleImputer(missing_values=np.nan,
strategy='constant', fill_value=0)
# 找到用户没有评分的电影
imr = imputer.fit(np_arr.iloc[:, :-1])
# 将用户没有评分的电影评分用0填充
imputed_df = imr.transform(np_arr.iloc[:, :-1]) return imputed_df imputed_df = imputer_data(df)
imputed_df
array([[0., 4., 0., 4., 0., 5., 0.],
[4., 0., 5., 3., 5., 0., 0.],
[3., 4., 0., 3., 2., 3., 3.],
[2., 3., 0., 3., 3., 2., 0.],
[3., 4., 0., 5., 3., 3., 0.],
[0., 0., 4., 0., 4., 2., 0.],
[3., 0., 1., 5., 3., 3., 2.],
[2., 0., 2., 0., 1., 0., 2.],
[1., 2., 2., 0., 1., 1., 0.],
[0., 5., 0., 4., 0., 3., 3.]])

获取了数据并对数据进行了预处理,接下来就是从数据中得到我们想要的信息,然而我们想要获取什么信息呢?

一般我们想要获取两个用户,或两个电影之间的相似度,以下两点将是我们要从数据中获得的信息。

  1. 获取用户之间的相似度,然后基于其他用户算出没看过电影的用户可能会给电影的评分。
  2. 获取相似度最高的电影,然后基于用户看过的电影算出用户可能会给电影的评分。

通过以上两种方式,设定一个评分阈值,如果用户可能会给该电影的评分大于该阈值,则可以放心的给用户推荐电影,反之则不推荐给用户。

四、协同过滤算法-基于用户的推荐

如果我们想要获取用户user_1和用户user_2之间的相似度时,可以考虑使用余弦相似度来评估两者之间的相似度。余弦相似度的取值范围为\((-1,1)\),余弦相似度越大,则用户user_1与用户user_2之间的相似度越大,反之则两者之间的相似度越小。

4.1 余弦相似度

余弦相似度:

\[w_{uv}=\frac{|N(u)\bigcap{N(v)}|}{\sqrt{|N(u)||{N(v)}|}}
\]

# 数据标准化前用户之间的相似度
user_1 = imputed_df[[0]]
user_2 = imputed_df[[1]]
user_8 = imputed_df[[7]]
user_9 = imputed_df[[8]]
print('电影名:{}'.format(df.columns[:-1].values))
print('刘一:{}'.format(user_1))
print('陈二:{}'.format(user_2))
print('周八:{}'.format(user_8))
print('吴九:{}'.format(user_9)) print('刘一和陈二的余弦相似度:{}'.format(cosine_similarity(user_1, user_2)))
print('陈二和周八的余弦相似度:{}'.format(cosine_similarity(user_2, user_8)))
print('周八和吴九的余弦相似度:{}'.format(cosine_similarity(user_8, user_9)))
电影名:['《肖申克的救赎》' '《控方证人》' '《这个杀手不太冷》' '《霸王别姬》' '《美丽人生》' '《阿甘正传》' '《辛德勒的名单》']
刘一:[[0. 4. 0. 4. 0. 5. 0.]]
陈二:[[4. 0. 5. 3. 5. 0. 0.]]
周八:[[2. 0. 2. 0. 1. 0. 2.]]
吴九:[[1. 2. 2. 0. 1. 1. 0.]]
刘一和陈二的余弦相似度:[[0.18353259]]
陈二和周八的余弦相似度:[[0.73658951]]
周八和吴九的余弦相似度:[[0.58536941]]

从上面的输出的结果可以看到

  1. 刘一和陈二只对电影《霸王别姬》都共同评分过,其他的都没有共同评分过,两个人之间有很低的相似度是很正常的。
  2. 陈二和周八虽然对很多电影都共同评分过,但是他们的评分中陈二的评分都是偏高的,而周八都是偏低的,但是两者之间却有着较高的相似度,这明显是不合理的。
  3. 周八和吴九对很多电影都共同评分过,并且两个人的评分都较偏低,但是应该远没有达到\(0.70\)的相似度,一般\(0.70\)的相似度是极高的。

对于上述情况是因为评分为\(0\)在余弦相似度看来是有意义的,也就是较之评分为\(1\)而言评分为\(0\)更差。即余弦相似度认为两个人对某一部电影评分都是\(0\)的话,那两个人给电影评分都很低,两者自然会有很高的相似性,这也是为什么刘一和陈二的相似度很低,而陈二和周八相似度及周八和吴九的相似度都很高的原因。

4.2 数据标准化处理

上一节讲到了余弦相似度可能会把电影评分为\(0\)较于评分\(1\)认为用户可能讨厌某部电影,即把\(0\)变得有意义。然而这部电影评分为\(0\)即用户没有看过此电影,它并无实际意义,即在余弦相似度中的\(0\)是应该是中性,也就说不能通过用户对电影的评分为\(0\)就因此判断用户喜不喜欢这部电影,因此我们需要对数据做标准化处理。

首先考虑的可能是热编码处理,它能够让数据都变成中性,但是热编码之后,用户对其他电影的评分可能也变得没有意义。而其他的标准化处理,如归一化是为了做统一尺度处理。因此我们可以自定义一个标准化的方式。

该自定义的标准化方式是重新生成所有用户的评分,使得用户对所有电影的平均评分为\(0\),这样在用户把用户没有打分的电影设为\(0\)的时候这个\(0\)就成了一个中性值,即\(0\)在余弦相似度看来是中性的。而使得用户的平均评分为\(0\)的方法也很简单,可以对某个用户的非零评分的每一个评分值使用如下公式

\[s_{std}^{(i)} = x^{(i)}-\mu
\]

其中\(x^{(i)}\)表示用户对某部电影的评分,\(\mu\)表示用户对所有电影评分的平均评分。

# 标准化评分
def nonzero_mean(np_arr):
"""计算矩阵内每一行不为0元素的平均数"""
# 找到数组内评分不为0的即非0元素
exist = (np_arr != 0)
# 行非0元素总和
arr_sum = np_arr.sum(axis=1)
# 行非0元素总个数
arr_num = exist.sum(axis=1) return arr_sum/arr_num def standard_data(np_arr):
standardized_df = np_arr.copy()
# 非0元素行下标
nonzero_rows = np.nonzero(np_arr)[0]
# 非0元素列下标
nonzero_columns = np.nonzero(np_arr)[1]
# 非0元素行平均值
nonzero_rows_mean = nonzero_mean(np_arr)
# 遍历并修改所有非0元素
for ind in range(len(nonzero_rows)):
# 第ind个元素的行标和列标确定一个元素
i = nonzero_rows[ind]
j = nonzero_columns[ind]
standardized_df[i, j] = round(
np_arr[i, j]-nonzero_rows_mean[i], 2) return standardized_df standardized_df = standard_data(imputed_df)
# 数据标准化后用户之间的相似度
user_1 = standardized_df[[0]]
user_2 = standardized_df[[1]]
user_8 = standardized_df[[7]]
user_9 = standardized_df[[8]]
print('电影名:{}'.format(df.columns[:-1].values))
print('刘一:{}'.format(user_1))
print('陈二:{}'.format(user_2))
print('周八:{}'.format(user_8))
print('吴九:{}'.format(user_9)) print('刘一和陈二的余弦相似度:{}'.format(cosine_similarity(user_1, user_2)))
print('陈二和周八的余弦相似度:{}'.format(cosine_similarity(user_2, user_8)))
print('周八和吴九的余弦相似度:{}'.format(cosine_similarity(user_8, user_9)))
电影名:['《肖申克的救赎》' '《控方证人》' '《这个杀手不太冷》' '《霸王别姬》' '《美丽人生》' '《阿甘正传》' '《辛德勒的名单》']
刘一:[[ 0. -0.33 0. -0.33 0. 0.67 0. ]]
陈二:[[-0.25 0. 0.75 -1.25 0.75 0. 0. ]]
周八:[[ 0.25 0. 0.25 0. -0.75 0. 0.25]]
吴九:[[-0.4 0.6 0.6 0. -0.4 -0.4 0. ]]
刘一和陈二的余弦相似度:[[0.30464382]]
陈二和周八的余弦相似度:[[-0.3046359]]
周八和吴九的余弦相似度:[[0.36893239]]

从上面输出的结果可以看到刘一和陈二的相似度提高了,并且陈二和周八的相似度明显降低了,这是符合我们心理预期的,由于\(0\)变成了中性,周八和吴九的相似度也有着大幅的降低。

五、预测

上述过程其实我们已经自定义了一个模型,只是这个模型可能并没有用到我们之前学习的传统机器学习算法,他用到的是另一种算法,即一个推荐算法——《协同过滤算法》。

现在我们可以测试我们的模型,当然由于没有真实数据,只能预测某个新用户对某一部他没看过的电影给多少评分。现在假设我们从某个不知名网站弄来了王二麻子和烂谷子对电影的评分,我们可以做一个模型基于上述十个人对电影的评分预测他们会给他们没看过的电影评多少分。

该模型主要是获取某个人如王二麻子观看了所有的电影的评分,然后计算王二麻子与其他所有人之间的余弦相似度,之后通过王二麻子与其他用户的相似度\(*\)相似度对应用户对王二麻子未看电影的评分\(/\)王二麻子与其他用户的总相似度。假设王二麻子与张三的相似度为\(0.2\),与李四的相似度为\(0.6\),王二麻子没看的电影为《霸王别姬》,而张三对《霸王别姬》的评分为\(5\),李四对《霸王别姬》的评分为\(2\),则王二麻子对《霸王别姬》的加权评分为

\[{\frac{0.2*5+0.6*2}{0.2+0.6}}=2.75
\]

# 预测
# 对新数据处理成np.array数组
new_user = '''
1,2,,2,2,2,,王二麻子
2,1,2,,5,1,4,烂谷子
1,2,2,2,3,,4,大芝麻
''' def predict(new_user, similarity_tool='cosine_similarity'):
rating_list = []
movie_list = [] # 对于输入数据为或str和numpy数组做不同的处理
if isinstance(new_user, str):
new_df = pd.read_csv(io.StringIO(new_user), header=None)
else:
new_df = pd.DataFrame(new_user) new_df.columns = ['《肖申克的救赎》', '《控方证人》', '《这个杀手不太冷》',
'《霸王别姬》', '《美丽人生》', '《阿甘正传》', '《辛德勒的名单》', '姓名'] # 填充数据并对数据进行标准化
imputed_new_df = imputer_data(new_df)
standardized_new_user = standard_data(imputed_new_df) # 通过余弦相似度计算预测用户与已有样本之间的相似度
user_similarity_list = []
for ind in range(len(standardized_df)):
user = standardized_df[[ind]]
mod = sys.modules['__main__']
file = getattr(mod, similarity_tool, None)
user_similarity_list.append(cosine_similarity(
user, standardized_new_user)[0]) # 将余弦相似度列表构造成numpy数组方便计算
users_similarity_arr = np.array(user_similarity_list).reshape(
standardized_df.shape[0], standardized_new_user.shape[0]) # 遍历所有用户对她没有评分的电影计算预测评分值
for ind in range(len(new_df)):
empty_rating_ind = []
# 获取名字信息
name = new_df['姓名'][ind]
nonzero_list = np.nonzero(imputed_new_df[[ind], :])[1]
user_similarity_arr = users_similarity_arr[:, [ind]].reshape(1, -1) # 找到预测用户没有评分电影的索引
for j in range(standardized_new_user.shape[1]):
if j not in nonzero_list:
empty_rating_ind.append(j) # 遍历预测用户没有评分的电影计算预测评分值
for rating_ind in empty_rating_ind:
# 计算用户的加权评分总和
user_rating_list = imputed_df[:, rating_ind].reshape(1, -1)
rating_arr = user_similarity_arr*user_rating_list
rating_sum = rating_arr.sum(axis=1)
# 计算用户的总相似度
user_similarity_sum = user_similarity_arr.sum(axis=1) # 当用户总相似度为0时打印提示消息
if rating_sum == 0:
print('亲,{}不怎么看电影我实在无能为力!'.format(name))
else:
rating = rating_sum/user_similarity_sum
print('*{}*可能会给电影{}评分{}'.format(name,
df.columns[:-1].values[rating_ind], round(rating[0], 2)))
# 统计评分
rating_list.append(round(rating[0], 2)) empty_rating_ind = [] return rating_list rating_list = predict(new_user)
*王二麻子*可能会给电影《这个杀手不太冷》评分-0.21
*王二麻子*可能会给电影《辛德勒的名单》评分-0.31
*烂谷子*可能会给电影《霸王别姬》评分2.79
*大芝麻*可能会给电影《阿甘正传》评分3.13

从上面的预测的数据看到,其实预测效果还很不错。

上面讲到了其实还有一种方法,即基于电影(项目)的推荐,即获取相似度较高的电影。流程为计算所有被你评分的电影与你未评分的电影之间的余弦相似度,然后通过与基于用户推荐相同的方法就可以实现电影选择你。实现方法即对上述给出的表格转置然后修改代码中的参数即可,此处不多赘述。

六、测试

l = np.random.randint(0, 6, size=(50, 8))
l[:, [-1]] = 0 rating_list = predict(l)
*0*可能会给电影《这个杀手不太冷》评分0.09
*0*可能会给电影《肖申克的救赎》评分2.59
*0*可能会给电影《控方证人》评分1.9
*0*可能会给电影《肖申克的救赎》评分4.62
*0*可能会给电影《控方证人》评分19.66
*0*可能会给电影《肖申克的救赎》评分3.34
*0*可能会给电影《美丽人生》评分1.26
*0*可能会给电影《阿甘正传》评分9.15
*0*可能会给电影《控方证人》评分0.27
*0*可能会给电影《控方证人》评分2.42
*0*可能会给电影《这个杀手不太冷》评分0.36
*0*可能会给电影《美丽人生》评分3.18
*0*可能会给电影《控方证人》评分0.46
*0*可能会给电影《这个杀手不太冷》评分1.67
*0*可能会给电影《控方证人》评分3.79
*0*可能会给电影《美丽人生》评分2.18
*0*可能会给电影《霸王别姬》评分1.67
*0*可能会给电影《美丽人生》评分2.36
*0*可能会给电影《阿甘正传》评分-1.8
*0*可能会给电影《这个杀手不太冷》评分1.89
*0*可能会给电影《霸王别姬》评分2.5
*0*可能会给电影《辛德勒的名单》评分0.31
*0*可能会给电影《霸王别姬》评分0.87
*0*可能会给电影《美丽人生》评分2.98
*0*可能会给电影《肖申克的救赎》评分1.95
*0*可能会给电影《美丽人生》评分1.37
*0*可能会给电影《肖申克的救赎》评分-0.26
亲,0不怎么看电影我实在无能为力!
亲,0不怎么看电影我实在无能为力!
亲,0不怎么看电影我实在无能为力!
亲,0不怎么看电影我实在无能为力!
*0*可能会给电影《肖申克的救赎》评分2.36
*0*可能会给电影《霸王别姬》评分-6.45
*0*可能会给电影《控方证人》评分1.23
*0*可能会给电影《这个杀手不太冷》评分0.41
*0*可能会给电影《霸王别姬》评分-3.71
*0*可能会给电影《美丽人生》评分1.7
*0*可能会给电影《这个杀手不太冷》评分0.8
*0*可能会给电影《美丽人生》评分1.82
*0*可能会给电影《肖申克的救赎》评分2.37
*0*可能会给电影《这个杀手不太冷》评分-0.43
*0*可能会给电影《霸王别姬》评分1.25
*0*可能会给电影《肖申克的救赎》评分1.73
*0*可能会给电影《这个杀手不太冷》评分1.02
*0*可能会给电影《阿甘正传》评分2.18
*0*可能会给电影《辛德勒的名单》评分-0.66
*0*可能会给电影《美丽人生》评分3.2
*0*可能会给电影《这个杀手不太冷》评分-0.83
*0*可能会给电影《肖申克的救赎》评分2.59
*0*可能会给电影《美丽人生》评分2.14
*0*可能会给电影《辛德勒的名单》评分2.2
*0*可能会给电影《美丽人生》评分2.9
*0*可能会给电影《美丽人生》评分1.86
*0*可能会给电影《阿甘正传》评分0.82
*0*可能会给电影《美丽人生》评分7.91
*0*可能会给电影《控方证人》评分10.1
*0*可能会给电影《这个杀手不太冷》评分-4.76
*0*可能会给电影《这个杀手不太冷》评分9.9
*0*可能会给电影《美丽人生》评分2.69
*0*可能会给电影《辛德勒的名单》评分2.41
*0*可能会给电影《肖申克的救赎》评分2.07
*0*可能会给电影《辛德勒的名单》评分2.55
*0*可能会给电影《肖申克的救赎》评分1.78
*0*可能会给电影《霸王别姬》评分1.12
*0*可能会给电影《肖申克的救赎》评分1.67
*0*可能会给电影《美丽人生》评分1.59
*0*可能会给电影《肖申克的救赎》评分1.7
*0*可能会给电影《这个杀手不太冷》评分3.54
*0*可能会给电影《美丽人生》评分2.0

测试结果可以看出模型其实还行,因为评分过高和无评分的现象很少,即符合正态分布。

C-02 推荐系统的更多相关文章

  1. “猜你喜欢”的背后揭秘--10分钟教你用Python打造推荐系统

    欲直接下载代码文件,关注我们的公众号哦!查看历史消息即可! 话说,最近的瓜实在有点多,从我科校友李雨桐怒锤某男.陈羽凡吸毒被捕.蒋劲夫家暴的三连瓜,到不知知网翟博士,再到邓紫棋解约蜂鸟.王思聪花千芳隔 ...

  2. 基于卷积神经网络CNN的电影推荐系统

    本项目使用文本卷积神经网络,并使用MovieLens数据集完成电影推荐的任务. 推荐系统在日常的网络应用中无处不在,比如网上购物.网上买书.新闻app.社交网络.音乐网站.电影网站等等等等,有人的地方 ...

  3. 文章翻译:Recommending items to more than a billion people(面向十亿级用户的推荐系统)

    Web上数据的增长使得在完整的数据集上使用许多机器学习算法变得更加困难.特别是对于个性化推荐问题,数据采样通常不是一种选择,需要对分布式算法设计进行创新,以便我们能够扩展到这些不断增长的数据集. 协同 ...

  4. 推荐系统之隐语义模型(LFM)

    LFM(latent factor model)隐语义模型,这也是在推荐系统中应用相当普遍的一种模型.那这种模型跟ItemCF或UserCF的不同在于: 对于UserCF,我们可以先计算和目标用户兴趣 ...

  5. 推荐系统之矩阵分解及其Python代码实现

    有如下R(5,4)的打分矩阵:(“-”表示用户没有打分) 其中打分矩阵R(n,m)是n行和m列,n表示user个数,m行表示item个数 那么,如何根据目前的矩阵R(5,4)如何对未打分的商品进行评分 ...

  6. Comprehensive Guide to build a Recommendation Engine from scratch (in Python) / 从0开始搭建推荐系统

    https://www.analyticsvidhya.com/blog/2018/06/comprehensive-guide-recommendation-engine-python/, 一篇详细 ...

  7. 推荐系统之隐语义模型LFM

    LFM(latent factor model)隐语义模型,这也是在推荐系统中应用相当普遍的一种模型.那这种模型跟ItemCF或UserCF的不同在于: 对于UserCF,我们可以先计算和目标用户兴趣 ...

  8. 基于baseline、svd和stochastic gradient descent的个性化推荐系统

    文章主要介绍的是koren 08年发的论文[1],  2.3部分内容(其余部分会陆续补充上来).koren论文中用到netflix 数据集, 过于大, 在普通的pc机上运行时间很长很长.考虑到写文章目 ...

  9. 推荐系统--隐语义模型LFM

    主要介绍 隐语义模型 LFM(latent factor model). 隐语义模型最早在文本挖掘领域被提出,用于找到文本的隐含语义,相关名词有 LSI.pLSA.LDA 等.在推荐领域,隐语义模型也 ...

随机推荐

  1. JS-特效 ~ 03. 楼层跳跃、事件对象event的获取与使用、event的主要内容、screenX、pageX、clientX的区别、放大镜、模拟滚动条

    楼层跳跃 100%子盒子会继承父盒子的宽高.父盒子继承body宽高.Body继承html的宽高. 盒子属性:auto:适应盒子自身的宽度或者高度.(对自己负责) 盒子属性:100%:适应盒子父盒子的宽 ...

  2. 使用dig/nslookup命令查看dns解析详情

    dig-DNS lookup utility 当域名出现访问故障时,可通过域名解析来判断是否有错误的解析导致的问题. 可以看到有请求段和应答段,最后解析出的A记录有两条 dig命令做迭代查询 dig ...

  3. android小工具-系统音量管理器

    简介:调节系统音量的小工具,能够快捷的调节系统铃声,媒体音乐.闹钟和通话声音.你可能会想,手机自带的音量键还不够快捷吗?还得写个程序?首先,用音量键调音只能调节一种声音,像闹钟这种声音不能直接调.其次 ...

  4. Android 网络通信框架Volley(一)

    转自:http://blog.csdn.net/t12x3456/article/details/9221611 1. 什么是Volley 在这之前,我们在程序中需要和网络通信的时候,大体使用的东西莫 ...

  5. JSP实例:彩色验证码

    本例使用一个JavaBean,名为Image.java,包com.zempty.bean下; 三个JSP文件,分别为image.jsp.login.jsp.check.jsp.其中login.jsp是 ...

  6. 前端 页面加载完成事件 - onload,五种写法

    在js和jquery使用中,经常使用到页面加载完成后执行某一方法.通过整理,大概是五种方式(其中有的只是书写方式不一样). 1:使用jQuery的$(function){}; 2:使用jquery的$ ...

  7. selenium WebDriver 截取网站的验证码

    在做爬虫项目的时候,有时候会遇到验证码的问题,由于某些网站的验证码是动态生成的,即使是同一个链接,在不同的时间访问可能产生不同的验证码, 一 刚开始的思路就是打开这个验证码的链接,然后通过java代码 ...

  8. maven引入本地jar包的方法

    maven作为包管理工具,好处不必多说 但是有些情况,比如需要引入第三方包,如快递鸟,支付宝,微信等jar包(当然有可能直接提供maven依赖) 如果直接下载到本地之后,怎么整合到自己的maven工程 ...

  9. 个人微信Hook-C#Demo开发SDK

    目录 基础信息类 好友操作 群操作类 发送信息 接收信息 Demo源码 基础信息类 获取个人信息 从网络获取群成员信息 从网络获取个人信息 获取公众号信息 获取群组信息 获取群成员信息 获取单个好友信 ...

  10. SpringBoot的注解注入功能移植到.Net平台(开源)

    *:first-child { margin-top: 0 !important; } .markdown-body>*:last-child { margin-bottom: 0 !impor ...