Tôi gặp một chút rắc rối khi lắp đường cong vào một số dữ liệu, nhưng không thể tìm ra nơi tôi đang đi sai.Đường cong phân rã theo cấp số nhân phù hợp với vũng nước và scipy
Trong quá khứ tôi đã làm điều này với numpy.linalg.lstsq cho hàm mũ và scipy.optimize.curve_fit cho các chức năng sigmoid. Lần này tôi muốn tạo một kịch bản lệnh cho phép tôi chỉ định các hàm khác nhau, xác định các tham số và kiểm tra sự phù hợp của chúng với dữ liệu. Trong khi làm điều này tôi nhận thấy rằng Scipy leastsq
và Numpy lstsq
dường như cung cấp các câu trả lời khác nhau cho cùng một bộ dữ liệu và cùng một chức năng. Hàm này chỉ đơn giản là y = e^(l*x)
và bị hạn chế sao cho y=1
tại x=0
.
Đường xu hướng Excel đồng ý với kết quả Numpy lstsq
, nhưng khi Scipy leastsq
có thể thực hiện bất kỳ chức năng nào, bạn nên tìm ra vấn đề là gì.
import scipy.optimize as optimize
import numpy as np
import matplotlib.pyplot as plt
## Sampled data
x = np.array([0, 14, 37, 975, 2013, 2095, 2147])
y = np.array([1.0, 0.764317544, 0.647136491, 0.070803763, 0.003630962, 0.001485394, 0.000495131])
# function
fp = lambda p, x: np.exp(p*x)
# error function
e = lambda p, x, y: (fp(p, x) - y)
# using scipy least squares
l1, s = optimize.leastsq(e, -0.004, args=(x,y))
print l1
# [-0.0132281]
# using numpy least squares
l2 = np.linalg.lstsq(np.vstack([x, np.zeros(len(x))]).T,np.log(y))[0][0]
print l2
# -0.00313461628963 (same answer as Excel trend line)
# smooth x for plotting
x_ = np.arange(0, x[-1], 0.2)
plt.figure()
plt.plot(x, y, 'rx', x_, fp(l1, x_), 'b-', x_, fp(l2, x_), 'g-')
plt.show()
Edit - thêm thông tin
Các MWe trên đã bao gồm một mẫu nhỏ của tập dữ liệu. Khi lắp dữ liệu thực tế, đường cong scipy.optimize.curve_fit trình bày R^2 là 0,82, trong khi đường cong numpy.linalg.lstsq, tương tự như được tính toán bằng Excel, có R^2 trong tổng số 0,41 .
Cảm ơn @ Jaime - câu trả lời tuyệt vời!Thật không may là kiến thức toán học của tôi không phải là tuyệt vời; là viết hay sai [cũng thấy sửa đổi ở trên], hoặc chúng chỉ khác về cơ bản ...? Các hàm ý cho các hàm khác, ví dụ, nếu tôi muốn kiểm tra sự phù hợp của đường cong Sigmoid hoặc Gompertz với cùng một dữ liệu? – StacyR
@StacyR Tôi không có kiến thức để trả lời đúng câu hỏi của bạn, nhưng tôi khá chắc chắn rằng phù hợp với một hàm mũ như bạn đã làm với 'np.linalg.lstsq' chỉ là một mẹo nhanh chóng mà không tính toán lỗi đúng cách. Có một số cuộc thảo luận (khó khăn cho tôi để làm theo) ở đây: http://mathworld.wolfram.com/LeastSquaresFittingExponential.html Nếu bạn không muốn lặn sâu vào công cụ này, tôi sẽ đi với phương pháp của scipy cho tất cả mọi thứ: nó nên cung cấp cho phù hợp hơn, và kết quả của bạn sẽ phù hợp cho tất cả các chức năng. – Jaime
cảm ơn một lần nữa! Tôi đã làm một số nghiên cứu thêm về điều này và, như bạn đã đề cập, đã tìm thấy rằng phương pháp 'np.linalg.lstsq' quá trọng số lỗi y ở các giá trị x thấp. Liên kết mà bạn đã chia sẻ và một số tài nguyên khác tôi tìm thấy, cho phép tôi lấy được một phương pháp phân tích khác (điều làm cho nó phức tạp là ràng buộc --- tất cả các sách mô tả phương pháp cho y = a * e^b * x thay vì hơn y = e^b * x), tuy nhiên, điều này cũng tạo ra một đường cong phù hợp tồi tệ hơn so với 'scipy.optimize.leastsq' lặp lại. – StacyR