通过椭圆的线性回归显示出意外的行为

时间:2019-02-26 15:28:59

标签: python scikit-learn linear-regression

我正在空白图像上绘制2D椭圆。现在,我想在椭圆中拟合一条线以获取主轴。知道有很多选择(PCA,图像矩等)后,我想到了线性回归应该可以胜任。但是,仅当椭圆的旋转平行于x轴时才“起作用”。为什么是这样?对称分布的对称点云不应该给中线吗?

这是我使用的代码:

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
from skimage.draw import ellipse
from ipywidgets import interact
from sklearn.linear_model import LinearRegression

@interact
def rotateAndFit(rot:(-90,90)=-90):
    im = np.zeros((300,300), dtype=np.float64)
    im[ellipse(im.shape[0]//2, # center x
               im.shape[1]//2-10, # center y
               120,            # radius major axis
               40,             # radius minor axis
               im.shape,       # image shape
               rot/180*np.pi)] = 1  # rotation angle in degree,


    # Get corresponding x and y values
    y, x = np.where(im)

    # Do Linear Regression
    lr = LinearRegression()
    lr.fit(x[None].T,y)

    plt.imshow(im)
    plt.plot([0, 300], [lr.intercept_, lr.coef_[0]*300+lr.intercept_])
    plt.axis([0,300,300,0])
    plt.title('rotation $r = {}°$'.format(rot))

代码提供以下输出:

Rotation of ellipse and corresponding linear fit

我真的很困惑,有什么想法吗?我使用了ridge和lasso回归来调整权重,但是它们降低了权重,但是似乎权重(即斜率必须更陡峭),我认为线性回归低估了斜率。有趣的是,线性回归通常是“点”对称的,但在整个直线上不是对称的...行为接近0°,我知道斜率不能无穷大。但是它至少应该在低旋转度下工作。

2 个答案:

答案 0 :(得分:3)

回归线不能与主轴重合,因为回归在y方向上最小化,而不是垂直于回归线。以下示例使用正交距离回归代替y中的线性回归,并给出了所需的结果:

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
from skimage.draw import ellipse
from ipywidgets import interact
from sklearn.linear_model import LinearRegression
from scipy.odr import ODR, Model, Data

def lin(beta, x):
    a,b = beta
    return a*x+b

@interact(rot=(-90,90))
def rotateAndFit(rot=-90):
    im = np.zeros((300,300), dtype=np.float64)
    im[ellipse(im.shape[0]//2, # center x
               im.shape[1]//2-10, # center y
               120,            # radius major axis
               40,             # radius minor axis
               im.shape,       # image shape
               rot/180*np.pi)] = 1  # rotation angle in pi (40°),


    y, x = np.where(im)

    d = Data(x,y)
    m = Model(lin)
    o = ODR(d, m, [0,0])
    out = o.run()
    a,b = out.beta

    plt.imshow(im)
    plt.plot([0, 300], [b, a*300+b])
    plt.axis([0,300,300,0])
    plt.title('rotation $r = {}°$'.format(rot))

答案 1 :(得分:2)

要添加到上面的答案中,以下是使用带椭圆点的OLS进行操作的示意图。由于每个x都有两个点,因此您实际上是在每个x上找到y的均值。对于未旋转的椭圆(图中的顶部椭圆),这可以按预期工作。但是,当您旋转椭圆形(底部椭圆形)时,在给定的x处,椭圆上两点之间的中间点与椭圆的主轴线完全偏离。是的,您必须最小化与旋转轴正交的坐标。

schematic result of an OLS regression for points of an ellipse