sklearn 的 predict_proba returns 无限概率
sklearn's predict_proba returns infinite probabilties
我在一些数据上使用 scikit-learn 的 CalibratedClassifierCV
和 GaussianNB()
到 运行 二进制分类。
我已经验证了 .fit(X_train, y_train)
中的输入,它们具有匹配的尺寸并且都通过了 np.isfinite
测试。
我的问题是 运行 .predict_proba(X_test)
。
对于某些样本,返回的概率是array([-inf, inf])
,我真的不明白为什么。
当我尝试 运行ning brier_score_loss
结果预测时发现了这一点,它抛出了一个 ValueError: Input contains NaN, infinity or a value too large for dtype('float64')
.
我已将一些数据添加到此 Google drive link。
它比我想要的要大,但我无法用较小的数据集获得一致的再现。
复制代码位于下方。
代码有一些随机性,所以如果没有找到无穷大,请尝试 运行 再试一次,但根据我的实验,它应该在第一次尝试时找到它们。
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))]
Isotonic 回归(由 CalibratedClassifierCV 使用)似乎提供了 inf
值。
更准确地说,它来自 Isotonic 中的线性回归:
- 在此声明 - https://github.com/scikit-learn/scikit-learn/blob/a24c8b46/sklearn/isotonic.py#L266
- 在这里调用 - https://github.com/scikit-learn/scikit-learn/blob/a24c8b46/sklearn/isotonic.py#L389
对非常小的值(低于某个阈值但高于 0)调用的回归给出 inf
。
在调试模式下 self.f_([0, 3.2392382784e-313])
returns [0.10430463576158941, inf]
这是一个奇怪的行为。 interpolate.interp1d
的实现可能无法处理这种 "super-small" 值。希望对你有帮助。
我在一些数据上使用 scikit-learn 的 CalibratedClassifierCV
和 GaussianNB()
到 运行 二进制分类。
我已经验证了 .fit(X_train, y_train)
中的输入,它们具有匹配的尺寸并且都通过了 np.isfinite
测试。
我的问题是 运行 .predict_proba(X_test)
。
对于某些样本,返回的概率是array([-inf, inf])
,我真的不明白为什么。
当我尝试 运行ning brier_score_loss
结果预测时发现了这一点,它抛出了一个 ValueError: Input contains NaN, infinity or a value too large for dtype('float64')
.
我已将一些数据添加到此 Google drive link。 它比我想要的要大,但我无法用较小的数据集获得一致的再现。 复制代码位于下方。 代码有一些随机性,所以如果没有找到无穷大,请尝试 运行 再试一次,但根据我的实验,它应该在第一次尝试时找到它们。
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))]
Isotonic 回归(由 CalibratedClassifierCV 使用)似乎提供了 inf
值。
更准确地说,它来自 Isotonic 中的线性回归:
- 在此声明 - https://github.com/scikit-learn/scikit-learn/blob/a24c8b46/sklearn/isotonic.py#L266
- 在这里调用 - https://github.com/scikit-learn/scikit-learn/blob/a24c8b46/sklearn/isotonic.py#L389
对非常小的值(低于某个阈值但高于 0)调用的回归给出 inf
。
在调试模式下 self.f_([0, 3.2392382784e-313])
returns [0.10430463576158941, inf]
这是一个奇怪的行为。 interpolate.interp1d
的实现可能无法处理这种 "super-small" 值。希望对你有帮助。