通过率 0% · 提交 0 · 通过 0
给定一批完整训练样本,先用带偏置项的岭回归训练线性模型,再对每个只缺失一个特征的样本,根据给定目标值恢复这个缺失特征。偏置项不参与正则化;如果缺失列在训练出的模型中权重接近 0,则该特征无法由目标值稳定恢复,输出 NA。
这类题属于算法机考高频题型中「华为 AI 岗 / 岭回归」方向的高频题型,通常考察对「华为 AI 岗 / 岭回归」的建模能力与边界条件处理。掌握本题的解题思路后,可举一反三应对同类真题方向,稳步提升机考通过率。
第一行输入三个整数 n d m。第二行输入实数 lambda。接下来 n 行,每行输入 d 个特征值和一个标签 y。随后 m 行,每行输入 d 个特征值和一个目标值 y,其中恰好一个特征位置为 ?。
输出 m 行。若可以恢复,输出缺失特征值并保留四位小数;若对应权重绝对值小于 1e-10,输出 NA。绝对值小于 0.00005 的数输出为 0.0000。
示例 1
输入示例
5 2 2 0.01 0 0 2.000000 1 0 5.000000 0 1 1.000000 2 1 7.000000 -1 2 -3.000000 ? 1 7 2 ? 5
输出示例
2.0030 2.9917
二维样本恢复缺失特征
示例 2
输入示例
4 2 1 0.1 0 0 5.000000 1 0 7.000000 2 0 9.000000 3 0 11.000000 2 ? 9
输出示例
NA
目标几乎不受缺失列影响时输出 NA
时间限制 3000 ms · 内存限制 256 MB
本平台为独立第三方培训机构,与华为技术有限公司无任何关联;课程的服务内容与权益以购买协议为准,学习效果因个人情况而异。「华为 OD」「华为可信」等仅为对岗位与考试方向的客观描述,相关商标归各自权利人所有。
这些是真正决定能不能 AC、但通用题解里常被略过的点。
岭回归的法方程解法 + 用训练好的模型反推缺失特征。前半是把公式翻成方程组并解出来,后半是一元一次方程,难度全在细节约定。
把偏置并入设计矩阵:每个样本前面补一个 1,参数向量为 [b, w_1, …, w_d]。岭回归的法方程是:
(Xᵀ X + λR) β = Xᵀ y
其中 R 是对角矩阵——第 0 个对角元(对应偏置)为 0,其余为 1。偏置不参与正则化是标准约定,也是判题用例的重点:λ 很大时权重被压小,偏置仍然自由。
矩阵规模只有 (d+1)×(d+1),d ≤ 8,用高斯消元直接解即可;消元时选列主元(按绝对值最大行交换)保证数值稳定。
模型训练好后,预测式是 y = b + Σ w_j·x_j。查询样本恰好缺一个特征 x_k,其余已知,目标值 y 已给:
x_k = (y − b − Σ_{j≠k} w_j·x_j) / w_k
除法成立的前提是 w_k 够大。规则约定 |w_k| < 1e-10 时该特征无法由目标值稳定恢复,输出 NA——不判 0,不吞异常,就按阈值判。
1. 构造增广矩阵 A = XᵀX + λR、右端 XᵀY,高斯消元解出 β。 2. 对每个查询:定位 ? 所在列,代公式;|w_k| 按 1e-10 判 NA。 3. 数值输出保留四位小数,绝对值小于 0.00005 输出 0.0000。
时间 O(n·d² + d³ + m·d),空间 O(d² + n·d)。d ≤ 8 之下 d³ 可以忽略不计。
? 的解析:它可能出现在任意特征位。-0.0000 未钳制。样例 1:5 个二维样本、lambda=0.01,两个查询。第一个查询 ? 1 7:缺第 1 个特征,已知 x_2=1、目标 y=7。模型训练出 [b, w_1, w_2] 后代入:
x_1 = (7 − b − w_2×1) / w_1 ≈ 2.0030
第二个查询 2 ? 5 同理解 x_2,得 2.9917。流程里矩阵只有 3×3(d+1 阶),高斯消元十几行代码。要点在正则矩阵:对角线是 [0, λ, λ]——第 0 位是偏置,免罚。把它写成 [λ, λ, λ],训练出的 b 偏小,两个查询的输出都会漂。
这道题的面试版本通常是「岭回归和普通最小二乘的区别」。可复述的答案:法方程从 XᵀXβ=Xᵀy 变成 (XᵀX+λR)β=Xᵀy,对角线上加的 λ 一方面惩罚大权重防过拟合,一方面让矩阵远离奇异、数值上更稳——两个作用一体两面。追问「偏置为什么不正则」:惩罚偏置等于惩罚输出的整体平移,和「防止对单个特征押注过重」的初衷无关。反推缺失特征那一半则展示了一个朴素观念:训练好的模型就是一个方程,任何一个未知量都可以从其余量里解出来,前提是它的系数别太接近零。
第一步打印训练出的 [b, w₁, …, w_d],和样例描述对参数而非对最终输出——参数错说明法方程或消元有问题,参数对说明错在反推那一行。第二步专查正则矩阵第 0 位是否为 0。第三步用 λ=0 的用例退化成普通最小二乘验证消元本身。
# 岭回归法方程 (X'X+λR)β=X'y,R 对角阵且偏置位为 0(偏置不正则);高斯消元选列主元。
# 反推缺失特征 x_k=(y−b−Σ其余)/w_k;|w_k|<1e-10 输出 NA。
import sys
def gauss(a, b):
n = len(b)
for col in range(n):
pivot = max(range(col, n), key=lambda r: abs(a[r][col]))
if abs(a[pivot][col]) < 1e-12:
raise RuntimeError("singular")
a[col], a[pivot] = a[pivot], a[col]
b[col], b[pivot] = b[pivot], b[col]
div = a[col][col]
for j in range(col, n):
a[col][j] /= div
b[col] /= div
for r in range(n):
if r == col:
continue
factor = a[r][col]
if factor == 0:
continue
for j in range(col, n):
a[r][j] -= factor * a[col][j]
b[r] -= factor * b[col]
return b
def solve() -> None:
tokens = sys.stdin.read().split()
if not tokens:
return
at = 0
n = int(tokens[at]); at += 1
d = int(tokens[at]); at += 1
m = int(tokens[at]); at += 1
lam = float(tokens[at]); at += 1
size = d + 1
a = [[0.0] * size for _ in range(size)]
b = [0.0] * size
for _ in range(n):
z = [1.0]
for _ in range(d):
z.append(float(tokens[at])); at += 1
y = float(tokens[at]); at += 1
for r in range(size):
b[r] += z[r] * y
for c in range(size):
a[r][c] += z[r] * z[c]
for j in range(1, size):
a[j][j] += lam
w = gauss(a, b)
ans = []
for _ in range(m):
row = []
missing = -1
for j in range(d):
token = tokens[at]; at += 1
if token == "?":
missing = j
row.append(0.0)
else:
row.append(float(token))
target = float(tokens[at]); at += 1
denom = w[missing + 1]
if abs(denom) < 1e-10:
ans.append("NA")
continue
known = w[0]
for j in range(d):
if j != missing:
known += w[j + 1] * row[j]
value = (target - known) / denom
if abs(value) < 0.00005:
value = 0.0
ans.append(f"{value:.4f}")
print("\n".join(ans))
if __name__ == "__main__":
solve()
登录后可查看你在本题的历史提交,以及每次的各用例通过情况。
© 2026 广州慕课网络科技有限公司 · 吴师兄学算法官网 版权所有