yoyololicon / pytorch-NMF

A pytorch package for non-negative matrix factorization.
https://pytorch-nmf.readthedocs.io/
MIT License
223 stars 24 forks source link

Is there function equivalent to sklearn's transform? #1

Closed devangini27 closed 2 years ago

devangini27 commented 4 years ago

I would like to use your code for NMF. I am able to learn the NMF model using your code but I am not sure of how to transform new data using the trained NMF model. In sklearn there is a function called transform: https://scikit-learn.org/stable/modules/generated/sklearn.decomposition.NMF.html#sklearn.decomposition.NMF.transform, is there a similar function in your code?

yoyololicon commented 4 years ago

I didn't implement transform() in the current version, but you can get the same result using fit_transform().

transform() in sklearn is to learn a new activation matrix H given new data X, while reusing the learned template matrix W. So W is fixed during training.

In torchnmf, once the model have trained, to learn a new H while keeping W fixed, you can pass update_W=False to fit_transform(). This will only update matrix H, and you can get it directly as model attribute after training; pass update_H=False will do the opposite.

Sorry for lacks of examples and documentation cuz I'm working on some other projects, will update them soon.

expectopatronum commented 4 years ago

Sorry if this a stupid question, but do I understand this correctly if I run _, V = net.fit_transform(S) and later _, V2 = net.fit_transform(S2) it will learn from scratch and I do not need a new variable net?

yoyololicon commented 4 years ago

Sorry if this a stupid question, but do I understand this correctly if I run _, V = net.fit_transform(S) and later _, V2 = net.fit_transform(S2) it will learn from scratch and I do not need a new variable net?

No. It will continue with the last time learned weights. To learn it from scratch, besides create new variable, you can also pass random or custom initial weights using argmuments, ex: W=initial_weights_W, H=initial_weights_H.

njt005 commented 2 years ago

Hello, I have the same question as devangini27. It looks like the torchnmf module has been updated since this question was originally asked, since I do not see a fit_transform function for NMF. Is there an alternative way to use the current module to transform new input data V from an existing trained NMF model in the same way as the sklearn model.transform function? Thank you very much.

yoyololicon commented 2 years ago

Hello, I have the same question as devangini27. It looks like the torchnmf module has been updated since this question was originally asked, since I do not see a fit_transform function for NMF. Is there an alternative way to use the current module to transform new input data V from an existing trained NMF model in the same way as the sklearn model.transform function? Thank you very much.

@njt005 yes, the above solution doesn't work anymore in later versions, we dropped fit_transform due to some concerns about the overall design of the package. The best practice would be to construct a new NMF module for the new input data V with W being initialized and fixed from the previous NMF. I hope this helps.

model1 = NMF(V.shape)
model1.fit(V)
model2 = NMF(W=model1.W.detach(), H=(V_new.shape[0], model1.H.shape[1]), trainable_W=False)
model2.fit(V_new)
njt005 commented 2 years ago

Thank you very much! This was helpful.

On Wed, Dec 29, 2021 at 9:33 PM Chin-Yun Yu @.***> wrote:

Hello, I have the same question as devangini27. It looks like the torchnmf module has been updated since this question was originally asked, since I do not see a fit_transform function for NMF. Is there an alternative way to use the current module to transform new input data V from an existing trained NMF model in the same way as the sklearn model.transform function? Thank you very much.

@njt005 https://github.com/njt005 yes, the above solution doesn't work anymore in later versions, we dropped fit_transform due to some concerns about the overall design of the package. The best practice would be to construct a new NMF module for the new input data V with W being initialized and fixed from the previous NMF. I hope this helps.

model1 = NMF(V.shape)model1.fit(V)model2 = NMF(W=model1.W.detach(), H=(V_new.shape[0], model1.H.shape[1]), trainable_W=False)model2.fit(V_new)

— Reply to this email directly, view it on GitHub https://github.com/yoyololicon/pytorch-NMF/issues/1#issuecomment-1002847056, or unsubscribe https://github.com/notifications/unsubscribe-auth/AKWKVBYIPP3HR2CAEH3JYDDUTPAJBANCNFSM4JE5F3SA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you were mentioned.Message ID: @.***>

yoyololicon commented 2 years ago

@njt005 @expectopatronum @devangini27 I summarized some sklearn-equivalent approaches in the discussions forum https://github.com/yoyololicon/pytorch-NMF/discussions/21#discussion-3780381, and I will close this issue.