2017-01-27 1 views
1

와 NumPy와 구분을 할 수없는 I는 Y 데이터 3 개 세그먼트

x = np.array([-1.280199006, -1.136209343, -1.048070216, -0.9616764178, -0.8752826199, -0.7871434926, -0.6981317008, -0.6108652382, -0.5235987756, -0.4372049776, 
-0.3490658504, -0.2644173817, -0.1762782545, 
-0.0907571211, 0, 0.09250245036, 0.1762782545, 0.2661627109, 0.3516838443, 0.4345869837, 0.529707428, 0.6108652382, 0.7007496947, 0.7880161573, 0.872664626, 
0.9616764178, 1.055051533, 1.160643953, 1.274090354, 1.413716694]) 

y = np.array([-0.05860218717, -0.05275174988, -0.04961805822, -0.02860635697, -0.04150466841, -0.02672933264, -0.02422597285, -0.03056176732, -0.02885180089, -0.02085851636, 
-0.02873319291, -0.02374542821, -0.02132671806, 
-0.02088924602, -0.0216617248, -0.01835553738, -0.01369531698, -0.01331112368, -0.01156455074, -0.009163690404, -0.003542622659, -0.003515924976, -0.003828831726, -0.002622163805, -0.001622083468, 
-0.00297346133, -0.001845415856, -0.001913228234, -0.001495496086, -0.001454621173]) 

적어도 3 선분

와 NumPy와 구분과 맞하고자는 I이

을 다음 X 시도
def piecewise_linear(x, x0, x1, y0, y1, k1, k2, k3): 
    conds = [x<x0, (x>=x0) & (x<x1),x>=x1] 
    funcs = [lambda x:k1*(x-x0) + y0, lambda x:k2*(x-x0) + y0, lambda x:k2*(x1-x0) + y0 + k3*(x-x1)] 
    return np.piecewise(x, conds, funcs) 
p , e = curve_fit(piecewise_linear, x, y) 
xd = np.linspace(-1.3, 1.5, 100) 
plt.plot(x, y, "o") 
plt.plot(xd, piecewise_linear(xd, *p)) 

하지만

X1 설정 = 0.266162745743

X0 = 0.323723668069

즉 높이 X0> X1. 그것은 2 개의 세그먼트 적합을 끝내는 것을 끝낸다.

내가 뭘 잘못하고 있니? 데이터를 확장해야합니까? 좀 더 일반적으로 세그먼트별로 사용하는 세그먼트의 수를 제어하는 ​​방법이 있습니까?

+1

문제는'piecewise'가 아닌'curve_fit'과 함께있을 가능성이 큽니다. 그것에 대해 생각해보십시오. 그것은'x0'과'x1'을 선택하는'curve_fit'입니다. 당신은 초기 추측으로'curve_fit'를 시도하고'x1'이'x0'보다 더 큰지 확인하십시오. –

+0

@ Paul Panzer 좋은 지적. 별다른 변화없이 몇 가지 초기 추측을 시도했습니다. 좀 더 노력할 것입니다. – JennyToy

+1

그리고 람다 중 세 번째가'λ x : k2 * (x1-x0) + y0 + k3 * (x-x1)'이되어서는 안됩니까? 그건 적어도 당신이 조각을 연결하게하는 데 필요한 것입니다. –

답변

1

문제는 piecewise이 함수 대신 배열을 반환한다는 것입니다. 따라서 y1은 독립적 인 매개 변수가 아닙니다. 함수를 정의 길는 연산 환경 (1 = 참, 거짓 = 0)에서 부울 값을 사용하는 것이다 : 여기

def f(x,x0,y0,x1,k1,k2,k3): 
    # x0,y0 : first breakpoint 
    # x1 : second breakpoint 
    # k1,k2,k3 : 3 slopes. 

    y1=y0+ k2*(x1-x0) # for continuity 
    return (
    (x<x0)    * (y0 + k1*(x-x0))  + 
    ((x>=x0) & (x<x1)) * (y0 + k2*(x-x0))  + 
    (x>=x1)    * (y1 + k3*(x-x1))) 

p0=(-.7,-0.03,.5,0.03,0.02,0.01) 
p , e = curve_fit(f, x, y,p0) 
close() 
plt.plot(x, y, "o") 
plot(x,f(x,*p)) 
show() 

가 적합하다. enter image description here