📅  最后修改于: 2023-12-03 15:11:33.424000             🧑  作者: Mango
该题目为《须藤放置》第1章第6节问题9。
在二维平面内,有一些点,找到一条直线,使得这些点到直线的距离之和最小。
首先需要定义一下点到直线的距离。
假设直线的方程为 $ax+by+c=0$,点 $P(x_0,y_0)$,则点 $P$ 到直线的距离为
$$\frac{|ax_0+by_0+c|}{\sqrt{a^2+b^2}}$$
现在假设有 $n$ 个点,给出这 $n$ 个点的坐标 $(x_i,y_i)$,需要找到一条直线 $ax+by+c=0$,使得这些点到直线的距离之和最小。
我们可以通过最小二乘法求解。具体来说,就是要最小化下面这个函数:
$$f(a,b,c)=\sum_{i=1}^n(\frac{|ax_i+by_i+c|}{\sqrt{a^2+b^2}})^2$$
使用梯度下降法,可以求解出 $a,b,c$ 的取值。
具体求解过程是,先对上面这个函数关于 $a,b,c$ 求偏导,然后根据梯度下降法的思想,不停地沿着负梯度的方向更新参数的取值。最后当梯度的逆范数的值小到一定程度时,就停止迭代,获得 $a,b,c$ 的最优取值。
import numpy as np
def gradient_descent(X, y, alpha=0.001, max_iter=1000, tol=1e-3):
m, n = X.shape
theta = np.random.randn(n, 1)
for i in range(max_iter):
h = np.dot(X, theta)
diff = h - y
grad = np.dot(X.T, diff) / m
theta -= alpha * grad
if np.linalg.norm(grad) < tol:
break
return theta
def line_fitting(X, y):
X = np.hstack((X, np.ones((X.shape[0], 1))))
theta = gradient_descent(X, y)
a, b, c = theta[0, 0], theta[1, 0], theta[2, 0]
return a, b, c
其中 X
是一个 $n \times 2$ 的矩阵,每一行代表一个点的坐标,y
是一个 $n \times 1$ 的向量,代表每个点到直线的距离,alpha
是学习率,max_iter
是最大迭代次数,tol
是梯度的逆范数小于这个值时停止迭代。最后返回直线的参数 $a,b,c$。