Análisis y construcción de curvas ROC: comunicación con el radar

Formulación del problema

Muchos han oído hablar de la curva ROC, que se usa a menudo en ML . Al decodificar esta abreviatura, obtenemos esa ROC ( característica operativa del receptor ). Traducido del inglés, esto significa RHP ( rendimiento del receptor ). Este concepto está tomado de la teoría de la detección de señales. La curva ROC se puede asociar a una estación de radar ( radar ), considerándola desde el punto de vista de la detección de objetos. Describamos esto de manera más formal.





El radar envía pulsos que rebotan en los objetos. La señal reflejada es Xrecibida por la antena receptora del radar ( Fig. 1 ). Si hay algún objeto ubicado en la zona de detección ( DZ ) ^ 1 , entonces la señal reflejada será más alta que el umbral de detección \ lambday esto significará la presencia del objeto (D_1). Si la señal reflejada está por debajo del umbral de detección, esto significa que no hay ningún objeto (D_0).





Higo.  1 Dibujo explicativo!
Higo. 1 Dibujo explicativo!
ZO

^ 1La zona de detección de radar es el área del espacio dentro de la cual el radar asegura la detección de objetos con probabilidades de detección correcta no peores que las requeridas.





H_1, H_0. X— . , (una), .





\ Grande f _ {(X | H_0)} (x│H_0), \ f _ {(X | H_1)} (x│H_1) \ \ \ \ (1)

, , X , (una) . ,





\ Grande E [X│H_0] <E [X│H_1] \ \ \ \ (2)

X, - , :





Higo.  2 densidades condicionales (1)
. 2 (1)

. 2 \ eta_0, \ eta_1X H_0H_1 . , (2), , η_0 <η_1.





, X , λ. D_1 D_0. . 2 λ, D_1D_0, :





Higo.  3 Distribuciones de densidad condicionales (1) con la designación del nivel umbral λ y los rangos de toma de decisiones D₀ y D₁
. 3 (1) c λ D₀ D₁

:





\Large \begin{array}{l} P_{d}=P\left(D_{1} \mid H_{1}\right)=\displaystyle \int_{D_{1}} f_{X \mid H_{1}}\left(x \mid H_{1}\right) d x \\ P_{f a}=P\left(D_{1} \mid H_{0}\right)= \displaystyle  \int_{D_{1}} f_{X \mid H_{0}}\left(x \mid H_{0}\right) d x \end{array} (3)

(3) :





  • P_d– , H_1, .. .





  • P_{fa}– , .. D_1, , H_0, .. .





(3), :





. 4   P_d  P_fa     (1)
. 4 P_d P_fa (1)

, λ , , P_dP_{fa} .





, P_d P_{fa} λ, ROC- (. Receiver Operating Characteristic, ).





X - (, . Signal-to-Noise Ratio, . SNR), :





\Large S N R=10 \log _{10}\left(\frac{P_{\text {signal }}}{P_{\text {noise }}}\right)[dB]  \ \ \ (4)
  • P_{signal}– ;





  • P_{noise}– .





(4)P_{signal}=1, P_{signal}=σ^2– , :





\Large S N R=10 \log _{10}\left(\frac{1}{\sigma^{2}}\right)[d B]\ \ (5)

 ROC-

:





\Large \begin{array}{c} f_{X \mid H_{0}}\left(x \mid H_{0}\right)=  \frac{1}{\sqrt{2 \pi \sigma^{2}}} e^{-\frac{x^{2}}{2 \sigma^{2}}} \\ f_{X \mid H_{1}}\left(x \mid H_{1}\right)=\frac{1}{\sqrt{2 \pi \sigma^{2}}} e^{-\frac{(x-1)^{2}}{2 \sigma^{2}}} \end{array}  \ \ \ (6) \Large S N R \in[-1,5]\ \ \ (7) \\ \Large  \lambda \in[0,1]\ \ \ (8)

(6), , , .. X \mid H_{0} \sim \mathcal{N}\left(0, \sigma^{2}\right) X \mid H_{1} \sim \mathcal{N}\left(1, \sigma^{2}\right), \mathcal{N}\left(\mu, \sigma^{2}\right)\mu \sigma^{2}. η_0, η_1 X. (6), , η_0= Ε[X│H_0 ]=0, η_1= Ε[X│H_1 ]=1.





(7) , \sigma^2. (5)\sigma:





\Large \begin{array}{c} S N R=10 \log _{10}\left(\frac{1}{\sigma^{2}}\right)=10 \log _{10}\left(\sigma^{-2}\right)=-2 \cdot 10 \log _{10} \sigma=-20 \log _{10} \sigma \\ -\frac{S N R}{20}=\log _{10} \sigma \\ \sigma=10^{-\frac{S N R}{20}} \ \ (9) \end{array}

(7), :





\Large \begin{aligned} &\sigma \in\left[\left.10^{-\frac{S N R}{20}}\right|_{S N R=5},\left.10^{-\frac{S N R}{20}}\right|_{S N R=-1}\right]\\ &\sigma \in\left[10^{-\frac{5}{20}}, 10^{-\frac{-1}{20}}\right]\\ &\sigma \in\left[\sqrt[4]{\frac{1}{10}}, \sqrt[20]{10}\right]  (10)\end{aligned}

SNR ROC- :





\Large \overrightarrow{{S N R}_{\text {values }}}=(-1,0.5,1,1.5,2,2.5,3,3.5,4,4.5,5)^{T} \text { (11) }

(11) \scriptsize \frac{1}{2}, .. \small ∆_{SNR}=\frac{1}{2}. ROC- P_d P_{fa}, λ∈[0,1]. (3) (6), :





\Large \text { ROC }_{\text {curve }}(\sigma, \lambda)=\left\{ \begin{array}{r} P_{f a}= \displaystyle\frac{1}{\sqrt{2 \pi \sigma^{2}}} \displaystyle \int_{\lambda}^{+\infty} e^{-\frac{x^{2}}{2 \sigma^{2}}} d x \\ P_{d}= \displaystyle\frac{1}{\sqrt{2 \pi \sigma^{2}}} \displaystyle \int_{\lambda}^{+\infty} e^{-\frac{(x-1)^{2}}{2 \sigma^{2}}} d x \end{array} \right. (12)

\sigma– ROC- ROC-.





λ:





\Large \overrightarrow{\lambda_{\text {values }}}=(0,0.01,0.02, \ldots, 0.98,0.99,1)^{T}  (13)

(13) \small \frac{1}{100} , .. \small ∆_λ=\frac{1}{100}. (13) 101, .. 101 . , .





ROC-.





Python.





#   
from scipy.stats import norm
from scipy.misc import derivative
import numpy as np
import pandas as pd

import matplotlib.pyplot as plt
import seaborn as sns; sns.set()
%matplotlib inline
      
      



#   SNR  lambda
SNR_values = np.arange(-1, 5.5, 1/2) 
lambda_values = np.arange(0, 1.01, 1/100) 

# ,    sigma    SNR
def snr_to_sigma(SNR):
    return np.power(10, -SNR/20)
  
# ,    Pfa  Pd   sigma  lambda
def roc_curve(sigma, lambda_):
    return 1 - norm.cdf(lambda_/sigma), 1 - norm.cdf((lambda_ - 1)/sigma)

#  DataFrame      Pfa, Pd, SNR
data = []
for SNR in SNR_values:
    for lambda_ in lambda_values:
        Pfa, Pd = roc_curve(snr_to_sigma(SNR), lambda_)
        data.append([Pfa, Pd, str(SNR)])
        
data = pd.DataFrame(data, columns=['Pfa', 'Pd', 'SNR'])
      
      



fig, ax = plt.subplots(figsize=(18, 14))
sns.set_context('poster')
plt.title('$ROC$-     $SNR$', fontsize=40)
plt.xlabel('$P_{fa}$', fontsize=40)
plt.xticks(np.arange(0, 0.7, 0.05), fontsize=30)
plt.yticks(np.arange(0.5, 1, 0.05), fontsize=30)
plt.ylabel('$P_d$', fontsize=40, rotation=0, labelpad=40)
sns.lineplot(x='Pfa', y='Pd', hue='SNR', 
             data=data, palette='gist_ncar', ax=ax)

ax.annotate(" $\lambda$", xy=(0.15, 0.81),  xycoords='data',
            xytext=(90, 150), textcoords='offset points',
            size=30, ha='left', 
            arrowprops=dict(arrowstyle="->", color='black',
                            connectionstyle="arc3,rad=0.1"))
plt.grid(color='black', linestyle='--', linewidth=1, alpha=0.3)

plt.legend(fontsize='small', shadow=True, title='$SNR(dB)$',
           borderpad=0.9, fancybox=True);
      
      



. 5 ROC-     SNR
. 5 ROC- SNR

:





  1. P_{fa}=0.5 P_d=0.5;





  2. SNR, ROC- (0,1);





  3. ;





  4. ROC - . , .





(8). , ROC-, λ, , [-10,10].





#  DataFrame      Pfa, Pd, SNR
data2 = []
for SNR in SNR_values:
    for lambda_ in np.arange(-10, 10.1, 1/10) :
        Pfa, Pd = roc_curve(snr_to_sigma(SNR), lambda_)
        data2.append([Pfa, Pd, str(SNR)])
        
data2 = pd.DataFrame(data2, columns=['Pfa', 'Pd', 'SNR'])
      
      



fig, ax = plt.subplots(figsize=(18, 14))
sns.set_context('poster')
plt.title('$ROC$-     $SNR$', fontsize=40)
plt.xlabel('$P_{fa}$', fontsize=40)
plt.xticks(np.arange(0, 1.05, 0.1), fontsize=20)
plt.yticks(np.arange(0, 1.05, 0.1), fontsize=20)
plt.ylabel('$P_d$', fontsize=40, rotation=0, labelpad=40)
sns.lineplot(x='Pfa', y='Pd', hue='SNR', 
             data=data2, palette='gist_ncar', ax=ax)

ax.annotate(" $\lambda$", xy=(0.15, 0.81),  xycoords='data',
            xytext=(90, 110), textcoords='offset points',
            size=20, ha='left', 
            arrowprops=dict(arrowstyle="->", color='black',
                            connectionstyle="arc3,rad=0.1"))
plt.grid(color='black', linestyle='--', linewidth=1, alpha=0.3)

plt.legend(fontsize='small', shadow=True, title='$SNR(dB)$',
           borderpad=0.9, fancybox=True);
      
      



. 6 ROC-     SNR c   λ.
. 6 ROC- SNR c λ.

, P_d P_{fa}. , SNR, σ, (9). , (6) SNR.





# ,         sigma 
def conditional_density(x, sigma):
    return norm.pdf(x/sigma), norm.pdf((x - 1)/sigma)
  
  
  
#  DataFrame         SNR
data3 = []
x_range = np.linspace(-5, 5, 100)
for SNR in SNR_values:
    for x in x_range :
        cond_dens1, cond_dens2 = conditional_density(x, snr_to_sigma(SNR))
        data3.append([cond_dens1, cond_dens2, str(SNR), x])
        
data3 = pd.DataFrame(data3, columns=['cond_dens1', 'cond_dens2', 'SNR', 'x'])
      
      



fig, ax = plt.subplots(figsize=(20, 10))
sns.set_context('poster')
plt.title('      $SNR$', 
          fontsize=30)
plt.xlabel('$x$', fontsize=40)
plt.xticks(np.arange(-5, 5.5, 0.5), fontsize=20)
plt.yticks(np.arange(0, 0.45, 0.05), fontsize=20)
plt.ylabel('  ', fontsize=20, 
           labelpad=30)

sns.lineplot(x='x', y='cond_dens2', hue='SNR', 
             data=data3, palette='gist_ncar', ax=ax)

sns.lineplot(x='x', y='cond_dens1', hue='SNR', 
             data=data3, palette='gist_ncar', ax=ax, legend=False)

ax.legend(fontsize='small', shadow=True, title='$SNR(dB)$',
           borderpad=0.9, fancybox=True, loc='upper left')

ax.annotate("$f_{X|H_0}(x|H_0)$", xy=(-0.6, 0.35),  xycoords='data',
            xytext=(-90, 20), textcoords='offset points',
            size=30, ha='right', 
            arrowprops=dict(arrowstyle="->", color='black',
                            connectionstyle="arc3,rad=0.1"))

ax.annotate("$f_{X|H_1}(x|H_1)$", xy=(1.6, 0.35),  xycoords='data',
            xytext=(100, 20), textcoords='offset points',
            size=30, ha='left', 
            arrowprops=dict(arrowstyle="->", color='black',
                            connectionstyle="arc3,rad=0.1"))

plt.grid(color='black', linestyle='--', linewidth=1, alpha=0.3);
      
      



. 7   (6)    SNR
. 7 (6) SNR

. 7 , SNR, , , , . P_d λ:





data4 = []
for SNR in SNR_values:
    for lambda_ in lambda_values:
        Pfa, Pd = roc_curve(snr_to_sigma(SNR), lambda_)
        data4.append([Pfa, Pd, str(SNR), lambda_])
        
data4 = pd.DataFrame(data4, columns=['Pfa', 'Pd', 'SNR', 'lambda'])
      
      



fig, ax = plt.subplots(figsize=(16, 12))
sns.set_context('poster')
plt.title(' $P_d$  $\lambda$   $SNR$', fontsize=40)
plt.xlabel('$\lambda$', fontsize=40)
plt.xticks(np.arange(0, 1.05, 0.1), fontsize=20)
plt.yticks(np.arange(0.5, 1.05, 0.1), fontsize=20)
plt.ylabel('$P_d$', fontsize=40, rotation=0, labelpad=40)
sns.lineplot(x='lambda', y='Pd', hue='SNR', 
             data=data4, palette='gist_ncar', ax=ax)

ax.annotate(" $\lambda$", xy=(0.5, 0.85),  xycoords='data',
            xytext=(-10, 50), textcoords='offset points',
            size=20, ha='right', 
            arrowprops=dict(arrowstyle="->", color='black',
                            connectionstyle="arc3,rad=-0.2"))
plt.grid(color='black', linestyle='--', linewidth=1, alpha=0.3)

plt.legend(fontsize='small', shadow=True, title='$SNR(dB)$',
           borderpad=0.9, fancybox=True);
      
      



. 8   P_d  λ    SNR
. 8 P_d λ SNR

P_d λ=0 SNR=5. :





fig, ax = plt.subplots(figsize=(16, 12))
sns.set_context('poster')
plt.title(' $P_{fa}$  $\lambda$   $SNR$', fontsize=40)
plt.xlabel('$\lambda$', fontsize=40)
plt.ylabel('$P_{fa}$', fontsize=40, rotation=0, labelpad=40)
sns.lineplot(x='lambda', y='Pfa', hue='SNR', 
             data=data4, palette='gist_ncar', ax=ax)

ax.annotate(" $\lambda$", xy=(0.5, 0.35),  xycoords='data',
            xytext=(-10, 90), textcoords='offset points',
            size=30, ha='right', 
            arrowprops=dict(arrowstyle="->", color='black',
                            connectionstyle="arc3,rad=0.2"))
plt.grid(color='black', linestyle='--', linewidth=1, alpha=0.3)

plt.legend(fontsize='small', shadow=True, title='$SNR(dB)$',
           borderpad=0.9, fancybox=True);
      
      



. 9   P_{fa}  λ    SNR.
. 9 P_{fa} λ SNR.

λ=0, \small \frac{1}{2},





\large \left.\frac{1}{\sqrt{2 \pi \sigma^{2}}} \int_{\lambda}^{+\infty} e^{-\frac{x^{2}}{2 \sigma^{2}}} d x\right|_{\lambda=\eta_{0}}

+∞, \small \frac{1}{2}, .





, ROC- (6) λ, P_d P_{fa} .









\Large \tan \left(\alpha_{\lambda}\right):=\frac{\left(\frac{d P_{d}}{d \lambda}\right)}{\left(\frac{d P_{f a}}{d \lambda}\right)} \ \ ,(14)

:





\Large \begin{aligned} &\tan \left(\alpha_{\lambda}\right)= \frac{\frac{d}{d \lambda}\left(\frac{1}{\sqrt{2 \pi \sigma^{2}}} \displaystyle  \int_{\lambda}^{+\infty} e^{-\frac{(x-1)^{2}}{2 \sigma^{2}}} d x\right)}{\frac{d}{d \lambda}\left(\frac{1}{\sqrt{2 \pi \sigma^{2}}} \displaystyle  \int_{\lambda}^{+\infty} e^{-\frac{x^{2}}{2 \sigma^{2}}} d x\right)}=\frac{-\frac{1}{\sqrt{2 \pi \sigma^{2}}} e^{-\frac{(\lambda-1)^{2}}{2 \sigma^{2}}}}{-\frac{1}{\sqrt{2 \pi \sigma^{2}}} e^{-\frac{(\lambda)^{2}}{2 \sigma^{2}}}}=\\ &=\frac{e^{-\frac{(\lambda-1)^{2}}{2 \sigma^{2}}}}{e^{-\frac{(\lambda)^{2}}{2 \sigma^{2}}}}=e^{-\frac{(\lambda-1)^{2}}{2 \sigma^{2}}+\frac{(\lambda)^{2}}{2 \sigma^{2}}}=e^{\frac{-\lambda^{2}+2 \lambda-1+\lambda^{2}}{2 \sigma^{2}}}=e^{\frac{2 \lambda-1}{2 \sigma^{2}}} \ \ \ (15) \end{aligned}

(15):





\ Large \ begin {array} {l} \ displaystyle \ lim _ {\ lambda \ rightarrow- \ infty} \ left (\ tan \ left (\ alpha _ {\ lambda} \ right) \ right) = \ lim _ { \ lambda \ rightarrow- \ infty} \ left (e ^ {\ frac {2 \ lambda-1} {2 \ sigma ^ {2}}} \ right) = 0 \\ \ displaystyle \ lim _ {\ lambda \ rightarrow + \ infty} \ left (\ tan \ left (\ alpha _ {\ lambda} \ right) \ right) = \ lim _ {\ lambda \ rightarrow + \ infty} \ left (e ^ {\ frac {2 \ lambda -1} {2 \ sigma ^ {2}}} \ right) = + \ infty \ end {matriz} (16)

(15) (dieciséis), ROC- 0 + ∞ λ -∞ + ∞. , λ = -∞ \ tan⁡ (α_λ) = 0, , α_λ = 0 °. λ = + ∞, tan⁡ (α_λ) = + ∞, .. α_λ = 90 °( ).





# ,    Pfa  Pd   sigma  lambda
def dif_roc_curve(sigma, lambda_):
    return (derivative(lambda x: 1 - norm.cdf(x/sigma), lambda_, dx=1e-10),
           derivative(lambda x: 1 - norm.cdf((x - 1)/sigma), lambda_, dx=1e-10))


data5 = []
for SNR in SNR_values:
    for lambda_ in [0, 0.5, 1]:
        dPfa, dPd = dif_roc_curve(snr_to_sigma(SNR), lambda_)
        Pfa, Pd = roc_curve(snr_to_sigma(SNR), lambda_)
        tan = dPd/dPfa
        for i in np.arange(0.01/tan, 0.2/tan, 0.01/tan):
            data5.append([tan*(i - Pfa) + Pd, i, str(SNR), lambda_])
        
data5 = pd.DataFrame(data5, columns=['y', 'x', 'SNR', 'lambda'])
      
      



fig, ax = plt.subplots(figsize=(18, 14))
sns.set_context('poster')
plt.title('$ROC$-  $3^{}$ ', fontsize=40)
plt.xlabel('$P_{fa}$', fontsize=40)
plt.xticks(np.arange(0, 1.05, 0.1), fontsize=20)
plt.yticks(np.arange(0, 1.05, 0.1), fontsize=20)
plt.ylabel('$P_d$', fontsize=40, rotation=0, labelpad=40)
sns.lineplot(x='Pfa', y='Pd', hue='SNR', legend=False,
             data=data[data['SNR']  == '5.0'], palette='gist_ncar', ax=ax)
sns.lineplot(x='x', y='y', hue='lambda', linestyle='--',
             data=data5[data5['SNR']  == '5.0'], 
             palette='dark:b', legend=True,  ax=ax)

plt.grid(color='black', linestyle='--', linewidth=1, alpha=0.3)

plt.legend(fontsize='small', shadow=True, title='  $\lambda=$',
           borderpad=0.9, fancybox=True, loc=4);
      
      



/





Higo.  10 Curva ROC SNR = 5 con tres tangentes en los puntos.
. 10 ROC- SNR=5 .

. 10 \ left (P_ {fa} (0), P_ {d} (0) \ right), \ left (P_ {fa} (0.5), P_ {d} (0.5) \ right), \ left (P_ {fa } (1), P_ {d} (1) \ derecha).





ROC- (12). ROC- . , , SNR, σ. , ROC-, λ.





  • - . , . 1. , --, 1968, , . , . . . . . ., « », 1972, 744 .





  • Tyapkin V.N. Fundamentos de la construcción de estaciones de radar de tropas radio-técnicas: libro de texto / V.N. Tyapkin, A.N. Fomin, E.N. Garin [et al.]; debajo del total. ed. V.N. Tyapkin. - Krasnoyarsk: Sib. Feder. un-t. - 2011 .-- 536 p.





Adicionalmente

Enlace a github con código fuente.








All Articles