При использовании LabelPropagation я часто сталкиваюсь с этим предупреждением (imho это должна быть ошибка, потому что она полностью не позволяет распространение):
/usr/local/lib/python3.5/dist-packages/sklearn/semi_supervised/label_propagation.py:79: RuntimeWarning: недопустимое значение, обнаруженное в true_divide self.label_distributions_/= normalizer
Поэтому, после нескольких попыток с ядром RBF, я обнаружил влияние paramater gamma
.
РЕДАКТИРОВАТЬ:
Проблема исходит из этих строк:
if self._variant == 'propagation':
normalizer = np.sum(
self.label_distributions_, axis=1)[:, np.newaxis]
self.label_distributions_ /= normalizer
Я не понимаю, как label_distributions_ могут быть всеми нулями, особенно когда его определение:
self.label_distributions_ = safe_sparse_dot(
graph_matrix, self.label_distributions_)
Гамма влияет на graph_matrix (потому что graph_matrix является результатом _build_graph(), который вызывает функцию ядра). ХОРОШО. Но до сих пор. Что-то не так
OLD POST (перед редактированием)
Я напоминаю вам, как вычисляются веса графа для распространения: W = exp (-gamma * D), D - матрица попарного расстояния между всеми точками набора данных.
Проблема в следующем: np.exp(x)
возвращает 0.0, если x очень мало.
Представим себе, что у нас есть две точки i
и j
такие, что dist(i, j) = 10
.
>>> np.exp(np.asarray(-10*40, dtype=float)) # gamma = 40 => OKAY
1.9151695967140057e-174
>>> np.exp(np.asarray(-10*120, dtype=float)) # gamma = 120 => NOT OKAY
0.0
На практике я не настраиваю гамму вручную, но я использую метод, описанный в этой статье (раздел 2.4).
Итак, как бы избежать этого деления на ноль, чтобы получить правильное распространение?
Единственный способ, с помощью которого я могу думать, - нормализовать набор данных в каждом измерении, но мы теряем геометрическое/топологическое свойство набора данных (прямоугольник 2x10 становится квадратом 1x1, например)
Воспроизводимый пример:
В этом примере это худшее: даже с гамма = 20 он терпит неудачу.
In [11]: from sklearn.semi_supervised.label_propagation import LabelPropagation
In [12]: import numpy as np
In [13]: X = np.array([[0, 0], [0, 10]])
In [14]: Y = [0, -1]
In [15]: LabelPropagation(kernel='rbf', tol=0.01, gamma=20).fit(X, Y)
/usr/local/lib/python3.5/dist-packages/sklearn/semi_supervised/label_propagation.py:279: RuntimeWarning: invalid value encountered in true_divide
self.label_distributions_ /= normalizer
/usr/local/lib/python3.5/dist-packages/sklearn/semi_supervised/label_propagation.py:290: ConvergenceWarning: max_iter=1000 was reached without convergence.
category=ConvergenceWarning
Out[15]:
LabelPropagation(alpha=None, gamma=20, kernel='rbf', max_iter=1000, n_jobs=1,
n_neighbors=7, tol=0.01)
In [16]: LabelPropagation(kernel='rbf', tol=0.01, gamma=2).fit(X, Y)
Out[16]:
LabelPropagation(alpha=None, gamma=2, kernel='rbf', max_iter=1000, n_jobs=1,
n_neighbors=7, tol=0.01)
In [17]: