【算法岗面试】某小厂E机器学习

简介: FM模型的FM使用了隐向量特征交叉。

1.deepFM的FM特点,deep部分设置了多少层,依据

FM模型的FM使用了隐向量特征交叉。

  • 为了解决POLY2模型的缺陷,2010年提出FM模型。如下式子是FM(Factor Machine,因子分解机)二阶部分的数学表达式
  • image.png

FM和POLY2的区别是,FM用两个向量的内积( w j 1 ⋅ w j 2 ) \left(\boldsymbol{w}_{j_{1}} \cdot \boldsymbol{w}_{j_{2}}\right)(w

j

1

⋅w

j

2

)取代了单一的权重系数W h ( j 1 , j 2 ) W_{h\left(j_{1}, j_{2}\right)}W

h(j

1

,j

2

)

FM权重参数量少了,降低训练开销;

FM虽然丢失了某些具体特征组合的精确记忆能力,但泛化能力大大提高。

FM的二阶以上交叉没有很强的意义,因为没法加速。

FM为每个特征学习了一个隐权重向量(和矩阵分解,用隐向量代表 user 和 item 思想一样,从单纯的 user、item隐向量扩展到了所有特征上)。在特征交叉时,使用两个特征隐向量的内积作为交叉特征的权重。

FM引入隐向量,更好解决数据稀疏性问题,ex:

商品推荐场景,样本有两个特征:频道(channel)和品牌(brand),某训练样本的特征组合是(ESPN, Adidas)。

在POLY2中,只有当ESPN和Adidas同时出现在一个训练样本时,模型才能学习到这个组合特征对应的权重;

在FM中,ESPN的隐向量也可以通过(ESPN, Gucci)样本进行更新,Adidas的隐向量也可以通过(NBC, Adidas)样本进行更新,即大幅降低模型,对数据稀疏性的要求。

deep设置了3层。层数要根据具体网络,如GCN就不能太深,否则会导致拉普拉斯平滑问题。这里设置3层解决非线性的问题。


2.算法题:爬楼梯

其实就是青蛙跳台阶的题目:

d p [ i ] dp[i]dp[i]是青蛙跳上一个n级的台阶总共跳法数。

class Solution {
public:
    int numWays(int n) {
        vector<int>dp(n+1,0);
        if(n==0) return 1;//否则当n=0时下面这句的dp[1]就访问越界了
        dp[0]=dp[1]=1;
        for(int i=2;i<=n;i++){
            dp[i]=(dp[i-1]+dp[i-2])% 1000000007;
        }
        return dp[n];
    }
};

递归写法:

int fib(int N) {
    if (N == 1 || N == 2) return 1;
    return fib(N - 1) + fib(N - 2);
}

3.算法题:最大子数组和

image.png

  • dp[i]=max{nums[i],dp[i1]+nums[i]}
  • 边界+初始条件:只有一个数字时dp[0] = nums[0]
  • 计算顺序:从小到大。

4.sql题:商品id、类别、价格,mysql找出找出每类前10大的商品

建表:

START TRANSACTION;
CREATE TABLE employee (
    name text, 
    department text, 
    salary bigint
);
INSERT INTO employee VALUES ( 'alice', 'it', 1000 );
INSERT INTO employee VALUES ( 'bob', 'it', 2000 );
INSERT INTO employee VALUES ( 'david', 'it', 3000 );
INSERT INTO employee VALUES ( 'john', 'it', 2000 );
INSERT INTO employee VALUES ( 'mike', 'it', 9000 );
INSERT INTO employee VALUES ( 'henry', 'sales', 500000 );
INSERT INTO employee VALUES ( 'jason', 'sales', 9999999 );
COMMIT;

给每个部门的人,根据薪资进行部门内排序,可以使用窗口函数,对部门分类,对部门内排序DENSE_RANK(无间隔的分级):

SELECT *, DENSE_RANK() OVER(
    PARTITION BY department
    ORDER BY salary DESC
) AS innerrank
FROM employee;

最后:

SELECT * FROM (
    SELECT *, DENSE_RANK() OVER(
        PARTITION BY department
        ORDER BY salary DESC
    ) AS innerrank
    FROM employee
) AS t WHERE innerrank <= 3;

5.1000个学生成绩排序,比快排更快的方法

面试官说没有学生ID,最后输出排序后的学生成绩就好。

听了就懵了,还有比快排更快的方法?!说了一个哈希表的方法(不太确定), 以学生成绩为key值,以key为成绩的学生个数作为哈希表的value值。然后因为C++的STL中的map底层用了红黑树,排序一波会更快。


6.常用的数据预处理有哪些操作

去除唯一属性、处理缺失值、属性编码、数据标准化正则化、特征选择、主成分分析。


缺失值处理:

直接使用含有缺失值的特征

删除含有缺失值的特征(该方法在包含缺失值的属性含有大量缺失值而仅仅包含极少量有效值时是有效的)

缺失值补全:如果样本属性的距离是可度量的,则使用该属性有效值的平均值来插补缺失的值

高维映射(最精确):将属性映射到高维空间,采用独热码编码(one-hot)。将包含K个离散取值范围的属性值扩展为K+1个属性值,若该属性值缺失,则扩展后的第K+1个属性值置为1。

建模预测:将缺失的属性作为预测目标来预测,将数据集按照是否含有特定属性的缺失值分为两类,利用现有的机器学习算法对待预测数据集的缺失值进行预测。

数据标准化(归一化):样本属性值缩放为一定范围,如min-max标准化映射结果为0到1的区间中。

正则化

特征选择(降维):从给定的特征集合中选出相关特征子集。这是为了减轻维数灾难问题,降低学习任务的难度。常见降维方法:SVD、PCA、LDA。

7.transformer的文本抽取

类似作QA的bert模型可以。


8.反欺诈(风控)的分类算法

LR、GBDT / XGBoost分类


9.大数据spark和hadoop

(1)Scala和PySpark

(1)Scala 是一门多范式(multi-paradigm)的编程语言,设计初衷是要集成面向对象编程和函数式编程的各种特性。


Scala 运行在 Java 虚拟机上,并兼容现有的 Java 程序。

Scala 源代码被编译成 Java 字节码,所以它可以运行于 JVM 之上,并可以调用现有的 Java 类库。


(2)Apache Spark是用 Scala编程语言 编写的。为了用Spark支持Python,Apache Spark社区发布了一个工具PySpark。使用PySpark,也可以使用Python编程语言中的 RDD 。


(3)PySpark提供了 PySpark Shell,它将Python API链接到spark核心并初始化Spark上下文。将Python与Spark集成就对数据科学研究更加方便。


Spark的开发语言是Scala,这是Scala在并行和并发计算方面优势的体现,这是微观层面函数式编程思想的一次胜利。此外,Spark在很多宏观设计层面都借鉴了函数式编程思想,如接口、惰性求值和容错等。


(2)Spark原理

Spark是业界主流的大数据处理利器。


分布式:指的是计算节点之间不共享内存,需要通过网络通信的方式交换数据。

Spark 是一个分布式计算平台。Spark 最典型的应用方式就是建立在大量廉价的计算节点上,这些节点可以是廉价主机,也可以是虚拟的 Docker Container(Docker 容器)。

Spark 的架构图中:


Spark 程序由 Manager Node(管理节点)进行调度组织

由 Worker Node(工作节点)进行具体的计算任务执行

最终将结果返回给 Drive Program(驱动程序)。

在物理的 Worker Node 上,数据还会分为不同的 partition(数据分片),可以说 partition 是 Spark 的基础数据单元。


image.png


图1 Spark架构图

Spark 计算集群能够比传统的单机高性能服务器具备更强大的计算能力,就是由这些成百上千,甚至达到万以上规模的工作节点并行工作带来的。


(3)一个具体栗子

那在执行一个具体任务的时候,Spark 是怎么协同这么多的工作节点,通过并行计算得出最终的结果呢?这里我们用一个任务来解释一下 Spark 的工作过程。


一个具体任务过程:

(1)先从本地硬盘读取文件 textFile;

(2)再从分布式文件系统 HDFS 读取文件 hadoopFile;

(3)然后分别对它们进行处理;

(4)再把两个文件按照 ID 都 join 起来得到最终的结果。


在 Spark 平台上处理这个任务的时候,会将这个任务拆解成一个子任务 DAG(Directed Acyclic Graph,有向无环图),再根据 DAG 决定程序各步骤执行的方法。从图 2 中可以看到,这个 Spark 程序分别从 textFile 和 hadoopFile 读取文件,再经过一系列 map、filter 等操作后进行 join,最终得到了处理结果。

image.png

图2 某Spark程序的任务有向无环图

最关键的过程是要理解哪些是可以纯并行处理的部分,哪些是必须 shuffle(混洗)和 reduce 的部分:这里的 shuffle 指的是所有 partition 的数据必须进行洗牌后才能得到下一步的数据,最典型的操作就是图 2 中的 groupByKey 操作和 join 操作。以 join 操作为例,必须对 textFile 数据和 hadoopFile 数据做全量的匹配才可以得到 join 后的 dataframe(Spark 保存数据的结构)。而 groupByKey 操作则需要对数据中所有相同的 key 进行合并,也需要全局的 shuffle 才能完成。


与之相比,map、filter 等操作仅需要逐条地进行数据处理和转换,不需要进行数据间的操作,因此各 partition 之间可以完全并行处理。


在得到最终的计算结果之前,程序需要进行 reduce 的操作,从各 partition 上汇总统计结果,随着 partition 的数量逐渐减小,reduce 操作的并行程度逐渐降低,直到将最终的计算结果汇总到 master 节点(主节点)上。可以说,shuffle 和 reduce 操作的触发决定了纯并行处理阶段的边界。


image.png

图3 被shuffle操作分割的DAG stages

注意:

(1)shuffle 操作需要在不同计算节点之间进行数据交换,非常消耗计算、通信及存储资源,因此 shuffle 操作是 spark 程序应该尽量避免的。shuffle可以理解为一个串行操作,需要等到在此之前的并行工作完成之后才可以顺序开始。


(2)简述Spark 的计算过程:Stage 内部数据高效并行计算,Stage 边界处进行消耗资源的 shuffle 操作或者最终的 reduce 操作。


10.如何避免局部最优解

以不同的参数值初始化多个神经网络,取最小的作为结果

使用随机梯度下降:与标准梯度下降精确计算梯度不一样,随机梯度下降法在计算梯度时加入随机的因素,于是即便其陷入到局部的极小值点,他计算的梯度仍可能不为0,这样就有可能跳出局部的极小值而继续进行搜索。

momentum 设置冲量。本次前进的步伐,根据上一次的步伐,适当调大,好比从高处降落的石头,会更有机率跨过一些小坑,如果坑非常大,依靠冲量的惯性是没法逃出的。

11.除了adam系列和momentum系列,还有什么优化器

优化器:根据网络反向传播的梯度信息来更新网络的参数,以起到降低loss函数计算值,使得模型输出更加接近真实标签。


(1)深度学习的优化算法一般分为两类:


调整学习率,使得优化更加稳定;

梯度估计修正,优化训练速度。

image.png

(2)看adam论文中的伪代码(上图):

从while循环往下看,第一行是更新step,

第二行是计算梯度,

第三行计算一阶矩的估计,即mean均值

第四行计算二阶距的估计,即variance,和方差类似,都是二阶距的一种。

第五、六行则是对mean和var进行校正,因为mean和var的初始值为0,所以它们会向0偏置,这样处理后会减少这种偏置影响。

第七行是梯度下降。注意alpha后的梯度是用一阶距和二阶距估计的。


各类深度学习的优化算法的演变过程:SGD -> SGDM -> NAG ->AdaGrad -> AdaDelta -> Adam -> Nadam 这样的历程。


优化算法的框架:

首先定义:待优化的参数为w,目标函数为f(w),初始的学习速率为 α \alphaα,现在要开始迭代优化,在每个epoch t中:

image.pngimage.png

其中:


⊙ \odot⊙ 和 / // 分别是按照元素进行相乘和相除。

β 2 \beta_{2}β

2

是0-1之间值的超参数(一般设置为0.99)。

问:adam加上v \sqrt{\mathbf{v}}

v

后,哪些参数会得到更大的更新?为啥有助于学习呢?


答:v vv 实际上是指数移动平均(EMA)的梯度的elementwise square。v \sqrt{\mathbf{v}}

v

可看作是EMA的绝对值或者是动量momentum m的magnitude。对m mm进行标准化(即m / v m/\sqrt{\mathbf{v}}m/

v

操作),使得大的数变小,小的数变大。这样能给模型参数,小梯度,更大的参数更新,从而能够更快的收敛。


相关文章
|
26天前
|
算法 Java 数据库
美团面试:百亿级分片,如何设计基因算法?
40岁老架构师尼恩分享分库分表的基因算法设计,涵盖分片键选择、水平拆分策略及基因法优化查询效率等内容,助力面试者应对大厂技术面试,提高架构设计能力。
美团面试:百亿级分片,如何设计基因算法?
|
1月前
|
算法 前端开发 Java
数据结构与算法学习四:单链表面试题,新浪、腾讯【有难度】、百度面试题
这篇文章总结了单链表的常见面试题,并提供了详细的问题分析、思路分析以及Java代码实现,包括求单链表中有效节点的个数、查找单链表中的倒数第k个节点、单链表的反转以及从尾到头打印单链表等题目。
30 1
数据结构与算法学习四:单链表面试题,新浪、腾讯【有难度】、百度面试题
|
20天前
|
机器学习/深度学习 算法 Java
机器学习、基础算法、python常见面试题必知必答系列大全:(面试问题持续更新)
机器学习、基础算法、python常见面试题必知必答系列大全:(面试问题持续更新)
|
25天前
|
算法 Java 数据库
美团面试:百亿级分片,如何设计基因算法?
40岁老架构师尼恩在读者群中分享了关于分库分表的基因算法设计,旨在帮助大家应对一线互联网企业的面试题。文章详细介绍了分库分表的背景、分片键的设计目标和建议,以及基因法的具体应用和优缺点。通过系统化的梳理,帮助读者提升架构、设计和开发水平,顺利通过面试。
美团面试:百亿级分片,如何设计基因算法?
|
1月前
|
算法 Java 数据中心
探讨面试常见问题雪花算法、时钟回拨问题,java中优雅的实现方式
【10月更文挑战第2天】在大数据量系统中,分布式ID生成是一个关键问题。为了保证在分布式环境下生成的ID唯一、有序且高效,业界提出了多种解决方案,其中雪花算法(Snowflake Algorithm)是一种广泛应用的分布式ID生成算法。本文将详细介绍雪花算法的原理、实现及其处理时钟回拨问题的方法,并提供Java代码示例。
62 2
|
2月前
|
机器学习/深度学习 JavaScript 算法
面试中的网红虚拟DOM,你知多少呢?深入解读diff算法
该文章深入探讨了虚拟DOM的概念及其diff算法,解释了虚拟DOM如何最小化实际DOM的更新,以此提升web应用的性能,并详细分析了diff算法的实现机制。
|
3月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
3天前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
4天前
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
22 4
|
1月前
|
JSON 安全 前端开发
第二次面试总结 - 宏汉科技 - Java后端开发
本文是作者对宏汉科技Java后端开发岗位的第二次面试总结,面试结果不理想,主要原因是Java基础知识掌握不牢固,文章详细列出了面试中被问到的技术问题及答案,包括字符串相关函数、抽象类与接口的区别、Java创建线程池的方式、回调函数、函数式接口、反射以及Java中的集合等。
27 0
下一篇
无影云桌面