Home

1AFC rating task for signal detection theory (SDT)

 

In One-alternative forced choice (1AFC) task, one of the two stimulus, e.g., noise only stimulus and noise + signal stimulus, is presented, and the observer is asked to judge which one was presented. The sensation of the noise only stimulus is represented by , and that of the signal stimulus by . They are assumed to have the following distribution

Origin and unit of the sensation are assumed so that . Hence we have

The observer is required to respond with rating about his/her judgment. For example, Certainly noise only stimulus, Probably signal stimulus, and so on.

In K category rating task, lets the judgment be represented by integer from 1 to K. 1 represents the most certain judgment of the noise only, and K the most certain judgment of the stimulus. Corresponding to the category judgment, the sensation dimension is partitioned by  category boundaries.

When the sensation is between  and , judgment k is done.

So, we have the following equations:

where  represents the cumulative distribution function of the standard normal distribution.

The difference between the means of sensations  and  is denoted by , that is,

 

Data of 1AFC rating task can be summarized like Table 1.

 

Tabnle 1 Data of 1AFC rating task

 

Category-1

Category-K

Noise only

N(n1)

N(nK)

Noise + Signal

N(s1)

N(sK)

 

N(nk) and N(sk) denote the number of judgment category-k for the noise stimulus and the noise+signal stimulus, respectively.

The likelihood function for the data of Table 1 is given by

(1)        

Stan script for eq,(1) is shown in Listing 1.

Python script using the Stan script in Listing 1 is shown in Listing 2.

Files of these scripts are archived in the file sdt1afc_files.zip, which can be freely downloaded and used.

For information about how to install Python and PyStan (Python interface to Stan), check this website.

 

The file name of the script in Listing 2 is main.py.

To execute the script file main.py, run the following code.

The code was run on Python 3.7 virtual environment of Anaconda on windows 10 using PyStan 2.17.1.0.

For an example using PyStan 3, check the latter part of this website.

 

python main.py

 

When the script is executed, the number of judgment categories K is required to be set as follows.

 

XXXXX\sdt1afc_files> python main.py

INFO:numexpr.utils:NumExpr defaulting to 8 threads.

 K =

 

As an example, lets use the data in Table 2.

 

Table 2. Example of 1AFC rating task data. Number of judgments

Judgment

Stimulus presented

Noise stimulus

Signal stimulus

Sure Noise

6

1

Noise

18

3

Maybe Noise

34

12

Uncertain

31

28

Maybe Signal

8

38

Signal

3

12

Sure Signal

0

6

 

In case of Table 2, the number of categories is 7, so input 7.

After setting the value of K, number of judgments of each category to the noise stimulus is set by separating each value by space.

Then, numbers of judgments to the signal stimulus are set.

 

K = 7

 Data for Noise = 6 18 34 31 8 3 0

 Data for Signal = 1 3 12 28 38 12 6

 

After setting the values for the signal stimulus, press the Enter key, then calculation starts.

After MCMC sampling, graph of the posterior distribution of  is displayed (Figure 1).

Figure 1

 

Close the window of the posterior distribution of , graph of the posterior distribution of  is displayed (Figure 2).

Figure 2

 

After closing the window of the posterior distribution of , it takes some time for calculation.

After the calculation, graph of ROC curve is displayed (Figure 3).

Figure 3

 

Close the window of ROC curve, graph of posterior distributions of criterion boundaries is displayed (Figure 4).

Figure 4

 

Close the window, then execution of the script ends.

Execution of the script produces a text file Output .txt, in which some information of the analysis is stored as follows:

 

Data for Noise:

    [6, 18, 34, 31, 8, 3, 0]

 

Data for Signal:

    [1, 3, 12, 28, 38, 12, 6]

mu:

    MAP est. = 1.336

    med.     = 1.317

    mean     = 1.321

    95% CI   = [0.954, 1.715]

 

sigma:

    MAP est. = 1.161

    med.     = 1.175

    mean     = 1.183

    95% CI   = [0.916, 1.505]

 

 

C1:

    MAP est. = -1.579

    median   = -1.562

    mean     = -1.566

    95% CI   = [-1.953, -1.206]

 

C2:

    MAP est. = -0.725

    median   = -0.720

    mean     = -0.721

    95% CI   = [-0.983, -0.465]

 

C3:

    MAP est. = 0.188

    median   = 0.184

    mean     = 0.184

    95% CI   = [-0.052, 0.418]

 

C4:

    MAP est. = 1.184

    median   = 1.187

    mean     = 1.188

    95% CI   = [0.899, 1.484]

 

C5:

    MAP est. = 2.299

    median   = 2.291

    mean     = 2.298

    95% CI   = [1.844, 2.796]

 

C6:

    MAP est. = 3.067

    median   = 3.147

    mean     = 3.169

    95% CI   = [2.491, 3.987]

 

 

The script was executed with PyStan 2.17.1.0 installed in Python 3.7 virtual environment of Anaconda in Windows 10.

For information about installation of PyStan, check the following websites:

 

http://y-okamoto-psy1949.la.coocan.jp/Python/en/PythonAnaconda/

http://y-okamoto-psy1949.la.coocan.jp/Python/en/BeginningPython/

http://y-okamoto-psy1949.la.coocan.jp/Python/en1/PyStanInstalling/

 

 

Listing 1. Stan script for 1AFC rating task data (file name: YN_rating.stan)

 

data {

    int<lower = 3> K;

    int<lower = 0> Freq_Noise[K];

    int<lower = 0> Freq_Signal[K];

}

parameters {

    real mu;

    real<lower = 0.0, upper = 5.0> sigma;

    ordered[K-1] c;

}

transformed parameters {

    vector[K] theta_n;

    vector[K] theta_s;

 

    theta_n[1] = normal_cdf(c[1], 0.0, 1.0); 

    theta_n[K] = 1.0 - normal_cdf(c[K-1], 0.0, 1.0);

    for (k in 2:(K-1))

        theta_n[k] = normal_cdf(c[k], 0.0, 1.0) - normal_cdf(c[k-1], 0.0, 1.0);  

    theta_s[1] = normal_cdf((c[1] - mu) / sigma, 0.0, 1.0);

    theta_s[K] = 1.0 - normal_cdf((c[K-1] - mu) / sigma, 0.0, 1.0);  

    for (k in 2:(K-1))

        theta_s[k] =normal_cdf((c[k] - mu) / sigma, 0.0, 1.0) -

                      normal_cdf((c[k-1] - mu) / sigma, 0.0, 1.0);}

model {

    mu ~ normal(0.0, 10.0);

    sigma ~ uniform(0, 5);

    Freq_Noise ~ multinomial(theta_n);

    Freq_Signal ~ multinomial(theta_s);

}

 

 

Listing 2. Python script using YN_rating.stan in Listing 1 (file name: main.py)

 

import pystan

import matplotlib.pyplot as plt

import numpy as np

from pystan import StanModel

import seaborn as sb

import scipy.stats as ss

 

 

def CalcMAPEst(samples, a = 0.05, n_points = 2000):

    """

        Calculatte a MAP estimate from a KDE graph on [Lp, Up]

        Lp and Up are 100*a/2 and 100(1-a/2) percentile points of samples

    """

    Lp, Up = np.percentile(samples, [100 * a/2, 100 * (1 - a/2)])  # import numpy as np

    coord = np.linspace(Lp, Up, n_points)

    est_pdf = ss.gaussian_kde(samples).pdf(coord)  # import scipy.stats as ss

    map_idx = np.argmax(est_pdf)

    MAP_Est = coord[map_idx]      

    return MAP_Est, est_pdf[map_idx]

 

 

fout = open('Output.txt', 'w')

 

K = int(input('K = '))

s = input('Data for Noise = ')

Data_Noise = []

for v in s.split():

    Data_Noise.append(int(v))

s = input('Data for Signal = ')

Data_Signal = []

for v in s.split():

    Data_Signal.append(int(v))

 

fout.write('\nData for Noise:\n')

fout.write('    {}\n'.format(Data_Noise))

fout.write('\nData for Signal:\n')

fout.write('    {}'.format(Data_Signal))

 

 

Data = {'K': K, 'Freq_Noise': Data_Noise, 'Freq_Signal': Data_Signal}

 

sm = pystan.StanModel(file = 'YN_rating.stan')

 

fit = sm.sampling(data = Data, iter = 10000, n_jobs = 1)

print(fit)

 

mu = fit['mu']

sigma = fit['sigma']

mu_mean = mu.mean()

mu_MAP = CalcMAPEst(mu)[0]

mu_q025, mu_med, mu_q975 = np.percentile(mu, [2.5, 50, 97.5]) # mu_s[int(len(mu_s) / 2)]

sgm_mean = sigma.mean()

sgm_MAP = CalcMAPEst(sigma)[0]

sgm_q025, sgm_med, sgm_q975 = np.percentile(sigma, [2.5, 50, 97.5])  # sgm_s[int(len(sgm_s) / 2)]

 

fout.write('\nmu:\n')

fout.write('    MAP est. = {0:.3f}\n'.format(mu_MAP))

fout.write('    med.     = {0:.3f}\n'.format(mu_med))

fout.write('    mean     = {0:.3f}\n'.format(mu_mean))

fout.write('    95% CI   = [{0:.3f}, {1:.3f}]\n'.format(mu_q025, mu_q975))

 

fout.write('\nsigma:\n')

fout.write('    MAP est. = {0:.3f}\n'.format(sgm_MAP))

fout.write('    med.     = {0:.3f}\n'.format(sgm_med))

fout.write('    mean     = {0:.3f}\n'.format(sgm_mean))

fout.write('    95% CI   = [{0:.3f}, {1:.3f}]\n'.format(sgm_q025, sgm_q975))

 

sb.kdeplot(mu)

plt.title((r'$\mu$') + (r'($\Delta$') + 'm) = ' +

           '{0:<.3f}(mode)'.format(mu_MAP),

          fontsize = 18)

plt.yticks([])

plt.ylabel('Density', fontsize = 14)

plt.xlabel('$\mu$', fontsize = 16)

plt.tight_layout()

plt.savefig('Figure_mu.png')

plt.show()

 

sb.kdeplot(sigma)

plt.title("$\sigma$ = {0:<.3f}(mode) ".format(sgm_MAP), fontsize = 18)

plt.yticks([])

plt.ylabel('Density', fontsize = 14)

plt.xlabel('$\sigma$', fontsize = 18)

plt.tight_layout()

plt.savefig('Figure_sgm.png')

plt.show()

 

c = fit['c']

 

c_comp = []

for i in range(3):

    c_comp.append([])

 

for v in c:

    for j in range(3):

        c_comp[j].append(v[j])

 

z_values = np.arange(-4.0, 4.001, 0.1)

x_values = 1.0 - ss.norm(0.0, 1.0).cdf(z_values)

y_values = 1.0 - ss.norm(mu_MAP, sgm_MAP).cdf(z_values)

 

plt.figure(figsize = (5,5))

plt.plot(x_values, y_values, 'b-')

plt.title("ROC-curve", fontsize = 18)

plt.xlabel("P(False Alarm)", fontsize = 14)

plt.ylabel("P(Hit)", fontsize = 14)

 

cum_freq_n = []

cum_freq_s = []

for k in range(K):

    cum_freq_n.append(Data_Noise[K - 1 - k])

    cum_freq_s.append(Data_Signal[K - 1 - k])

 

for k in range(1, K):

    cum_freq_n[k] += cum_freq_n[k-1]

    cum_freq_s[k] += cum_freq_s[k-1]

 

x_fa = []

y_ht = []

for k in range(K-1):

    x_fa.append(cum_freq_n[k] / cum_freq_n[K-1])

    y_ht.append(cum_freq_s[k] / cum_freq_s[K-1])

plt.plot(x_fa, y_ht, 'ro', label = 'Data')

 

print('\nI am calculating...')

 

c_means = np.zeros(K-1)

c_meds = np.zeros(K-1)

c_MAPs = np.zeros(K-1)

c_q025s = np.zeros(K-1)

c_q975s = np.zeros(K-1)

for k in range(K-1):

    c_means[k] = c.T[k].mean()

    c_MAPs[k] = CalcMAPEst(c.T[k])[0]

    c_q025s[k], c_meds[k], c_q975s[k] = np.percentile(c.T[k], [2.5, 50, 97.5])

 

fout.write('\n')

for k in range(K-1):

    fout.write('\nC{}:\n'.format(k+1))

    fout.write('    MAP est. = {0:.3f}\n'.format(c_MAPs[k]))

    fout.write('    median   = {0:.3f}\n'.format(c_meds[k]))

    fout.write('    mean     = {0:.3f}\n'.format(c_means[k]))

    fout.write('    95% CI   = [{0:.3f}, {1:.3f}]\n'.format(

                    c_q025s[k], c_q975s[k]))

   

x_fa = []

y_ht = []

 

for k in range(K-1):

    x_fa.append(1.0 - ss.norm().cdf(c_MAPs[k])) 

    y_ht.append(1.0 - ss.norm(mu_MAP, sgm_MAP).cdf(c_MAPs[k])) 

plt.plot(x_fa, y_ht, 'gs', label = 'Prediction')

 

plt.legend(fontsize = 12)

plt.tight_layout()

plt.savefig('Figure_ROC.png')

plt.show()

 

for k in range(K-1):

    sb.kdeplot(c.T[k], label = '$C_{0}$: mode = {1:.3f}'.format(k+1, c_MAPs[k]))

title_str = "Criterions"

plt.title(title_str, fontsize = 18)

plt.yticks([])

plt.ylabel('Density', fontsize = 14)

plt.xlabel('C', fontsize = 14)

plt.legend(fontsize = 12)

plt.tight_layout()

plt.savefig('Figure_Cs.png')

plt.show()

 

fout.close()

 

 

 

Using PyStan 3

 

An example of a script using PyStan 3 is shown in Listing 3.

We cannot run a PyStan 3 script directly on Windows. But a PyStan 3 script can be run on WSL (Windows Subsystem for Linux). When we use PyStan 3, the script must be run on WSL, on which we cannot use a graphic library, e.g, matplotlib.

The script in Listing 2 was divided into two parts, one for MCMC sampling using PyStan 3, and the other for analysis of MCMC sample, which uses graphic libraries.

The script for MCMC sampling is shown in Listing 3, which is run on a Python 3.10 virtual environment of Anaconda on WSL on Windows. PyStan 3 is installed on the Python 3.10 virtual environment with the following command. The Stan script used in Listing 3 is the one in Listing 1.

 

pip install pystan

.

Analysis of the MCMC sample is done by the script in Listing 4, which can be run on Windows.

 

Script files are archived in the ZIP file sdt1afc_ps3_files.zip , which can be downloaded freely.

 

Run the script in Listing 3 as follows

 

(py310) yasuharu@PSY-PM-PC:/mnt/d/yasuharu/.../sdt1afc_ps3_files$ python mcmc_ps3.py

 

When the script starts, the number of categories, and frequencies of the categorical responses are required to be set.

When the data in Table 2 is analyzed, input as follows:

 

K = 7

Data for Noise = 6 18 34 31 8 3 0

Data for Signal = 1 3 12 28 38 12 6

 

Notice that values are separated by whitespaces.

After the above setting of input data, the building, then the sampling starts.

The MCMC sample is stored in the files infrnc_d.pkl and d_frame.pk by the following codes. 

 

with open('infrnc_d.pkl', 'wb') as f:

    pickle.dump(infrnc_d, f)

 

and

 

with open('d_frame.pkl', 'wb') as f:

    pickle.dump(d_frame, f)

 

The MCMC samples saved in the files are analyzed by the script in Listing 4.

Run the script file anal_ps3.py, then a trace graph is displayed (Figure B1).

Figure B1

 

Close the form of Figure B1, then some posterior distributions are displayed.

The graph of ROC curve is also displayed after some time of calculation (Figure B2).

Figure B2

 

After posterior distributions of criterion Cs are displayed, the script ends.

Some statistics of the posterior distributions are saved in Output_Anal.txt.

Contents of the file Output_Anal.txt are as follows:

 

Data for Noise:

    [6, 18, 34, 31, 8, 3, 0]

 

Data for Signal:

    [1, 3, 12, 28, 38, 12, 6]

 

mu:

    MAP est. = 1.293

    med.     = 1.314

    mean     = 1.320

    95% CI   = [0.951, 1.721]

 

sigma:

    MAP est. = 1.159

    med.     = 1.172

    mean     = 1.182

    95% CI   = [0.913, 1.508]

 

 

C1:

    MAP est. = -1.550

    median   = -1.563

    mean     = -1.568

    95% CI   = [-1.964, -1.204]

 

C2:

    MAP est. = -0.721

    median   = -0.720

    mean     = -0.721

    95% CI   = [-0.984, -0.466]

 

C3:

    MAP est. = 0.187

    median   = 0.185

    mean     = 0.185

    95% CI   = [-0.048, 0.419]

 

C4:

    MAP est. = 1.187

    median   = 1.186

    mean     = 1.189

    95% CI   = [0.899, 1.493]

 

C5:

    MAP est. = 2.275

    median   = 2.289

    mean     = 2.298

    95% CI   = [1.829, 2.801]

 

C6:

    MAP est. = 3.088

    median   = 3.145

    mean     = 3.167

    95% CI   = [2.472, 3.980]

 

 

 

Listing 3. A script using PyStan 3 (mcmc_ps3.py)

 

import stan

import arviz as az

import pickle

import pandas as pd

 

pd.set_option('display.max_columns', None)

 

fout = open('Output.txt', 'w')

 

K = int(input('K = '))

s = input('Data for Noise = ')

Data_Noise = []

for v in s.split():

    Data_Noise.append(int(v))

s = input('Data for Signal = ')

Data_Signal = []

for v in s.split():

    Data_Signal.append(int(v))

 

with open('noise.pkl', 'wb') as f:

    pickle.dump(Data_Noise, f)

with open('signal.pkl', 'wb') as f:

    pickle.dump(Data_Signal, f)

 

fout.write('\nData for Noise:\n')

fout.write('    {}\n'.format(Data_Noise))

fout.write('\nData for Signal:\n')

fout.write('    {}'.format(Data_Signal))

 

Data = {'K': K, 'Freq_Noise': Data_Noise, 'Freq_Signal': Data_Signal}

with open('YN_rating.stan', 'r') as f:

    pm = stan.build(f.read(), data = Data)

 

fit = pm.sample(num_samples = 10000)

 

print('fit =\n', fit)

 

infrnc_d = az.from_pystan(posterior = fit, posterior_model = pm )

print('\nSummary =\n', az.summary(infrnc_d))

 

with open('infrnc_d.pkl', 'wb') as f:

    pickle.dump(infrnc_d, f)

 

d_frame = fit.to_frame()

print(d_frame.keys())

with open('d_frame.pkl', 'wb') as f:

    pickle.dump(d_frame, f)

 

fout.close()

print('Output.txt was saved.')

 

 

 

Listing 4. Analysis of MCMC sample (anal_ps3.py)

 

import arviz as az

import matplotlib.pyplot as plt

import numpy as np

import seaborn as sb

import scipy.stats as ss

import pickle

import pandas as pd

 

pd.set_option('display.max_columns', None)

 

def CalcMAPEst(samples, a = 0.05, n_points = 2000):

    """

        Calculatte a MAP estimate from a KDE graph on [Lp, Up]

        Lp and Up are 100*a/2 and 100(1-a/2) percentile points of samples

    """

    Lp, Up = np.percentile(samples, [100 * a/2, 100 * (1 - a/2)])  # import numpy as np

    coord = np.linspace(Lp, Up, n_points)

    est_pdf = ss.gaussian_kde(samples).pdf(coord)  # import scipy.stats as ss

    map_idx = np.argmax(est_pdf)

    MAP_Est = coord[map_idx]      

    return MAP_Est, est_pdf[map_idx]

 

fout = open('Output_Anal.txt', 'w')

 

with open('noise.pkl', 'rb') as f:

    Data_Noise = pickle.load(f)

with open('signal.pkl', 'rb') as f:

    Data_Signal = pickle.load(f)

K = len(Data_Noise)

 

fout.write('\nData for Noise:\n')

fout.write('    {}\n'.format(Data_Noise))

fout.write('\nData for Signal:\n')

fout.write('    {}'.format(Data_Signal))

fout.write('\n')

 

with open('infrnc_d.pkl', 'rb') as f:

    infrnc_d = pickle.load(f)

with open('d_frame.pkl', 'rb') as f:

    d_frame = pickle.load(f)

 

az.plot_trace(infrnc_d)

plt.tight_layout()

plt.savefig('FigTrace.png')

plt.show()

 

mu = d_frame['mu']  

sigma = d_frame['sigma']  

mu_mean = mu.mean()

mu_MAP = CalcMAPEst(mu)[0]

mu_q025, mu_med, mu_q975 = np.percentile(mu, [2.5, 50, 97.5])

sgm_mean = sigma.mean()

sgm_MAP = CalcMAPEst(sigma)[0]

sgm_q025, sgm_med, sgm_q975 = np.percentile(sigma, [2.5, 50, 97.5]) 

 

fout.write('\nmu:\n')

fout.write('    MAP est. = {0:.3f}\n'.format(mu_MAP))

fout.write('    med.     = {0:.3f}\n'.format(mu_med))

fout.write('    mean     = {0:.3f}\n'.format(mu_mean))

fout.write('    95% CI   = [{0:.3f}, {1:.3f}]\n'.format(mu_q025, mu_q975))

 

fout.write('\nsigma:\n')

fout.write('    MAP est. = {0:.3f}\n'.format(sgm_MAP))

fout.write('    med.     = {0:.3f}\n'.format(sgm_med))

fout.write('    mean     = {0:.3f}\n'.format(sgm_mean))

fout.write('    95% CI   = [{0:.3f}, {1:.3f}]\n'.format(sgm_q025, sgm_q975))

 

sb.kdeplot(mu)

plt.title((r'$\mu$') + (r'($\Delta$') + 'm) = ' +

           '{0:<.3f}(mode)'.format(mu_MAP),

          fontsize = 18)

plt.yticks([])

plt.ylabel('Density', fontsize = 14)

plt.xlabel('$\mu$', fontsize = 16)

plt.tight_layout()

plt.savefig('Figure_mu.png')

plt.show()

 

sb.kdeplot(sigma)

plt.title("$\sigma$ = {0:<.3f}(mode) ".format(sgm_MAP), fontsize = 18)

plt.yticks([])

plt.ylabel('Density', fontsize = 14)

plt.xlabel('$\sigma$', fontsize = 18)

plt.tight_layout()

plt.savefig('Figure_sgm.png')

plt.show()

 

c = [0]*(K-1)

for k in range(K-1):

    c[k] = d_frame[f'c.{k+1}']

c = np.array(c).T

print('c =\n', c)

 

z_values = np.arange(-4.0, 4.001, 0.1)

x_values = 1.0 - ss.norm(0.0, 1.0).cdf(z_values)

y_values = 1.0 - ss.norm(mu_MAP, sgm_MAP).cdf(z_values)

 

plt.figure(figsize = (5,5))

plt.plot(x_values, y_values, 'b-')

plt.title("ROC-curve", fontsize = 18)

plt.xlabel("P(False Alarm)", fontsize = 14)

plt.ylabel("P(Hit)", fontsize = 14)

 

cum_freq_n = []

cum_freq_s = []

for k in range(K):

    cum_freq_n.append(Data_Noise[K - 1 - k])

    cum_freq_s.append(Data_Signal[K - 1 - k])

 

for k in range(1, K):

    cum_freq_n[k] += cum_freq_n[k-1]

    cum_freq_s[k] += cum_freq_s[k-1]

 

x_fa = []

y_ht = []

for k in range(K-1):

    x_fa.append(cum_freq_n[k] / cum_freq_n[K-1])

    y_ht.append(cum_freq_s[k] / cum_freq_s[K-1])

plt.plot(x_fa, y_ht, 'ro', label = 'Data')

 

print('\nI am calculating...')

 

c_means = np.zeros(K-1)

c_meds = np.zeros(K-1)

c_MAPs = np.zeros(K-1)

c_q025s = np.zeros(K-1)

c_q975s = np.zeros(K-1)

for k in range(K-1):

    c_means[k] = c.T[k].mean()

    c_MAPs[k] = CalcMAPEst(c.T[k])[0]

    c_q025s[k], c_meds[k], c_q975s[k] = np.percentile(c.T[k], [2.5, 50, 97.5])

 

fout.write('\n')

for k in range(K-1):

    fout.write('\nC{}:\n'.format(k+1))

    fout.write('    MAP est. = {0:.3f}\n'.format(c_MAPs[k]))

    fout.write('    median   = {0:.3f}\n'.format(c_meds[k]))

    fout.write('    mean     = {0:.3f}\n'.format(c_means[k]))

    fout.write('    95% CI   = [{0:.3f}, {1:.3f}]\n'.format(

                    c_q025s[k], c_q975s[k]))

   

x_fa = []

y_ht = []

 

for k in range(K-1):

    x_fa.append(1.0 - ss.norm().cdf(c_MAPs[k])) 

    y_ht.append(1.0 - ss.norm(mu_MAP, sgm_MAP).cdf(c_MAPs[k])) 

plt.plot(x_fa, y_ht, 'gs', label = 'Prediction')

 

plt.legend(fontsize = 12)

plt.tight_layout()

plt.savefig('Figure_ROC.png')

plt.show()

 

for k in range(K-1):

    sb.kdeplot(c.T[k], label = '$C_{0}$: mode = {1:.3f}'.format(k+1, c_MAPs[k]))

title_str = "Criterions"

plt.title(title_str, fontsize = 18)

plt.yticks([])

plt.ylabel('Density', fontsize = 14)

plt.xlabel('C', fontsize = 14)

plt.legend(fontsize = 12)

plt.tight_layout()

plt.savefig('Figure_Cs.png')

plt.show()

 

fout.close()

print('Output_Anal.txt was saved.')

 

 

 

Home