如何在Python中对具有正斜率和负斜率的线应用分段线性拟合? [英] How to apply piecewise linear fit for a line with both positive and negative slopes in Python?

查看:63
本文介绍了如何在Python中对具有正斜率和负斜率的线应用分段线性拟合?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在代码中提供的数据具有负斜率和正斜率,如图所示:

I have data provided in the code which have negative and positive slopes as shown in figure:

使用本文中应用的代码拟合一条曲线以处理由两个不同的方案组成的数据,我创建了此代码.它适用于正斜率或负斜率的相同斜率,但是当一个正斜率和另一个负斜率时,将无法正确拟合线条.

Using the code applied in this post Fit a curve for data made up of two distinct regimes, I created this code. It works for same slopes either both positive or both negative, but when one is positive and other negative, it is not able to fit the lines properly.

from scipy import optimize
from scipy import optimize, interpolate
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
import numpy as np


x = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20])
y = np.array([4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4])


def two_lines(x, a, b, c, d):
    one = a*x + b
    two = c*x + d
    return np.maximum(one, two)


'''Compute approximate slope and intercept of the two lines'''
poly_low = np.polyfit(x[0:int(0.5*(len(x) + 1))], y[0:int(0.5*(len(x) + 1))], deg=1)
poly_high = np.polyfit(x[int(0.5*(len(x) + 1)):len(x)], y[int(0.5*(len(x) + 1)):len(x)], deg=1)

# This part of the code credit goes to askewchan
pw0 = (poly_low[0], poly_low[1], poly_high[0], poly_high[1]) # a guess for slope, intercept, slope, intercept
pw, cov = curve_fit(two_lines, x, y, pw0)
crossover = (pw[3] - pw[1]) / (pw[0] - pw[2])


figure = plt.figure(figsize=(5.15, 5.15))
figure.clf()
plot = plt.subplot(111)
plt.plot(x, y, 'o', x, two_lines(x, *pw), '-')
plot.set_ylabel('Y', labelpad = 6)
plot.set_xlabel('X', labelpad = 6)
plt.show()

输出

对于不同的坡度:

对于相同的斜率都为负(对于正斜率也适用):

For same slope both negative (works fine for positive slopes also):

我有两个问题:

  1. 如何在Python中对这种情况应用分段线性拟合?
  2. 如何将其扩展到三个或更多个政权?

推荐答案

您可以将分段区域用于分段功能:

You could use masked regions for piece-wise functions:

def two_lines(x, a, b, c, d):
    out = np.empty_like(x)
    mask = x < 10
    out[mask] = a*x[mask] + b
    out[~mask] = c*x[~mask] + d
    return out

第一次测试有两个不同的正斜率:

First test with two different positive slopes:

x = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
              17, 18, 19, 20])
y = np.array([4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 25, 26, 27, 28, 29,
    30, 31, 32, 33, 34])

具有正斜率和负斜率的第二项测试(来自您的示例的数据):

Second test with a positive and a negative slope (data from your example):

这篇关于如何在Python中对具有正斜率和负斜率的线应用分段线性拟合?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆