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

标签 python scikit-learn linear-regression

我在空图像上绘制二维椭圆。现在,我想通过椭圆拟合一条线以获得长轴。知道有很多选择(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

我真的很困惑,有什么想法吗?我正在使用岭回归和套索回归来调整权重,但它们降低了权重,但似乎权重,即斜率必须更陡,我认为线性回归低估了斜率。有趣的是,线性回归通常是一种“点”对称,但不是跨线对称......我理解接近 0° 的行为,斜率不能是无穷大。但它至少应该适用于低度旋转。

最佳答案

回归线不能与主轴重合,因为回归在 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))

关于python - 通过椭圆的线性回归显示意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54888950/

相关文章:

python - 如何使用 Python Gekko 解决绝对值 abs() 目标?

python - 带有 pandas 的日期正则表达式过滤器不起作用

Python列表元素与转换为元组以进行字符串格式化

scikit-learn - 无法使用 sklearn 0.24.1 导入 LSHForest

python - 我怎样才能让 GradientBoostingRegressor 与 scikit-learn 中的 BaseEstimator 一起工作?

python - 混淆OneClassSVM的 "dual_coef_"

machine-learning - 为范围内存在的输入值选择机器学习算法

python - 如何从 "cell"对象的 "groupby"获取值?

data-science - 分类变量的标准化或缩放

encoding - 回归分析中如何区分分类变量和序数变量?