零、项目提问
0.1 用户画像
首先是离线处理部分:获取数据:爬取数据后画像处理。
MongoDB中的用户画像,来自mysql中的用户注册表和用户日志数据(如阅读量、点赞数、收藏数等)。
用户画像和物品画像,物料存入MongoDB中的SinaNews数据库中;这里我们用MongoDB是因为其文档类似于JSON对象,增删字段非常方便。
处理完的物料会存入redis中(直接从MongoDB拉去会比较卡)。离线将推荐列表和热门列表存入redis。前端展示。
PS:这里为了方便搭建,数据并不是实时在线获得,但是每晚固定时间会爬取数据。
阅读:利用AI构建动态用户画像的七步法
0.2 负责的模块
数据清洗,算法模型等。
0.3 冷启动问题
根据以下思维导图进行分析该问题:
一、机器学习算法
1.0 随机森林的随机性体现在哪里
随机森林中的随机主要来自三个方面:
其一为bootstrap抽样导致的训练集随机性,
其二为每个节点随机选取特征子集进行不纯度计算的随机性,
其三为当使用随机分割点选取时产生的随机性(此时的随机森林又被称为Extremely Randomized Trees)。
1.1 GBDT和随机森林区别
(一)GBDT=决策树+AdaBoost集成学习。GBDT是利用残差训练的(用负梯度去拟合残差),在预测的过程中,我们也需要把所有树的预测值加起来,得到最终的预测结果。
(二)随机森林是以决策树(常用CART树)为基学习器的bagging算法。
(1)随机森林当处理回归问题时,输出值为各学习器的均值;
(2)随机森林当处理分类问题时有两种策略:
第一种是原始论文中使用的投票策略,即每个学习器输出一个类别,返回最高预测频率的类别;
第二种是sklearn中采用的概率聚合策略,即通过各个学习器输出的概率分布先计算样本属于某个类别的平均概率,在对平均的概率分布取 a r g m a x argmaxargmax 以输出最可能的类别。
1.2 bagging和boosting区别
基分类器的错误 = 偏差 + 方差
Boosting通过逐步聚集基分类器分错的样本,减少集成分类器的偏差;训练好一个弱分类器后,计算其错误或残差,作为下一个分类器的输入——该过程在不断减小损失函数,使模型不断逼近“靶心”。
Bagging通过分而治之的策略,通过对训练样本多次采用,综合决策多个训练出来的模型,来减少集成分类器的方差。 有点不严谨地说,对n个独立不相关的模型的预测结果取平均, 方差是原来单个模型的1/n。
二、推荐算法
(1)NeuralCF训练过程,采样过程。
(2)为啥DIN要引入注意力机制。
其中DeepFM模型:
三、Python基础
3.1 Python内存管理机制
不可变对象:数字 字符串 元组 ;可变对象:字典 列表 字节数组。
不可变对象包括int,float,long,str,tuple等
对于不可变类型的变量,如果要更改变量,则会创建一个新值,把变量绑定到新值上,而旧值如果没有被引用就等待垃圾回收。
Python垃圾回收主要以引用计数为主,缺点:不能解决对象的“循环引用”、需要额外空间维护引用计数
以下四种情况,对象的引用计数+1:
对象被创建(a=11)、对象被引用(b=a)、对象被作为参数传到函数中 func(a)、对象作为一个元素存储在容器中(如lst1=[a,a])
以下四种情况,对象的引用计数-1:
对象的别名被显式销毁 del a、对象的别名被赋予新的对象 a=66、一个对象离开其作用域(如fun函数执行完,fun里的局部变量,注意全局变量不会),对象所在的容器被销毁或从容器中删除对象
#!/usr/bin/python ## -*- coding: utf-8 -*- import sys def func(c): print ('in func function',sys.getrefcount(c)-1) print ('init',sys.getrefcount(11)-1) a=11 print ('after a=11----',sys.getrefcount(11)-1) b=a print ('after b=a----',sys.getrefcount(11)-1) func(11) #调用函数中是+2:另一个引用是函数栈保存了入参对形参的引用 print ('after func(11)----',sys.getrefcount(11)-1) lst1=[a,12,14] print ('after lst1=[a,12,14]----',sys.getrefcount(11)-1) a=666 print ('after a=666----',sys.getrefcount(11)-1) del a print ('after del a----',sys.getrefcount(11)-1) del b print ('after del b----',sys.getrefcount(11)-1) del lst1 print ('after del lst1----',sys.getrefcount(11)-1)
结果为
init 50 after a=11---- 51 after b=a---- 52 in func function 54 after func(11)---- 52 after lst1=[a,12,14]---- 53 after a=666---- 52 after del a---- 52 after del b---- 51 after del lst1---- 50
四、Redis相关
4.1 redis中××的源码实现
第一阶段:阅读Redis的数据结构部分
基本位于如下文件中:内存分配 zmalloc.c和zmalloc.h
动态字符串 sds.h和sds.c
双端链表 adlist.c和adlist.h
字典 dict.h和dict.c
跳跃表 server.h文件里面关于zskiplist结构和zskiplistNode结构,以及t_zset.c中所有zsl开头的函数,比如 zslCreate、zslInsert、zslDeleteNode等等。
基数统计 hyperloglog.c 中的 hllhdr 结构, 以及所有以 hll 开头的函数
第二阶段:熟悉Redis的内存编码结构
整数集合数据结构 intset.h和intset.c
压缩列表数据结构 ziplist.h和ziplist.c
第三阶段:熟悉Redis数据类型的实现
对象系统 object.c
字符串键 t_string.c
列表建 t_list.c
散列键 t_hash.c
集合键 t_set.c
有序集合键 t_zset.c中除 zsl 开头的函数之外的所有函数
HyperLogLog键 hyperloglog.c中所有以pf开头的函数
第四阶段 熟悉Redis数据库的实现
数据库实现 redis.h文件中的redisDb结构,以及db.c文件
通知功能 notify.c
RDB持久化 rdb.c
AOF持久化 aof.c
以及一些独立功能模块的实现
发布和订阅 redis.h文件的pubsubPattern结构,以及pubsub.c文件
事务 redis.h文件的multiState结构以及multiCmd结构,multi.c文件
第五阶段 熟悉客户端和服务器端的代码实现
事件处理模块 ae.c/ae_epoll.c/ae_evport.c/ae_kqueue.c/ae_select.c
网路链接库 anet.c和networking.c
服务器端 redis.c
客户端 redis-cli.c
这个时候可以阅读下面的独立功能模块的代码实现
lua脚本 scripting.c
慢查询 slowlog.c
监视 monitor.c
第六阶段 这一阶段主要是熟悉Redis多机部分的代码实现
复制功能 replication.c
Redis Sentinel sentinel.c
集群 cluster.c