Как написать мультипликативные правила обновления для матричной факторизации, если у вас нет доступа ко всей матрице? - PullRequest
0 голосов
/ 17 января 2019

Итак, мы хотим приблизить матрицу A с m строками и n столбцами с произведением двух матриц P и Q, которые имеют размерность mxk и kxn соответственно. Вот реализация мультипликативного правила обновления из-за Ли в C ++ с использованием библиотеки Eigen.

void multiplicative_update()
{
Q = Q.cwiseProduct((P.transpose()*matrix).cwiseQuotient(P.transpose()*P*Q));
P = P.cwiseProduct((matrix*Q.transpose()).cwiseQuotient(P*Q*Q.transpose()));
}

, где P, Q и matrix (матрица = A) являются глобальными переменными в class mat_fac. Таким образом, я тренирую их, используя следующий метод,

void train_2(){
double error_trial = 0;
for (int count = 0;count < num_iterations; count ++)
    {
        multiplicative_update();
        error_trial = (matrix-P*Q).squaredNorm();
        if (error_trial < 0.001)
            {
                break;
            }
    }
}

, где num_iterations также является глобальной переменной в class mat_fac.

Проблема в том, что я работаю с очень большими матрицами и, в частности, у меня нет доступа ко всей матрице. Учитывая тройку (i, j, matrix [i] [j]), у меня есть доступ к вектору строки P [i] [:] и вектору столбца Q [:] [j]. Поэтому моя цель - написать переписать правило мультипликативного обновления таким образом, чтобы я обновлял эти два вектора каждый раз, когда вижу ненулевое значение матрицы.

В коде я хочу что-то вроде этого:

void multiplicative_update(int i, int j, double mat_value)
{
Eigen::MatrixXd q_vect = get_vector(1, j); // get_vector returns Q[:][j] as a column vector

Eigen::MatrixXd p_vect = get_vector(0, i); // get_vector returns P[i][:] as a column vector

// Somehow compute coeff_AQ_t, coeff_PQQ_t, coeff_P_tA and coeff_P_tA. 


for(int i = 0; i< k; i++):
        p_vect[i] = p_vect[i]* (coeff_AQ_t)/(coeff_PQQ_t)
        q_vect[i] = q_vect[i]* (coeff_P_tA)/(coeff_P_tA)  

}

Таким образом, проблема сводится к вычислению требуемых коэффициентов с учетом двух векторов. Это возможно сделать? Если нет, какие дополнительные данные мне нужны для мультипликативного обновления, чтобы работать таким образом?

...