При использовании LabelPropagation , я часто сталкиваюсь с этим предупреждением (imho, это должно быть ошибкой, потому что это полностью не дает распространения):
/ usr / local / lib / python3.5 / dist-packages / sklearn / semi_supervised / label_propagation.py: 279: RuntimeWarning: недопустимое значение, встречающееся в true_divide
self.label_distributions_ / = normalizer
Итак, после нескольких попыток с ядром RBF я обнаружил, что параметр gamma
оказывает влияние.
EDIT:
Проблема возникает из этих строк :
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 (), который вызывает функцию ядра). ХОРОШО. Но до сих пор. Что-то не так
СТАРЫЙ ПОСТ (перед редактированием)
Я напоминаю вам, как вычисляются веса графиков для распространения: 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]: