如何访问此模型 class 中的数据?
How to access data in this model class?
我正在使用程序包 libmf
进行并行非负矩阵分解,即 X = WH。我使用 class MF
中的方法 fit
。如下文所述,生成的矩阵存储在 MF.model
.
中
def fit(self, X):
"""
factorize the i x j data matrix X into (j, k) (k, i) sized matrices stored in MF.model
:param X: (n, 3) shaped numpy array [known index and values of the data matrix]
"""
ensure_width(X, 3)
d = X.astype(np.float32)
data_p = d.ctypes.data_as(c_float_p)
nnx = ctypes.c_int(X.shape[0])
mf.fit_interface.restype = ctypes.POINTER(MFModel)
mf.fit_interface.argtypes = (ctypes.c_int, c_float_p, options_ptr)
out = mf.fit_interface(nnx, data_p, self._options)
self.model = out.contents
从包的GitHub page,classMFModel
是
class MFModel(ctypes.Structure):
_fields_ = [("fun", ctypes.c_int),
("m", ctypes.c_int),
("n", ctypes.c_int),
("k", ctypes.c_int),
("b", ctypes.c_float),
("P", c_float_p),
("Q", c_float_p)]
你能解释一下如何从这个 class 中提取信息吗?
# !pip install libmf
import numpy as np
from libmf import mf
X = np.array([[1, 2, 3],
[0, 11, 0],
[5, 0, 7]])
row, col = X.nonzero()
values = X[np.nonzero(X)]
res = np.array(list(zip(row.tolist(), col.tolist(), values.tolist())))
engine = mf.MF(k = 2)
engine.fit(res)
engine.model
为了方便,我也把notebook放在了Colab上here。
我对该库的了解并不深入,但这里有一些可能很有趣的观察结果:(建立在提供的代码之上)
TL;DR
您可以使用 engine.q_factors;engine.p_factors
获取 P;Q
矩阵,也可以遍历 engine.model.P[i]
:
print(engine.p_factors())
# [[0.37909135 0.70226544]
# [2.561905 2.0429273 ]
# [1.7700745 2.0010414 ]]
print(engine.model.P[0:(engine.model.m * engine.model.k)])
# [0.37909135222435, 0.7022654414176941, 2.5619049072265625, 2.0429272651672363, 1.770074486732483, 2.0010414123535156]
1。 P/Q-Factors 方法
对象 engine
有两个有趣的方法:p_factors;q_factors
。在我们的设置中,这些方法吐出两个 (3, 2)
矩阵:
P = engine.p_factors()
P
# array([[0.37909135, 0.70226544],
# [2.561905 , 2.0429273 ],
# [1.7700745 , 2.0010414 ]], dtype=float32)
Q = engine.q_factors()
Q
# array([[0.87586826, 1.6112198 ],
# [2.5359864 , 2.095469 ],
# [1.6843219 , 2.0822709 ]], dtype=float32)
第一反应是:我们相乘吧!
RES = np.matmul(P, Q.transpose())
RES
# array([[ 1.463538 , 2.432946 , 2.1008186],
# [ 5.535496 , 10.777846 , 8.569 ],
# [ 4.7744694, 8.682005 , 7.1480856]], dtype=float32)
现在,我对库和主题的(使用)还不够深入,无法对该产品进行有根据的评估。
2。方法源代码
下一步是研究这两种方法p-q_factors
。这是源代码(MF.p_factors
):
def p_factors(self):
if self.model is None:
return LookupError("no model data is saved, try running model.mf_fit(...) first")
out = np.zeros(self.model.m * self.model.k)
out = out.astype(np.float32)
mf.get_P(ctypes.c_void_p(out.ctypes.data), ctypes.byref(self.model))
return out.reshape((self.model.m, self.model.k))
这有点让人难以理解,因为似乎有趣的事情发生在 mf.get_P
中,其中 mf 是底层 c++ 库。
3。 C++
继续我们的探索,mf.get_P
(在 `libmf_interface.cpp 中)的源代码如下:
#ifdef __cplusplus
extern "C" float* get_P(float *out, mf::mf_model *model)
#else
float* get_P(float *out, mf::mf_model *model)
#endif
{
for (int i = 0; i < model->m; i++){
for(int j = 0; j < model->k; j++){
int idx = i * model->k + j;
out[idx] = model->P[idx];
}
}
return out;
}
这段代码(非常)粗略地翻译成
def get_P(out, model: mf.MFMODEL) -> np.ndarray:
for i in range(model.m):
for j in range(model.k):
idx = i * model.k + j
out[idx] = model.P[idx]
return out
似乎通过索引从 model.P
访问数据。
因此您可以按如下方式访问数据 engine.model.P[i]
。
我正在使用程序包 libmf
进行并行非负矩阵分解,即 X = WH。我使用 class MF
中的方法 fit
。如下文所述,生成的矩阵存储在 MF.model
.
def fit(self, X):
"""
factorize the i x j data matrix X into (j, k) (k, i) sized matrices stored in MF.model
:param X: (n, 3) shaped numpy array [known index and values of the data matrix]
"""
ensure_width(X, 3)
d = X.astype(np.float32)
data_p = d.ctypes.data_as(c_float_p)
nnx = ctypes.c_int(X.shape[0])
mf.fit_interface.restype = ctypes.POINTER(MFModel)
mf.fit_interface.argtypes = (ctypes.c_int, c_float_p, options_ptr)
out = mf.fit_interface(nnx, data_p, self._options)
self.model = out.contents
从包的GitHub page,classMFModel
是
class MFModel(ctypes.Structure):
_fields_ = [("fun", ctypes.c_int),
("m", ctypes.c_int),
("n", ctypes.c_int),
("k", ctypes.c_int),
("b", ctypes.c_float),
("P", c_float_p),
("Q", c_float_p)]
你能解释一下如何从这个 class 中提取信息吗?
# !pip install libmf
import numpy as np
from libmf import mf
X = np.array([[1, 2, 3],
[0, 11, 0],
[5, 0, 7]])
row, col = X.nonzero()
values = X[np.nonzero(X)]
res = np.array(list(zip(row.tolist(), col.tolist(), values.tolist())))
engine = mf.MF(k = 2)
engine.fit(res)
engine.model
为了方便,我也把notebook放在了Colab上here。
我对该库的了解并不深入,但这里有一些可能很有趣的观察结果:(建立在提供的代码之上)
TL;DR
您可以使用 engine.q_factors;engine.p_factors
获取 P;Q
矩阵,也可以遍历 engine.model.P[i]
:
print(engine.p_factors())
# [[0.37909135 0.70226544]
# [2.561905 2.0429273 ]
# [1.7700745 2.0010414 ]]
print(engine.model.P[0:(engine.model.m * engine.model.k)])
# [0.37909135222435, 0.7022654414176941, 2.5619049072265625, 2.0429272651672363, 1.770074486732483, 2.0010414123535156]
1。 P/Q-Factors 方法
对象 engine
有两个有趣的方法:p_factors;q_factors
。在我们的设置中,这些方法吐出两个 (3, 2)
矩阵:
P = engine.p_factors()
P
# array([[0.37909135, 0.70226544],
# [2.561905 , 2.0429273 ],
# [1.7700745 , 2.0010414 ]], dtype=float32)
Q = engine.q_factors()
Q
# array([[0.87586826, 1.6112198 ],
# [2.5359864 , 2.095469 ],
# [1.6843219 , 2.0822709 ]], dtype=float32)
第一反应是:我们相乘吧!
RES = np.matmul(P, Q.transpose())
RES
# array([[ 1.463538 , 2.432946 , 2.1008186],
# [ 5.535496 , 10.777846 , 8.569 ],
# [ 4.7744694, 8.682005 , 7.1480856]], dtype=float32)
现在,我对库和主题的(使用)还不够深入,无法对该产品进行有根据的评估。
2。方法源代码
下一步是研究这两种方法p-q_factors
。这是源代码(MF.p_factors
):
def p_factors(self):
if self.model is None:
return LookupError("no model data is saved, try running model.mf_fit(...) first")
out = np.zeros(self.model.m * self.model.k)
out = out.astype(np.float32)
mf.get_P(ctypes.c_void_p(out.ctypes.data), ctypes.byref(self.model))
return out.reshape((self.model.m, self.model.k))
这有点让人难以理解,因为似乎有趣的事情发生在 mf.get_P
中,其中 mf 是底层 c++ 库。
3。 C++
继续我们的探索,mf.get_P
(在 `libmf_interface.cpp 中)的源代码如下:
#ifdef __cplusplus
extern "C" float* get_P(float *out, mf::mf_model *model)
#else
float* get_P(float *out, mf::mf_model *model)
#endif
{
for (int i = 0; i < model->m; i++){
for(int j = 0; j < model->k; j++){
int idx = i * model->k + j;
out[idx] = model->P[idx];
}
}
return out;
}
这段代码(非常)粗略地翻译成
def get_P(out, model: mf.MFMODEL) -> np.ndarray:
for i in range(model.m):
for j in range(model.k):
idx = i * model.k + j
out[idx] = model.P[idx]
return out
似乎通过索引从 model.P
访问数据。
因此您可以按如下方式访问数据 engine.model.P[i]
。