'Compute score using chi-square test of independence.
If mosaic colors by class distribution, chi-square is computed by
comparing the expected (prior) and observed class distribution in
each cell. Otherwise, compute the independence of the shown attributes.'

def compute_score(self, state):

    master = self.master
    data = master.discrete_data
    domain = data.domain
    attrlist = [self.attr_ordering[i] for i in state]
    cond_dist = get_conditional_distribution(data, attrlist)[0]
    n = cond_dist['']
    ss = 0
    if self._compute_class_dists():
        class_values = domain.class_var.values
    else:
        class_values = None
        attr_indices = [domain.index(attr) for attr in attrlist]
    for indices in product(*(range(len(a.values)) for a in attrlist)):
        attr_vals = '-'.join((attr.values[ind] for (attr, ind) in zip(attrlist, indices)))
        total = cond_dist[attr_vals]
        if class_values:
            for (i, class_val) in enumerate(class_values):
                expected = (total * self.marginal[i])
                if (expected > 1e-06):
                    observed = cond_dist[((attr_vals + '-') + class_val)]
                    ss += (((expected - observed) ** 2) / expected)
        else:
            observed = cond_dist[attr_vals]
            expected = (n * reduce(mul, (self.marginal[attr_idx][ind] for (attr_idx, ind) in zip(attr_indices, indices))))
            if (expected > 1e-06):
                ss += (((expected - observed) ** 2) / expected)
    if class_values:
        dof = ((len(class_values) - 1) * reduce(mul, (len(attr.values) for attr in attrlist)))
    else:
        dof = reduce(mul, ((len(attr.values) - 1) for attr in attrlist))
    return distributions.chi2.sf(ss, dof)
