Pytorchを利用して、MFをしてみます。基本的には機械学習的手順がベースですので、PyTorchの機能を使って簡単にMFできました。
Let's try implementing MF using PyTorch. Since the basic procedure is based on machine learning, we can easily perform MF using PyTorch's functionalities.
Matrix Factorization / 行列因子分解
https://blueqat.com/yuichiro_minato2/986db794-ebaf-451f-8f08-a234a5a79975
まずは元となる行列の準備、潜在変数を準備し、PとQの行列を別々にランダム値で用意します。
First, we prepare the original matrix and the number of latent variables, and then we randomly initialize the P and Q matrices separately with random values.
import matplotlib.pyplot as plt
import torch.optim as optim
import torch
import numpy as np
%matplotlib inline
#initial matrix
R = np.array([[1.,1,0,3],[2,5,0,5],[3,1,2,2],[0,1,3,0],[1,0,3,1]])
#get number of rows and columns
rows, cols = R.shape
#latent variable
r = 2
#initialize two matrix with random numbers
P = np.random.rand(r, rows)
Q = np.random.rand(r, cols)
次に行列をテンソルに変換します。最適化をAdamを設定し、損失関数を設定して最適化します。
Next, we convert the matrices into tensors, set the optimization method to Adam, define the loss function, and optimize the parameters through training.
Rt = torch.tensor(R,requires_grad=True)
Pt = torch.tensor(P,requires_grad=True)
Qt = torch.tensor(Q,requires_grad=True)
arr = []
#the first variable is list of paramters.
op = optim.Adam([Pt,Qt],lr=0.05)
for _ in range(100):
non_zero_mask = Rt != 0
filtered_matrix = (Rt-Pt.T@Qt) * non_zero_mask
loss = torch.sum(torch.square(filtered_matrix))
arr.append(loss.item()) # Add the item to the arr list
op.zero_grad()
loss.backward()
op.step()
plt.plot(arr)
plt.show()
最後に行列がどう再構築されるかみてみましょう。
Finally, let's take a look at how the matrices are reconstructed.
Pt.T@Qt
tensor([[1.2601, 1.8230, 3.3896, 2.1821],
[1.8241, 4.7143, 8.1274, 5.2432],
[3.2414, 0.6212, 2.4065, 1.5272],
[2.1939, 1.2149, 2.8616, 1.8316],
[0.9252, 1.4124, 2.6035, 1.6764]], dtype=torch.float64,
grad_fn=<MmBackward0>)
Rt
tensor([[1., 1., 0., 3.],
[2., 5., 0., 5.],
[3., 1., 2., 2.],
[0., 1., 3., 0.],
[1., 0., 3., 1.]], dtype=torch.float64, requires_grad=True)