Hướng dẫn python curve fitting without function - khớp đường cong trăn mà không có chức năng

Thông thường để làm mịn mà không đoán được chức năng tạo, mọi người sử dụng spline. Đây là một ví dụ sử dụng dữ liệu của bạn:

Hướng dẫn python curve fitting without function - khớp đường cong trăn mà không có chức năng

import matplotlib.pyplot as plt
from scipy.interpolate import UnivariateSpline
import numpy as np

x = range(30)
y = [1, 1, 1, 2, 1, 1, 1, 2, 4, 5, 8, 12, 13, 14, 12, 11, 9, 6, 5, 4, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1 ]

s = UnivariateSpline(x, y, s=5)
xs = np.linspace(0, 29, 100)
ys = s(xs)

plt.plot(x, y, 'o')
plt.plot(xs, ys)
plt.show()

Như bạn có thể đoán, từ khóa

# Function to calculate the exponential with constants a and b
def exponential(x, a, b):
return a*np.exp(b*x)
0 được sử dụng để đặt mức độ phù hợp của phù hợp với dữ liệu, trong đó
# Function to calculate the exponential with constants a and b
def exponential(x, a, b):
return a*np.exp(b*x)
1 sẽ đi qua mọi điểm.

SPLINE về cơ bản phù hợp với một chức năng đơn giản với các bộ điểm cục bộ từ đường cong và sau đó khớp với các dẫn xuất ở các ranh giới để kết nối các đường cong cục bộ này để kết quả cuối cùng trông trơn tru.

Có một loạt các thói quen spline để lựa chọn trong Scipy.

Khoa học Python âm mưu

Hướng dẫn cơ bản để sử dụng Python để phù hợp với các chức năng phi tuyến tính với các điểm dữ liệu thử nghiệm

Ảnh của Chris Liverani trên unplash

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 đặt chúng vào 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 phù hợp với một tập hợp các điểm cho một phương trình mô hình đã biết, mà chúng tôi 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)
2. Những điều cơ bản về âm mưu dữ liệu trong Python cho các ấn phẩm khoa học có thể được tìm thấy trong bài viết trước của tôi ở đây. Tôi sẽ trải qua ba loại phụ kiện phi tuyến tính chung: (1) theo cấp số nhân, (2) luật công suất và (3) đỉnh Gaussian.

Để sử dụng 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)
3, chúng tôi sử dụng câu lệnh
# Function to calculate the exponential with constants a and b
def exponential(x, a, b):
return a*np.exp(b*x)
4 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

# Function to calculate the exponential with constants a and b
def exponential(x, a, b):
return a*np.exp(b*x)
5, vì vậy chúng tôi có thể trực tiếp nhập chỉ
# Function to calculate the exponential with constants a and b
def exponential(x, a, b):
return a*np.exp(b*x)
3.

Phù hợp theo cấp số nhân

Hãy nói rằng chúng tôi có một hàm số mũ chung của hình thức sau và chúng tôi biết biểu thức này phù hợp với dữ liệu của chúng tôi (trong đó A và B là hằng số chúng tôi sẽ phù hợp):

Hàm số mũ chung

Đầu tiên, chúng ta phải xác định hàm hàm mũ như được hiển thị ở trên, vì vậy

# Function to calculate the exponential with constants a and b
def exponential(x, a, b):
return a*np.exp(b*x)
3 có thể sử dụng nó để thực hiện 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 một bộ dữ liệu giả hình của người Viking để phù hợp với chức năng này. Để tạo ra 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 được chỉ định, chúng tôi có thể 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)
8.

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

# Function to calculate the exponential with constants a and b
def exponential(x, a, b):
return a*np.exp(b*x)
9 - 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)
0 - Giá trị kết thúc của chuỗi của chúng tôi (sẽ bao gồm giá trị này trừ khi bạn cung cấp đối số bổ sung
# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
1)

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
2 - Số điểm để chia khoảng thời gian lên (mặc định là
# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
3)

Lưu ý rằng bạn không cần phải ghi rõ ràng các tên đầu vào -

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
4 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.

# Calculate y-values based on dummy x-values
y_dummy = exponential(x_dummy, 0.5, 0.5)

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

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

# Add noise from a Gaussian distribution
noise = 5*np.random.normal(size=y_dummy.size)
y_dummy = y_dummy + noise

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

Bây giờ, hãy để âm mưu dữ liệu giả của chúng tôi để 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 ra một biểu đồ phân tán, mà chúng tôi có thể dễ dàng thực hiện bằng cách sử dụng hàm

# Generate dummy dataset
x_dummy = np.linspace(start=5, stop=15, num=50)
8. 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 của các điểm, tôi trực tiếp sử dụng mã thập lục phân.

# Plot the noisy exponential data
ax.scatter(x_dummy, y_dummy, s=20, color='#00b3b3', label='Data')

# Function to calculate the exponential with constants a and b
def exponential(x, a, b):
return a*np.exp(b*x)
0-Kích thước điểm đánh dấu tính theo đơn vị (điểm) ², vì vậy 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 dữ liệu hàm mũ giả với tiếng ồn Gaussian được thêm vào

Một phương pháp thường hữu ích hơn khi trực quan hóa dữ liệu hàm mũ là với cốt truyện 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:

# Set the y-axis scaling to logarithmic
ax.set_yscale('log')

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

# Calculate y-values based on dummy x-values
y_dummy = exponential(x_dummy, 0.5, 0.5)
0:

# Set the y-ticks
ax.yaxis.set_major_locator(mpl.ticker.LogLocator(base=10.0))
# Set the y-axis limits
ax.set_ylim(0.1, 1000)

# Calculate y-values based on dummy x-values
y_dummy = exponential(x_dummy, 0.5, 0.5)
1 - Cơ sở để sử dụng cho các ve chính của trục logarit

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

Bây giờ chúng ta có thể phù hợp với dữ liệu của mình với hàm hàm mũ chung để trích xuất các tham số A và B và tăng cường sự phù hợp với dữ liệu. Lưu ý rằng mặc dù chúng tôi đã trình bày một âm mưu bán log ở trên, chúng tôi thực sự chưa thay đổi dữ liệu y-chúng tôi chỉ thay đổi thang đo của trục y. Vì vậy, chúng tôi vẫn phù hợp với dữ liệu phi tuyến tính, thường tốt hơn vì tuyến tính hóa dữ liệu trước khi lắp có thể thay đổi phần dư và phương sai của sự phù hợp.

# Fit the dummy exponential datapars, cov = curve_fit(f=exponential, xdata=x_dummy, ydata=y_dummy, p0=[0, 0], bounds=(-np.inf, np.inf))

Đầu vào

# Calculate y-values based on dummy x-values
y_dummy = exponential(x_dummy, 0.5, 0.5)
2 - Chức năng được sử dụng để lắp (trong trường hợp này là
# Calculate y-values based on dummy x-values
y_dummy = exponential(x_dummy, 0.5, 0.5)
3)

# Calculate y-values based on dummy x-values
y_dummy = exponential(x_dummy, 0.5, 0.5)
4-Mảng Data X để phù hợp

# Calculate y-values based on dummy x-values
y_dummy = exponential(x_dummy, 0.5, 0.5)
5-Mảng Y-Data để phù hợp

# Calculate y-values based on dummy x-values
y_dummy = exponential(x_dummy, 0.5, 0.5)
6 - Mảng dự đoán ban đầu cho các tham số phù hợp (cả A và B là 0)

# Calculate y-values based on dummy x-values
y_dummy = exponential(x_dummy, 0.5, 0.5)
7-giới hạn cho các tham số (-∞ đến ∞)

Đầu ra

# Calculate y-values based on dummy x-values
y_dummy = exponential(x_dummy, 0.5, 0.5)
8 - Mảng tham số từ FIT (trong trường hợp này là
# Calculate y-values based on dummy x-values
y_dummy = exponential(x_dummy, 0.5, 0.5)
9)

# Add noise from a Gaussian distribution
noise = 5*np.random.normal(size=y_dummy.size)
y_dummy = y_dummy + noise
0 - hiệp phương sai ước tính của
# Calculate y-values based on dummy x-values
y_dummy = exponential(x_dummy, 0.5, 0.5)
8 có thể được sử dụng để xác định độ lệch chuẩn của các tham số phù hợp (rễ vuông 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 so với các đầu ra

# Function to calculate the exponential with constants a and b
def exponential(x, a, b):
return a*np.exp(b*x)
3 và tính toán phần dư bằng cách trừ đi giá trị được tính toán (từ sự phù hợp của chúng tôi) từ các giá trị quan sát thực tế (dữ liệu giả của chúng tôi)

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

# Add noise from a Gaussian distribution
noise = 5*np.random.normal(size=y_dummy.size)
y_dummy = y_dummy + noise
3 - Cho phép chúng tôi bỏ qua mảng
# Calculate y-values based on dummy x-values
y_dummy = exponential(x_dummy, 0.5, 0.5)
8, tức là
# Calculate y-values based on dummy x-values
y_dummy = exponential(x_dummy, 0.5, 0.5)
9 được nhập dưới dạng
# Add noise from a Gaussian distribution
noise = 5*np.random.normal(size=y_dummy.size)
y_dummy = y_dummy + noise
6

Phù hợp với các tham số và độ lệch chuẩn

A = 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à

# Add noise from a Gaussian distribution
noise = 5*np.random.normal(size=y_dummy.size)
y_dummy = y_dummy + noise
7 và
# Add noise from a Gaussian distribution
noise = 5*np.random.normal(size=y_dummy.size)
y_dummy = y_dummy + noise
8 vì vậy hàm
# Function to calculate the exponential with constants a and b
def exponential(x, a, b):
return a*np.exp(b*x)
3 hội tụ đến các giá trị chính xác. Bây giờ chúng ta có thể phủ lên sự phù hợp trên đầu dữ liệu phân tán và cũng vẽ các phần dư, nên được phân phối ngẫu nhiên và gần 0, xác nhận rằng chúng ta có một sự phù hợp tốt.

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

# Plot the noisy exponential data
ax.scatter(x_dummy, y_dummy, s=20, color='#00b3b3', label='Data')
0 - Kiểu đường của dòng được vẽ (
# Plot the noisy exponential data
ax.scatter(x_dummy, y_dummy, s=20, color='#00b3b3', label='Data')
1 cho một đường nét đứt)

Biểu đồ phân tán của dữ liệu hàm mũ giả với dòng phù hợp được phủ lên của phần dư từ độ phù hợp theo cấp số nhân

Phù hợp với luật điện

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

Chức năng pháp luật chung

Tương tự như cách chúng tôi đã phù hợp trước đó, trước tiên chúng tôi xác định chức năng:

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

Sau đó, chúng tôi một lần nữa có thể tạo một bộ dữ liệu giả, thêm nhiễu và vẽ đồ thị chức năng pháp luật của chúng tôi.

# Import curve fitting package from scipy
from scipy.optimize import curve_fit
3 Lô đất của dữ liệu luật điện giả với tiếng ồn Gaussian được thêm vào

Tương tự như trường hợp phù hợp theo cấp số nhân, dữ liệu ở dạng hàm luật công suất có thể được tuyến tính hóa bằng cách vẽ trên biểu đồ logarit-lần này, cả hai trục X và Y đều được chia tỷ lệ.

# Import curve fitting package from scipy
from scipy.optimize import curve_fit
4 Lô đất của dữ liệu định nghĩa công suất 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 cho dữ liệu theo cấp số nhân:

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

Phù hợp với các tham số và độ lệch chuẩn

A = 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à
# Add noise from a Gaussian distribution
noise = 5*np.random.normal(size=y_dummy.size)
y_dummy = y_dummy + noise
7 và
# Add noise from a Gaussian distribution
noise = 5*np.random.normal(size=y_dummy.size)
y_dummy = y_dummy + noise
8 vì vậy hàm
# Function to calculate the exponential with constants a and b
def exponential(x, a, b):
return a*np.exp(b*x)
3 hội tụ đến các giá trị chính xác. Bây giờ chúng ta có thể phủ lên sự phù hợp trên đầu dữ liệu phân tán và cũng vẽ các phần dư, nên được phân phối ngẫu nhiên và gần 0, xác nhận rằng chúng ta có một sự phù hợp tốt.

# Plot the noisy exponential dataax.scatter(x_dummy, y_dummy, s=20, color='#00b3b3', label='Data')0 - Kiểu đường của dòng được vẽ (# Plot the noisy exponential dataax.scatter(x_dummy, y_dummy, s=20, color='#00b3b3', label='Data')1 cho một đường nét đứt)

Biểu đồ phân tán của dữ liệu hàm mũ giả với dòng phù hợp được phủ lên của phần dư từ độ phù hợp theo cấp số nhân

Phù hợp với luật điện

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

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

Chức năng pháp luật chung

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

Tương tự như cách chúng tôi đã phù hợp trước đó, trước tiên chúng tôi xác định chức năng:

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

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

Phù hợp với các tham số và độ lệch chuẩn

A = 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à

# Add noise from a Gaussian distribution
noise = 5*np.random.normal(size=y_dummy.size)
y_dummy = y_dummy + noise
7 và
# Add noise from a Gaussian distribution
noise = 5*np.random.normal(size=y_dummy.size)
y_dummy = y_dummy + noise
8 vì vậy hàm
# Function to calculate the exponential with constants a and b
def exponential(x, a, b):
return a*np.exp(b*x)
3 hội tụ đến các giá trị chính xác. Bây giờ chúng ta có thể phủ lên sự phù hợp trên đầu dữ liệu phân tán và cũng vẽ các phần dư, nên được phân phối ngẫu nhiên và gần 0, xác nhận rằng chúng ta có một sự phù hợp tốt.

# Plot the noisy exponential data
ax.scatter(x_dummy, y_dummy, s=20, color='#00b3b3', label='Data')
0 - Kiểu đường của dòng được vẽ (
# Plot the noisy exponential data
ax.scatter(x_dummy, y_dummy, s=20, color='#00b3b3', label='Data')
1 cho một đường nét đứt)

Biểu đồ phân tán của dữ liệu hàm mũ giả với dòng phù hợp được phủ lên của phần dư từ độ phù hợp theo cấp số nhân

Phù hợp với luật điện