我正在使用带有CalibratedClassifierCV
的scikit-learn GaussianNB()
来对某些数据运行二进制分类。
我已验证.fit(X_train, y_train)
中的输入,并且它们具有匹配的维度,并且都通过了np.isfinite
测试。
我的问题是当我运行.predict_proba(X_test)
时。
对于某些样本,返回的概率为array([-inf, inf])
,我无法理解为什么。
当我尝试在结果预测上运行brier_score_loss
时,会出现这种情况,并且它会抛出ValueError: Input contains NaN, infinity or a value too large for dtype('float64')
。
我已向此Google drive link添加了一些数据。 它比我想要的要大,但我无法用较小的数据集进行一致的再现。 复制的代码如下。 代码有一些随机性,所以如果没有找到infinite,请尝试再次运行它,但是从我的实验中它应该在第一次尝试时找到它们。
from sklearn.naive_bayes import GaussianNB
from sklearn.calibration import CalibratedClassifierCV
from sklearn.model_selection import StratifiedShuffleSplit
import numpy as np
loaded = np.load('data.npz')
X = loaded['X']
y = loaded['y']
num = 2*10**4
sss = StratifiedShuffleSplit(n_splits = 10, test_size = 0.2)
cal_classifier = CalibratedClassifierCV(GaussianNB(), method = 'isotonic', cv = sss)
classifier_fit = cal_classifier.fit(X[:num], y[:num])
predicted_probabilities = classifier_fit.predict_proba(X[num:num+num//4])[:,1]
predicted_probabilities[np.argwhere(~np.isfinite(predicted_probabilities))]
答案 0 :(得分:1)
似乎Isotonic回归(CalibratedClassifierCV使用)提供inf
值。
更确切地说,它来自Isotonic的线性回归:
回归调用非常小的值(低于某个阈值但高于0)得到inf
。
在调试模式下self.f_([0, 3.2392382784e-313])
返回[0.10430463576158941, inf]
,这是一种奇怪的行为。 interpolate.interp1d
的实现可能无法处理这种“超小”值。希望它有所帮助。