import numpy as np
# 读取训练样本数 k
k = int(input())
# 读取训练数据:共 k*4 个整数(每样本 3 特征 + 1 标签)
data = list(map(int, input().split()))
# 读取预测样本数 n
n = int(input())
# 读取待预测数据:共 n*3 个整数(每样本 3 特征)
pred_data = list(map(int, input().split()))
# 构建训练集 x (特征) 和 y (标签)
x = []
y = []
for i in range(k):
start = i * 4
feature = data[start:start + 3] # 前3个是特征
price = data[start + 3] # 第4个是价格(标签)
x.append(feature)
y.append(price)
x = np.array(x, dtype=float) # 转为浮点型(梯度下降需要)
x = np.c_[np.ones(x.shape[0]), x] # 添加偏置列(全1)
y = np.array(y, dtype=float)
# ========== 梯度下降替代正规方程 ==========
m, p = x.shape # m: 样本数, p: 特征数(含偏置)
theta = np.zeros(p) # 初始化参数 theta 为 0
learning_rate = 0.01 # 学习率(可调)
num_iterations = 10000 # 迭代次数(可调)
# 梯度下降主循环
for _ in range(num_iterations):
# 计算预测值
y_pred = x @ theta
# 计算梯度:(1/m) * X^T (Xθ - y)
gradient = (1 / m) * x.T @ (y_pred - y)
# 更新参数
theta = theta - learning_rate * gradient
# ========== 预测部分(保持不变)==========
x_pred = []
for i in range(n):
start = i * 3
feature = pred_data[start:start + 3]
x_pred.append(feature)
x_pred = np.array(x_pred, dtype=float)
x_pred = np.c_[np.ones(x_pred.shape[0]), x_pred] # 添加偏置列
# 使用学到的 theta 进行预测
y_pred = x_pred @ theta
y_pred_rounded = [round(i) for i in y_pred]
# 输出结果(拼接成字符串)
print(''.join(map(str, y_pred_rounded)))
🔧 关键改动说明
| 原代码(正规方程) | 新代码(梯度下降) |
|---|---|
theta = np.linalg.inv(x.T@x)@x.T@y | 用 for 循环迭代更新 theta |
| 不需要设置超参数 | 需要设置 learning_rate 和 num_iterations |
| 一步求解 | 多次迭代逼近最优解 |
⚙️ 超参数建议(可根据数据调整)
learning_rate:- 如果 loss 震荡或发散 → 减小(如
0.001) - 如果收敛太慢 → 增大(如
0.1)
- 如果 loss 震荡或发散 → 减小(如
num_iterations:- 一般
1000~10000足够;也可加早停机制(当 loss 变化很小时停止)
- 一般
💡 提示:如果特征尺度差异大(比如一个特征是“面积=100”,另一个是“房间数=3”),建议先做特征标准化(如
(x - mean)/std),否则梯度下降会很慢。但本题输入是整数且未说明范围,暂时省略。
✅ 示例输入/输出(验证用)
输入:
2
1 2 3 10 4 5 6 30
1
7 8 9
- 训练样本1: [1,2,3] → 10
- 训练样本2: [4,5,6] → 30
- 预测样本: [7,8,9] → ?
输出(近似):
50
(因为模型学到大致是 y ≈ x1 + x2 + x3,7+8+9=24?但实际拟合可能不同;若用正规方程得精确解,梯度下降应接近)
1149

被折叠的 条评论
为什么被折叠?



