1.自我介绍
2.介绍推荐系统架构
3.LR原理 loss推导
LR是在线性模型的基础上,对特征进行线性组合,在通过sigmoid函数映射成结果是0和1的概率
lnL(w)=∑[yi*wx(i)-ln(1+e^{wx(i)}]
loss=-1/N *lnL(w)
公式推导
二项LR的条件概率如下:
P(Y=1|x)=\frac{e^{w*x}}{1+e^{w*x}}
P(Y=0|x)=\frac{1}{1+e^{w*x}}
事件发生概率为p,时间发生的几率为
odds=\frac{p}{1-p}
取对数几率
log(p)=log\frac{p}{1-p}
对于逻辑回归而言,Y=1的对数几率就是
\log(\frac{P(Y=1|x)}{1-P(Y=1|x)})=wx
常常使用极大似然估计法来求解,即找到一组参数,使得在这组参数下,我们的数据的似然度(概率)最大
设P(Y=1|x)=πx P(Y=0|x)=1-πx
似然函数
L(w)=\prod[π(x_i)^{y_i}][1-π(x_i)^{1-y_i}]
对数似然函数
lnL(w)=\sum[y_i\ln(π(x_i))+(1-y_i)ln(1-π(x_i))]
=\sum[y_i\ln(\frac{π(x_i)}{1-π(x_i)}+\ln(1-π(x_i))]
=\sum[y_i*wx_i-\ln(1+e^{wx_i})]
如果取整个数据集上的平均对数似然损失,我们恰好可以得到:
J(w)=-\frac{1}{N}*lnL(w)
LR如何防止过拟合
- 加入正则项p=1,2,标识L1,L2范数
- 特征降维(PCA,LDA)
LR 为什么使用sigmoid
- 由最大熵推导
- 一般概率都趋于正态分布,sigmoid函数与正态分布相似
LR如何输入非线性特征
- one-hot编码
- FM算法
LR为什么要对连续特征做离散化处理
- 离散特征增加减少都容易,易于模型的快速迭代
- 系数向量的內积乘法运算速度快
- 离散化后的特征对异常数据有更好的鲁棒性
- 简化了LR模型,降低了模型过拟合的风险
4.XGBoost原理
首先说一下GBDT,GBDT是一个boosting算法,每次学习前面t-1颗树的残差
XGBoost进行了一系列优化 比如损失函数进行了二阶泰勒展开、目标函数加入正则项等
决策树原理
决策树是一个树形结构,一套的if else规则,常常用于分类
一个样本进来,经过层层if else规则之后,最终落到哪个叶子结点就属于该类别,决策树由特征选择、树的生成、树的剪枝散步组成
GBDT原理
前向分布的加法模型
loss为mse时候拟合残差
分类树和回归树的区别
CART启发函数{
分类树:gini,
回归:平方差
}
结点值不同:{
分类:存储的是最优分裂特征,
回归:存储的是最佳切分点
}
Xgboost和GBDT的不同:
- 基分类器:XGBoost不仅支持CART决策树,还支持线性分类器
- 导数信息:XGBoost对loss做了二阶泰勒展开
- XGboost对目标函数加了正则项
- XGBoost对缺失值进行了处理
- 并行化:对特征维度的并行。预先将每个特征值排好序,存储为块状结构,分裂节点可以采用多线程并行查找每个特征的最佳分割点
5.spark怎么取平均值
groupByKey
6.map Reduce原理
基础
map
p = re.compile(r'\w+')
# data_path = './data/test.txt'
data_path = './data/The_man_of_property.txt'
with open(data_path,'r', encoding='utf-8') as f:
# for i in range(2):
# print(f.readlines())
for line in f.readlines(): # ['a b c\n', 'c b d']
word_lst = line.strip().split(" ") # ['a', 'b', 'c']
# print(word_lst)
for word in word_lst:
re_word = p.findall(word)
if len(re_word)==0:
continue
word = re_word[0].lower()
print('%s,%s'%(word,1))
reduce
data_path = './data/reduce_test'
cur_word = None # null
sum = 0
with open(data_path,'r', encoding='utf-8') as f:
for line in f.readlines():
word,val = line.strip().split(',')
if cur_word == None:
cur_word = word
if cur_word!=word:
print('%s,%s'%(cur_word,sum))
cur_word=word
sum = 0
sum += int(val) # sum = sum+val
print('%s,%s' % (cur_word, sum))
7.二叉树求最大深度
def find_depth(node):
depth = 0
if node is not None:
depth = 1 + max(find_depth(node.left), find_depth(node.right))
return depth
8.简述CF计算流程
graph TD
计算用户相似度-用余弦公式-->找出前20个相似用户
找出前20个相似用户-->获取相似用户的物品集合
获取相似用户的物品集合-->定义Udf过滤掉相同物品
定义Udf过滤掉相同物品-->计算相似度
计算相似度-->相同物品打分取sum
相同物品打分取sum-->rating后生成推荐列表
计算过程
1.生成CF:{user_id:{item_id:score}}
2.协同过滤(user_CF,item_CF)
3.LR训练得到模型(保存特征映射和模型)
4.加载模型做预估(LR0.3+协同过滤0.7)
9.SVM对比LR
条件 | SVM | LR |
---|---|---|
相同点 | ||
算法类型 | 分类算法 | 分类算法 |
模型特点 | 有监督学习 | 有监督学习 |
模型类别 | 判别模型 | 判别模型 |
不同点 | ||
损失函数 | 1/2w^2+C∑εi | lnL(w)=∑[yi*wx(i)-ln(1+e^{wx(i)}] |
Normalization | 线性SVM是距离度量,需要Normalization | 不需要 |
正则化 | 自带 | 需要额外添加 |
核函数 | 有 | 不用 |
10.K-Means
优点:
- 简单快速
- 对处理大数据,该算法保持可伸缩性和高效性
- 当接近高斯分布时,效果较好
缺点: - K是预先给定的,K的选择难以估计
- 以来初始聚类中心的选择
原理:
将一堆数据聚集为K个簇,每个簇有一个中心点成为均值点
TF-IDF
TF=某词次数/总词数
IDF=log(文档总数/包含该词的文档数+1)
CNN
卷积神经网络(CNN) 属于人工神经网络的一种,它的权重共享的网络结构显著降低了模型的复杂度,减少了权值的数量。卷积神经网络可以直接将图片作为网络的输入,自动提取特征,并且对图片的变形(如平移、比例缩放、倾斜)等具有高度不变形。
局部感知:网络部分连通,每个神经元只和上一层的部分神经元相连,只感知局部,而不是整幅图像
局部像素关系紧密,较远的像素相关性弱,因此只需要局部感知,在更高层将局部的信息综合起来就得到了全局的信息
权值共享:从一个局部区域学习到的信息,应用到图像的其它地方去。即用一个相同的卷积核去卷积整幅图像,不同的特征靠多个不同的卷积核实现
1*1卷积核的作用
- 降维
- 保证feature map 不变的情况下增加非线性
pooling层的作用
- 整合特征,减少计算复杂度
- 对不同位置的特征进行聚合统计
- 卷积窗口有重叠,因此得到的结果有大量冗余,用pooling可以消除冗余,权值共享可以带来评议的不变形
池化层的作用:对输入的特征图进行压缩,一方面使得特征图变小,简化网络计算复杂度,一方面进行特征压缩,提取主要特征
卷积层的作用
- 相当于一个特征提取器来提取特征
- 提供了位置信息
- 减少了参数个数
relu函数的优点
- 防止梯度弥散
- 稀疏激活性(负半轴导数为0,不会更新梯度)
- 加快计算(导数好计算)
代码实现
class CNN(nn.Module):
def __init__(self):
super(CNN, self).__init__()
self.layer1 = nn.Sequential(
nn.Conv2d(1, 16, kernel_size=5, padding=2),#卷积:1 input image channel, 16 output channels, 5x5 square convolution kernel,2 zero padding)
nn.BatchNorm2d(16),#归一化
nn.ReLU(),#非线性激活函数ReLU
nn.MaxPool2d(2))#池化层
self.layer2 = nn.Sequential(
nn.Conv2d(16, 32, kernel_size=5, padding=2),
nn.BatchNorm2d(32),
nn.ReLU(),
nn.MaxPool2d(2))
self.fc = nn.Linear(7*7*32, 10)#全连接层,in_features, out_features, bias=True
def forward(self, x):
out = self.layer1(x)
out = self.layer2(out)
out = out.view(out.size(0), -1)
out = self.fc(out)
return out
# 正常情况下, 我们都会用类进行封装一个网络
cnn = CNN()
Spark相关
1.Spark Streaming+kafka 防止数据丢失
spark RDD 内部机制可以保证数据at-least语义
- Receiver方式:开启WAL(write ahead log)将从kafka接收到的数据写入到日志文件中,所有数据从失败中可恢复
- Direct方式:依靠checkpoint 机制来保证
2.Spark Streaming如何与kafka对接,以及如何保证数据有序
- Receiver方式:将kafka数据读取到Spark内存中,zookeeper管理offset,kafka topic中partition的数目与Spark streaming中partition无关
- Direct方式:调用kafka的低阶API,自己管理offset,kafka topic中partition的数量与Spark rdd中一致
3.kafka的优缺点
优点 | 缺点 |
---|---|
支持broker横向扩展 | 由于批量发送,数据并非真正实时 |
高性能、低延迟 | 监控不完善 |
4.hive优化
- 排序sortBy的效率高于orderby
- 数据倾斜:group by设置hive.group.sviwind=true实现负载均衡
- 小表Join大表
5.python迭代器
- 对象有iter()和next()方法
- 优点:节省内存,缺点:一次性
6.Spark的一些算子
distinct
reduceByKey groupBykey() aggregateByKey()
sortByKey() sortBy()
join
模型跑 4个小时|迭代2000次
4-5万的活跃用户、每天4G左右的数据