私はそれをプロットし、350のドキュメントのスコアを有していて、この形状を有している:ラインにベクターの2次元直交投影を
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
のリストを参照してください)。
今、私はもともと私がthis postに感謝を発見し、このL-shape
曲線のelbow point
見つける必要がありました。
ここで、次のプロットでは、赤いベクトルp
がエルボーポイントを表します。ベクトルb
上の点x=(?,?)
(黄色の星)が、b
にp
の正射影に対応することを確認したいと思います。
プロット上の赤い点は、(明らかに間違っている)私は得るものです。それは以下を実行得る:b
へp
の突起は、その始点と終点、すなわちs
とx
(黄色の星)によって定義されている場合、今
b_hat = b/np.linalg.norm(b) #unit vector of b
proj_p_onto_b = p.dot(b_hat)*b_hat
red_point = proj_p_onto_b + s
を、したがって、そのproj_p_onto_b = x - s
x = proj_p_onto_b + s
以下?
ここでミスを犯しましたか?
EDIT:答えで @cxwする、ここでは、エルボ点を計算するためのコードです:
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
はEDIT:ここでは、プロットのためのコードは次のとおりです。
>>> 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()
解決策が正しいかどうかを視覚的に判断するためにプロットを使用する場合は、各軸に同じスケールを使用してデータをプロットする必要があります。つまり、 'plt.axis( 'equal')'を使用します。軸のスケールが等しくない場合、線の間の角度はプロット内で歪んで表示されます。 –
うわー、これはトリックだと思う...私はすぐに試してみましょう –
@WarrenWeckesserまあ、これは事だった、私はダム感じる。それを指摘してくれてありがとう、私はそれを受け入れることができるように答えとして書くことができますか? –