Я пытаюсь реализовать алгоритм нелинейного уменьшения размерности, известный как Sammon Mapping
, в функции с именем sammon
. Это должно принять как вход:
(а) данные Х уменьшают в виде матрицы n × p (n наблюдений по p признакам); (б) максимальное число итераций для шага 3;
(c) порог ошибки ε для этапа 3; а также
(d) скорость обучения α для этапа 4.
Он должен генерировать в качестве выходного вектора n × 2 с окончательным двумерным макетом.
Алгоритм может быть реализован с градиентным спуском с использованием следующих шагов:
1. Начните со случайного двумерного расположения точек Y (Y - матрица n × 2).
2. Вычислить напряжение E Y.
3. Если E <ε или если достигнуто максимальное число итераций, остановитесь.
4. Для каждого yi из Y найдите следующий вектор yi (t + 1), основанный на текущем yi (t).
5. Перейдите к шагу 2. </p>
def sammon(X, max_iter,lr):
x = X
y = np.random.normal(1,5,[x.shape[0],2])
safe_div = lambda x: 0.0001 if x<=0.00000001 else x
diss_x = euclidean_distances(X, X)
for n_iter in range(max_iter):
diss_y = euclidean_distances(y, y)
e0 = 1/(diss_x.sum()/2)
e1 = (diss_y - diss_x)**2
e2 = diss_x
E = e0 * (e1/np.where(e2<=0.00000001 , 0.0001,e2 )).sum()/2
print('E = ',E)
for i in range(y.shape[0]):
delta0 = np.zeros(y.shape[1])
delta1 = np.zeros(y.shape[1])
for j in range(y.shape[0]):
if i == j :
continue
diff_xy = (diss_x[i,j] - diss_y[i,j])
mult_xy = (diss_x[i,j] * diss_y[i,j])
delta0 = delta0 +(diff_xy/np.where(mult_xy<=0.00000001,
0.0001 , mult_xy))*(y[i]-y[j])
delta1_0 = 1 + diff_xy/safe_div(diss_y[i,j])
delta1_1 = (y[i]-y[j])**2/safe_div(diss_y[i,j])
delta1 = delta1 + ((1/safe_div(mult_xy)) * (diff_xy - delta1_1
* delta1_0))
delta = delta0/np.absolute(delta1)
y[i] = y[i] - lr * delta
когда я пытался применить его к данным радужной оболочки от Sklearn, на каждой итерации E
напряжение возрастало.
Мне просто интересно, что пропущено? E
Предположим, уменьшилось.
но, к сожалению, я получаю такой результат, который неверен.
sammon(X, 5, 0.03)
E = 21.771582459972667
E = 23.312512407210253
E = 24.968563833599646
E = 26.748792128398676
E = 28.663238408887047