scikit-learn
Выбор функции
Поиск…
Удаление функции с небольшим разбросом
Это очень простой метод выбора объектов.
Его основная идея заключается в том, что если функция постоянна (т. Е. Имеет 0 дисперсию), то она не может быть использована для поиска каких-либо интересных шаблонов и может быть удалена из набора данных.
Следовательно, эвристический подход к устранению признаков состоит в том, чтобы сначала удалить все функции, отклонения которых ниже некоторого (низкого) порога.
Исходя из примера в документации , предположим, что мы начинаем с
X = [[0, 0, 1], [0, 1, 0], [1, 0, 0], [0, 1, 1], [0, 1, 0], [0, 1, 1]]
Здесь имеется 3 булевых функции, каждая из которых имеет 6 экземпляров. Предположим, мы хотим удалить те, которые являются постоянными, по крайней мере, в 80% случаев. Некоторые вероятностные вычисления показывают, что эти функции должны иметь дисперсию ниже 0,8 * (1 - 0,8) . Следовательно, мы можем использовать
from sklearn.feature_selection import VarianceThreshold
sel = VarianceThreshold(threshold=(.8 * (1 - .8)))
sel.fit_transform(X)
# Output: array([[0, 1],
[1, 0],
[0, 0],
[1, 1],
[1, 0],
[1, 1]])
Обратите внимание, как первая функция была удалена.
Этот метод следует использовать с осторожностью, поскольку низкая дисперсия не обязательно означает, что функция «неинтересна». Рассмотрим следующий пример, где мы строим набор данных, который содержит 3 функции, первые два из которых состоят из случайно распределенных переменных и третьей равномерно распределенных переменных.
from sklearn.feature_selection import VarianceThreshold
import numpy as np
# generate dataset
np.random.seed(0)
feat1 = np.random.normal(loc=0, scale=.1, size=100) # normal dist. with mean=0 and std=.1
feat2 = np.random.normal(loc=0, scale=10, size=100) # normal dist. with mean=0 and std=10
feat3 = np.random.uniform(low=0, high=10, size=100) # uniform dist. in the interval [0,10)
data = np.column_stack((feat1,feat2,feat3))
data[:5]
# Output:
# array([[ 0.17640523, 18.83150697, 9.61936379],
# [ 0.04001572, -13.47759061, 2.92147527],
# [ 0.0978738 , -12.70484998, 2.4082878 ],
# [ 0.22408932, 9.69396708, 1.00293942],
# [ 0.1867558 , -11.73123405, 0.1642963 ]])
np.var(data, axis=0)
# Output: array([ 1.01582662e-02, 1.07053580e+02, 9.07187722e+00])
sel = VarianceThreshold(threshold=0.1)
sel.fit_transform(data)[:5]
# Output:
# array([[ 18.83150697, 9.61936379],
# [-13.47759061, 2.92147527],
# [-12.70484998, 2.4082878 ],
# [ 9.69396708, 1.00293942],
# [-11.73123405, 0.1642963 ]])
Теперь первая функция была удалена из-за ее низкой дисперсии, в то время как третья функция (то есть самая неинтересная) была сохранена. В этом случае было бы уместнее рассмотреть коэффициент вариации, поскольку он не зависит от масштабирования.