如何计算拟合超平面与样本点之间的距离?
点与拟合超平面的距离计算问题
我需要计算拟合超平面与5个样本点之间的距离,查阅到的多数方案基于SVM,但我并非要做分类任务,对此感到困惑。
样本点如下:
[[ 163.3828172 169.65537306 144.69201418] [-212.50951396 -167.06555958 56.69388025] [-164.65129832 -163.42420063 -149.97008725] [ 41.8704004 52.2538316 14.0683657 ] [-128.38386078 -102.76840542 -303.4960438 ]]
我用SVD求解拟合平面的系数,实现代码如下:
def fit_plane(points): assert points.shape[1] == 3 centroid = points.mean(axis=0) x = points - centroid[None, :] U, S, Vt = np.linalg.svd(x.T @ x) #normal vector of best fitting plane is the left #singular vector corresponding to the least singular value normal = U[:, -1] #calculate the distance from origin origin_distance = normal @ centroid return np.hstack([normal, -origin_distance]) fit_plane(X)
得到的平面方程为:-0.67449074x + 0.73767288y -0.03001614z -10.75632119 = 0
我了解到SVM中常用距离公式d = |w^Tx +b|/||w||,但不清楚如何将自己得到的平面方程对应到该公式,进而计算点与超平面的距离。
问题解答
1. 平面方程与距离公式的对应关系
你得到的平面方程是标准的三维平面形式 ax + by + cz + d = 0(将你的方程整理后,d = -10.75632119),而SVM里的距离公式本质就是点到平面的欧氏距离公式,和分类任务无关,对应关系如下:
w对应平面的法向量[a, b, c]w^Tx是法向量与点x=(x0,y0,z0)的点积,即a*x0 + b*y0 + c*z0- SVM公式里的
b对应你平面方程中的常数项d
最终点到平面的距离公式可统一为:
d = |a*x0 + b*y0 + c*z0 + d| / sqrt(a² + b² + c²)
2. 针对你的场景的计算步骤
结合你得到的平面参数:
- 法向量
w = [-0.67449074, 0.73767288, -0.03001614] - 常数项
d_plane = -10.75632119
对每个样本点 (x_p, y_p, z_p):
- 计算分子:
|w[0]*x_p + w[1]*y_p + w[2]*z_p + d_plane| - 计算分母:法向量的L2范数
sqrt(a² + b² + c²) - 距离 = 分子 / 分母
3. 代码实现
可以直接扩展现有代码,计算所有点的距离:
import numpy as np # 你的样本点 X = np.array([ [163.3828172, 169.65537306, 144.69201418], [-212.50951396, -167.06555958, 56.69388025], [-164.65129832, -163.42420063, -149.97008725], [41.8704004, 52.2538316, 14.0683657], [-128.38386078, -102.76840542, -303.4960438] ]) def fit_plane(points): assert points.shape[1] == 3 centroid = points.mean(axis=0) x = points - centroid[None, :] U, S, Vt = np.linalg.svd(x.T @ x) normal = U[:, -1] origin_distance = normal @ centroid return np.hstack([normal, -origin_distance]) # 获取平面参数 a, b, c, d_plane = fit_plane(X) # 计算所有点到平面的距离 def calculate_distances(points, a, b, c, d): numerator = np.abs(a * points[:,0] + b * points[:,1] + c * points[:,2] + d) denominator = np.sqrt(a**2 + b**2 + c**2) return numerator / denominator distances = calculate_distances(X, a, b, c, d_plane) print("各点到平面的距离:", distances)
运行后即可得到每个样本点与拟合平面的距离值。
内容的提问来源于stack exchange,提问作者ethan tenison
相关产品推荐
相关产品推荐

