python中的分段线性回归

时间:2012-01-25 07:55:38

标签: python linear-regression

python中有一个库可以segmented linear regression吗? 我想自动为我的数据添加多行来得到这样的东西: segmented regression

顺便说一下。我知道段的数量。

3 个答案:

答案 0 :(得分:2)

答案 1 :(得分:0)

enter image description here

如上面的评论中所述,分段线性回归带来了许多自由参数的问题。因此,我决定放弃使用n_segments * 3-1参数(即n_segments-1个细分位置,n_segment y-offest,n_segment斜率)并执行数值优化的方法。相反,我要寻找斜率已经基本恒定的区域。

算法

  • 计算所有点的斜率
  • 具有与分段相似的斜率的聚类点(由DecisionTree完成)
  • 对线段执行LinearRegression,在上一步中找到

使用决策树而不是聚类算法来获取连接的段而不是(非相邻)点集。可以通过决策树参数(当前为max_leaf_nodes)来调整细分的细节。

代码

import numpy as np
import matplotlib.pylab as plt
from sklearn.tree import DecisionTreeRegressor
from sklearn.linear_model import LinearRegression

# parameters for setup
n_data = 20

# segmented linear regression parameters
n_seg = 3

np.random.seed(0)
fig, (ax0, ax1) = plt.subplots(1, 2)

# example 1
#xs = np.sort(np.random.rand(n_data))
#ys = np.random.rand(n_data) * .3 + np.tanh(5* (xs -.5))

# example 2
xs = np.linspace(-1, 1, 20)
ys = np.random.rand(n_data) * .3 + np.tanh(3*xs)

dys = np.gradient(ys, xs)

rgr = DecisionTreeRegressor(max_leaf_nodes=n_seg)
rgr.fit(xs.reshape(-1, 1), dys.reshape(-1, 1))
dys_dt = rgr.predict(xs.reshape(-1, 1)).flatten()

ys_sl = np.ones(len(xs)) * np.nan
for y in np.unique(dys_dt):
    msk = dys_dt == y
    lin_reg = LinearRegression()
    lin_reg.fit(xs[msk].reshape(-1, 1), ys[msk].reshape(-1, 1))
    ys_sl[msk] = lin_reg.predict(xs[msk].reshape(-1, 1)).flatten()
    ax0.plot([xs[msk][0], xs[msk][-1]],
             [ys_sl[msk][0], ys_sl[msk][-1]],
             color='r', zorder=1)

ax0.set_title('values')
ax0.scatter(xs, ys, label='data')
ax0.scatter(xs, ys_sl, s=3**2, label='seg lin reg', color='g', zorder=5)
ax0.legend()

ax1.set_title('slope')
ax1.scatter(xs, dys, label='data')
ax1.scatter(xs, dys_dt, label='DecisionTree', s=2**2)
ax1.legend()

plt.show()

答案 2 :(得分:-1)

您只需要按升序对X进行排序并创建多个线性回归。您可以使用sklearn中的LinearRegression。

例如,将曲线分为2就是这样的:

from sklearn.linear_model import LinearRegression
import numpy as np
import matplotlib.pyplot as plt
X = np.array([-5,-4,-3,-2,-1,0,1,2,3,4,5])
Y = X**2
X=X.reshape(-1,1)
reg1 = LinearRegression().fit(X[0:6,:], Y[0:6])
reg2 = LinearRegression().fit(X[6:,:], Y[6:])

fig = plt.figure('Plot Data + Regression')
ax1 = fig.add_subplot(111)
ax1.plot(X, Y, marker='x', c='b', label='data')
ax1.plot(X[0:6,],reg1.predict(X[0:6,]), marker='o',c='g', label='linear r.')
ax1.plot(X[6:,],reg2.predict(X[6:,]), marker='o',c='g', label='linear r.')
ax1.set_title('Data vs Regression')
ax1.legend(loc=2)
plt.show()

enter image description here

我做了类似的实现,下面是代码: https://github.com/mavaladezt/Segmented-Algorithm