Làm thế nào để bạn phù hợp với một đường cong phi tuyến tính trong python?

Ngoài việc vẽ các điểm dữ liệu từ các thí nghiệm của chúng tôi, chúng tôi thường phải khớp chúng với một mô hình lý thuyết để trích xuất các tham số quan trọng. Bài viết ngắn này sẽ phục vụ như một hướng dẫn về cách khớp một tập hợp các điểm với một phương trình mô hình đã biết, mà chúng ta sẽ thực hiện bằng cách sử dụng hàm

# Function to calculate the exponential with constants a and b
def exponential(x, a, b):
return a*np.exp(b*x)
9. Bạn có thể tìm thấy kiến ​​thức cơ bản về vẽ biểu đồ dữ liệu trong Python cho các ấn phẩm khoa học trong bài viết trước của tôi tại đây. Tôi sẽ đi qua ba loại phụ kiện phi tuyến tính phổ biến. (1) hàm mũ, (2) định luật lũy thừa và (3) đỉnh Gaussian

Để sử dụng hàm

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
0, chúng ta sử dụng câu lệnh
# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
1 sau

# Import curve fitting package from scipy
from scipy.optimize import curve_fit

Trong trường hợp này, chúng tôi chỉ sử dụng một chức năng cụ thể từ gói

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
2, vì vậy chúng tôi chỉ có thể nhập trực tiếp
# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
0

Lắp theo cấp số nhân

Giả sử chúng ta có một hàm mũ tổng quát có dạng sau và chúng ta biết biểu thức này phù hợp với dữ liệu của mình (trong đó a và b là các hằng số mà chúng ta sẽ khớp)

Hàm số mũ tổng quát

Trước tiên, chúng ta phải xác định hàm mũ như hình trên để

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
0 có thể sử dụng nó để thực hiện phép tính phù hợp

# Function to calculate the exponential with constants a and b
def exponential(x, a, b):
return a*np.exp(b*x)

Chúng tôi sẽ bắt đầu bằng cách tạo tập dữ liệu “giả” để phù hợp với chức năng này. Để tạo một tập hợp các điểm cho các giá trị x của chúng tôi được phân phối đều trong một khoảng thời gian xác định, chúng tôi có thể sử dụng hàm

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
5

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
6 - giá trị bắt đầu của chuỗi của chúng tôi

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
7 — giá trị kết thúc của chuỗi của chúng ta (sẽ bao gồm giá trị này trừ khi bạn cung cấp thêm đối số
# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
8 )

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
9 — số điểm để chia khoảng thời gian thành (mặc định là
# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
40 )

Lưu ý rằng bạn không cần viết rõ ràng các tên đầu vào —

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
41 đều có giá trị như nhau, nhưng với mục đích của bài viết này, nó giúp mọi thứ dễ theo dõi hơn

Đối với tập dữ liệu giả của chúng tôi, chúng tôi sẽ đặt cả hai giá trị của a và b thành 0. 5

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
4

Để đảm bảo rằng tập dữ liệu của chúng tôi không hoàn hảo, chúng tôi sẽ đưa một số nhiễu vào dữ liệu của mình bằng cách sử dụng

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
42 , lấy một số ngẫu nhiên từ phân phối (Gaussian) bình thường. Sau đó, chúng tôi sẽ nhân giá trị ngẫu nhiên này với hệ số vô hướng (trong trường hợp này là 5) để tăng lượng nhiễu

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
8

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
43 — hình dạng của mảng đầu ra gồm các số ngẫu nhiên (trong trường hợp này giống với kích thước của
# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
44)

Bây giờ, hãy vẽ sơ đồ tập dữ liệu giả của chúng ta để kiểm tra xem nó trông như thế nào. Vì chúng tôi có một tập hợp các điểm dữ liệu ồn ào, chúng tôi sẽ tạo một biểu đồ phân tán, chúng tôi có thể dễ dàng thực hiện việc này bằng cách sử dụng hàm

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
45. Tôi sẽ bỏ qua rất nhiều sửa đổi thẩm mỹ cốt truyện, được thảo luận chi tiết trong bài viết trước của tôi. Để gán màu cho các điểm, tôi trực tiếp sử dụng mã thập lục phân

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
2

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
46 — kích thước điểm đánh dấu theo đơn vị (điểm)², do đó, kích thước điểm đánh dấu được nhân đôi khi giá trị này tăng gấp bốn lần

Biểu đồ phân tán của dữ liệu hàm mũ giả với nhiễu Gaussian được thêm vào

Một phương pháp trực quan hóa dữ liệu hàm mũ thường hữu ích hơn là sử dụng biểu đồ bán logarit vì nó tuyến tính hóa dữ liệu. Để đặt tỷ lệ của trục y từ tuyến tính thành logarit, chúng tôi thêm dòng sau

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
4

Bây giờ chúng ta cũng phải đặt giới hạn dưới của trục y lớn hơn 0 do tiệm cận trong hàm logarit. Ngoài ra, đối với các dấu tick, bây giờ chúng ta sẽ sử dụng hàm

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
47

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
6

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
48 — cơ sở để sử dụng cho các tích tắc chính của trục logarit

Biểu đồ phân tán của dữ liệu hàm mũ giả với trục y logarit

Giờ đây, chúng ta có thể khớp dữ liệu của mình với hàm mũ tổng quát để trích xuất các tham số a và b, đồng thời áp đặt sự phù hợp lên dữ liệu. Lưu ý rằng mặc dù chúng tôi đã trình bày biểu đồ bán nhật ký ở trên, nhưng chúng tôi chưa thực sự thay đổi dữ liệu y — chúng tôi chỉ thay đổi tỷ lệ của trục y. Vì vậy, chúng tôi vẫn đang điều chỉnh dữ liệu phi tuyến tính, điều này thường tốt hơn vì việc tuyến tính hóa dữ liệu trước khi điều chỉnh có thể thay đổi phần dư và phương sai của điều chỉnh

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
8

đầu vào

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
49 — chức năng được sử dụng để lắp (trong trường hợp này là
# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
80)

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
81 — mảng dữ liệu x để khớp

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
82 — mảng dữ liệu y để khớp

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
83 — mảng các dự đoán ban đầu cho các tham số phù hợp (cả a và b đều bằng 0)

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
84 — giới hạn cho các tham số (-∞ đến ∞)

đầu ra

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
85 — mảng các tham số từ sự phù hợp (trong trường hợp này là
# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
86)

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
87 — hiệp phương sai ước tính của
# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
85 có thể được sử dụng để xác định độ lệch chuẩn của các tham số phù hợp (căn bậc hai của các đường chéo)

Chúng tôi có thể trích xuất các tham số và độ lệch chuẩn của chúng từ đầu ra

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
0 và tính toán phần dư bằng cách trừ giá trị được tính toán (từ mức độ phù hợp của chúng tôi) khỏi giá trị quan sát thực tế (dữ liệu giả của chúng tôi)

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
0

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
20 — cho phép chúng tôi hủy kiểm soát mảng
# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
85, tôi. e.
# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
86 được nhập là
# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
23

Thông số phù hợp và độ lệch chuẩn

một = 0. 509 ± 0. 017

b = 0. 499 ± 0. 002

Chúng tôi thấy rằng cả hai tham số phù hợp đều rất gần với các giá trị đầu vào của chúng tôi là

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
24 và
# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
25, vì vậy hàm
# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
0 đã hội tụ thành các giá trị chính xác. Bây giờ chúng ta có thể phủ sự phù hợp lên trên dữ liệu phân tán, đồng thời vẽ biểu đồ phần dư, phần còn lại sẽ được phân phối ngẫu nhiên và gần bằng 0, xác nhận rằng chúng ta có sự phù hợp tốt

# Function to calculate the exponential with constants a and b
def exponential(x, a, b):
return a*np.exp(b*x)
0

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
27 — kiểu đường của đường được vẽ (
# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
28 cho đường đứt nét)

Biểu đồ phân tán của dữ liệu hàm mũ giả với đường phù hợp được phủ

Đồ thị của phần dư từ hàm mũ phù hợp Power-Law Fitting

Một chức năng phù hợp thường được sử dụng khác là luật lũy thừa, trong đó một công thức chung có thể được

Hàm định luật lũy thừa tổng quát

Tương tự như cách chúng tôi đã thực hiện điều chỉnh trước đó, trước tiên chúng tôi xác định chức năng

# Function to calculate the exponential with constants a and b
def exponential(x, a, b):
return a*np.exp(b*x)
1

Sau đó, chúng ta lại có thể tạo tập dữ liệu giả, thêm nhiễu và vẽ đồ thị hàm định luật lũy thừa

# Function to calculate the exponential with constants a and b
def exponential(x, a, b):
return a*np.exp(b*x)
2

Biểu đồ phân tán của dữ liệu định luật lũy thừa giả với nhiễu Gaussian được thêm vào

Tương tự như trường hợp khớp hàm mũ, dữ liệu ở dạng hàm định luật lũy thừa có thể được tuyến tính hóa bằng cách vẽ đồ thị trên biểu đồ logarit — lần này, cả trục x và trục y đều được chia tỷ lệ

# Function to calculate the exponential with constants a and b
def exponential(x, a, b):
return a*np.exp(b*x)
3

Biểu đồ phân tán của dữ liệu định luật lũy thừa giả với các trục logarit

Bây giờ chúng ta có thể làm theo các bước phù hợp giống như chúng ta đã làm đối với dữ liệu hàm mũ

# Function to calculate the exponential with constants a and b
def exponential(x, a, b):
return a*np.exp(b*x)
4

Thông số phù hợp và độ lệch chuẩn

một = 1. 057 ± 0. 096

b = 0. 492 ± 0. 014

Biểu đồ phân tán của dữ liệu định luật lũy thừa giả với đường phù hợp được phủ lên

Âm mưu của phần dư từ phù hợp với định luật quyền lựcGaussian Peak Fitting

Sự phù hợp cực đại với Gaussian, Lorentzian hoặc kết hợp cả hai chức năng thường được sử dụng trong các thí nghiệm như nhiễu xạ tia X và phát quang để xác định độ rộng của đường và các thuộc tính khác. Trong ví dụ này, chúng ta sẽ xử lý sự phù hợp của đỉnh Gaussian, với công thức chung bên dưới

Hàm Gaussian tổng quát____05

Biểu đồ phân tán của dữ liệu Gaussian giả có thêm tiếng ồn

Cũng giống như trong chỉnh hợp hàm mũ và luật lũy thừa, chúng ta sẽ cố gắng thực hiện chỉnh hợp Gaussian với các dự đoán ban đầu là 0 cho mỗi tham số

# Function to calculate the exponential with constants a and b
def exponential(x, a, b):
return a*np.exp(b*x)
6

Tuy nhiên, khi chúng tôi làm điều này, chúng tôi nhận được kết quả sau

# Function to calculate the exponential with constants a and b
def exponential(x, a, b):
return a*np.exp(b*x)
7

Có vẻ như dự đoán ban đầu của chúng tôi không cho phép hội tụ các tham số phù hợp, vì vậy chúng tôi có thể chạy lại điều chỉnh với dự đoán ban đầu thực tế hơn. Bạn có thể làm điều này bằng cách kiểm tra đỉnh mà bạn đang cố gắng điều chỉnh và chọn các giá trị ban đầu hợp lý

# Function to calculate the exponential with constants a and b
def exponential(x, a, b):
return a*np.exp(b*x)
8

Lần này, sự phù hợp của chúng tôi thành công và chúng tôi còn lại các tham số phù hợp và phần dư sau đây

Thông số phù hợp và độ lệch chuẩn

một = 8. 074 ± 0. 128

b = –0. 948 ± 0. 054

c = 2. 945 ± 0. 054

Biểu đồ phân tán của dữ liệu Gaussian giả với sự phù hợp được phủ lên

Đồ thị phần dư của phù hợp GaussianKết luận

Hy vọng rằng, theo hướng dẫn của các ví dụ trước, bây giờ bạn có thể khớp dữ liệu thử nghiệm của mình với bất kỳ hàm phi tuyến tính nào. Tôi hy vọng bạn thích hướng dẫn này và tất cả các ví dụ được trình bày ở đây có thể được tìm thấy tại kho lưu trữ Github này

không phải là gì

Một nhóm khớp đường cong là tuyến tính và nhóm còn lại được gọi là khớp đường cong phi tuyến tính. Loại khớp đường cong này là phương pháp tìm mô hình phi tuyến tính để tìm mối quan hệ giữa một biến phụ thuộc và một tập hợp các biến độc lập .

Mà có thể được sử dụng để phù hợp với không

Tổng của các số bình phương này càng nhỏ thì hàm khớp với các điểm dữ liệu trong tập hợp càng tốt. Hồi quy phi tuyến tính sử dụng hàm logarit, hàm lượng giác, hàm mũ, hàm lũy thừa, đường cong Lorenz, hàm Gaussian và các phương pháp khớp khác .