Как решить ошибку "значение слишком большое для dtype ('float32')?" - PullRequest
1 голос
/ 05 июля 2019

Я прочитал много вопросов, похожих на это, но до сих пор не могу понять это.

clf = DecisionTreeClassifier()
clf.fit(X_train, y_train)

X_to_predict = array([[  1.37097033e+002,   0.00000000e+000,  -1.82710826e+296,
          1.22703799e+002,   1.37097033e+002,  -2.56391552e+001,
          1.11457878e+002,   1.37097033e+002,  -2.56391552e+001,
          9.81898928e+001,   1.22703799e+002,  -2.45139066e+001,
          9.24341823e+001,   1.11457878e+002,  -1.90236954e+001]])

clf.predict_proba(X_to_predict)

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

Моя проблема не в значениях nan и inf, поскольку:

np.isnan(X_to_predict).sum()
Out[147]: 0

np.isinf(X_to_predict).sum()
Out[148]: 0

Вопрос: Как я могу преобразовать X_to_predict в значения, которые не слишком велики для float32, сохраняя столько цифр после десятичной запятой, сколько возможно?

1 Ответ

1 голос
/ 05 июля 2019

Если вы проверяете dtype вашего массива X_to_predict, он должен показывать float64.

# slightly modified array from the question
X_to_predict = np.array([1.37097033e+002, 0.00000000e+000, -1.82710826e+296,
                         1.22703799e+002, 1.37097033e+002, -2.56391552e+001,
                         1.11457878e+002, 1.37097033e+002, -2.56391552e+001,
                         9.81898928e+001, 1.22703799e+002, -2.45139066e+001]).reshape((3, 4))

print(X_to_predict.dtype)
>>> float64

RandomForestClassifier sklearn молча преобразует массив в float32, см. Обсуждение здесь для источника сообщения об ошибке.

Вы можете преобразовать его самостоятельно

print(X_to_predict.astype(np.float32)))

>>> array([[137.09703 ,   0.      ,       -inf, 122.7038  ],
           [137.09703 , -25.639154, 111.45788 , 137.09703 ],
           [-25.639154,  98.189896, 122.7038  , -24.513906]], 
          dtype=float32)

Третье значение (-1.82710826e + 296) становится -inf в float32.Единственный способ обойти это - заменить значения inf на максимум с плавающей точкой32.Вы потеряете некоторую точность, насколько я знаю, в настоящее время нет параметров или обходного пути, за исключением изменения реализации в sklearn и его перекомпиляции.

Если вы используете np.nan_to_num, ваш массив должен выглядеть следующим образом:

new_X = np.nan_to_num(X_to_predict.astype(np.float32))
print(new_X)

>>> array([[ 1.3709703e+02,  0.0000000e+00, -3.4028235e+38,  1.2270380e+02],
           [ 1.3709703e+02, -2.5639154e+01,  1.1145788e+02,  1.3709703e+02],
           [-2.5639154e+01,  9.8189896e+01,  1.2270380e+02, -2.4513906e+01]],
          dtype=float32)

, который должен быть принят вашим классификатором.


Полный код

import numpy as np
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris

iris = load_iris()
clf = RandomForestClassifier(n_estimators=10,
                             random_state=42)
clf.fit(iris.data, iris.target)

X_to_predict = np.array([1.37097033e+002, 0.00000000e+000, -1.82710826e+296,
                         1.22703799e+002, 1.37097033e+002, -2.56391552e+001,
                         1.11457878e+002, 1.37097033e+002, -2.56391552e+001,
                         9.81898928e+001, 1.22703799e+002, -2.45139066e+001]).reshape((3, 4))

print(X_to_predict.dtype)

print(X_to_predict.astype(np.float32))

new_X = np.nan_to_num(X_to_predict.astype(np.float32))

print(new_X)

#should return array([2, 2, 0])
print(clf.predict(new_X))



# should crash
clf.predict(X_to_predict)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...