J'ai 350 notes de documents qui, quand je les intrigue, ont cette forme:projection 2D Orthogonal du vecteur sur la ligne avec numpy donne un résultat erroné
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)]
J'ai posté le tableau complet here sur pastebin
(elle correspond à la liste dataPoints
sur le code ci-dessous).
Maintenant, il me fallait d'abord trouver la elbow point
de cette courbe L-shape
, que j'ai trouvé grâce à this post.
Maintenant, sur le graphique suivant, le vecteur rouge p
représente le point de coude. Je voudrais trouver le point x=(?,?)
(l'étoile jaune) sur le vecteur b
qui correspond à la projection orthogonale de p
sur b
.
Le point rouge sur la parcelle est celui que j'obtenir (ce qui est évidemment faux). Je l'obtiens procédant comme suit:
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
Maintenant, si la projection de p
sur b
est définie par la son point de départ et de fin, à savoir s
et x
(l'étoile jaune), il en résulte que proj_p_onto_b = x - s
donc x = proj_p_onto_b + s
?
Ai-je commis une erreur ici?
EDIT: En réponse à @cxw, voici le code pour le calcul du point de coude:
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: Voici le code de la parcelle:
>>> 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()
Si vous utilisez le tracé pour déterminer visuellement si la solution semble correcte, vous devez tracer les données en utilisant la même échelle sur chaque axe, c'est-à-dire utiliser 'plt.axis ('equal')'. Si les axes n'ont pas d'échelles égales, les angles entre les lignes sont déformés dans le tracé. –
Wow, je pense que c'est l'astuce ...laissez-moi essayer rapidement –
@WarrenWeckesser Eh bien, c'était la chose, je me sens bête. Merci beaucoup d'avoir signalé cela, pouvez-vous l'écrire comme réponse pour que je puisse l'accepter? –