svd分解-LMLPHP

 sklearn中svd分解

class sklearn.decomposition.TruncatedSVD(n_components=2, *, algorithm='randomized', n_iter=5, random_state=None, tol=0.0)
from sklearn.decomposition import TruncatedSVD
from scipy.sparse import csr_matrix
import numpy as np
np.random.seed(0)

X_dense = np.random.rand(10, 10)
X_dense[:, 2 * np.arange(5)] = 0

X = csr_matrix(X_dense)
print('稀疏矩阵\n',X)
#定义svd模型
svd = TruncatedSVD(n_components=3, n_iter=7, random_state=42)
#训练模型
svd.fit(X)

print('所选特征方差百分比',svd.explained_variance_ratio_)
print('方差百分比',svd.explained_variance_ratio_.sum())
print('每个特征的奇异值',svd.singular_values_)
print('模型的参数',svd.get_params(deep=True))
x=np.random.rand(1, 10)
print('之前的数据',x)
print('转换后的数据',svd.transform(x))

svd分解-LMLPHP

from sklearn.decomposition import TruncatedSVD
from scipy.sparse import random as r
import numpy as np
# 假设数据是5*10的
x=np.random.randint(1,10,size=[5,10])
# print("原始数据\n",x)
print('原始数据维度',x.shape)

svd=TruncatedSVD(n_components=5)
svd.fit(x)
new_x=svd.transform(x)
print('新的数据维度',new_x.shape)

# 手工降维,right即为svd分解后的右矩阵
right=svd.components_
print(right.shape)
# 计算
print('手工降维',np.dot(x,right[:,:].T))

# sklearn可以直接复原
print(svd.inverse_transform(new_x))

svd分解-LMLPHP

使用numpy进行降维和复原

import numpy as np
# 假设数据是5*10的
x=np.random.randint(1,10,size=[5,10])
# print("原始数据\n",x)
print('原始数据维度',x.shape)

# 可以得到三个矩阵
u,s,v=np.linalg.svd(x)
print("u,s,v的形状:")
print("u:",u.shape)
print("s:",s.shape)
print("v:",v.shape)

svd分解-LMLPHP

降维,利用x,v实现降维

import numpy as np
# 假设数据是5*10的
x=np.random.randint(1,10,size=[5,10])
# print("原始数据\n",x)
print('原始数据维度',x.shape)

# 可以得到三个矩阵
u,s,v=np.linalg.svd(x)
print("u,s,v的形状:")
print("u:",u.shape)
print("s:",s.shape)
print("v:",v.shape)

# 降维结果与sklearn基本一致,假设降维到n_com=5
print(np.dot(x,v[:5,:].T))

svd分解-LMLPHP

利用u,s,v复原

import numpy as np
# 假设数据是5*10的
x=np.random.randint(1,10,size=[5,10])
print("原始数据\n",x)
print('原始数据维度',x.shape)

# 可以得到三个矩阵
u,s,v=np.linalg.svd(x)
print("u,s,v的形状:")
print("u:",u.shape)
print("s:",s.shape)
print("v:",v.shape)

# 降维结果与sklearn基本一致,假设降维到n_com=5
print(np.dot(x,v[:5,:].T))

# m为原始行数,n为原始列数
m = 5
n = 10
# 将u、v、s三个矩阵进行运算,将结果累加到a中并返回
a = np.zeros([m, n])

for i in range(0,5):
    # 依次取出u和v矩阵的对应数据,并reshape
    ui = u[:, i].reshape(m, 1)
    vi = v[i].reshape(1, n)
    # 将其按照s的权重进行累加
    a += s[i] * np.dot(ui, vi)
# 结果与原始数据基本一致
print(a)

svd分解-LMLPHP

参考文献

用截断奇异值分解(Truncated SVD)降维_纸上得来终觉浅~的博客-CSDN博客_截断奇异值分解

12-09 16:00