sum of square within and between group ANOVA python

Viewed 2009

I've got some data that looks like this:

allgroups = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]

I want to calculate the sum of square between and within group, but I have no idea how to do this. I already calculated the mean, variance , and grand mean. From what I know the

sswithin = sum((variance-1)*size of each list)
ssbetween = sum(((mean-grandmean)**2)*size of each list)

Here is my code:

def avg(allgroups): #Average List
    return [float(sum(i))/len(i) for i in allgroups]
def variance(allgroups): #Variance List
    return [sum((x - sum(group) / len(group)) ** 2 for x in group) / (len(group) - 1) for group in allgroups]
def calcavg(allgroups): #Grand Average
    return float(sum(avg(allgroups)) / len(avg(allgroups)))
def size(allgroups): #Size of the sameples in list
    return [len(group) for group in allgroups]
TheAvg=avg(allgroups)
    print(TheAvg)
    Variance=variance(allgroups)
    print(Variance)
    calcAvg=calcavg(allgroups)
    print(calcAvg)
    sizeSample=size(allgroups)
    print(sizeSample)

I will be grateful for any help. P/S: I can't use any library for this problem such as numpy or statistic.

1 Answers

Sum of squares is defined as the sum of squared residuals

enter image description here

And to get sample variance we take the above and divide by n-1. Below we also refer to this as mean squared error.

So we use the above to calculate the total sum of squares, using the grand mean as ybar, and this can be partitioned into the explained sum of squares (ESS) and the residual sum of squares (RSS)

enter image description here

ESS is also your within group SS (hence explained) and between group variance is RSS. So we can use something similar to the functions you have:

def avg(group): #Average List
    return float(sum(group))/len(group)
def sum_of_squares(group):
    mean = avg(group)
    return sum([(i-mean)**2 for i in group])

flat_list = [y for x in allgroups for y in x]

TSS = sum_of_squares(flat_list)
RSS = sum([sum_of_squares(i) for i in allgroups])
ESS = TSS - RSS

The mean sum of squares is the sum of squares divided by the degree of freedom, which is n-1:

MS_explained = ESS/(len(allgroups)-1)
MS_residuals = RSS/(len(flat_list)-len(allgroups))
[MS_explained,MS_residuals]
[45.0, 1.0]

I suppose the within group variance you wanted is MS_explained and the between is MS_residuals

We can also cross check this in with statsmodel:

import statsmodels.api as sm
from statsmodels.formula.api import ols
import numpy as np
data = pd.DataFrame({'group':np.repeat(np.arange(4),3),'value':flat_list})
moore_lm = ols('value ~ C(group)',data=data).fit()
sm.stats.anova_lm(moore_lm, typ=1)

    df  sum_sq  mean_sq F   PR(>F)
C(group)    3.0 135.0   45.0    45.0    0.000024
Residual    8.0 8.0 1.0 NaN NaN
Related