문제

저는 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 등급 매트릭스의 경우에도 여전히 매우 느립니다.나는 이것이 아마도 루프에 대한 희소 행렬 때문이라고 생각했습니다.나는 멋진 인덱싱을 사용하여 q와 p 변경 사항을 표현하려고 시도했지만 아직 scipy와 numpy에 익숙하지 않기 때문에 더 나은 방법을 찾을 수 없습니다.

희소 행렬의 행과 열에 대한 반복을 명시적으로 방지할 수 있는 방법에 대한 조언이 있습니까?

도움이 되었습니까?

해결책

추천 시스템에 대한 모든 것을 거의 잊어버렸기 때문에 귀하의 코드가 잘못 번역되었을 수 있지만 귀하는 재평가합니다. self.model-np.dot(self.p,self.q.T) 각 루프 내에서 단계당 한 번씩 평가되어야 한다고 거의 확신합니다.

그런 다음 행렬 곱셈을 손으로 수행하는 것 같습니다. 직접 행렬 곱셈을 사용하면 속도가 빨라질 수 있습니다(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 라이브러리의 경우, 스파 스 매트릭스의 요소에 직접 액세스하려는 경우 느린 병목 현상이있을 것입니다.scipy-sparse-matrix에서 등급 매트릭스의 요소에 액세스하는 대신 각 단계에서 특정 행과 열을 RAM으로 가져온 다음 계산을 수행 할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top