2016-10-06 43 views
5

tôi đang có các thông tin sau (dataframe) trong pythonLàm thế nào để chạy hồi quy phi tuyến tính trong python

product baskets scaling_factor 
12345 475  95.5 
12345 108  57.7 
12345 2  1.4 
12345 38  21.9 
12345 320  88.8 

và tôi muốn chạy phi tuyến tính hồi quyước tính các thông số sau.

a, b và c

phương trình mà tôi muốn để phù hợp với:

scaling_factor = a - (b*np.exp(c*baskets)) 

Trong sas chúng ta thường chạy mô hình sau: (sử dụng phương pháp gauss newton)

proc nlin data=scaling_factors; 
parms a=100 b=100 c=-0.09; 
model scaling_factor = a - (b * (exp(c*baskets))); 
output out=scaling_equation_parms 
parms=a b c; 

là có một cách tương tự để ước tính các tham số trong Python bằng cách sử dụng hồi quy không tuyến tính, làm thế nào tôi có thể thấy cốt truyện trong python.

+3

Tôi đề nghị bạn kiểm tra hồi quy phi tuyến tính trong scipy http://scipy-cookbook.readthedocs.io/items/robust_regression.html –

+0

vâng, chỉ nhìn vào điều đó, nhưng không thể tìm ra cách, làm thế nào họ đã sử dụng t_train trong y_train – Mukul

Trả lời

3

Đồng ý với Chris Mueller, tôi cũng sử dụng scipy nhưng scipy.optimize.curve_fit. Mã này trông giống như:

###the top two lines are required on my linux machine 
import matplotlib 
matplotlib.use('Qt4Agg') 
import matplotlib.pyplot as plt 
from matplotlib.pyplot import cm 
import numpy as np 
from scipy.optimize import curve_fit #we could import more, but this is what we need 
###defining your fitfunction 
def func(x, a, b, c): 
    return a - b* np.exp(c * x) 
###OP's data 
baskets = np.array([475, 108, 2, 38, 320]) 
scaling_factor = np.array([95.5, 57.7, 1.4, 21.9, 88.8]) 
###let us guess some start values 
initialGuess=[100, 100,-.01] 
guessedFactors=[func(x,*initialGuess) for x in baskets] 
###making the actual fit 
popt,pcov = curve_fit(func, baskets, scaling_factor,initialGuess) 
#one may want to 
print popt 
print pcov 
###preparing data for showing the fit 
basketCont=np.linspace(min(baskets),max(baskets),50) 
fittedData=[func(x, *popt) for x in basketCont] 
###preparing the figure 
fig1 = plt.figure(1) 
ax=fig1.add_subplot(1,1,1) 
###the three sets of data to plot 
ax.plot(baskets,scaling_factor,linestyle='',marker='o', color='r',label="data") 
ax.plot(baskets,guessedFactors,linestyle='',marker='^', color='b',label="initial guess") 
ax.plot(basketCont,fittedData,linestyle='-', color='#900000',label="fit with ({0:0.2g},{1:0.2g},{2:0.2g})".format(*popt)) 
###beautification 
ax.legend(loc=0, title="graphs", fontsize=12) 
ax.set_ylabel("factor") 
ax.set_xlabel("baskets") 
ax.grid() 
ax.set_title("$\mathrm{curve}_\mathrm{fit}$") 
###putting the covariance matrix nicely 
tab= [['{:.2g}'.format(j) for j in i] for i in pcov] 
the_table = plt.table(cellText=tab, 
        colWidths = [0.2]*3, 
        loc='upper right', bbox=[0.483, 0.35, 0.5, 0.25]) 
plt.text(250,65,'covariance:',size=12) 
###putting the plot 
plt.show() 
###done 

Cuối cùng, đem lại cho bạn: enter image description here

+0

woah.điều này hoàn toàn phù hợp với đầu ra của sas. cảm ơn rất nhiều – Mukul

+0

@Mukul Bạn rất vui. Lưu ý rằng bạn có thể đạt được kết quả tương tự với một số chức năng 'scipy', bao gồm' giảm thiểu' theo đề xuất của Chris Mueller và 'leastsq', ví dụ: người thứ hai cũng có thể cung cấp ma trận hiệp phương sai nếu bạn áp dụng tùy chọn 'full_output'. Cũng lưu ý, một dự đoán tốt cho các giá trị ban đầu luôn luôn giúp đỡ, nhưng tôi đoán bạn đã có điều đó rồi. – mikuszefski

5

Đối với các vấn đề như thế này, tôi luôn sử dụng scipy.optimize.minimize với chức năng hình vuông nhỏ nhất của riêng tôi. Thuật toán tối ưu hóa không xử lý sự khác biệt lớn giữa các đầu vào khác nhau, vì vậy bạn nên chia tỷ lệ các tham số trong hàm của mình để các tham số tiếp xúc với scipy là tất cả theo thứ tự 1 như tôi đã thực hiện bên dưới.

import numpy as np 

baskets = np.array([475, 108, 2, 38, 320]) 
scaling_factor = np.array([95.5, 57.7, 1.4, 21.9, 88.8]) 

def lsq(arg): 
    a = arg[0]*100 
    b = arg[1]*100 
    c = arg[2]*0.1 
    now = a - (b*np.exp(c * baskets)) - scaling_factor 
    return np.sum(now**2) 

guesses = [1, 1, -0.9] 
res = scipy.optimize.minimize(lsq, guesses) 

print(res.message) 
# 'Optimization terminated successfully.' 

print(res.x) 
# [ 0.97336709 0.98685365 -0.07998282] 

print([lsq(guesses), lsq(res.x)]) 
# [7761.0093358076601, 13.055053196410928] 

Tất nhiên, như với tất cả các vấn đề giảm thiểu, điều quan trọng là sử dụng các dự đoán ban đầu tốt vì tất cả các thuật toán có thể bị kẹt ở mức tối thiểu địa phương. Có thể thay đổi phương pháp tối ưu hóa bằng cách sử dụng từ khóa method; một số khả năng là

  • 'Nelder-Mead'
  • 'Powell'
  • 'CG'
  • 'BFGS'
  • 'Newton-CG'

Giá trị mặc định là BFGS theo the documentation.

+0

cảm ơn nhiều vì điều này, ngoài sự tò mò mà phương pháp nào được sử dụng theo mặc định? Tôi có thể sử dụng đoán = [100,100, -0,09] như đã đề cập trong nlin proc trong sas ở trên. Ngoài ra làm thế nào là điều này khác nhau từ "scipy.optimize nhập khẩu most_squares" – Mukul

+0

@Mukul Tôi đã không nhận ra đó là những dự đoán của bạn, tôi không quen thuộc với SAS. Tôi đã cập nhật câu trả lời để sử dụng các giá trị đó. Lưu ý rằng tôi đã thu nhỏ các thông số trong hàm bình phương nhỏ nhất để giữ chúng gần như 1. –

+0

ok. điều này dường như đã làm việc. nhưng nhận được thông báo sau "Lỗi mong muốn không nhất thiết phải đạt được do mất chính xác" – Mukul

Các vấn đề liên quan