2017-08-13 125 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