Scipy - 확률적 경사하강법을 위해 희소 행렬 코드를 추가로 최적화하는 방법
-
21-12-2019 - |
문제
저는 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으로 가져온 다음 계산을 수행 할 수 있습니다.