Python 2.7 使用scikit learn删除差异较小的功能
scikit learn提供了各种删除描述符的方法,下面给出的教程提供了用于此目的的基本方法 但是,本教程没有提供任何方法或方法来告诉您如何保留已删除或保留的功能列表 下面的代码取自教程Python 2.7 使用scikit learn删除差异较小的功能,python-2.7,scikit-learn,scikits,Python 2.7,Scikit Learn,Scikits,scikit learn提供了各种删除描述符的方法,下面给出的教程提供了用于此目的的基本方法 但是,本教程没有提供任何方法或方法来告诉您如何保留已删除或保留的功能列表 下面的代码取自教程 from sklearn.feature_selection import VarianceThreshold X = [[0, 0, 1], [0, 1, 0], [1, 0, 0], [0, 1, 1], [0, 1, 0], [0, 1, 1]] sel = VarianceTh
from sklearn.feature_selection import VarianceThreshold
X = [[0, 0, 1], [0, 1, 0], [1, 0, 0], [0, 1, 1], [0, 1, 0], [0, 1, 1]]
sel = VarianceThreshold(threshold=(.8 * (1 - .8)))
sel.fit_transform(X)
array([[0, 1],
[1, 0],
[0, 0],
[1, 1],
[1, 0],
[1, 1]])
上面给出的示例代码只描述了两个描述符“shape(6,2)”,但在我的例子中,我有一个巨大的数据帧,其形状为(第51行,第9000列)。在找到合适的模型后,我希望跟踪有用和无用的特征,因为我可以通过只计算有用的特征来节省测试数据集特征计算期间的计算时间
例如,当您使用WEKA 6.0执行机器学习建模时,它在特征选择方面提供了极大的灵活性,并且在删除无用的特征后,您可以获得丢弃特征的列表以及有用的特征
谢谢那么,如果我没有错的话,你能做的是: 在的情况下,可以调用方法
fit
,而不是fit\u transform
。这将适合数据,并且产生的差异将存储在vt.variances\uu
中(假设vt
是您的对象)
使用threhold,您可以提取转换的特征,就像fit\u transform
所做的那样:
X[:, vt.variances_ > threshold]
或者将索引获取为:
idx = np.where(vt.variances_ > threshold)[0]
或者作为面具
mask = vt.variances_ > threshold
PS:默认阈值为0
编辑:
更直接的方法是使用类VarianceThreshold
的方法get\u support
。从文件中:
get_support([indices]) Get a mask, or integer index, of the features selected
您应该在
fit
或fit\u transform
之后调用此方法。这对我来说很有效。如果您想准确查看阈值化后保留的列,可以使用此方法:
import numpy as np
import pandas as pd
from sklearn.feature_selection import VarianceThreshold
# Just make a convenience function; this one wraps the VarianceThreshold
# transformer but you can pass it a pandas dataframe and get one in return
def get_low_variance_columns(dframe=None, columns=None,
skip_columns=None, thresh=0.0,
autoremove=False):
"""
Wrapper for sklearn VarianceThreshold for use on pandas dataframes.
"""
print("Finding low-variance features.")
try:
# get list of all the original df columns
all_columns = dframe.columns
# remove `skip_columns`
remaining_columns = all_columns.drop(skip_columns)
# get length of new index
max_index = len(remaining_columns) - 1
# get indices for `skip_columns`
skipped_idx = [all_columns.get_loc(column)
for column
in skip_columns]
# adjust insert location by the number of columns removed
# (for non-zero insertion locations) to keep relative
# locations intact
for idx, item in enumerate(skipped_idx):
if item > max_index:
diff = item - max_index
skipped_idx[idx] -= diff
if item == max_index:
diff = item - len(skip_columns)
skipped_idx[idx] -= diff
if idx == 0:
skipped_idx[idx] = item
# get values of `skip_columns`
skipped_values = dframe.iloc[:, skipped_idx].values
# get dataframe values
X = dframe.loc[:, remaining_columns].values
# instantiate VarianceThreshold object
vt = VarianceThreshold(threshold=thresh)
# fit vt to data
vt.fit(X)
# get the indices of the features that are being kept
feature_indices = vt.get_support(indices=True)
# remove low-variance columns from index
feature_names = [remaining_columns[idx]
for idx, _
in enumerate(remaining_columns)
if idx
in feature_indices]
# get the columns to be removed
removed_features = list(np.setdiff1d(remaining_columns,
feature_names))
print("Found {0} low-variance columns."
.format(len(removed_features)))
# remove the columns
if autoremove:
print("Removing low-variance features.")
# remove the low-variance columns
X_removed = vt.transform(X)
print("Reassembling the dataframe (with low-variance "
"features removed).")
# re-assemble the dataframe
dframe = pd.DataFrame(data=X_removed,
columns=feature_names)
# add back the `skip_columns`
for idx, index in enumerate(skipped_idx):
dframe.insert(loc=index,
column=skip_columns[idx],
value=skipped_values[:, idx])
print("Succesfully removed low-variance columns.")
# do not remove columns
else:
print("No changes have been made to the dataframe.")
except Exception as e:
print(e)
print("Could not remove low-variance features. Something "
"went wrong.")
pass
return dframe, removed_features
from sklearn.feature_selection import VarianceThreshold
threshold_n=0.95
sel = VarianceThreshold(threshold=(threshold_n* (1 - threshold_n) ))
sel_var=sel.fit_transform(data)
data[data.columns[sel.get_support(indices=True)]]
在测试特性时,我编写了这个简单的函数,它告诉我在应用
VarianceThreshold
后,哪些变量仍保留在数据帧中
从sklearn.feature\u选择导入变量阈值
从itertools导入压缩
def fs_方差(df,阈值:浮点=0.1):
"""
根据阈值返回选定变量的列表。
"""
#数据框中的列列表
功能=列表(df.columns)
#初始化并适应该方法
vt=方差阈值(阈值=阈值)
_=vt.fit(df)
#获取通过阈值的列名
feat_select=list(压缩(功能,例如获取支持())
返回专长选择
返回所选列名的列表。例如:
['col_2'、'col_14'、'col_17']
Sklearn的工作原理不同于WEKA。在本例中,sklearn不提供最佳功能的列表,而是直接返回具有最佳功能的新数组。你真的需要这份清单吗?我想他们的列表可以通过一种变通方法来计算,但确实需要吗?@iluengo根据我的理解(因为我在ML方面不是很有经验,但学习热情很高),培训和测试集应该有相同数量的功能,具有相同的索引,否则在weka it rase出错的情况下。如果测试集是通过数据分割内部派生的,我将始终具有相同的功能和相同的索引,但是如果我们使用外部数据测试集或未知数据集,在不知道功能名称的情况下进行预测,我们如何生成未知数据。是的,你说得对。我只想在拟合后的训练中,可以使用:df.loc[:,sel.get_support()]
获得过滤后的数据帧,其中df
是熊猫数据帧,sel
是方差阈值。@arun:我认为你的解决方案实际上是最好的。谢谢。非常有用的方法。我还发现,将skip_列的初始值设置为空列表[]而不是None非常有用,因为如果我不打算跳过任何列,则任何列都不会抛出异常columns@Sarah对的但是,您可以只使用标准的sklearn.feature\u selection.VarianceThreshold
和底层的numpy
数组,而不是pandas.DataFrame
:)@JasonWolosonovich当我尝试上述方法时,我得到了“UnboundLocalError:赋值前引用的局部变量'removed_features'”……有任何修正吗??