簡體   English   中英

如何擬合散點 plot 數據的正態分布

[英]How to fit a normal distribution for scatter plot data

我有一個 dataframe ,其 x (第 x 列)和 y (第 1 列)值低於我得到meanstdev

接下來我將它們一起繪制在一張圖表上,但它看起來非常錯誤,不僅僅是擬合曲線移動了,我不確定它有什么問題。

import matplotlib.pyplot as plt
from scipy import stats
from scipy import optimize
import numpy as np

data_sample = {'x': [0,1,2,3,4,5,6,7,8,9,10], '1': [0,1,2,3,4,5,4,3,2,1,0]}  
def test_func(x, a, b): 
    return stats.norm.pdf(x,a,b)

params, cov_params = optimize.curve_fit(test_func, data_sample['x'], data_sample['1'])

print(params)

plt.scatter(data_sample['x'], data_sample['1'], label='Data')
plt.plot(data_sample['x'] , test_func(data_sample['x'], params[0], params[1]), label='Fitted function')

plt.legend(loc='best')

plt.show()

在此處輸入圖像描述

需要對數據進行歸一化,使曲線下的面積為 1。要計算面積,當所有 x 值相差 1 時,您需要 y 值的總和 如果 x 值之間的空間大於或小於 1,則還應包括該因子。 另一種計算面積的方法是np.trapz()

進行擬合時需要使用歸一化因子。 使用原始數據繪制曲線時需要發生相反的情況。

當您嘗試將高斯 pdf function 擬合到非歸一化點時,“最佳”擬合是一個非常窄、非常高的峰值。 這個峰值試圖接近中心的y=5值。

下面的示例代碼將列表轉換為 numpy arrays,因此可以更輕松地編寫函數。 此外,為了繪制平滑曲線,使用更詳細的 x 值。

import matplotlib.pyplot as plt
from scipy import stats
from scipy import optimize
import numpy as np

def test_func(x, a, b):
    return stats.norm.pdf(x, a, b)

data_sample = {'x': np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]),
               '1': np.array([0, 1, 2, 3, 4, 5, 4, 3, 2, 1, 0])}

# x_dist = (data_sample['x'].max() - data_sample['x'].min()) / (len(data_sample['x']) - 1)
# normalization_factor = sum(data_sample['1']) * x_dist
normalization_factor = np.trapz(data_sample['1'], data_sample['x'])  # area under the curve
params, pcov = optimize.curve_fit(test_func, data_sample['x'], data_sample['1'] / normalization_factor)

plt.scatter(data_sample['x'], data_sample['1'], clip_on=False, label='Data')
x_detailed = np.linspace(data_sample['x'].min() - 3, data_sample['x'].max() + 3, 200)
plt.plot(x_detailed, test_func(x_detailed, params[0], params[1]) * normalization_factor,
         color='crimson', label='Fitted function')

plt.legend(loc='best')
plt.margins(x=0)
plt.ylim(ymin=0)
plt.tight_layout()
plt.show()

將正態曲線擬合到某些點

PS:使用原始代碼(沒有歸一化),但使用更詳細的 x 值,窄曲線會更明顯:

x_detailed = np.linspace(min(data_sample['x']) - 1, max(data_sample['x']) + 1, 500)
plt.plot(x_detailed, test_func(x_detailed, params[0], params[1]), color='m', label='Fitted function')

非歸一化數據的窄高斯曲線

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM