大数据与人工智能实验室机器学习组20201008测试题解析

    科技2026-04-10  6

    一、选择题 1、线性表采用链式存储时,结点的存储地址(  )。 A. 必须是不连续的 B. 连续与否均可 C. 必须是连续的 D. 和头结点的存储地址相连续 【答案:B】 2、下列属于聚类算法的是(  )。 A. Decision Tree B. Support Vector Machine C. K-Means D. Singular Value Decomposition 【答案:C】 【解析:机器学习算法一般可划分为监督学习、无监督学习和强化学习三大类,监督学习可以大致分为分类和回归两类,无监督学习可以大致分为聚类和降维两类。Decision Tree(决策树)和Support Vector Machine(支持向量机)都属于监督学习算法;K-Means(K均值)属于无监督学习的聚类算法;Singular Value Decomposition(奇异值分解)属于无监督学习的降维算法。】 3、下述程序段输出结果为(  )。

    import numpy as np a = np.array([3, 5, 8]) b = np.array([[1, 2, 3], [4, 5, 6], [5, 7, 9]]) print(a * b)

    A.

    [[ 3 10 24] [ 4 5 6] [ 5 7 9]]

    B.

    [[ 3 10 24] [12 25 48] [15 35 72]]

    C.

    [ 63 87 111]

    D.

    ValueError: frames are not aligned

    【答案:B】 【解析:在NumPy中,*运算符的功能是,对数组执行对应位置元素相乘(相当于np.multiply()),对矩阵执行矩阵乘法运算(相当于np.dot())。】 4、设指针q指向单链表中结点A,指针p指向单链表中结点A的后继结点B,指针s指向待插入的结点X,则在结点A和结点B之间插入结点X的操作序列为(  )。 A. p->next = s; s->next = q; B. p->next = s->next; s->next = p; C. q->next = s; s->next = p; D. s->next = p->next; p->next = s; 【答案:C】 【解析:如下图所示。】

    5、一棵完全二叉树含1001个结点,其中叶子结点的个数是(  )。 A. 501 B. 500 C. 251 D. 250 【答案:A】 【解析:根据满二叉树的性质易得,有1023个结点的完全二叉树是满二叉树,该树有512个叶子结点。题目中所给完全二叉树有1001个结点,比满二叉树少22个结点。在满二叉树中,这22个结点对应的11个父亲结点即为题中完全二叉树的叶子结点。所以完全二叉树的叶子结点个数为512-22+(22÷2)=501个。】

    二、填空题 1、设有算术表达式x+a*(y-b)-c/d,该表达式的前缀表示为:____________,后缀表示为:____________。 【答案:-+x*a-yb/cd;xayb-*+cd/-】 【解析:中缀表达式转换前(后)缀表达式的方法:首先按照运算符的优先级对所有的运算单位加括号,原式变为((x+(a*(y-b)))-(c/d));转化为前缀表达式时,把运算符号移动到对应的括号前面,即-(+(x*(a-(yb)))/(cd)),去掉括号后的结果-+x*a-yb/cd即为前缀表达式;转化为后缀表达式时,把运算符号移动到对应的括号后面,即((x(a(yb)-)*)+(cd)/)-,去掉括号后的结果xayb-*+cd/-即为后缀表达式。】 2、在循环队列中,当队列为空时,有front = rear;而当所有队列空间全占满时,也有front = rear。为了区别这两种情况,规定循环队列最多只能有MAXSIZE - 1个队列元素,当循环队列中只剩下一个空存储单元时,队列就已经满了。因此,队列判空的条件是____________,队列判满的条件是____________。 【答案:front == rear;front == (rear + 1) % MAXSIZE】 【解析:采用顺序存储结构实现队列,由于存储空间是固定的,随着入队和出队的进行,存储的数据会溢出,如下图一所示。为了解决这个问题,我们可以采用循环队列的方法,如下图二所示。此时,无论是队列为空时,还是队列为满时,都有front = rear。此时,我们可以规定循环队列最多只能有MAXSIZE - 1个队列元素,那么当队列为空时,front = rear;当队列为满时,front = (rear + 1) % MAXSIZE。】

    3、通常我们把分类错误的样本数占样本总数的比例称为____________;算法模型对于新样本的适应能力被称为____________;当模型把训练样本的特点当作所有潜在样本的特点,导致泛化能力下降,这种现象称为____________,与之对应的是____________。 【答案:错误率;泛化能力;过拟合;欠拟合】 4、Fayyed过程模型主要包含以下七个阶段知识表示:____________、____________、____________、____________、____________、____________、____________。 【答案:知识表示;数据清理;数据集成;数据选择;数据变换;数据挖掘;模式评估】

    三、简答题 1、已知一棵树的先根遍历序列和后根遍历序列如下,请构造出该树。 先序序列:ABCDEFGHIJ 后序序列:CDEBFHIJGA 【答案:树形结构如下图所示】

    2、给定一组权值(15, 9, 3, 2, 7, 6),试设计相应的哈夫曼树,并计算相应的WPL。 【答案:哈夫曼树如下图所示;WPL=(2+3)×4+6×3+(15+7+9)×2=100。】

    3、简述决策树的构造逻辑,ID3算法和C4.5算法的计算过程和特点。 【答案:决策树的构造过程可以理解成寻找纯净划分的过程,就是让目标变量的分歧最小。信息熵表示了信息的不确定度(纯度),计算上来讲就是信息量的统计均值。对于树中一个内部结点来说,有多种划分的选择,每种选择都对应一种属性,这个结点选择哪个属性进行划分得到的结果最纯,如何选择判定准则就是关键。在ID3算法中,计算出每个分支的信息熵,再赋上权重,可以获得该节点对应属性的信息增益。然而ID3算法对于可取值数目较多的属性有明显的偏好,这会给整体带来不利影响。C4.5算法在此基础上做了改变,它采用信息增益率(用原本的信息增益除以该属性的“固有值”)作为划分准则。直接选取信息增益率会导致对于数目少的属性偏好,因此C4.5算法从信息增益高出平均水平的属性里计算信息增益率。这两种算法都是基于离散的属性,如果为了使用而将连续的属性离散化,会造成一定的损失。】 4、监督学习通过定义一个模型,并根据训练集上的数据估计最优参数。梯度下降法是一个广泛被用来最小化模型误差的参数优化算法。梯度下降法通过多次迭代,并在每一步中最小化成本函数来估计模型的参数。 (1) 请指出下面公式中各部分的意义。 ω j = ω j − λ ∂ F ( ω j ) ∂ ω j \omega j=\omega j-\lambda \frac{∂F(\omega j)}{∂\omega j} ωj=ωjλωjF(ωj) (2) 为了能够使得梯度下降法有较好的性能,我们需要把 λ \lambda λ的值设定在合适的范围内。请简单叙述一下如何选取和调整 λ \lambda λ。 【答案:(1) ω j \omega j ωj是模型参数, F ( ) F() F()是成本函数, ∂ F ( ω j ) ∂ ω j \frac{∂F(\omega j)}{∂\omega j} ωjF(ωj) ω j \omega j ωj的一阶导数, λ \lambda λ是学习率。(2) 学习率,梯度下降算法中迭代步长。假设待优化函数为 f ( x ) f(x) f(x) d \rm{d} d x x x为函数对变量 x x x的导数,即下降方向。如果不用学习率,或者说学习率为1,使用负梯度,即最速下降法,有些情况下永远无法下降到最优值(即0点处),做一次梯度下降,就移动相对称的点上,来来回回走。学习率大,容易震荡,学习率小,收敛速度慢。一般情况下,随着迭代过程的继续,学习率应当适当减小,这样才能更稳妥地到达极值点。这种想法就是通过权重衰减因子实现的。 λ = λ 0 × ( 1 1 + d e c a y × i ) \lambda=\lambda_0\times(\frac{1}{1+decay\times i}) λ=λ0×(1+decay×i1),其中 d e c a y decay decay为衰减因子,取值范围 [ 0 , 1 ] [0,1] [0,1],随着 i i i的增加,学习率逐渐减小。】

    四、算法题 1、LeetCode 78. 子集 给定一组不含重复元素的整数数组nums,返回该数组所有可能的子集(幂集)。 说明:解集不能包含重复的子集。 示例:

    输入: nums = [1,2,3] 输出: [ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ] /** * Return an array of arrays of size *returnSize. * The sizes of the arrays are returned as *returnColumnSizes array. * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free(). */ int** subsets(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) { }

    【解法:迭代法实现子集枚举,时间复杂度:O(n×2n),空间复杂度:O(n)】

    /** * Return an array of arrays of size *returnSize. * The sizes of the arrays are returned as *returnColumnSizes array. * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free(). */ int** subsets(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) { int total = 1 << numsSize; * returnColumnSizes = malloc(sizeof(int) * total); * returnSize = total; int** ret = malloc(sizeof(int*) * total); int t[numsSize], tSize; int* tmp; for (int mask = 0; mask < total; mask++) { tSize = 0; for (int i = 0; i < numsSize; i++) { if ((1 << i) & mask) { t[tSize++] = nums[i]; } } tmp = malloc(sizeof(int) * tSize); memcpy(tmp, t, sizeof(int) * tSize); (* returnColumnSizes)[mask] = tSize; ret[mask] = tmp; } return ret; }

    【解析:记原序列中元素的总数为n。原序列中的每个数字ai的状态可能有两种,即在子集中和不在子集中。我们用111表示在子集中,000表示不在子集中,那么每一个子集可以对应一个长度为n的 0/1序列,第i位表示ai是否在子集中。可以发现0/1序列对应的二进制数正好从0到2n−1。我们可以枚举mask∈[0,2n−1],mask的二进制表示是一个0/1序列,我们可以按照这个0/1序列在原集合当中取数。当我们枚举完所有2n个mask,我们也就能构造出所有的子集。】 2、剑指Offer 03. 数组中重复的数字 找出数组中重复的数字。 在一个长度为n的数组nums里的所有数字都在0~n-1的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。 示例:

    输入: [2, 3, 1, 0, 2, 5, 3] 输出:2 或 3

    限制:2 <= n <= 100000

    int findRepeatNumber(int* nums, int numsSize) { }

    【解法1:HashMap,时间复杂度:O(n),空间复杂度:O(n)】

    int findRepeatNumber(int* nums, int numsSize) { int *hash = (int*)calloc(numsSize, sizeof(int)); for (int i = 0; i < numsSize; i++) { if (hash[nums[i]] == 1) { return nums[i]; } else { hash[nums[i]]++; } } return -1; }

    【解法2:利用原来的空间,不使用额外空间,时间复杂度:最坏条件下O(n),空间复杂度:O(1)】

    int findRepeatNumber(int* nums, int numsSize) { for (int i = 0; i < numsSize; i++) { while (nums[i] != i) { if (nums[i] == nums[nums[i]]) { return nums[i]; } int t = nums[i]; nums[i] = nums[t]; nums[t] = t; } } return -1; }
    Processed: 0.010, SQL: 9