<jupyter_start><jupyter_text>Diagnostics for importance samplingThis notebook illustrates the use of some simple diagnostics for Importance Sampling. For IS, in extreme settings only a few samples may have a significant weight, yielding poor approximations of the target pdf $p(x)$. A popular diagnostics is the Effective Sample Size (ESS), which is theoretically defined as the number of independent samples generated directly form the target distribution that are required to obtain an estimator with same variance as the one obtained from IS. Heuristically, ESS approximates how many i.i.d. samples, drawn from the target, are equivalent to $N$ weighted samples drawn from the IS or MCMC approximation. An approximation of the ESS is given by [1]:$$ ESS = \frac{1}{\sum \tilde{w}^2} $$where $\tilde{w}$ are the normalized weights.[1] *Sequential Monte Carlo Methods in Practice*, <NAME>, <NAME>, and <NAME>, 2001, Springer, New York<jupyter_code>from UQpy.Distributions import Uniform, JointInd
from UQpy.SampleMethods import IS
import time
import matplotlib.pyplot as plt
import numpy as np
def log_Rosenbrock(x, param):
     return (-(100*(x[:, 1]-x[:, 0]**2)**2+(1-x[:, 0])**2)/param)
proposal = JointInd([Uniform(loc=-8, scale=16), Uniform(loc=-10, scale=60)])
print(proposal.get_params())
w = IS(log_pdf_target=log_Rosenbrock, args_target=(20, ), nsamples=5000, proposal=proposal)<jupyter_output><empty_output><jupyter_text>Look at distribution of weights<jupyter_code>print('max_weight = {}, min_weight = {} \n'.format(max(w.weights), min(w.weights)))

fig, ax = plt.subplots(figsize=(8, 3))
ax.scatter(w.weights, np.zeros((np.size(w.weights), )), s=w.weights * 600, marker='o')
ax.set_xlabel('weights')
ax.set_title('Normalized weights out of importance sampling')
ax.tick_params(which='both', left=False, labelleft=False) # labels along the bottom edge are off
plt.show(fig)<jupyter_output>max_weight = 0.031633907624027915, min_weight = 0.0<jupyter_text>Compute the effective sample size<jupyter_code>effective_sample_size = 1. / np.sum(w.weights ** 2, axis=0)

print('Effective sample size is ne={}, out of a total number of samples={} \n'.
      format(effective_sample_size, np.size(w.weights)))<jupyter_output>Effective sample size is ne=62.64543221873556, out of a total number of samples=5000
{'fraction_non_alphanumeric': 0.11991341991341992, 'fraction_numerical': 0.03463203463203463, 'mean_word_length': 6.221875, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '369640', 'license': 'MIT', 'n_tokens_mistral': 770, 'n_tokens_neox': 709, 'n_words': 242, 'path': 'example/SampleMethods/IS/IS_diagnostics.ipynb', 'repo_name': 'shellshocked2003/UQpy', 'size': '2323'}