lines perpendicular to the x-axis cannot be calculated when y=kx+b is used. Therefore, the normal ysin (theta) +xcos (theta) = dist is used. It seems that the use of a bit complicated, direct use of ax+by=1 do not know can calculate, not tested.
# 修改自 http://www.cnblogs.com/NanShan2016/p/5493429.html
### 最小二乘法 python leastsq###
import numpy as np
import math
from scipy.optimize import leastsq
###采样点(Xi,Yi)###
Xi=np.array([-1,-1])
Yi=np.array([0,10])
# p是个数组,表示所有参数!!!
### 定义误差函数,拟合y=kx+b,p[0]表示k,p[1]表示b
### 法线式 y*sin(theta)+x*cos(theta) = dist
def error ( p x y
return y*math.sin(p[0])+x*math.cos(p[0])-p[1] #x、y都是列表,故返回值也是个列表
###主函数从此开始###
# 可能是使用梯度下降法而非矩阵运算,因此需要给定初始参数p0
p0=[0,1]
Para=leastsq(error,p0,args=(Xi,Yi)) #把error函数中除了p以外的参数打包到args中
theta = Para[0][0]
dist = Para[0][1]
print("theta=",theta,‘\n‘,"dist=",dist)
###绘图,看拟合效果###
import matplotlib.pyplot as plt
plt.axis([-10,10,-10,10])
plt.scatter(Xi,Yi,color="red",label="Sample Point",linewidth=3) #画样本点
if theta != 0:
x=np.linspace(-10,10,10)
y=dist/math.sin(theta)-x/math.tan(theta)
else:
x = dist
y = np.linspace(-10,10,10)
plt.plot(x,y,color="orange",label="Fitting Line",linewidth=2) #画拟合直线
plt.legend()
plt.show()
From Wiznote
Python least squares leastsq function for normal solution and x-axis vertical problem