Скажем, у вас есть одна функция и цель с 3 возможными значениями.
X = np.array([3.4, 3.4, 3. , 2.8, 2.7, 2.9, 3.3, 3. , 3.8, 2.5])
y = np.array([0, 0, 0, 1, 1, 1, 2, 2, 2, 2])
X y
0 3.4 0
1 3.4 0
2 3.0 0
3 2.8 1
4 2.7 1
5 2.9 1
6 3.3 2
7 3.0 2
8 3.8 2
9 2.5 2
Сначала мы бинаризируем цель
y = LabelBinarizer().fit_transform(y)
X y1 y2 y3
0 3.4 1 0 0
1 3.4 1 0 0
2 3.0 1 0 0
3 2.8 0 1 0
4 2.7 0 1 0
5 2.9 0 1 0
6 3.3 0 0 1
7 3.0 0 0 1
8 3.8 0 0 1
9 2.5 0 0 1
Затем выполните скалярное произведение между функцией и целью, т. Е. Суммируйте все значения функций по значению класса.
observed = y.T.dot(X)
>>> observed
array([ 9.8, 8.4, 12.6])
Затем возьмите сумму значений признаков и рассчитайте частоту класса.
feature_count = X.sum(axis=0).reshape(1, -1)
class_prob = y.mean(axis=0).reshape(1, -1)
>>> class_prob, feature_count
(array([[0.3, 0.3, 0.4]]), array([[30.8]]))
Теперь, как и в первом шаге, мы берем скалярное произведение и получаем ожидаемую и наблюдаемую матрицы.
expected = np.dot(class_prob.T, feature_count)
>>> expected
array([[ 9.24],[ 9.24],[12.32]])
Наконец, мы вычисляем значение chi^2:
chi2 = ((observed.reshape(-1,1) - expected) ** 2 / expected).sum(axis=0)
>>> chi2
array([0.11666667])
У нас есть значение chi^2, теперь нам нужно оценить, насколько оно экстремально. Для этого мы используем распределение chi^2 с number of classes - 1
степенями свободы и вычисляем площадь из chi^2 до бесконечности, чтобы вероятность chi^2 была такой же или более экстремальной, чем у нас есть. Это p-значение. (используя функцию выживания хи-квадрат из scipy)
p = scipy.special.chdtrc(3 - 1, chi2)
>>> p
array([0.94333545])
Сравните с SelectKBest
:
s = SelectKBest(chi2, k=1)
s.fit(X.reshape(-1,1),y)
>>> s.scores_, s.pvalues_
(array([0.11666667]), [0.943335449873492])
person
hellpanderr
schedule
30.07.2019