Maximum Likelihood (ML) Schätzer
Hier wird ein Maximum-Likelihood-Schätzer für die Leistung des sauberen Signals abgeleitet, der jedoch die Ergebnisse hinsichtlich des quadratischen Mittelwertfehlers für jedes SNR im Vergleich zur spektralen Leistungssubtraktion nicht verbessert.
Einführung
Lassen Sie uns die normalisierte saubere Amplitude und die normalisierte verrauschte Größe einführen, die durch die Rauschstandardabweichung normalisiert sindeinmσ::
a = | X.k|σ,m = | Y.k|σ.(1)
Der Schätzer in Gl. 3 der Frage gibt eine Schätzung von als:ein^ein
ein^= 1σ| X.k|2ˆ- -- -- -- -√= 1σmax ( ( σm )2- σ2, 0 )- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -√= { m2- 1- -- -- -- -- -- -√0wenn m > 1 ,wenn m ≤ 1.(2)
Maximum Likelihood Estimator
Um einen möglicherweise besseren Schätzer für als Gl. 2 folgen wir dem Verfahren von Sijbers et al. 1998. (siehe Frage), um einen Maximum-Likelihood (ML) -Schätzer zu konstruierenEs gibt den Wert von , der die Wahrscheinlichkeit des gegebenen Wertes von maximierteinaein^M L..einm .
Das PDF vonist Rician mit dem Parameterund Parameter (der Klarheit später zu ersetzen)| Y.k|ν R i c e = | X kνR i c e= | X.k|σR i c e= 12√σ::
P D F ( | Y.k| )= | Y.k|σ2R i c eexp⎛⎝⎜- ( | Y.k|2+ | X.k|2)2 σ2R i c e⎞⎠⎟ich0( | Y.k| | X.k|σ2R i c e) ,(3)
wobei eine modifizierte Bessel-Funktion der ersten Art ist . Ersetzen von undichα| X k | = σ a , | Y k | = σ m , σ 2 R i c e = 1| X.k| =σa , | Y.k| =σm ,σ2R i c e= 12σ2::
=PDF(σm)=2mσe−(m2+a2)I0(2ma),(3.1)
und verwandeln:
⇒PDF(m)=σPDF(σm)=2me−(m2+a2)I0(2ma).(3.2)
Das durch parametrisierte Rician-PDF von ist unabhängig von der RauschvarianzDer Maximum-Likelihood-Schätzer von Parameter ist der Wert von , der maximiert . Es ist eine Lösung von:maσ2.a^MLaaPDF(m)
mI1(2ma^ML)I0(2ma^ML)−a^ML=0.(4)
Die Lösung zu Gl. 4 hat die Eigenschaft, dass:
a^ML=0 if m≤1.(5)
Andernfalls muss es numerisch gelöst werden.
Abbildung 1. blau, oben: der Maximum-Likelihood-Schätzer und orange, unten: der Leistungsspektral-Subtraktionsschätzer der Frage der normalisierten sauberen Amplitude als Funktion der normalisierten verrauschten Größea^MLa^am.
σa^ML ist der Maximum-Likelihood-Schätzer von und durch funktionale Invarianz der Maximum-Likelihood-Schätzung ist der Maximum-Likelihood-Schätzer von|Xk|,σ2a^2ML|Xk|2.
Empirische Laurent-Reihe des ML-Schätzers
Ich habe versucht, die Laurent-Reihe von numerisch zu berechnen (siehe Skript weiter unten) aber sie scheint nicht für den Bereich von zu konvergieren . Hier ist eine Kürzung der Laurent-Reihe, soweit ich sie berechnet habe:a^2ML,m
a^2ML≈m2−121m0−123m2−325m4−1227m6−5729m8−309211m10−1884213m12−12864215m14−98301217m16−839919219m18−7999311221m20(6)
Ich konnte die Zähler- oder Nenner-Ganzzahlsequenzen in der Online-Enzyklopädie der Ganzzahlsequenzen (OEIS) nicht finden. Nur für die ersten fünf Terme mit negativer Leistung stimmen die Zählerkoeffizienten mit A027710 überein . Nachdem ich die berechnete Sequenz ( ) an OEIS Superseeker gesendet hatte , erhielt ich dies in der Antwort (von der ich die nächsten drei vorgeschlagenen Nummern durch eine erweiterte Berechnung):1,−1,−1,−3,…−84437184,−980556636,−12429122844
Guesss suggests that the generating function F(x)
may satisfy the following algebraic or differential equation:
-1/2*x+1/2+(-x+1/2)*x*diff(F(x),x)+(x-3/2)*F(x)-1/2*F(x)*x*diff(F(x),x)+F(x)^2 = 0
If this is correct the next 6 numbers in the sequence are:
[-84437184, -980556636, -12429122844, -170681035692, -2522486871192, -39894009165525]
Tabellarische Annäherung und Schätzfehlerverstärkung
Eine linear interpolierte Tabelle (siehe Skripte unten), die ungleichmäßig verteilte Stichproben von ergibt eine Näherung mit einem maximalen Fehler von ungefähr124071a^2ML−m26×10−11.
Approximation der kleinsten Quadrate des ML-Schätzers
Eine Näherung der kleinsten Quadrate (mit zusätzlichem Gewicht bei ) der Stichproben der Schätzerkurve wurde in einer Form erstellt, die von den Experimenten der Laurent-Reihe inspiriert wurde (siehe Oktavschrift weiter unten). Der konstante Term wurde geändert, um die Möglichkeit eines negativen bei zu beseitigen Die Näherung gilt für und hat einen maximalen Fehler von ungefähr (Abb 3) bei der Annäherung vonm2=1- 0.5
- 0.49999998237308493999
a2m2=1.m2≥12×10−5a^2ML:
a^2 = m^2 - 0.49999998237308493999 -0.1267853520007855/m^2 - 0.02264263789612356/m^4 - 1.008652066326489/m^6 + 4.961512935048501/m^8 - 12.27301424767318/m^10 + 5.713416605734312/m^12 + 21.55623892529696/m^14 - 38.15890985013438/m^16 + 24.77625343690267/m^18 - 5.917417766578400/m^20
Abbildung 3. Fehler der Approximation der kleinsten Quadrate vona^2ML.
Das Skript scheint in der Lage zu sein, die Anzahl der negativen Potenzen von erhöhen wobei immer kleinere Fehler auftreten, wobei die Anzahl der Extrema-Fehler zunimmt, jedoch mit einem recht langsamen maximalen Fehlerabfall. Die Annäherung ist fast gleich, würde aber dennoch ein wenig von der Verfeinerung des Remez-Austauschs profitieren .m2,
Unter Verwendung der Näherung wurden die folgenden erwarteten Fehlerverstärkungskurven erhalten:
Abbildung 2. Monte-Carlo-Schätzungen mit einer Stichprobengröße von von: Solid: Gewinn der Summe der quadratischen Fehler bei der Schätzung vondurch im Vergleich zur Schätzung mit
gestrichelt: Gewinn der Summe der quadratischen Fehler bei der Schätzung von durch im Vergleich zur Schätzung mit gepunktet: Gewinn der Summe der quadratischen Fehler bei der Schätzung von durch im Vergleich zur Schätzung mitBlau: ML-Schätzer, Orange: geklemmte spektrale Leistungssubtraktion.105,|Xk||Xk|ˆ|Yk|,|Xk|2|Xk|2ˆ|Yk|2,Xk|Xk|ˆeiarg(Yk)Yk.
Überraschenderweise ist der ML-Schätzer in fast allen Aspekten schlechter als die geklemmte spektrale Leistungssubtraktion, außer dass er für die Signalschätzung bei SNR> etwa 5 dB und die Amplitudenschätzung bei SNR> etwa 3 dB geringfügig besser ist. Bei diesen SNR sind die beiden Schätzer schlechter als nur das verrauschte Signal als Schätzung zu verwenden.
Python-Skript A für Abb. 1
Dieses Skript erweitert das Skript A der Frage.
def est_a_sub(m):
m = mp.mpf(m)
if m > 1:
return mp.sqrt(m**2 - 1)
else:
return 0
def est_a_ML(m):
m = mp.mpf(m)
if m > 1:
return mp.findroot(lambda a: m*mp.besseli(1, 2*a*m)/(mp.besseli(0, 2*a*m)) - a, [mp.sqrt(2*m**2*(m**2 - 1)/(2*m**2 - 1)), mp.sqrt(m**2-0.5)])
else:
return 0
def est_a_ML_fast(m):
m = mp.mpf(m)
if m > 1:
return mp.sqrt(m**2 - mp.mpf('0.49999998237308493999') - mp.mpf('0.1267853520007855')/m**2 - mp.mpf('0.02264263789612356')/m**4 - mp.mpf('1.008652066326489')/m**6 + mp.mpf('4.961512935048501')/m**8 - mp.mpf('12.27301424767318')/m**10 + mp.mpf('5.713416605734312')/m**12 + mp.mpf('21.55623892529696')/m**14 - mp.mpf('38.15890985013438')/m**16 + mp.mpf('24.77625343690267')/m**18 - mp.mpf('5.917417766578400')/m**20)
else:
return 0
ms = np.arange(0, 5.0078125, 0.0078125)
est_as = [[est_a_ML(m) for m in ms], [est_a_sub(m) for m in ms]];
plot_est(ms, est_as)
Python-Skript zur numerischen Berechnung von Laurent-Reihen
Dieses Skript berechnet numerisch die ersten Terme der Laurent-Reihe vonEs basiert auf dem Skript in dieser Antwort .a^2ML−m2.
from sympy import *
from mpmath import *
num_terms = 10
num_decimals = 12
num_use_decimals = num_decimals + 5 #Ad hoc headroom
def y(a2):
return sqrt(m2)*besseli(1, 2*sqrt(a2*m2))/besseli(0, 2*sqrt(a2*m2)) - sqrt(a2)
c = []
h = mpf('1e'+str(num_decimals))
denominator = mpf(2) # First integer denominator. Use 1 if unsure
denominator_ratio = 4 # Denominator multiplier per step. Use 1 if unsure
print("x")
for i in range(0, num_terms):
mp.dps = 2*2**(num_terms - i)*num_use_decimals*(i + 2) #Ad hoc headroom
m2 = mpf('1e'+str(2**(num_terms - i)*num_use_decimals))
r = findroot(y, [2*m2*(m2 - 1)/(2*m2 - 1), m2-0.5]) #Safe search range, must be good for the problem
r = r - m2; # Part of the problem definition
for j in range(0, i):
r = (r - c[j])*m2
c.append(r)
mp.dps = num_decimals
print '+'+str(nint(r*h)*denominator/h)+'/('+str(denominator)+'x^'+str(i)+')'
denominator *= denominator_ratio
Python-Skript zur Tabellierung des ML-Schätzers
Dieses Skript erstellt eine ungleichmäßig abgetastete Tabelle von -Paaren, die für die lineare Interpolation geeignet sind, wobei ungefähr der definierte maximale absolute lineare Interpolationsfehler der Approximation von für den BereichDie Tabellengröße wird automatisch durch Hinzufügen von Stichproben zu den schwierigen Teilen erhöht, bis der Spitzenfehler klein genug ist. Wenn gleich plus einer ganzzahligen Potenz von alle Abtastintervalle Potenzen von Am Ende der Tabelle gibt es einen diskontinuitätsfreien Übergang zu einer großen Näherung[m2,a^2ML]a^2MLm=0…mmax.mmax22,2.ma^2ML=m2−12.Wenn benötigt wird, ist es meiner Meinung nach besser, die Tabelle unverändert zu interpolieren und dann die Konvertierunga^MLa^ML=a^2ML−−−√.
Leiten Sie die Ausgabe zur Verwendung in Verbindung mit dem nächsten Skript weiter > linear.m
.
import sys # For writing progress to stderr (won't pipe when piping output to a file)
from sympy import *
from mpmath import *
from operator import itemgetter
max_m2 = 2 + mpf(2)**31 # Maximum m^2
max_abs_error = 2.0**-34 #Maximum absolute allowed error in a^2
allow_over = 0 #Make the created samples have max error (reduces table size to about 7/10)
mp.dps = 24
print('# max_m2='+str(max_m2))
print('# max_abs_error='+str(max_abs_error))
def y(a2):
return sqrt(m2)*besseli(1, 2*sqrt(a2*m2))/besseli(0, 2*sqrt(a2*m2)) - sqrt(a2)
# [m2, a2, following interval tested good]
samples = [[0, 0, True], [1, 0, False], [max_m2, max_m2 - 0.5, True]]
m2 = mpf(max_m2)
est_a2 = findroot(y, [2*m2*(m2 - 1)/(2*m2 - 1), m2-0.5])
abs_error = abs(est_a2 - samples[len(samples) - 1][1])
if abs_error > max_abs_error:
sys.stderr.write('increase max_m, or increase max_abs_error to '+str(abs_error)+'\n')
quit()
peak_taken_abs_error = mpf(max_abs_error*allow_over)
while True:
num_old_samples = len(samples)
no_new_samples = True
peak_trial_abs_error = peak_taken_abs_error
for i in range(num_old_samples - 1):
if samples[i][2] == False:
m2 = mpf(samples[i][0] + samples[i + 1][0])/2
est_a2 = mpf(samples[i][1] + samples[i + 1][1])/2
a2 = findroot(y, [2*m2*(m2 - 1)/(2*m2 - 1), m2-0.5])
est_abs_error = abs(a2-est_a2)
if peak_trial_abs_error < est_abs_error:
peak_trial_abs_error = est_abs_error
if est_abs_error > max_abs_error:
samples.append([m2, a2 + max_abs_error*allow_over, False])
no_new_samples = False
else:
samples[i][2] = True
if peak_taken_abs_error < est_abs_error:
peak_taken_abs_error = est_abs_error
if no_new_samples == True:
sys.stderr.write('error='+str(peak_taken_abs_error)+', len='+str(len(samples))+'\n')
print('# error='+str(peak_taken_abs_error)+', len='+str(len(samples)))
break
sys.stderr.write('error='+str(peak_trial_abs_error)+', len='+str(len(samples))+'\n')
samples = sorted(samples, key=itemgetter(0))
print('global m2_to_a2_table = [')
for i in range(len(samples)):
if i < len(samples) - 1:
print('['+str(samples[i][0])+', '+str(samples[i][1])+'],')
else:
print('['+str(samples[i][0])+', '+str(samples[i][1])+']')
print('];')
Python-Skript B für Abb. 2
Dieses Skript erweitert das Skript B der Frage.
def est_a_ML_fast(m):
mInv = 1/m
if m > 1:
return np.sqrt(m**2 - 0.49999998237308493999 - 0.1267853520007855*mInv**2 - 0.02264263789612356*mInv**4 - 1.008652066326489*mInv**6 + 4.961512935048501*mInv**8 - 12.27301424767318*mInv**10 + 5.713416605734312*mInv**12 + 21.55623892529696*mInv**14 - 38.15890985013438*mInv**16 + 24.77625343690267*mInv**18 - 5.917417766578400*mInv**20)
else:
return 0
gains_SSE_a_ML = [est_gain_SSE_a(est_a_ML_fast, a, 10**5) for a in as_]
gains_SSE_a2_ML = [est_gain_SSE_a2(est_a_ML_fast, a, 10**5) for a in as_]
gains_SSE_complex_ML = [est_gain_SSE_complex(est_a_ML_fast, a, 10**5) for a in as_]
plot_gains_SSE(as_dB, [gains_SSE_a_ML, gains_SSE_a_sub], [gains_SSE_a2_ML, gains_SSE_a2_sub], [gains_SSE_complex_ML, gains_SSE_complex_sub])
Oktavskript für kleinste Quadrate
Dieses Oktavskript (eine Anpassung dieser Antwort ) passt die kleinsten Quadrate der Potenzen von in . Die Beispiele wurden vom Python-Skript etwas oben vorbereitet.m2a^2ML−(m2−12)
graphics_toolkit("fltk");
source("linear.m");
format long
dup_zero = 2000000 # Give extra weight to m2 = 1, a2 = 0
max_neg_powers = 10 # Number of negative powers in the polynomial
m2 = m2_to_a2_table(2:end-1,1);
m2 = vertcat(repmat(m2(1), dup_zero, 1), m2);
A = (m2.^-[1:max_neg_powers]);
a2_target = m2_to_a2_table(2:end-1,2);
a2_target = vertcat(repmat(a2_target(1), dup_zero, 1), a2_target);
fun_target = a2_target - m2 + 0.5;
disp("Cofficients for negative powers of m^2:")
x = A\fun_target
a2 = A*x + m2 - 0.5;
plot(sqrt(m2), sqrt(a2)) # Plot approximation
xlim([0, 3])
ylim([0, 3])
a2(1) # value at m2 = 2
abs_residual = abs(a2-a2_target);
max(abs_residual) # Max abs error of a^2
max(abs(sqrt(a2)-sqrt(a2_target))) # Max abs error of a
plot(sqrt(log10(m2)), a2_target - a2) # Plot error
xlabel("sqrt(log(m^2))")
ylabel("error in approximation of hat a^2_{ML}")
Python-Skript A2 zur Approximation mit Chebyshev-Polynomen
Dieses Skript erweitert Skript A und gibt eine alternative Annäherung an den ML-Schätzer unter Verwendung von Chebyshev-Polynomen. Der erste Chebyshev-Knoten liegt beim=1 und die Anzahl der Chebyshev-Polynome ist so, dass die Approximation nicht negativ ist.
N = 20
est_a_ML_poly, err = mp.chebyfit(lambda m2Reciprocal: est_a_ML(mp.sqrt(1/m2Reciprocal))**2 - 1/m2Reciprocal, [0, 2/(mp.cos(mp.pi/(2*N)) + 1)], N, error=True)
def est_a_ML_fast(m):
global est_a_ML_poly
m = mp.mpf(m)
if m > 1:
return mp.sqrt(m**2 + mp.polyval(est_a_ML_poly, 1/m**2))
else:
return 0