2017-08-13 124 views
2

我试图绘制给定(x,y)数据点的最佳拟合线。2d中的点的最小二乘拟合不通过对称轴

image

在这里示出的数据点(红色像素)和估计线(绿色),I得到使用以下库。对于使用library module

我们可以看到数据点

import numpy as np  
m, c = np.linalg.lstsq(A, y)[0] 

文档大致对称分布。问题是为什么这条线没有类似于通过数据点的长对称轴的梯度?你能解释一下这个结果是否正确?那么,它如何给出最小误差? (使用由lstsq方法返回的渐变绘制的线条正确)。谢谢。

编辑

这里是我想要的代码。输入图像可以从here下载。在这段代码中,我并没有强制这条线穿过像素分布的中心。 (注:这里我用polyfit代替lstsq两个给出相同的结果。)

import numpy as np 
import cv2 
import math 

img = cv2.imread('points.jpg',1); 
h, w = img.shape[:2] 
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 

points = np.argwhere(gray>10) # get (x,y) pairs where red pixels exist 
y = points[:,0] 
x = points[:,1] 

m, c = np.polyfit(x, y, 1)  # calculate least square fit line 

# calculate two cordinates (x1,y1),(x2,y2) on the line 
angle = np.arctan(m) 
x1, y1, length = 0, int(c), 500 
x2 = int(round(math.ceil(x1 + length * np.cos(angle)),0)) 
y2 = int(round(math.ceil(y1 + length * np.sin(angle)),0)) 
# draw line on the color image 
cv2.line(img, (x1, y1), (x2, y2), (0,255,0), 1, cv2.LINE_8) 
# show output the image 
cv2.namedWindow("Display window", cv2.WINDOW_AUTOSIZE); 
cv2.imshow("Display window", img); 
cv2.waitKey(0); 
cv2.destroyAllWindows() 

我怎么能有行通过像素分布的最长的对称轴?我可以使用主成分分析吗?

+0

我同意绿线看起来不正确 –

+3

然而,这是不可重现的没有数据 –

+2

这不是一个密度图。如果情节的长手伸得很薄,而核心是密集的和倾斜的,你可以期望这种适合。最小二乘回归也不是一个可靠的方法。我会第二次请求上面张贴的Jared的数据。 –

回答

1

如果红点确实代表了您的数据,那么您可能会以强制直线穿过原点的方式应用线性回归函数。我怎么知道?当对两个变量x和y使用线性回归时,该线将截取几个特定点。例如x的平均值和y的平均值。此外,根据您的规格,计算或指定y轴的截距。如果x和y的所有变量都是正数,那么如果线被强制通过原点,您将会看到一条与您的线相似的线。在提供一些可重复的数据和代码之前,没有更多可以说的了。

编辑: 我没有与提供的样本reproducble多少运气,所以我用内置的随机数为例,阐述我原来的答复。我认为statsmodels是一个体面的线性回归分析库。首先,我要解决这个先前的评论:

如果x和y的所有变量都为正,你将有一行看起来像你如果线路强行通过原点。

你会看到越大的数字越大(离你的数字越远),你会看到越来越多的效果。使用sm.OLS(y,sm.add_constant(x)).fit()sm.OLS(y,x).fit()为两组不同的数字将向您显示我的意思。首先,我将对以下的数据集进行回归,而不是估计的常数(该线通过原点)。这将为我们提供一个情节,在类似于原来的情节:

# Libraries 
import statsmodels.api as sm 
import numpy as np 
import matplotlib.pyplot as plt 

# Data 
np.random.seed(123) 
x = np.random.normal(size=2500) + 100 
y = x * 2 + np.random.normal(size=2500) + 100 

# Regression 
results1 = sm.OLS(y,x).fit() 
regLine_origin = x*results1.params[0] 

# PLot 
fig, ax = plt.subplots() 
ax.scatter(x, y, c='red', s=4) 
ax.scatter(x, regLine_origin, c = 'green', s = 1) 

ax.patch.set_facecolor('black') 
plt.show() 

enter image description here

接下来,我将包括回归的常数。现在,黄线将代表什么,我认为你在你的问题是后:

# Libraries 
import statsmodels.api as sm 
import numpy as np 
import matplotlib.pyplot as plt 

# Data 
np.random.seed(123) 
x = np.random.normal(size=2500) + 100 
y = x * 2 + np.random.normal(size=2500) + 100 

# Regression 
results1 = sm.OLS(y,x).fit() 
results2 = sm.OLS(y,sm.add_constant(x)).fit() 
regLine_origin = x*results1.params[0] 
regLine_constant = results2.params[0] + x*results2.params[1] 

# PLot 
fig, ax = plt.subplots() 
ax.scatter(x, y, c='red', s=4) 
ax.scatter(x, regLine_origin, c = 'green', s = 1) 
ax.scatter(x, regLine_constant, c = 'yellow', s = 1) 

ax.patch.set_facecolor('black') 
plt.show() 

enter image description here

最后,我们可以看看当数字接近原点发生了什么。可以这么说。这里,当数生产,我会删除+100部分:

# The following is changed in the snippet above: 
# Data 
x = np.random.normal(size=2500) 
y = x * 2 + np.random.normal(size=2500) 

enter image description here

这就是为什么我认为你原来的回归线被设置为穿过原点。看看statsmodels包。在这里,您可以通过运行print(results2.summary())研究估计的细节:

enter image description here

正如你已经看到在上面的代码片段,您可以通过使用results2.params必须回归系数的直接访问。

enter image description here

EDIT2:我的解释仍然不是100%有效。 x和y值的大小必须有所不同才能看到这种效果。无论数字大小如何,您一定会发现线路经过原点的情况。 看看不同的x标签,你会明白我的意思。

3

很难说为什么会出现这种情况。底线是我看不到你正在使用的数据,我看不到你正在使用的数据的计算斜率和y截距。

下面是一些可以解释我们所看到的内容的事情: (1)数据点的密度实际上与随便看一眼看上去完全不同,而且一切正常。 (2)你正在向最小二乘函数发送错误的参数,并且你有GIGO情况。 (我没有使用numpy的最小二乘算法,所以我不能检查这个。) (3)散点图和线图不同意轴的比例。 (4)有问题的最小二乘函数被打破。 (5)当您传递给绘图例程时,您不会将相同的数据传递给最小二乘算法。 (6)数据格式很时髦,因此散点图和最小二乘例程以不同的方式解释您的数据。

我不知道这些是哪个问题,除非是(3),否则我希望我们需要更多的数据来区分这些可能性。

下面是我如果我是你的过程:(1)创建一个小的仿真数据集,将它放在一条线上,并将其传递给最小二乘函数,看看它是否吐出正确的数字。看看这些看起来是否正确,当绘制或不。 (2)如果这看起来没问题,记录最小二乘算法的输出,看看是否可以找到另一个最小平方程序来计算斜率和y截距并比较它们。如果它们是相同的,那可能不是常规,这可能与绘图有关。

如果你得到这么多,它仍然是一个谜,让我们知道你找到了什么,也许我们可以提出另一个建议。

祝你好运。

+0

我对已知数据集应用了相同的算法。以及其他未知数据集都与我的假设相一致。那些线穿过对称轴。这是我得到意想不到的结果的唯一案例。我会将问题更新为可重现的问题,给我2h。谢谢。 – TRiNE

+0

我添加了一个可重现的问题代码。谢谢。 – TRiNE

+0

我完全不理解你的第一句话,这个假设是什么?你认为什么是错的?我对你的代码不感兴趣,而不是你的数据。是否有可能您可以在某处连同您的线路的斜率和截距一起发布? – ngc5194