Scipy - Как дополнительно оптимизировать редкий матричный код для стохастического градиента спуска

StackOverflow https://stackoverflow.com//questions/20032353

Вопрос

Я работаю над реализации алгоритма спуска стохастического градиента для систем рекомендации, используя редкие матрицы с помощью Scipy.

Вот как выглядит первая базовая реализация:

    N = self.model.shape[0] #no of users
    M = self.model.shape[1] #no of items
    self.p = np.random.rand(N, K)
    self.q = np.random.rand(M, K)
    rows,cols = self.model.nonzero()        
    for step in xrange(steps):
        for u, i in zip(rows,cols):
            e=self.model-np.dot(self.p,self.q.T) #calculate error for gradient
            p_temp = learning_rate * ( e[u,i] * self.q[i,:] - regularization * self.p[u,:])
            self.q[i,:]+= learning_rate * ( e[u,i] * self.p[u,:] - regularization * self.q[i,:])
            self.p[u,:] += p_temp
.

К сожалению, мой код все еще довольно медленно, даже для небольших рейтингов 4x5 Ratings Matrix.Я думал, что это, вероятно, связано с редкой матрицей для петли.Я попытался выразить изменения q и p, используя причудливую индексацию, но поскольку я все еще довольно новичок в Scipy и Numpy, я не мог понять лучший способ сделать это.

Есть ли у вас какие-либо указатели на то, как я могу избежать итерации по рядам и столбцам редкой матрицы?

Это было полезно?

Решение

Я почти забыл все о рекомендации системы, поэтому я могу быть ошибочно переведен в ваш код, но вы переоцениваете self.model-np.dot(self.p,self.q.T) внутри каждого цикла, в то время как я почти убежден, его следует оценивать один раз на шаг.

Тогда кажется, что вы делаете матричное умножение вручную, что, вероятно, может быть ускорена с помощью прямого матрицы Mulithlication (Numpy или Scipy сделает это быстрее, чем вы вручную), что-то подобное:

for step in xrange(steps):
    e = self.model - np.dot(self.p, self.q.T)
    p_temp = learning_rate * np.dot(e, self.q)
    self.q *= (1-regularization)
    self.q += learning_rate*(np.dot(e.T, self.p))
    self.p *= (1-regularization)
    self.p += p_temp
.

Другие советы

Вы уверены, что вы реализуете SGD?Потому что на каждом этапе вы должны рассчитать ошибку одного рейтинга одного пользователя, а не ошибку всей матрицы рейтинга или, возможно, не могу понять эту строку вашего кода:

e=self.model-np.dot(self.p,self.q.T) #calculate error for gradient
.

А для Scipy Library, я уверен, что у вас будет медленное узкое место, если вы хотите получить доступ к элементам редкой матрицы напрямую.Вместо того, чтобы получить доступ к элементам матрицы рейтинга из Scipy-Bearse-Matrix, вы можете принести определенную строку и столбец в ОЗУ на каждый шаг, а затем выполнять расчет.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top