我遇到了一个错误,提示“数组包含NaN或无穷大”。我已经检查了训练集和测试集的数据,没有发现任何缺失值。
可能是我对“数组包含NaN或无穷大”这个错误信息的理解有误。
import numpy as npfrom sklearn import linear_modelfrom numpy import genfromtxt, savetxtdef main(): #创建训练集和测试集,跳过带有[1:]的标题行 dataset = genfromtxt(open('C:\\Users\\Owner\\training.csv','r'), delimiter=',')[0:50] target = [x[0] for x in dataset] train = [x[1:50] for x in dataset] test = genfromtxt(open('C:\\Users\\Owner\\test.csv','r'), delimiter=',')[0:50] #创建并训练SGD sgd = linear_model.SGDClassifier() sgd.fit(train, target) predictions = [x[1] for x in sgd.predict(test)] savetxt('C:\\Users\\Owner\\Desktop\\preds.csv', predictions, delimiter=',', fmt='%f')if __name__=="__main__": main()
我认为可能是数据类型导致了算法的混乱(它们是浮点数)。
我知道SGD可以处理浮点数,所以我不确定这种设置是否需要我声明数据类型。
例如以下之一:
>>> dt = np.dtype('i4') # 32位有符号整数>>> dt = np.dtype('f8') # 64位浮点数>>> dt = np.dtype('c16') # 128位复数浮点数>>> dt = np.dtype('a25') # 25字符字符串
以下是完整的错误信息:
---------------------------------------------------------------------------ValueError Traceback (most recent call last)<ipython-input-62-af5537e7802b> in <module>() 19 20 if __name__=="__main__":---> 21 main()<ipython-input-62-af5537e7802b> in main() 13 #create and train the SGD 14 sgd = linear_model.SGDClassifier()---> 15 sgd.fit(train, target) 16 predictions = [x[1] for x in sgd.predict(test)] 17C:\Anaconda\lib\site-packages\sklearn\linear_model\stochastic_gradient.pyc in fit(self, X, y, coef_init, intercept_init, class_weight, sample_weight) 518 coef_init=coef_init, intercept_init=intercept_init, 519 class_weight=class_weight,--> 520 sample_weight=sample_weight) 521 522C:\Anaconda\lib\site-packages\sklearn\linear_model\stochastic_gradient.pyc in _fit(self, X, y, alpha, C, loss, learning_rate, coef_init, intercept_init, class_weight, sample_weight) 397 self.class_weight = class_weight 398--> 399 X = atleast2d_or_csr(X, dtype=np.float64, order="C") 400 n_samples, n_features = X.shape 401C:\Anaconda\lib\site-packages\sklearn\utils\validation.pyc in atleast2d_or_csr(X, dtype, order, copy) 114 """ 115 return _atleast2d_or_sparse(X, dtype, order, copy, sparse.csr_matrix,--> 116 "tocsr") 117 118C:\Anaconda\lib\site-packages\sklearn\utils\validation.pyc in _atleast2d_or_sparse(X, dtype, order, copy, sparse_class, convmethod) 94 _assert_all_finite(X.data) 95 else:---> 96 X = array2d(X, dtype=dtype, order=order, copy=copy) 97 _assert_all_finite(X) 98 return XC:\Anaconda\lib\site-packages\sklearn\utils\validation.pyc in array2d(X, dtype,order, copy) 79 'is required. Use X.toarray() to convert to dense.') 80 X_2d = np.asarray(np.atleast_2d(X), dtype=dtype, order=order)---> 81 _assert_all_finite(X_2d) 82 if X is X_2d and copy: 83 X_2d = safe_copy(X_2d)C:\Anaconda\lib\site-packages\sklearn\utils\validation.pyc in _assert_all_finite(X) 16 if (X.dtype.char in np.typecodes['AllFloat'] and not np.isfinite(X.sum()) 17 and not np.isfinite(X).all()):---> 18 raise ValueError("Array contains NaN or infinity.") 19 20ValueError: Array contains NaN or infinity.
任何建议都将不胜感激。
回答:
正如错误报告中所述,您的数据中某处包含了np.nan
、np.inf
或-np.inf
。由于您是从文本文件中读取数据,并且您说您的数据中没有缺失值,这可能是由列标题或文件中的其他无法自动解释的值引起的。
genfromtxt
的文档显示,读取数组的默认dtype
是float
,这意味着您读取的所有值都必须通过float(x)
的等效检查。
如果您不确定这是否导致了错误,您可以按以下方式从numpy数组中删除非有限数:
dataset[ ~np.isfinite(dataset) ] = 0 # 将非有限数(nan, inf, -inf)设为零
如果这消除了错误,您就可以确定您的变量中某处有无效值。要找到哪里,您可以使用以下方法:
np.where(~np.isfinite(dataset))
这将返回一个包含无效值索引的列表,例如:
>>> import numpy as np>>> dataset = np.array([[0,1,1],[np.nan,0,0],[1,2,np.inf]])>>> datasetarray([[ 0., 1., 1.], [ nan, 0., 0.], [ 1., 2., inf]])>>> np.where(~np.isfinite(dataset))(array([1, 2]), array([0, 2]))