Return z-test scores for sample moments to match analytic moments. Given `samples`, check that the first sample `number_moments` match the given `dist` moments by doing a z-test. Args: samples: Samples from target distribution. number_moments: Python `int` describing how many sample
(
samples,
number_moments,
dist,
stride=0)
| 26 | |
| 27 | |
| 28 | def test_moment_matching( |
| 29 | samples, |
| 30 | number_moments, |
| 31 | dist, |
| 32 | stride=0): |
| 33 | """Return z-test scores for sample moments to match analytic moments. |
| 34 | |
| 35 | Given `samples`, check that the first sample `number_moments` match |
| 36 | the given `dist` moments by doing a z-test. |
| 37 | |
| 38 | Args: |
| 39 | samples: Samples from target distribution. |
| 40 | number_moments: Python `int` describing how many sample moments to check. |
| 41 | dist: SciPy distribution object that provides analytic moments. |
| 42 | stride: Distance between samples to check for statistical properties. |
| 43 | A stride of 0 means to use all samples, while other strides test for |
| 44 | spatial correlation. |
| 45 | Returns: |
| 46 | Array of z_test scores. |
| 47 | """ |
| 48 | |
| 49 | sample_moments = [] |
| 50 | expected_moments = [] |
| 51 | variance_sample_moments = [] |
| 52 | x = samples.flat |
| 53 | for i in range(1, number_moments + 1): |
| 54 | strided_range = x[::(i - 1) * stride + 1] |
| 55 | sample_moments.append(np.mean(strided_range ** i)) |
| 56 | expected_moments.append(dist.moment(i)) |
| 57 | variance_sample_moments.append( |
| 58 | (dist.moment(2 * i) - dist.moment(i) ** 2) / len(strided_range)) |
| 59 | |
| 60 | z_test_scores = [] |
| 61 | for i in range(1, number_moments + 1): |
| 62 | # Assume every operation has a small numerical error. |
| 63 | # It takes i multiplications to calculate one i-th moment. |
| 64 | total_variance = ( |
| 65 | variance_sample_moments[i - 1] + |
| 66 | i * np.finfo(samples.dtype).eps) |
| 67 | tiny = np.finfo(samples.dtype).tiny |
| 68 | assert np.all(total_variance > 0) |
| 69 | if total_variance < tiny: |
| 70 | total_variance = tiny |
| 71 | # z_test is approximately a unit normal distribution. |
| 72 | z_test_scores.append(abs( |
| 73 | (sample_moments[i - 1] - expected_moments[i - 1]) / np.sqrt( |
| 74 | total_variance))) |
| 75 | return z_test_scores |
| 76 | |
| 77 | |
| 78 | def chi_squared(x, bins): |