Я пытаюсь решить проблему матричной факторизации с помощью нелинейного сопряженного градиентного спуска Сципи.
Моя проблема пытается решить для A
и B
в: A @ np.transpose(B) = Y
при минимизации:
(1/N) * absolute_value_norm(Y-AB) + regularisation_params
Точная функция scipy.optimize.fmin_cg
требует f
и fprime
аргументы для целевой функции и ее градиента, поэтому вот мои входные данные:
def f(x, *args):
A_shape, B_shape, matrix, mask, l = args
A_cutoff = int(A_shape[0] * A_shape[1])
A = np.reshape(x[0:A_cutoff:1], (A_shape[0], A_shape[1]))
B = np.reshape(x[(A_cutoff):len(x)], (B_shape[0], B_shape[1]))
container = csr_matrix((matrix.shape))
product_AB = np.matmul(A, np.transpose(B))
product_AB_csr = csr_matrix(product_AB)
container[mask] = matrix[mask] - product_AB_csr[mask]
error = ((1 / mask.nnz) * container.__abs__().sum()) + (l * np.square(np.linalg.norm(A))) + \
(l * np.square(np.linalg.norm(B)))
return error
И:
def fprime(x, *args):
A_shape, B_shape, matrix, mask, l = args
A_cutoff = (A_shape[0] * A_shape[1])
A = np.reshape(x[0:(A_cutoff)], (A_shape[0], A_shape[1]))
B = np.reshape(x[(A_cutoff):len(x)], (B_shape[0], B_shape[1]))
container = csr_matrix((matrix.shape))
product_AB = np.matmul(A, np.transpose(B))
product_AB_csr = csr_matrix(product_AB)
container[mask] = matrix[mask] - product_AB_csr[mask]
original = - container / mask.nnz
grad_A, grad_B = get_abs_gradient(A, B, l, original)
# return np.asarray((grad_A, grad_B))
return np.concatenate((grad_A.flatten(), grad_B.flatten()))
Чтобы запустить весь конвейер, я использую:
train_matrix = sparse.load_npz("data.npz")
mask = csr_matrix(train_matrix > 0)
rank = 10
l = 0.001
A = np.random.random((train_matrix.shape[0], rank))
B = np.random.random((train_matrix.shape[1], rank))
matrices_flat = matrix_factorizer.flatten_matrices(A, B)
optimal = optimize.fmin_cg(f, matrices_flat,
fprime=fprime,
args=((A.shape), (B.shape), train_matrix, mask, l), full_output=True)
Однако я подозреваю, что моя функция градиента для суммы нормы абсолютного значения может быть неправильной, так как я получаю предупреждение, связанное с «потерей точности» в выходных данных:
Warning: Desired error not necessarily achieved due to precision loss.
Current function value: 0.193586
Iterations: 5
Function evaluations: 115
Gradient evaluations: 108
Я обнаружил очень похожую проблему в: fmin_cg: требуемая ошибка не обязательно достигается из-за потери точности
Но данные, которые я передаю, уже нормализованы, поэтому их решение не будетприменять.Сможет ли кто-нибудь догадаться по этому вопросу?