矢量二维正交投影到带numpy的直线上会产生错误的结果

2024-10-01 15:30:24 发布

您现在位置:Python中文网/ 问答频道 /正文

我有350个文档分数,当我绘制它们时,它们的形状如下:

docScores = [(0, 68.62998962), (1, 60.21374512), (2, 54.72480392), 
             (3, 50.71389389), (4, 49.39723969), ...,  
             (345, 28.3756237), (346, 28.37126923), 
             (347, 28.36397934), (348, 28.35762787), (349, 28.34219933)]

我在pastebin上发布了完整的数组here(它对应于下面代码中的dataPoints列表)。在

Score distribution

现在,我最初需要找到这条L-shape曲线的elbow point,这要归功于this post。在

现在,在下面的图中,红色的向量p表示肘点。我想找到向量x=(?,?)上的点b,它对应于p到{}的正交投影。在

enter image description here

图上的红点就是我得到的那个(这显然是错误的)。我通过以下操作获得:

^{pr2}$

现在,如果pb的投影是由它的起点和终点来定义的,即s和{}(黄星),那么{},因此{}?在

我在这里犯了错误吗?在

这里是代码编辑的答案:

def findElbowPoint(self, rawDocScores):
    dataPoints = zip(range(0, len(rawDocScores)), rawDocScores)
    s = np.array(dataPoints[0])
    l = np.array(dataPoints[len(dataPoints)-1])
    b_vect = l-s
    b_hat = b_vect/np.linalg.norm(b_vect)
    distances = []
    for scoreVec in dataPoints[1:]:
        p = np.array(scoreVec) - s
        proj = p.dot(b_hat)*b_hat
        d = abs(np.linalg.norm(p - proj)) # orthgonal distance between b and the L-curve
        distances.append((scoreVec[0], scoreVec[1], proj, d))

    elbow_x = max(distances, key=itemgetter(3))[0]
    elbow_y = max(distances, key=itemgetter(3))[1]
    proj = max(distances, key=itemgetter(3))[2]
    max_distance = max(distances, key=itemgetter(3))[3]

    red_point = proj + s

编辑:下面是绘图的代码:

>>> l_curve_x_values = [x[0] for x in docScores]
>>> l_curve_y_values = [x[1] for x in docScores]
>>> b_line_x_values = [x[0] for x in docScores]
>>> b_line_y_values = np.linspace(s[1], l[1], len(docScores))
>>> p_line_x_values = l_curve_x_values[:elbow_x]
>>> p_line_y_values = np.linspace(s[1], elbow_y, elbow_x)
>>> plt.plot(l_curve_x_values, l_curve_y_values, b_line_x_values, b_line_y_values, p_line_x_values, p_line_y_values)
>>> red_point = proj + s
>>> plt.plot(red_point[0], red_point[1], 'ro')
>>> plt.show()

Tags: keyinfornplinemaxpointproj
2条回答

首先,这个点是在~(50,37)p还是{}?如果p,那可能就是你的问题所在!如果你的p变量的Y分量是正的,那么当你做点积时,你不会得到你期望的结果。在

假设这一点是s+p,如果一点Post-It涂鸦是正确的

p_len = np.linalg.norm(p)
p_hat = p / p_len
red_len = p_hat.dot(b_hat) * p_len   # red_len = |x-s|
    # because p_hat . b_hat = 1 * 1 * cos(angle) = |x-s| / |p|
red_point = s + red_len * b_hat

未经测试!基督教青年会。希望这有帮助。在

如果使用绘图直观地确定解决方案是否正确,则必须在每个轴上使用相同的比例绘制数据,即使用plt.axis('equal')。如果轴的比例不相等,则线之间的角度在绘图中会失真。在

相关问题 更多 >

    热门问题