سؤال

هل هناك أي خوارزميات ستعيد معادلة الخط المستقيم من مجموعة نقاط البيانات ثلاثية الأبعاد؟يمكنني العثور على الكثير من المصادر التي ستعطي معادلة خط من مجموعات البيانات ثنائية الأبعاد، ولكن لا شيء ثلاثي الأبعاد.

شكرًا.

هل كانت مفيدة؟

المحلول

إذا كنت تحاول التنبؤ بقيمة واحدة من القيمتين الأخريين، فيجب عليك استخدام lstsq مع ال a الوسيطة كمتغيراتك المستقلة (بالإضافة إلى عمود من 1 لتقدير التقاطع) و 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

نصائح أخرى

إذا تم تصرف بياناتك بشكل جيد إلى حد ما ، فيجب أن تكون كافية للعثور على مجموع المربعات من مسافات المكون. ثم يمكنك العثور على الانحدار الخطي مع 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-Space (والتي لست متأكدًا حتى يشار إليها على أنها الانحدار الخطي). بعد ذلك ، أود أن أقوم بإنشاء وظيفة تقوم بحساب RSS واستخدام وظيفة تقليل Scipy.Optimize لحلها.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top