Skip to content

Latest commit

 

History

History
163 lines (141 loc) · 8.75 KB

Interview.md

File metadata and controls

163 lines (141 loc) · 8.75 KB

ML&DL

常见激活函数

  • sigmoid和softmax
    sigmoid只做值非线性变化映射到(0,1),用于二分类。
    softMax变化过程计算所有结果的权重,使得多值输出的概率和为1。用于多分类。指数运算速度慢。
  • tanh函数
    双曲正切函数。以0为中心,有归一化的作用。会产生梯度消失。
  • ReLu和Leaky ReLu
    大于0为1,小于0为0,计算速度快。
    leaky输入为负时,梯度仍有值,避免死掉。

优化器

  • 梯度下降法(gradient descent)
    GD, SGD, BSGD
    缺点
    如果学习率过小,收敛速度很慢。如果学习率过大,不收敛,即在极值点附近振荡。
    模型所有的参数每次更新都是使用相同的学习速率。
    陷入局部最小值和鞍点。

  • Momentum
    为了解决随机梯度下降上下波动,收敛速度慢的问题,提出了Momentum优化算法,基于SGD的,简单理解,就是为了防止波动,取前几次波动的平均值当做这次的W。
    缺点
    依旧使用同一学习率alpha,比较难学习一个较好的学习率。

  • Adagrad
    Adagrad在每一个更新步骤中对于每一个模型参数θi使用不同的学习速率ηi。Gt∈Rd×d是一个对角矩阵,其中第i行的对角元素eii为过去到当前第i个参数θi的梯度的平方和,epsilon是一个平滑参数,为了使得分母不为0。
    缺点
    梯度衰减问题,Gt是不断增加的,导致学习率不断衰减,最终变得非常小。

  • RMSprop
    RMSprop使用指数加权平均来代替历史梯度的平方和,RMSprop对梯度较大的方向减小其学习速率,相反的,在梯度较小的方向上增加其学习速率。
    缺点
    仍然需要全局学习率:n

  • Adam
    Adam是Momentum 和 RMSprop的结合,能有效适用于不同神经网络。是目前最常用的优化方法。

  • 选择方法:
    数据量小可以用SGD。
    稀疏数据则选择自适应学习率的算法;而且,只需设定初始学习率而不用再调整即很可能实现最好效果。
    Adagrad, (Adadelta, RMSprop), Adam可以视为一类算法。RMSprop 与 Adadelta本质相同,都是为了解决Adagrad的学习率消失问题。
    目前来看,无脑用 Adam 似乎已经是最佳选择

决策树剪枝

  • 预剪枝:提前结束决策树的增长,类别数量、方差减少,性能提升
  • 后剪枝:决策树生长完成之后再进行剪枝

数据分箱方法

  • 等距离(宽)
  • 等频率(深)
  • 卡方分箱(有监督)

随机森林

  • 常见调参:
    n_estimators: 森林中决策树的个数,默认是10
    criterion:度量分裂质量,信息熵或者基尼指数
    max_features:特征数达到多大时进行分割
    max_depth: 树的最大深度
    min_samples_split: 分割内部节点所需的最少样本数量
    bootstrap: 是否采用有放回式的抽样方式
    min_impurity_split:树增长停止的阀值

XGBoost

  • 特征重要性的评估:损失函数在特征分裂前后的平均增益
  • XGB的分裂准则:损失函数增益最大化
  • XGB常用调参:
    n_estimators: 迭代次数,子树的数量
    max_depth、min_child_weigh:树深,孩子节点最小样本权重和
    gamma、alpha、lambda:后剪枝比例,L1,L2正则化系数
    subsample、colsample_bytree:样本采样、列采样
    eta: 削减已学树的影响,为后面学习腾空间
    tree_method:gpu_histGPU 加速

LightGBM

  • 常用调参:
    num_iterations、learning_rate:迭代次数,学习率
    max_depth、min_data_in_leaf、num_leaves:控制树的大小
    lambda_l1、lambda_l2、min_split_gain:L1、L2、最小切分
    feature_fraction、bagging_fraction:随机采样特征和数据
    device:GPU

XGBoost与GBDT的区别是什么?

  • XGBoost加入了R2正则化项;
  • XGBoost生成CART树考虑了树的复杂度,GDBT未考虑;
  • XGB支持线性分类器做基分类器;
  • XGBoost是拟合上一轮损失函数的二阶导展开,GDBT是拟合上一轮损失函数的一阶导展开,因此XGBoost的准确性更高,且满足相同的训练效果需要的迭代次数更少;
  • 寻找分割点时不考虑缺失值。分别计算缺失值在左右的增益,默认在右。
  • XGboost计算特征增益时支持并行计算,GBDT只能串行计算。
  • 节点分裂方式不同,GBDT是基尼系数,XGB是Gain。
  • 近似直方图算法:采用加权分位数法来搜索近似最优分裂点。
  • Shrinkage(缩减):将学习到的模型 * 系数,削减已学模型的权重。
  • XGBoost里面有类似于随机森林的随机特征采样。

LightGBM与XGBoost的区别

LightGBM是基于XGBoost进行修改的,

  • 节点分裂准则:XGB一次分裂一层节点(浪费),LGB深度优先分裂(过拟合);
  • 决策树算法:基于histogram直方图分箱操作,减少了分裂点数;
  • 直接支持类别特征,无需独热操作;
  • 特征并行,数据并行;
  • 基于梯度的单边采样法,减少了样本数(保留了梯度较大的样本,对梯度较小的样本随机采样);
  • 互斥特征捆绑,用一个特征代替多个互斥特征。

SVM

  • 为什么要转化成对偶形式
    方便核函数的引入(转化后为支持向量内积计算,核函数可以在低维中计算高维的内积),改变复杂度(求W变成求a(支持向量数量))。
  • SVM的超参
    C和gamma,C正则系数,gamma决定支持向量的数量。
  • SVM的核函数
    有效性:核函数矩阵KK是对称半正定矩阵
    常见核函数:线性核函数,多项式核函数,高斯核函数,指数核函数
    区别:线性简单,可解释性强,只用于线性可分问题。多项式可解决非线性,参数太多。高斯只需要一个参数,计算慢,容易过拟合。
    选择方式: 特征维数高选择线性核, 样本数量可观、特征少选择高斯核(非线性核), 样本数量非常多选择线性核(避免造成庞大的计算量)。

Other

DNS(Domain Name System)

是一个分布式数据库,提供了主机名和 IP 地址之间相互转换的服务(域名解析)。这里的分布式数据库是指,每个站点只保留它自己的那部分数据。
域名具有层次结构,从上到下依次为:根域名、顶级域名、二级域名。
DNS 可以使用 UDP 或者 TCP 进行传输,大多数情况下使用 UDP 进行传输,必须自己处理超时和重传从而保证可靠性。

CDN(Content Delivery Network)

是构建在现有网络基础之上的智能虚拟网络,依靠部署在各地的边缘服务器(缓存),通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度 优势:
(1)相同的访问对象和页面缓存在本地,无需占用骨干网带宽,减少带宽需求量;
(2)网络加速,解决由于用户访问量大造成的服务器过载问题;
(3)能克服网站分布不均的问题,能降低网站自身建设和维护成本;   (4)提高网络访问的稳定性。

Python装饰器

本质上就是一个函数,他可以使别的函数在不变动代码的情况下增加其它功能,极大地实现了代码复用,装饰器返回的是一个函数对象(面向函数编程)。适用场景:插入日志、’性能测试、缓存、权限校验等场景。

Python深拷贝浅拷贝区别:

他们本质的区别是拷贝出来的对象的地址是否和原对象一样(复制地址还是复制值),可变对象拷贝后指向原地址(量子纠缠),不可变对象拷贝后指向不同地址(双胞胎)。浅拷贝只改变浅层数据结构的地址,内部别的可变对象还是指向原地址,所以一旦修改了新对象里的可变对象,原可变对象的值也被修改了。
不可变对象:int,float,long,str,unicode,tuple
可变对象:list

a = [1,2,{3:4}]  
b = a    # 简单赋值,地址不变  
c = a.copy()    # 浅拷贝,只改变浅层的地址  
d = copy.deepcopy(a)    # 深拷贝,连同深层的地址也改变了  

# 其余都为 True  
print(id(a) == id(c))    # False  
print(id(a) == id(d))    # False  
print(id(a[2] == id(d[2])))    # False  
# 对于 False 修改其中一个的值,另一个不变  

a == c   # True
a is c   # False  ### is是判断id(a)和id(c)是否一致

Python进程间用队列实现通信。

为什么多线程对I/O密集型任务有用?

因为Python遇到等待会释放GIL(Python解释器)供新的线程使用,实现了线程间的切换。

处理海量数据的方法:

  • hash映射, hash统计+堆/归并/快速排序
  • Bit-map, 针对特征设置(Gender/Race)
  • 字典树、B+树、数据库
  • 外排序
  • MapReduce