2016-10-02 1 views
4

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

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, поэтому я, наверное, просто делаю что-то глупое.

+0

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

ответ

7

бы что-то вроде этой помощи? Если вы передадите ему фрейм данных 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 
>>> def VarianceThreshold_selector(data): 
    columns = data.columns 
    selector = VarianceThreshold(.5) 
    selector.fit_transform(data) 
    labels = [columns[x] for x in selector.get_support(indices=True) if x] 
    return pd.DataFrame(selector.fit_transform(data), columns=labels) 

>>> VarianceThreshold_selector(df) 
    Pclass Age 
0  3 22 
1  1 38 
2  3 26 
5

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

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

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

+0

Я python noob, но было бы также правильно делать 'features = data.columns.values ​​[selector.get_support (индексы = True)]'? Мне не удалось получить ваш подход к работе с моими данными. – beldaz

1

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

Однако, вы можете Подмножество ли эти данные немного более чисто, как это:

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

Как я имел некоторые проблемы с функцией по Джарад, я смешал его с раствором по 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