Установка строке в 3D

Есть ли какие-либо алгоритмы, которые возвратят уравнение прямой линии от ряда 3D точек данных? Я могу найти много источников, которые дадут уравнение строки от 2D наборов данных, но ни одного в 3D.

Спасибо.

20
задан Saullo G. P. Castro 12 May 2013 в 21:42
поделиться

2 ответа

Если вы пытаетесь предсказать одно значение из двух других, вам следует использовать lstsq с аргументом a в качестве независимых переменных (плюс столбец единиц для оценки перехват) и b в качестве зависимой переменной.

Если, с другой стороны, вы просто хотите получить наиболее подходящую линию для данных, то есть линию, которая, если вы спроецируете на нее данные, минимизирует квадрат расстояния между реальной точкой и ее проекцией, тогда то, что вы хотите, - это первый главный компонент.

Один из способов определить это - линия, вектор направления которой является собственным вектором ковариационной матрицы, соответствующей наибольшему собственному значению, которое проходит через среднее значение ваших данных. Тем не менее, eig (cov (data)) - действительно плохой способ его вычисления, поскольку он выполняет множество ненужных вычислений и копий и потенциально менее точен, чем использование svd . См. Ниже:

import numpy as np

# Generate some data that lies along a line

x = np.mgrid[-2:5:120j]
y = np.mgrid[1:9:120j]
z = np.mgrid[-5:3:120j]

data = np.concatenate((x[:, np.newaxis], 
                       y[:, np.newaxis], 
                       z[:, np.newaxis]), 
                      axis=1)

# Perturb with some Gaussian noise
data += np.random.normal(size=data.shape) * 0.4

# Calculate the mean of the points, i.e. the 'center' of the cloud
datamean = data.mean(axis=0)

# Do an SVD on the mean-centered data.
uu, dd, vv = np.linalg.svd(data - datamean)

# Now vv[0] contains the first principal component, i.e. the direction
# vector of the 'best fit' line in the least squares sense.

# Now generate some points along this best fit line, for plotting.

# I use -7, 7 since the spread of the data is roughly 14
# and we want it to have mean 0 (like the points we did
# the svd on). Also, it's a straight line, so we only need 2 points.
linepts = vv[0] * np.mgrid[-7:7:2j][:, np.newaxis]

# shift by the mean to get the line in the right place
linepts += datamean

# Verify that everything looks right.

import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d as m3d

ax = m3d.Axes3D(plt.figure())
ax.scatter3D(*data.T)
ax.plot3D(*linepts.T)
plt.show()

Вот как это выглядит: a 3d plot of a fitted line

44
ответ дан 29 November 2019 в 23:27
поделиться

В меню можно включить строку состояния вызова.

Аппаратное обеспечение > Переключение строки состояния вызова

-121--3375257-

Мы знаем, что две звездные линии перпендикулярны, если произведение их откосов равно -1, так как плоскость дана мы можем найти наклоны трех последовательных линий, а затем умножить их, чтобы проверить, действительно ли они перпендикулярны или нет. Предположим, что у нас есть линии L1,L2,L3. Теперь если L1 перпендикулярен L2 и L2 перпендикулярен L3, то это прямоугольник и наклон m (L1) * m (L2) = -1 и m (L2) * m (L3) = -1, то это означает, что это прямоугольник. Код выглядит следующим образом

bool isRectangle(double x1,double y1,
        double x2,double y2,
        double x3,double y3,
        double x4,double y4){
    double m1,m2,m3;
    m1 = (y2-y1)/(x2-x1);
    m2 = (y2-y3)/(x2-x3);
    m3 = (y4-y3)/(x4-x3);

    if((m1*m2)==-1 && (m2*m3)==-1)
        return true;
    else
        return false;
}
-121--1061517-

Если ваши данные достаточно хорошо себя ведут, то должно быть достаточно найти сумму наименьших квадратов расстояния компонента. Тогда вы можете найти линейную регрессию с z независимо от x, а затем снова независимо от y.

Пример документации :

import numpy as np

pts = np.add.accumulate(np.random.random((10,3)))
x,y,z = pts.T

# this will find the slope and x-intercept of a plane
# parallel to the y-axis that best fits the data
A_xz = np.vstack((x, np.ones(len(x)))).T
m_xz, c_xz = np.linalg.lstsq(A_xz, z)[0]

# again for a plane parallel to the x-axis
A_yz = np.vstack((y, np.ones(len(y)))).T
m_yz, c_yz = np.linalg.lstsq(A_yz, z)[0]

# the intersection of those two planes and
# the function for the line would be:
# z = m_yz * y + c_yz
# z = m_xz * x + c_xz
# or:
def lin(z):
    x = (z - c_xz)/m_xz
    y = (z - c_yz)/m_yz
    return x,y

#verifying:
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt

fig = plt.figure()
ax = Axes3D(fig)
zz = np.linspace(0,5)
xx,yy = lin(zz)
ax.scatter(x, y, z)
ax.plot(xx,yy,zz)
plt.savefig('test.png')
plt.show()

Если вы хотите минимизировать фактические ортогональные расстояния от прямой (ортогональные к прямой) до точек в 3-пространстве (что, я не уверен, даже называется линейной регрессией). Тогда я бы построил функцию, которая вычисляет RSS и использовать scipy.optimize минимизацию функцию для ее решения.

3
ответ дан 29 November 2019 в 23:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: