Сохранение имен функций после выбора функций Scikit

#python #pandas #scikit-learn #output #feature-selection

#python #панды #scikit-learn #вывод #выбор функций

Вопрос:

После выполнения порога отклонения из Scikit-Learn для набора данных он удаляет пару объектов. Я чувствую, что делаю что-то простое, но глупое, но я бы хотел сохранить имена остальных функций. Следующий код:

 def VarianceThreshold_selector(data):
    selector = VarianceThreshold(.5) 
    selector.fit(data)
    selector = (pd.DataFrame(selector.transform(data)))
    return selector
x = VarianceThreshold_selector(data)
print(x)
  

изменяет следующие данные (это всего лишь небольшое подмножество строк):

 Survived    Pclass  Sex Age SibSp   Parch   Nonsense
0             3      1  22   1        0        0
1             1      2  38   1        0        0
1             3      2  26   0        0        0
  

в это (опять же, только небольшое подмножество строк)

      0         1      2     3
0    3      22.0      1     0
1    1      38.0      1     0
2    3      26.0      0     0
  

Используя метод get_support, я знаю, что это Pclass, Age, Sibsp и Parch, поэтому я бы предпочел, чтобы это возвращало что-то более похожее :

      Pclass         Age      Sibsp     Parch
0        3          22.0         1         0
1        1          38.0         1         0
2        3          26.0         0         0
  

Есть ли простой способ сделать это? Я очень новичок в Scikit Learn, поэтому, вероятно, я просто делаю что-то глупое.

Комментарии:

1. Сам Scikit не поддерживает pandas типы данных с именованными столбцами и т.п., Поэтому каждый раз, когда вы используете что-то вроде .transform метода объекта scikit, вы потеряете всю эту информацию. Если вы можете отслеживать его отдельно (т. Е. Извлекать имена столбцов, как вы описываете), вы можете передать его обратно, чтобы указать новые имена столбцов после воссоздания нового фрейма данных.

Ответ №1:

Поможет ли что-то подобное? Если вы передадите ему фрейм данных pandas, он получит столбцы и будет использовать get_support , как вы упомянули, для перебора списка столбцов по их индексам, чтобы извлечь только заголовки столбцов, которые соответствовали порогу отклонения.

 >>> df
   Survived  Pclass  Sex  Age  SibSp  Parch  Nonsense
0         0       3    1   22      1      0         0
1         1       1    2   38      1      0         0
2         1       3    2   26      0      0         0

>>> from sklearn.feature_selection import VarianceThreshold
>>> def variance_threshold_selector(data, threshold=0.5):
    selector = VarianceThreshold(threshold)
    selector.fit(data)
    return data[data.columns[selector.get_support(indices=True)]]

>>> variance_threshold_selector(df, 0.5)
   Pclass  Age
0       3   22
1       1   38
2       3   26
>>> variance_threshold_selector(df, 0.9)
   Age
0   22
1   38
2   26
>>> variance_threshold_selector(df, 0.1)
   Survived  Pclass  Sex  Age  SibSp
0         0       3    1   22      1
1         1       1    2   38      1
2         1       3    2   26      0
  

Комментарии:

1. не могли бы вы отредактировать свой ответ? selector.get_support(indexes=True) возвращает массив индексов. Таким образом, в этой строке: labels = [столбцы [x] для x в selector.get_support(индексы = True), если x] есть скрытая ошибка, из-за которой столбец 0 будет пропущен

2. Это выглядит правильно! Переменная columns больше не используется, но не имеет значения

Ответ №2:

Я пришел сюда в поисках способа получить transform() или fit_transform() вернуть фрейм данных, но я подозреваю, что он не поддерживается.

Однако вы можете немного более аккуратно подмножествовать данные следующим образом:

 data_transformed = data.loc[:, selector.get_support()]
  

Комментарии:

1. Это должно быть более высокое, элегантное и простое решение вопроса.

Ответ №3:

Вероятно, есть лучшие способы сделать это, но для тех, кому интересно, вот как я это сделал:

 def VarianceThreshold_selector(data):

    #Select Model
    selector = VarianceThreshold(0) #Defaults to 0.0, e.g. only remove features with the same value in all samples

    #Fit the Model
    selector.fit(data)
    features = selector.get_support(indices = True) #returns an array of integers corresponding to nonremoved features
    features = [column for column in data[features]] #Array of all nonremoved features' names

    #Format and Return
    selector = pd.DataFrame(selector.transform(data))
    selector.columns = features
    return selector
  

Комментарии:

1. У нас была в основном та же идея, за исключением преобразования против использования fit_transform. Рад, что вы это поняли.

2. Я новичок в Python, но было бы правильно это сделать features = data.columns.values[selector.get_support(indices = True)] ? У меня возникли проблемы с использованием вашего подхода к работе с моими данными.

3. Добавьте столбцы для анализа столбцов: features = [столбец для столбца в df_train.columns[features]]

Ответ №4:

Поскольку у меня были некоторые проблемы с функцией Jarad, я перепутал ее с решением pteehan, которое, как я обнаружил, является более надежным. Я также добавил замену NA в качестве стандарта, поскольку VarianceThreshold не любит значения NA.

 def variance_threshold_select(df, thresh=0.0, na_replacement=-999):
    df1 = df.copy(deep=True) # Make a deep copy of the dataframe
    selector = VarianceThreshold(thresh)
    selector.fit(df1.fillna(na_replacement)) # Fill NA values as VarianceThreshold cannot deal with those
    df2 = df.loc[:,selector.get_support(indices=False)] # Get new dataframe with columns deleted that have NA values

    return df2
  

Ответ №5:

как насчет этого в виде кода?

 columns = [col for col in df.columns]

low_var_cols = []

for col in train_file.columns:
if statistics.variance(df[col]) <= 0.1:
    low_var_cols.append(col)
  

затем удалить столбцы из фрейма данных?

Ответ №6:

Вы также можете использовать Pandas для определения порога

 data_new = data.loc[:, data.std(axis=0) > 0.75]