社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
本文所有代码和sql文件,全放在了github上,可自行下载:
https://github.com/8042965/recommenderSystem
几乎每个人都已经在使用了,如果你是一个购物狂你肯定使用过淘宝:
每个人的首页肯定是不一样的,为什么我的首页关于电子产品的比较多,因为我搜索过:
如果你喜欢听音乐:不难发现,也会根据你所听过的歌,给你推荐一些类型相似的歌
如果你喜欢看电视或着电影:
会根据你在看的和历史看的记录,给你推荐一些相似的视频:
如果你经常泡在博客系统或者其他看书的网站会发现也会有推荐:
等等,这些都是推荐,只是推荐的方法不一样。
可以根据用户的特征推荐,也可以根据物品的特征推荐。
这就是传说中的基于用户
的推荐系统和基于物品
的推荐系统。
如下图所示:
从下图中就可以看出来A与D的夹角完全重合了,说明了什么呢?
说明了,这俩相似度高。
再看一下D和B,和D和C;
根据这两对来比较的话,D与B的相似度要比D与C要高。
我们就可以利用这种求夹角的问题
,来解决相似度的问题
。
例子:
例如原来有下面几位朋友,他们的身高和身上带着的金钱分别为:
姓名 | 身高(厘米) | 金钱(元) |
---|---|---|
胡八一 | 185 | 532 |
二龙湖浩哥 | 179 | 550 |
喜洋洋 | 156 | 143 |
东北酒神九哥 | 210 | 340 |
突然有一天来了一个新朋友(假设就是你),名字叫肖能逗
,身高178
,身上带着540
元。
假设现在你已经穿越到了未来,可以一眼就看出来上面的信息,你该去和谁主动交朋友
?
经过一顿很猛的操作,你看出来了二龙湖浩哥
跟你的信息是最接近的,那你就可以去跟浩哥交朋友。
来看这个图:
可以看到肖能逗
与二龙湖浩哥的信息是最贴近的,因为他们的夹角小。所以一定推荐的就是二龙湖浩哥
了。
整个过程是:
利用余弦定理去计算肖能逗
与其余所有人的值
,这个值越小,说明越相似,相似度越高。
如下图:看到此图应该很熟悉了吧,是一个三角形;
我们在求这些夹角时,可以使用如下余弦定理公式:
但是我们只有2个维度的值
,分别为身高
,金钱
,而如上所示的计算夹角的公式,需要三个唯独的值,所以上面这种方式不能满足我们的需求,我们继续推导一下:
继续推导该公式
:
cos(θ)=∣a∣∣b∣a⋅b
向量的点积公式:
a⋅b=x1x2+y1y2
绝对值推导:
∣a∣=a2
把这俩带入到第一个里面,就可以得出:
cos(θ)=x12+y12x22+y22x1x2+y1y2
这样的话,就可以计算出来2个维度的数据了。
但是如果有N个维度的数据该怎么办?
我们继续推导:
这就得出了我们可以求N个数据维度的余弦定理公式。
我们只需要套进去这个公式,就可以求出我们想要的相似度对比数据(也就是夹角的数据)。
cos(θ)=∑i=1n(xi)2×∑i=1n(yi)2∑i=1n(xi×yi)
套公式时,我们需要给出两个数列例如:
当前
用户的:[1,2,3,4,5,6,7]
其他
用户的:[1,5,6,7,8,9,0]
如果是N个用户的话,那就可以把当前用户的数据与其余所有用户的数据都对比一下。
如下图所示,是我使用三组数据做的对比:结果很明显
说是算法,不如说就是计算一个数据。都没毛病。
如下代码所示,就是我用java代码实现的该算法,分别去求一下分子和分母,然后这个最终得出的数据,就是我们最终想要的。
private static Double compare(int[] o1, int[] o2) {
//分子求和
Double fenzi = 0.0 ;
for (int i = 0; i < o1.length; i++) {
fenzi += o1[i]*o2[i];
}
//分母第一部分
Double fenmu1 = 0.0;
for (int i = 0; i < o1.length; i++) {
fenmu1 += o1[i] * o1[i];
}
fenmu1 = Math.sqrt(fenmu1);
//分母第二部分
Double fenmu2 = 0.0;
for (int i = 0; i < o2.length; i++) {
fenmu2 += o2[i] * o2[i];
}
fenmu2 = Math.sqrt(fenmu2);
return fenzi / (fenmu1 * fenmu2);
}
我们就以农产品
为例子,来爬取我们想要的数据。
我们先找出重要的数据:
例如:付款人数
、售价
点进去可以看到,有:评价数量
、收藏人数
我们可以利用python或者其他手段进行爬取数据:
我这里爬去到了70多条:
处理完数据导入数据库之后还剩下40多条数据:
我们还有用户表:
还有订单表
create table member_user
(
USER_ID int(10) auto_increment
primary key,
USER_NAME varchar(20) null
)
engine = MyISAM
charset = utf8;
INSERT INTO testdb.member_user (USER_ID, USER_NAME) VALUES (1, '郑成功');
INSERT INTO testdb.member_user (USER_ID, USER_NAME) VALUES (2, '小红');
INSERT INTO testdb.member_user (USER_ID, USER_NAME) VALUES (7, '小李');
INSERT INTO testdb.member_user (USER_ID, USER_NAME) VALUES (19, '郑晖');
INSERT INTO testdb.member_user (USER_ID, USER_NAME) VALUES (10, '张三');
INSERT INTO testdb.member_user (USER_ID, USER_NAME) VALUES (11, '二龙湖浩哥');
INSERT INTO testdb.member_user (USER_ID, USER_NAME) VALUES (12, '张三炮');
INSERT INTO testdb.member_user (USER_ID, USER_NAME) VALUES (13, '赵四');
INSERT INTO testdb.member_user (USER_ID, USER_NAME) VALUES (14, '刘能');
INSERT INTO testdb.member_user (USER_ID, USER_NAME) VALUES (15, '刘能逗');
create table product_order
(
ORDER_ID int auto_increment
primary key,
USER_ID int not null,
PRODUCT_ID int not null,
GWCOUNT int null,
out_trade_no varchar(100) null
);
INSERT INTO testdb.product_order (ORDER_ID, USER_ID, PRODUCT_ID, GWCOUNT, out_trade_no) VALUES (1, 1, 1, 15, '202001');
INSERT INTO testdb.product_order (ORDER_ID, USER_ID, PRODUCT_ID, GWCOUNT, out_trade_no) VALUES (2, 2, 3, 42, '202002');
INSERT INTO testdb.product_order (ORDER_ID, USER_ID, PRODUCT_ID, GWCOUNT, out_trade_no) VALUES (3, 3, 4, 2, '202003');
INSERT INTO testdb.product_order (ORDER_ID, USER_ID, PRODUCT_ID, GWCOUNT, out_trade_no) VALUES (4, 4, 4, 20, '202004');
INSERT INTO testdb.product_order (ORDER_ID, USER_ID, PRODUCT_ID, GWCOUNT, out_trade_no) VALUES (5, 1, 2, 21, '202005');
INSERT INTO testdb.product_order (ORDER_ID, USER_ID, PRODUCT_ID, GWCOUNT, out_trade_no) VALUES (6, 5, 1, null, null);
INSERT INTO testdb.product_order (ORDER_ID, USER_ID, PRODUCT_ID, GWCOUNT, out_trade_no) VALUES (7, 5, 2, null, null);
INSERT INTO testdb.product_order (ORDER_ID, USER_ID, PRODUCT_ID, GWCOUNT, out_trade_no) VALUES (8, 5, 3, null, null);
INSERT INTO testdb.product_order (ORDER_ID, USER_ID, PRODUCT_ID, GWCOUNT, out_trade_no) VALUES (9, 6, 2, null, null);
INSERT INTO testdb.product_order (ORDER_ID, USER_ID, PRODUCT_ID, GWCOUNT, out_trade_no) VALUES (10, 6, 5, null, null);
INSERT INTO testdb.product_order (ORDER_ID,
版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_17623363/article/details/106745518
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
-
发表于 2020-06-27 21:57:30
- 阅读 ( 1545 )
- 分类:算法
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!