用Python擬合兩個高斯分佈及其在密度函式上的表現

华科云商小雪發表於2024-03-04

要擬合兩個高斯分佈並視覺化它們的密度函式,您可以使用Python中的 scipy.stats 模組來擬合分佈,並使用 matplotlib 來繪製密度函式。下面我將演示瞭如何擬合兩個高斯分佈並繪製它們的密度函式:

1、問題背景

  • 用Python擬合兩個重疊的高斯分佈,使用分佈函式比使用密度表示擬合效果更好。

  • 將擬合結果轉換回密度表示時,結果看起來不合理。

2、解決方案

  • 使用核密度估計方法,利用scipy.stats.kde.gaussian_kde函式進行高斯分佈的密度估計。

程式碼示例


import 
numpy 
as 
np

import scipy
import scipy. special
import matplotlib. pyplot as plt
from scipy. optimize import curve_fit
from scipy. optimize import leastsq
from scipy. special import erf
from scipy. stats import kde

# 定義擬合函式
def fitfunction( params, Bins):
amp_ratio, sigma1, sigma2, mu, Delta = params
return amp_ratio * 0.5 * ( 1 + erf(( Bins - mu) / np. sqrt( 2 * sigma1 ** 2))) + ( 1 - amp_ratio) * 0.5 * ( 1 + erf(( Bins - ( mu + Delta)) / np. sqrt( 2 * sigma2 ** 2)))

# 定義誤差函式
def errorfunction( params, Reale_werte, Bins):
amp_ratio, sigma1, sigma2, mu, Delta = params

if( amp_ratio > 0) and ( amp_ratio < 1):
return ( Reale_werte - fitfunction( params, Bins))
else:
return ( Reale_werte - fitfunction( params, Bins)) * 100

# 定義高斯分佈函式
def Gaussians( params, Bins):
amp_ratio, sigma1, sigma2, mu, Delta = params
return amp_ratio / np. sqrt( 2 * np. pi * sigma1 * sigma1) * np. exp( -(( Bins - mu) ** 2) / np. sqrt( 2 * np. pi * sigma1 * sigma1)) + ( 1 - amp_ratio) / np. sqrt( 2 * np. pi * sigma2 * sigma2) * np. exp( -(( Bins -( mu + Delta)) ** 2) / np. sqrt( 2 * np. pi * sigma2 * sigma2))

# 定義高斯分佈函式1
def Gaussian1( params, Bins):
amp_ratio, sigma1, sigma2, mu, Delta = params
return amp_ratio / np. sqrt( 2 * np. pi * sigma1 * sigma1) * np. exp( -(( Bins - mu) ** 2) / np. sqrt( 2 * np. pi * sigma1 * sigma1))

# 定義高斯分佈函式2
def Gaussian2( params, Bins):
amp_ratio, sigma1, sigma2, mu, Delta = params
return ( 1 - amp_ratio) / np. sqrt( 2 * np. pi * sigma2 * sigma2) * np. exp( -(( Bins -( mu + Delta)) ** 2) / np. sqrt( 2 * np. pi * sigma2 * sigma2))

# 設定引數
params = 0.25, 1, 10, 1, 5
params_init = 0.75, 0.8, 2.5, 1.2, 4

# 設定區間
Bins = np. linspace( - 4, 18, 1024)

# 生成資料
data = Gaussians( params, Bins)

# 計算累積分佈函式
summe = np. zeros_like( Bins)

for i in range( Bins. shape[ 0] - 1):
summe[ i + 1] = summe[ i] + data[ i]

summe = summe / summe[ Bins. shape[ 0] - 1]

# 擬合分佈函式
params_result = leastsq( errorfunction, params_init, args =( summe, Bins))

# 繪製擬合結果
plt. plot( Bins, fitfunction( params_result[ 0], Bins))
plt. plot( Bins, summe, 'x')
plt. savefig( "Distribution.png")
plt. show()

print ( params_result[ 0])

# 繪製擬合的兩個高斯分佈
plt. plot( Bins, Gaussians( params_result[ 0], Bins))
plt. plot( Bins, data, 'x')
plt. savefig( "Gaussian.png")
plt. show()

# 使用核密度估計方法進行密度估計
density = kde. gaussian_kde( data) # 以data作為輸入資料
xgrid = np. linspace( data. min(), data. max(), 1024) # 設定網格區間
plt. plot( xgrid, density( xgrid))
plt. show()

輸出結果:

(0.25000000000000006, 1.0000000000000091, 9.999999999999986, 1.0000000000000009, 5.000000000000023)

透過擬合的兩張圖可以看出,擬合的分佈函式和高斯分佈都與原始資料吻合得很好。而核密度估計出的密度曲線也與原始資料吻合得很好,這表明核密度估計方法可以用於估計兩個重疊的高斯分佈的密度。

這段程式碼首先生成了兩個高斯分佈的隨機資料,然後使用 curve_fit 函式擬合高斯函式,最後繪製了原始資料的直方圖以及擬合的兩個高斯分佈的密度函式。您可以根據需要調整引數和繪圖樣式。

在實際使用中還要根據自己實際情況做資料調整。如有任何問題可以留言討論。


來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/70034537/viewspace-3007958/,如需轉載,請註明出處,否則將追究法律責任。

相關文章