Как SelectKBest (chi2) подсчитывает баллы?

Я пытаюсь найти наиболее ценные функции, применяя методы выбора функций к моему набору данных. Сейчас я использую функцию SelectKBest. Я могу сгенерировать значения баллов и отсортировать их по своему усмотрению, но я не понимаю, как именно рассчитывается это значение баллов. Я знаю, что теоретически высокий балл более ценен, но мне нужна математическая формула или пример для расчета балла для глубокого изучения этого вопроса.

bestfeatures = SelectKBest(score_func=chi2, k=10)
fit = bestfeatures.fit(dataValues, dataTargetEncoded)
feat_importances = pd.Series(fit.scores_, index=dataValues.columns)
topFatures = feat_importances.nlargest(50).copy().index.values

print("TOP 50 Features (Best to worst) :\n")
print(topFatures)

заранее спасибо


person justRandomLearner    schedule 30.07.2019    source источник


Ответы (1)


Скажем, у вас есть одна функция и цель с 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
comment
Это один из лучших ответов, которые я когда-либо видел. Большое спасибо. Я полностью понимаю, как это работает, но для ясности, что вы там делали? p = специальный.chdtrc(3 - 1, chi2) - person justRandomLearner; 31.07.2019