Использование scikit-learn NMF с предварительно вычисленным набором базисных векторов (Python)
Я хочу использовать scikit-learn NMF ( отсюда) (или любой другой NMF, если он действительно выполняет свою работу).
В частности, у меня есть входная матрица (которая является спектрограммой величины звука), и я хочу разложить ее.
У меня уже есть предварительно вычисленная матрица W. Как использовать фиксированный W в sklearn.decompose.NMF
? Я не нашел другого вопроса, задающего это.
Я вижу, что этот метод также упоминает что-то похожее в параметре fit: "Если False, компоненты предполагаются предварительно вычисленными и сохраненными в преобразователе, а не изменены". Однако я не уверен, как сделать этот объект-трансформер.
1 ответ
Эта часть кода немного объясняет внутреннюю обработку.
Кажется, вы хотите исправить W. Согласно коду, вы можете исправить только H, оптимизируя W. Это не проблема, так как вы можете просто переключать эти матрицы (инвертировать их роли).
Делая это, код говорит: использовать init='custom'
и установить update_h=False
,
В общем, я бы ожидал, что использование будет выглядеть (на примере здесь):
Непроверенные!
import numpy as np
X = np.array([[1,1], [2, 1], [3, 1.2], [4, 1], [5, 0.8], [6, 1]])
fixed_W = np.array([[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]) # size=3 just an example
# might break
fixed_H = fixed_W.T # interpret W as H (transpose)
from sklearn.decomposition import NMF
model = NMF(n_components=2, init='custom', H=fixed_H, update_H=False, random_state=0)
model.fit(X)
Вы, вероятно, хотите переключить свои переменные после решения снова.
Изменить: как уже упоминалось в комментариях, непроверенный код выше не будет работать. Нам нужно использовать более низкоуровневую функцию, доступную для этого.
Вот быстрый взлом (где меня не волнует правильная предварительная обработка; транспонирование и совместная работа), который должен помочь вам решить вашу задачу:
import numpy as np
X = np.array([[1,1], [2, 1], [3, 1.2], [4, 1], [5, 0.8], [6, 1]])
fixed_W = np.array([[0.4,0.4],[0.2,0.1]]) # size=2 just an example
fixed_H = fixed_W.T # interpret W as H (transpose)
from sklearn.decomposition import NMF, non_negative_factorization
W, H, n_iter = non_negative_factorization(X, n_components=2, init='random', random_state=0)
print(W)
print(H)
print('error: ')
print(W.dot(H) - X) # just a demo, it's not the loss minimized!
W, H, n_iter = non_negative_factorization(X, n_components=2, init='custom', random_state=0, update_H=False, H=fixed_H)
print(W)
print(H)
print('error: ')
print(W.dot(H) - X)
Выход:
[[ 0. 0.46880684]
[ 0.55699523 0.3894146 ]
[ 1.00331638 0.41925352]
[ 1.6733999 0.22926926]
[ 2.34349311 0.03927954]
[ 2.78981512 0.06911798]]
[[ 2.09783018 0.30560234]
[ 2.13443044 2.13171694]]
error:
[[ 6.35579822e-04 -6.36528773e-04]
[ -3.40231372e-04 3.40739354e-04]
[ -3.45147253e-04 3.45662574e-04]
[ -1.31898319e-04 1.32095249e-04]
[ 9.00218123e-05 -9.01562192e-05]
[ 8.58722020e-05 -8.60004133e-05]]
[[ 3. 0. ]
[ 5. 0. ]
[ 4.51221142 2.98707026]
[ 0.04070474 9.95690087]
[ 0. 12.23529412]
[ 0. 14.70588235]]
[[ 0.4 0.2]
[ 0.4 0.1]]
error:
[[ 2.00000000e-01 -4.00000000e-01]
[ -2.22044605e-16 -1.11022302e-16]
[ -2.87327549e-04 1.14931020e-03]
[ -9.57758497e-04 3.83103399e-03]
[ -1.05882353e-01 4.23529412e-01]
[ -1.17647059e-01 4.70588235e-01]]