web-dev-qa-db-ja.com

SVD-行列変換Python

PythonでSVDを計算して、スペクトルの最も重要な要素を見つけ、最も重要な部分だけを含む行列を作成しようとしています。

python私は持っています:

u,s,v = linalg.svd(Pxx, full_matrices=True)

これにより、3つの行列が返されます。ここで、「s」にはu、vに対応する大き​​さが含まれます。

信号の重要な部分をすべて含む新しい行列を作成するには、「s」の最大値をキャプチャし、それらを「u」と「v」の列と一致させる必要があります。結果の行列は次のようになります。データの最も重要な部分。

問題は、Pythonでこれをどのように行うかわからないことです。たとえば、新しいマトリックスを作成するために、「s」で最大の数値を見つけ、「u」と「v」の列を選択するにはどうすればよいですか。

(私はPython and numpy)に慣れていないので、どんな助けでも大歓迎です

編集:

import wave, struct, numpy as np, matplotlib.mlab as mlab, pylab as pl
from scipy import linalg, mat, dot;
def wavToArr(wavefile):
    w = wave.open(wavefile,"rb")
    p = w.getparams()
    s = w.readframes(p[3])
    w.close()
    sd = np.fromstring(s, np.int16)
    return sd,p

def wavToSpec(wavefile,log=False,norm=False):
    wavArr,wavParams = wavToArr(wavefile)
    print wavParams
    return  mlab.specgram(wavArr, NFFT=256,Fs=wavParams[2],detrend=mlab.detrend_mean,window=mlab.window_hanning,noverlap=128,sides='onesided',scale_by_freq=True)

wavArr,wavParams = wavToArr("wavBat1.wav")

Pxx, freqs, bins = wavToSpec("wavBat1.wav")
Pxx += 0.0001

U, s, Vh = linalg.svd(Pxx, full_matrices=True)
assert np.allclose(Pxx, np.dot(U, np.dot(np.diag(s), Vh)))

s[2:] = 0
new_a = np.dot(U, np.dot(np.diag(s), Vh))
print(new_a)
10
Phorce

linalg.svdsを降順で返します。したがって、nsの最大数を選択するには、単純に次のように入力します。

s[:n]

sの小さい値をゼロに設定すると、

s[n:] = 0

次に、行列の乗算により、UとVの適切な列が「選択」されます。

例えば、

import numpy as np
LA = np.linalg

a = np.array([[1, 3, 4], [5, 6, 9], [1, 2, 3], [7, 6, 8]])
print(a)
# [[1 3 4]
#  [5 6 9]
#  [1 2 3]
#  [7 6 8]]
U, s, Vh = LA.svd(a, full_matrices=False)
assert np.allclose(a, np.dot(U, np.dot(np.diag(s), Vh)))

s[2:] = 0
new_a = np.dot(U, np.dot(np.diag(s), Vh))
print(new_a)
# [[ 1.02206755  2.77276308  4.14651336]
#  [ 4.9803474   6.20236935  8.86952026]
#  [ 0.99786077  2.02202837  2.98579698]
#  [ 7.01104783  5.88623677  8.07335002]]

ここのデータ を考えると、

import numpy as np
import scipy.linalg as SL
import matplotlib.pyplot as plt

Pxx = np.genfromtxt('mBtasJLD.txt')
U, s, Vh = SL.svd(Pxx, full_matrices=False)
assert np.allclose(Pxx, np.dot(U, np.dot(np.diag(s), Vh)))

s[2:] = 0
new_a = np.dot(U, np.dot(np.diag(s), Vh))
print(new_a)
plt.plot(new_a)
plt.show()

を生成します

enter image description here

13
unutbu