Как получить выбранные функции после сокращения LinearSVC в scikit

Название говорит само за себя, я проверил scikit, которые очень плохи для этой конкретной задачи, и я проверил несколько онлайн-ресурсов, включая этот пост.

Однако, похоже, они ошибаются. Для выбора функций мы можем сделать что-то вроде:

clf=LinearSVC(penalty="l1",dual=False,random_state=0)
X_reduced = clf.fit_transform(X_full,y_full)

Теперь, если мы посмотрим на форму X_reduced, станет очень ясно, сколько функций было выбрано. Итак, вопрос в том, какие именно?

Атрибут coef_ для LinearSVC очень важен, и предлагается перебрать его, а функции, которые coef_ отличаются от нуля, будут выбраны. Что ж, это неправильно, но вы можете очень близко приблизиться к реальному результату.

После проверки X_reduced я заметил, что получил 310 выбранных функций, и это точно, я имею в виду, что я проверяю результирующую матрицу, теперь, если я сделаю coef_, было выбрано 414 функций из общего числа 2000, так что это близок к реальному.

Согласно scikit LinearSVC docs для Threshold=None задействован mean(X), но я застрял, не знаю, что теперь делать.

ОБНОВЛЕНИЕ: вот ссылка с данными и кодом, которые воспроизводят ошибку, это всего несколько КБ


person RandomGuy42    schedule 07.07.2015    source источник


Ответы (1)


Я думаю, что LinearSVC() возвращает функции с ненулевыми коэффициентами. Не могли бы вы загрузить образец файла данных и сценарий кода (например, через ссылку общего доступа Dropbox), который может воспроизвести несоответствие, которое вы видели?

from sklearn.datasets import make_classification
from sklearn.datasets import load_svmlight_file
from sklearn.svm import LinearSVC
import numpy as np

X, y = load_svmlight_file("/home/Jian/Downloads/errorScikit/weirdData")

transformer = LinearSVC(penalty='l1', dual=False, random_state=0)
transformer.fit(X, y)
# set threshold eps
X_reduced = transformer.transform(X, threshold=np.finfo(np.float).eps)

print(str(X_reduced.shape[1]) + " is NOW equal to " + str((transformer.coef_ != 0).sum()))

414 is NOW equal to 414


# as suggested by user3914041, if you want both sides are 310
transformer.transform(X).shape

Out[46]: (62, 310)

(abs(transformer.coef_) > 1e-5).sum()

Out[47]: 310
person Jianxun Li    schedule 07.07.2015
comment
Спасибо, вот она: ссылка - person RandomGuy42; 07.07.2015
comment
@nxgtrturbo Я видел то же несоответствие, что и ты. Если я установлю порог очень маленьким значением (например, eps здесь), это даст ожидаемый результат. - person Jianxun Li; 07.07.2015
comment
Да, однако цель состоит в том, чтобы достичь 310 с обеих сторон, так как это часть пользовательского конвейера, который использует несколько различных методов сокращения (не все из них используют Threshold). Вы скажете, что это баг? или по крайней мере неправильная документация? - person RandomGuy42; 07.07.2015
comment
@nxgtrturbo Я согласен с тем, что документы не являются самый точный. Они упоминают, что вы можете установить порог, но я нигде не видел значения по умолчанию. Однако, глядя на исходный код, вы можете видеть, что для штрафа L1 порог по умолчанию равен 1e-5. - person ldirer; 07.07.2015
comment
@nxgtrturbo Как предполагает @user3914041, исходный код transformer.transform?? показывает, что 1e-5 используется в качестве порога по умолчанию. Я изменил код, чтобы получить 310. - person Jianxun Li; 08.07.2015