Exemplo n.º 1
0
    def test_bayesian_importance_sampling_avar(self):
        np.random.seed(1)
        nrandom_vars = 2
        Amat = np.array([[-0.5, 1]])
        noise_std = 0.1
        prior_variable = IndependentMultivariateRandomVariable(
            [stats.norm(0, 1)] * nrandom_vars)
        prior_mean = prior_variable.get_statistics('mean')
        prior_cov = np.diag(prior_variable.get_statistics('var')[:, 0])
        prior_cov_inv = np.linalg.inv(prior_cov)
        noise_cov_inv = np.eye(Amat.shape[0]) / noise_std**2
        true_sample = np.array([.4] * nrandom_vars)[:, None]
        collected_obs = Amat.dot(true_sample)
        collected_obs += np.random.normal(0, noise_std, (collected_obs.shape))
        exact_post_mean, exact_post_cov = \
            laplace_posterior_approximation_for_linear_models(
                Amat, prior_mean, prior_cov_inv, noise_cov_inv,
                collected_obs)

        chol_factor = np.linalg.cholesky(exact_post_cov)
        chol_factor_inv = np.linalg.inv(chol_factor)

        def g_model(samples):
            return np.exp(
                np.sum(chol_factor_inv.dot(samples - exact_post_mean),
                       axis=0))[:, None]

        nsamples = int(1e6)
        prior_samples = generate_independent_random_samples(
            prior_variable, nsamples)
        posterior_samples = chol_factor.dot(
            np.random.normal(0, 1, (nrandom_vars, nsamples))) + exact_post_mean

        g_mu, g_sigma = 0, np.sqrt(nrandom_vars)
        f, f_cdf, f_pdf, VaR, CVaR, ssd, ssd_disutil = \
            get_lognormal_example_exact_quantities(g_mu, g_sigma)

        beta = .1
        cvar_exact = CVaR(beta)

        cvar_mc = conditional_value_at_risk(g_model(posterior_samples), beta)

        prior_pdf = prior_variable.pdf
        post_pdf = stats.multivariate_normal(mean=exact_post_mean[:, 0],
                                             cov=exact_post_cov).pdf
        weights = post_pdf(prior_samples.T) / prior_pdf(prior_samples)[:, 0]
        weights /= weights.sum()
        cvar_im = conditional_value_at_risk(g_model(prior_samples), beta,
                                            weights)
        # print(cvar_exact, cvar_mc, cvar_im)
        assert np.allclose(cvar_exact, cvar_mc, rtol=1e-3)
        assert np.allclose(cvar_exact, cvar_im, rtol=2e-3)
Exemplo n.º 2
0
def solve_quantile_regression(tau,
                              samples,
                              values,
                              eval_basis_matrix,
                              normalize_vals=False,
                              opts={}):
    basis_matrix = eval_basis_matrix(samples)
    if basis_matrix.shape[0] < basis_matrix.shape[1]:
        raise ValueError("System is under-determined")
    if normalize_vals is True:
        factor = values[:, 0].std()
        vals = values.copy() / factor
    else:
        vals = values
    quantile_coef = quantile_regression(basis_matrix,
                                        vals.squeeze(),
                                        tau=tau,
                                        opts=opts)
    if normalize_vals is True:
        quantile_coef *= factor
    # assume first coefficient is for constant term
    quantile_coef[0] = 0
    centered_approx_vals = basis_matrix.dot(quantile_coef)[:, 0]
    deviation = conditional_value_at_risk(values[:, 0] - centered_approx_vals,
                                          tau)
    quantile_coef[0] = deviation
    return quantile_coef
Exemplo n.º 3
0
def oed_conditional_value_at_risk_deviation(beta,
                                            samples,
                                            weights,
                                            samples_sorted=True):
    cvars = np.empty(samples.shape[0])
    for ii in range(samples.shape[0]):
        mean = np.sum(samples[ii, :] * weights[ii, :])
        cvars[ii] = conditional_value_at_risk(
            samples[ii, :], beta, weights[ii, :], samples_sorted) - mean
    return cvars[:, None]
Exemplo n.º 4
0
 def test_triangle_superquantile(self):
     c = 0.5
     loc = -0.5
     scale = 2
     u = np.asarray([0.3, 0.75])
     cvar = triangle_superquantile(u, c, loc, scale)
     samples = triangle_quantile(np.random.uniform(0, 1, (100000)), c, loc,
                                 scale)
     for ii in range(len(u)):
         mc_cvar = conditional_value_at_risk(samples, u[ii])
     assert abs(cvar[ii] - mc_cvar) < 1e-2
Exemplo n.º 5
0
def solve_quantile_regression(tau, samples, values, eval_basis_matrix):
    basis_matrix = eval_basis_matrix(samples)
    quantile_coef = quantile_regression(basis_matrix,
                                        values.squeeze(),
                                        tau=tau)
    # assume first coefficient is for constant term
    quantile_coef[0] = 0
    centered_approx_vals = basis_matrix.dot(quantile_coef)[:, 0]
    deviation = conditional_value_at_risk(values[:, 0] - centered_approx_vals,
                                          tau)
    quantile_coef[0] = deviation
    return quantile_coef
Exemplo n.º 6
0
 def test_conditional_value_at_risk(self):
     N = 6
     p = np.ones(N) / N
     X = np.random.normal(0, 1, N)
     # X = np.arange(1,N+1)
     X = np.sort(X)
     beta = 7 / 12
     i_beta_exact = 3
     VaR_exact = X[i_beta_exact]
     cvar_exact = 1 / 5 * VaR_exact + 2 / 5 * (np.sort(X)[i_beta_exact +
                                                          1:]).sum()
     ecvar, evar = conditional_value_at_risk(X, beta, return_var=True)
     # print(cvar_exact,ecvar)
     assert np.allclose(cvar_exact, ecvar)
Exemplo n.º 7
0
    def test_weighted_value_at_risk_normal(self):
        mu, sigma = 1, 1
        # bias_mu,bias_sigma=1.0,1
        bias_mu, bias_sigma = mu, sigma

        from scipy.special import erf

        def VaR(alpha):
            return stats.norm.ppf(alpha, loc=mu, scale=sigma)

        def CVaR(alpha):
            vals = 0.5 * mu
            vals -= 0.5*mu*erf((VaR(alpha)-mu)/(np.sqrt(2)*sigma)) -\
                sigma*np.exp(-(mu-VaR(alpha))**2/(2*sigma**2))/np.sqrt(2*np.pi)
            vals /= (1 - alpha)
            return vals

        alpha = 0.8

        print(CVaR(alpha),
              cvar_gaussian_variable(stats.norm(loc=mu, scale=sigma), alpha))
        assert np.allclose(
            CVaR(alpha),
            cvar_gaussian_variable(stats.norm(loc=mu, scale=sigma), alpha))

        num_samples = int(1e5)
        samples = np.random.normal(bias_mu, bias_sigma, num_samples)
        target_pdf_vals = stats.norm.pdf(samples, loc=mu, scale=sigma)
        bias_pdf_vals = stats.norm.pdf(samples, loc=bias_mu, scale=bias_sigma)
        II = np.where(bias_pdf_vals < np.finfo(float).eps)[0]
        assert np.all(target_pdf_vals[II] < np.finfo(float).eps)
        J = np.where(bias_pdf_vals >= np.finfo(float).eps)[0]
        weights = np.zeros_like(target_pdf_vals)
        weights[J] = target_pdf_vals[J] / bias_pdf_vals[J]
        weights /= weights.sum()

        empirical_VaR, __ = value_at_risk(samples,
                                          alpha,
                                          weights,
                                          samples_sorted=False)
        # print('VaR',VaR(alpha),empirical_VaR)
        assert np.allclose(VaR(alpha), empirical_VaR, rtol=1e-2)

        empirical_CVaR = conditional_value_at_risk(samples, alpha, weights)
        # print('CVaR',CVaR(alpha),empirical_CVaR)
        assert np.allclose(CVaR(alpha), empirical_CVaR, rtol=1e-2)
Exemplo n.º 8
0
    def test_conditional_value_at_risk_using_opitmization_formula(self):
        """
        Compare value obtained via optimization and analytical formula
        """
        plot = False
        num_samples = 5
        alpha = np.array([1. / 3., 0.5, 0.85])
        samples = np.random.normal(0, 1, (num_samples))
        for ii in range(alpha.shape[0]):
            ecvar, evar = conditional_value_at_risk(samples,
                                                    alpha[ii],
                                                    return_var=True)

            def objective(tt):
                return np.asarray([
                    t + 1 /
                    (1 - alpha[ii]) * np.maximum(0, samples - t).mean()
                    for t in tt
                ])

            tol = 1e-8
            method = 'L-BFGS-B'
            options = {'disp': False, 'gtol': tol, 'ftol': tol}
            init_guess = 0
            result = minimize(objective,
                              init_guess,
                              method=method,
                              options=options)
            value_at_risk = result['x']
            cvar = result['fun']
            print(alpha[ii], value_at_risk, cvar, ecvar)
            assert np.allclose(ecvar, cvar)
            assert np.allclose(evar, value_at_risk)

            if plot:
                rv = stats.norm
                lb, ub = rv.interval(.99)
                xx = np.linspace(lb, ub, 101)
                obj_vals = objective(xx)
                plt.plot(xx, obj_vals)
                plt.plot(value_at_risk, cvar, 'ro')
                plt.show()
Exemplo n.º 9
0
def plot_lognormal_example_exact_quantities(
        num_samples=int(2e5), plot=False, mu=0, sigma=1):
    num_vars = 1
    if plot:
        assert num_samples <= 1e5
    else:
        assert num_samples >= 1e4

    f, f_cdf, f_pdf, VaR, CVaR, ssd, ssd_disutil = \
        get_lognormal_example_exact_quantities(mu, sigma)
    from pyapprox.low_discrepancy_sequences import transformed_halton_sequence
    # samples = np.random.normal(mu,sigma,(num_vars,num_samples))
    # values = f(samples)[:,0]
    samples = transformed_halton_sequence(
        [partial(stats.norm.ppf, loc=mu, scale=sigma)], num_vars, num_samples)
    values = f(samples)[:, 0]

    if plot:
        import matplotlib.pyplot as plt
        fig, axs = plt.subplots(1, 6, sharey=False, figsize=(16, 6))
        # from pyapprox.density import EmpiricalCDF
        ygrid = np.linspace(-1, 5, 100)
        # ecdf = EmpiricalCDF(values)
        # axs[0].plot(ygrid,ecdf(ygrid),'-')
        axs[0].plot(ygrid, f_cdf(ygrid), '--')
        # axs[0].set_xlim(ygrid.min(),ygrid.max())
        axs[0].set_title('CDF')
        # ecdf = EmpiricalCDF(-values)
        # axs[0].plot(-ygrid,ecdf(-ygrid),'-')

        ygrid = np.linspace(-1, 20, 100)
        # axs[1].hist(values,bins='auto',density=True)
        axs[1].plot(ygrid, f_pdf(ygrid), '--')
        axs[1].set_xlim(ygrid.min(), ygrid.max())
        axs[1].set_title('PDF')

    pgrid = np.linspace(1e-2, 1 - 1e-2, 100)
    evar = np.array([value_at_risk(values, p)[0] for p in pgrid])
    # print(np.linalg.norm(evar.squeeze()-VaR(pgrid),ord=np.inf))
    if plot:
        axs[2].plot(pgrid, evar, '-')
        axs[2].plot(pgrid, VaR(pgrid), '--')
        axs[2].set_title('VaR')
    else:
        assert np.allclose(evar.squeeze(), VaR(pgrid), atol=2e-1)

    pgrid = np.linspace(1e-2, 1 - 1e-2, 100)
    ecvar = np.array([conditional_value_at_risk(values, y) for y in pgrid])
    # print(np.linalg.norm(ecvar.squeeze()-CVaR(pgrid).squeeze(),ord=np.inf))
    print(CVaR(0.8))
    if plot:
        axs[3].plot(pgrid, ecvar, '-')
        axs[3].plot(pgrid, CVaR(pgrid), '--')
        axs[3].set_xlim(pgrid.min(), pgrid.max())
        axs[3].set_title('CVaR')
    else:
        assert np.allclose(ecvar.squeeze(), CVaR(pgrid).squeeze(), rtol=4e-2)

    # ygrid = np.linspace(-1,10,100)
    ygrid = np.linspace(stats.lognorm.ppf(0.0, np.exp(mu), sigma),
                        stats.lognorm.ppf(0.9, np.exp(mu), sigma), 101)
    essd = compute_conditional_expectations(ygrid, values, False)
    # print(np.linalg.norm(essd.squeeze()-ssd(ygrid),ord=np.inf))
    if plot:
        axs[4].plot(ygrid, essd, '-')
        axs[4].plot(ygrid, ssd(ygrid), '--')
        axs[4].set_xlim(ygrid.min(), ygrid.max())
        axs[4].set_title(r'$E[(\eta-Y)^+]$')
        axs[4].set_xlabel(r'$\eta$')
    else:
        assert np.allclose(essd.squeeze(), ssd(ygrid), atol=1e-3)

    # zoom into ygrid over high probability region of -Y
    ygrid = -ygrid[::-1]
    disutil_essd = compute_conditional_expectations(ygrid, values, True)
    assert np.allclose(disutil_essd,
                       compute_conditional_expectations(ygrid, -values, False))
    # print(np.linalg.norm(disutil_essd.squeeze()-ssd_disutil(ygrid),ord=np.inf))
    if plot:
        axs[5].plot(ygrid, disutil_essd, '-', label='Empirical')
        axs[5].plot(ygrid, ssd_disutil(ygrid), '--', label='Exact')
        axs[5].set_xlim((ygrid).min(), (ygrid).max())
        axs[5].set_title(r'$E[(\eta-(-Y))^+]$')
        axs[5].set_xlabel(r'$\eta$')
        axs[5].plot([0], [np.exp(mu + sigma**2 / 2)], 'o')
        axs[5].legend()
        plt.show()
    else:
        assert np.allclose(disutil_essd.squeeze(),
                           ssd_disutil(ygrid),
                           atol=1e-3)
Exemplo n.º 10
0
def plot_truncated_lognormal_example_exact_quantities(num_samples=int(1e5),
                                                      plot=False,
                                                      mu=0,
                                                      sigma=1):
    if plot:
        assert num_samples <= 1e5

    lb, ub = -1, 3

    f, f_cdf, f_pdf, VaR, CVaR, ssd, ssd_disutil = \
        get_truncated_lognormal_example_exact_quantities(lb, ub, mu, sigma)
    # lb,ub passed to stats.truncnorm are defined for standard normal.
    # Adjust for mu and sigma using
    alpha, beta = (lb - mu) / sigma, (ub - mu) / sigma
    samples = stats.truncnorm.rvs(alpha, beta, mu, sigma,
                                  size=num_samples)[np.newaxis, :]
    values = f(samples)[:, 0]

    ygrid = np.linspace(np.exp(lb) - 1, np.exp(ub) * 1.1, 100)
    if plot:
        import matplotlib.pyplot as plt
        fig, axs = plt.subplots(1, 6, sharey=False, figsize=(16, 6))
        from pyapprox.density import EmpiricalCDF
        ecdf = EmpiricalCDF(values)
        axs[0].plot(ygrid, ecdf(ygrid), '-')
        axs[0].plot(ygrid, f_cdf(ygrid), '--')
        axs[0].set_xlim(ygrid.min(), ygrid.max())
        axs[0].set_title('CDF')

    if plot:
        ygrid = np.linspace(np.exp(lb) - 1, np.exp(ub) * 1.1, 100)
        axs[1].hist(values, bins='auto', density=True)
        axs[1].plot(ygrid, f_pdf(ygrid), '--')
        axs[1].set_xlim(ygrid.min(), ygrid.max())
        axs[1].set_title('PDF')

    pgrid = np.linspace(0.01, 1 - 1e-2, 10)
    evar = np.array([value_at_risk(values, p)[0] for p in pgrid]).squeeze()
    if plot:
        axs[2].plot(pgrid, evar, '-')
        axs[2].plot(pgrid, VaR(pgrid), '--')
        axs[2].set_title('VaR')
    else:
        assert np.allclose(evar, VaR(pgrid), rtol=2e-2)

    pgrid = np.linspace(0, 1 - 1e-2, 100)
    ecvar = np.array([conditional_value_at_risk(values, p) for p in pgrid])
    # CVaR for alpha=0 should be the mean
    assert np.allclose(ecvar[0], values.mean())
    if plot:
        axs[3].plot(pgrid, ecvar, '-')
        axs[3].plot(pgrid, CVaR(pgrid), '--')
        axs[3].set_xlim(pgrid.min(), pgrid.max())
        axs[3].set_title('CVaR')
    else:
        assert np.allclose(ecvar.squeeze(), CVaR(pgrid).squeeze(), rtol=1e-2)

    ygrid = np.linspace(np.exp(lb) - 10, np.exp(ub) + 1, 100)
    essd = compute_conditional_expectations(ygrid, values, False)
    if plot:
        axs[4].plot(ygrid, essd, '-')
        axs[4].plot(ygrid, ssd(ygrid), '--')
        axs[4].set_xlim(ygrid.min(), ygrid.max())
        axs[4].set_title(r'$E[(\eta-Y)^+]$')
        axs[5].set_xlabel(r'$\eta$')
    else:
        assert np.allclose(essd.squeeze(), ssd(ygrid), rtol=2e-2)

    # zoom into ygrid over high probability region of -Y
    ygrid = -ygrid[::-1]
    disutil_essd = compute_conditional_expectations(ygrid, values, True)
    assert np.allclose(disutil_essd,
                       compute_conditional_expectations(ygrid, -values, False))
    # print(np.linalg.norm(disutil_essd.squeeze()-ssd_disutil(ygrid),ord=np.inf))
    if plot:
        axs[5].plot(ygrid, disutil_essd, '-', label='Empirical')
        axs[5].plot(ygrid, ssd_disutil(ygrid), '--', label='Exact')
        axs[5].set_xlim(ygrid.min(), ygrid.max())
        axs[5].set_title(r'$E[(\eta-(-Y))^+]$')
        axs[5].set_xlabel(r'$\eta$')
        axs[5].legend()

        plt.show()