<jupyter_start><jupyter_text>Chi-squared multinomial goodness of fit test (single sampleWhen you have a sample that has several categories in it you might want to test whether or not a certain multinomial distribution of categories exists in the population.  The link to Chi-Square distributionUsing https://en.wikipedia.org/wiki/Chi-squared_distributionWe have seen from the hypothesis test for the population proportion, the hypothesis test is as followsConsider a sample that has a proportion of positive results.Let:$ m $ be the number of successful trials, in the sample$ n $ be the sample size (or trials, to use the probability terminology)$ \hat{p} = \large \frac{m}{n} $ be the expected probability of successful trials$ p $ be the expected probability of successful trials$ q = 1-p $$ Z = \large \frac{\hat{p} - p}{\sqrt{ \frac{pq}{n}}} $$ Z = \large \frac{\frac{m}{n} - p}{\sqrt{ \frac{pq}{n}}} $ $ Z = \large \frac{ n \left(\frac{m}{n} - p \right)}{n \sqrt{ \frac{pq}{n}}} $ $ Z = \large \frac{m - np}{\sqrt{ np(1-p)}} $Note, the above looks wrong but it is correct: the result of $ n \sqrt \frac{1}{n} = \sqrt n $ If we try to use multiple proportions now, we will have problems. The values in the normal distribution might be positive or negative, so adding them up might mean those cancel out. Below, we derive a square, so that later we can make a sum of squares for each proportion being tested. This means that the test statistic uses absolute values and taking the sum of absolute values will be reliable.$ Z^2 = \large \frac{(m - np)^2}{np(1-p)} $ Now we have a general form that we can use for multinomial tests, including the difference between two proportions (although that can be treated as a single difference and calculated using the above process to derive a $ Z $ score directly.$ Z^2 $ has a $ \chi^2 $ distribution with 1 degree of freedom Now, instead of a single proportion from a single group in the sample, let's consider multiple groups, each with their own proportion.Let $ k $ be the number of these groups.$ Z^2 = \sum_{i=1}^k \large \frac{(m_i - n_i p_i)^2}{n_i p_i(1- p_i)} $This means that if the observed value is very different from the expected value then the test statistic will be large.We can rewrite it as$ Z^2 = \sum_{i=1}^k \large \frac{(o - e)^2}{e} $Then $ Z^2 $ has a $\chi^2 $ distribution with $ k-1 $ degrees of freedom.  The hypothesisGiven k different proportions (p), then $ \sum_i^k p_i = 1.0 $We must also specify their hypothesised values, as $ P $$ h_0 : p_i = P_i, p_{i+1} = P_{i+1} ... p_k = P_k $$ h_a $ : not all true$ \alpha : 0.05 $Note, this is always an upper tail test, so just use $ \alpha $ not $ \alpha/2 $<jupyter_code>alpha = 0.05

n = 100

observed = c(22,33,24,21)
expected = c(15,17,22,46)
# These should all add up to n
stopifnot(sum(observed) == n)
stopifnot(sum(expected) == n)

# And should be the same size
stopifnot(length(observed) == length(expected))
k = length(observed)
df = k-1

### Z^2
testStatistic = 0
for (i in 1:k) {
    o_i = observed[i]
    e_i = expected[i]
    testStatistic = testStatistic + (o_i - e_i)^2 / e_i
} 

testStatistic
### Region of rejection 

### This is always an upper tail test, so just alpha not alpha/2

criticalValue = qchisq(1-alpha, df)
criticalValue<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11228813559322035, 'fraction_numerical': 0.01725181598062954, 'mean_word_length': 4.0458015267175576, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 1, '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': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '540060', 'license': 'MIT', 'n_tokens_mistral': 1056, 'n_tokens_neox': 997, 'n_words': 466, 'path': 'statistics/chi_squared_multinomial_proportions_single_sample.ipynb', 'repo_name': 'JasonThomasData/algorithms', 'size': '3304'}