700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > sklearn.feature_selection.VarianceThreshold 方差过滤踩过的坑

sklearn.feature_selection.VarianceThreshold 方差过滤踩过的坑

时间:2023-11-27 06:59:00

相关推荐

sklearn.feature_selection.VarianceThreshold 方差过滤踩过的坑

报错信息:

Input contains NaN, infinity or a value too large for dtype('float64').

Input X must be non-negative.

输入值中包含空值,无穷值或超出dtype('float64')的范围!

输入值必须为正数。

源代码解析:

>>>X=array([[0.,0.,0.,...,nan,nan,nan],[1.,0.,1.,...,nan,nan,nan],[0.,0.,0.,...,1.,0.,0.],...,[0.,0.,0.,...,1.,0.,0.],[0.,0.,0.,...,1.,0.,1.],[0.,0.,0.,...,1.,0.,0.]])>>>fromsklearn.feature_selectionimportVarianceThreshold>>>selector=VarianceThreshold()#实例化,不填参数默认方差为0>>>x_var=selector.fit_transform(X)>>>x_fillna=pd.DataFrame(x_var).fillna(2)>>>score=[]>>>foriinrange(1400,499,-10):...X_chi=SelectKBest(chi2,k=i).fit_transform(x_fillna,y)...once=cross_val_score(RFC(n_estimators=10,random_state=0),X_chi,y,cv=5).mean()...score.append(once)...print((i,once))>>>plt.plot(range(1400,499,-10),score)>>>plt.show()ValueError:InputcontainsNaN,infinityoravaluetoolargefordtype('float64').

报错显示“输入值中包含空值,无穷值或超出dtype('float64')的范围!”,但明明已经填充缺失值了。

问题排查:

#检查是否包含缺失值>>> any(x_fillna.isnull().any())False#检查是否包含无穷数据>>> any(np.isinf(x_fillna).all())False

all(x)x元素都不为False、''、0或者x为空,则all(x)为True,也就是说只要x元素有一个为"假",则all(x)为False。"全 ‘真’ 为True,有 ‘假’ 为False"。

any(x)x的任何元素都为False、0,'',或者x全为空,则any(x)为False,也就是说所有的x都为'假',则any(x)为False。"全‘假’为False,有‘真’为True"。

np.isfinite(x).all()x 元素是否有限,全部为True 即为没有无限值。包含无限值为False,不包含无限值为True

np.isinf(x).all()x 元素是否无限,全部为True 即为都是无限值。包含有限值为False,不包含有限值为True

有网友踩过的坑:

解决方案:

若写出以下方式就会报错,因为此处只是输出x_fillna填充后的副本,原变量并未更改。

x_fillna=pd.DataFrame(x_var)x_fillna.fillna(2)

正确写法,以下三个均可行:

x_fillna=pd.DataFrame(x_var).fillna(2)

x_fillna=pd.DataFrame(x_var)x_fillna.fillna(-2,inplace=True)

x_fillna = pd.DataFrame(x_var)x_fillna = x_fillna.fillna(2)

一个问题已解决,但另一个问题出现:Input X must be non-negative.

但我并没有踩这个坑,毕竟我这么聪明....

继续问题排查:

在做方差过滤时出现一个警告:

因为有输出,就没有留意...

#方差过滤报错>>> fromsklearn.feature_selectionimportVarianceThreshold>>> selector=VarianceThreshold()#实例化,不填参数默认方差为0>>> x_var=selector.fit_transform(X)C:\Users\HP\anaconda3\lib\site-packages\sklearn\feature_selection\_variance_threshold.py:77:RuntimeWarning:Degreesoffreedom<=0forslice.self.variances_=np.nanvar(X,axis=0)C:\Users\HP\anaconda3\lib\site-packages\numpy\core\fromnumeric.py:52:RuntimeWarning:invalidvalueencounteredinreducereturngetattr(obj,method)(*args,**kwds)C:\Users\HP\anaconda3\lib\site-packages\sklearn\feature_selection\_variance_threshold.py:85:RuntimeWarning:All-NaNsliceencounteredself.variances_=np.nanmin(compare_arr,axis=0)C:\Users\HP\anaconda3\lib\site-packages\sklearn\feature_selection\_variance_threshold.py:88:RuntimeWarning:invalidvalueencounteredinless_equal(self.variances_<=self.threshold)):C:\Users\HP\anaconda3\lib\site-packages\sklearn\feature_selection\_variance_threshold.py:99:RuntimeWarning:invalidvalueencounteredingreaterreturnself.variances_>self.threshold

>>> np.all(X>0)False>>> np.all(X_var>0)False

而且

>>> np.var(X_var)nan

报错原因:原始数据csv文件中存在negative, NaN, inf.(负数、空值或者无穷数)

解决方案:

NaN--> 缺失值填补

X.fillna(0,inplace=True)

negative-->Max-Min归一化(一种线性变换方法,标准化后数据完全落入[0,1]区间,能够较好的保持原有数据结构)

fromsklearnimportpreprocessingminmax_scaler=preprocessing.MinMaxScaler()#建立模型对象data_scale=minmax_scaler.fit_transform(data)#标准化处理

inf.--> 当作异常值处理

另一种解决方案:

用python自带var()函数替代sklearn.feature_selection.VarianceThreshold:

x_col=X.columns[X.var()==0]#提取方差为0的字段x_var=X.loc[:,[iforiinX.columnsifinotinx_col]]#列表表达式过滤方差为0的字段X_var=pd.DataFrame(x_var).fillna(2)#用2填补缺失值score=[]foriinrange(1400,499,-10):X_chi=SelectKBest(chi2,k=i).fit_transform(x_fillna,y)once=cross_val_score(RFC(n_estimators=10,random_state=0),X_chi,y,cv=5).mean()score.append(once)print((i,once))plt.plot(range(1400,499,-10),score)plt.show()

结果是一样的,在需要知道删除了哪些变量时,运用var()sklearn更加实用

问题解决!

-- 数据STUDIO --

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。