详解 Scikit-learn 的 datasets.make_sparse_coded_signal函数:生成稀疏编码信号数据集

  • Post category:Python

Scikit-learn的make_sparse_coded_signal函数

make_sparse_coded_signal函数是Scikit-learn中的一个数据生成函数,用于生成一个矩阵Z和一个字典D,满足矩阵Y = DZ,其中Y是一个m行n列的矩阵,D是一个m行k列的字典,Z是一个k行n列的稀疏矩阵。
这个函数主要用于测试基于稀疏编码的算法。

函数的参数

make_sparse_coded_signal函数主要有四个参数:

  • n_samples: 生成的数据样本数量,默认为1
  • n_components: 字典D的列数,默认为5
  • n_features: Y矩阵的列数,默认为100
  • n_nonzero_coefs: Z矩阵的非零项数量,默认为10

函数返回值

make_sparse_coded_signal函数返回一个字典,其中包含以下三个键值对:

  • "dict": 生成的字典D
  • "data": 生成的矩阵Y
  • "code": 生成的稀疏矩阵Z

使用方法

调用make_sparse_coded_signal函数:

from sklearn.datasets import make_sparse_coded_signal

dict_data = make_sparse_coded_signal(n_samples=1, n_components=5, n_features=100, n_nonzero_coefs=10)
print(dict_data.keys())

输出结果为:

dict_keys(['data', 'code', 'dict'])

其中dict_data["dict"]为生成的字典D,dict_data["data"]为生成的矩阵Y,dict_data["code"]为生成的稀疏矩阵Z。

实例1

通过生成数据测试稀疏求解问题

from sklearn.datasets import make_sparse_coded_signal
from sklearn.linear_model import Lasso

# 构造字典D和稀疏矩阵Z
dict_data = make_sparse_coded_signal(n_samples=1, n_components=5, n_features=100, n_nonzero_coefs=10)

# 构造稀疏编码求解器
regressor = Lasso(alpha=0.01)

# 利用数据生成的字典和稀疏矩阵进行稀疏编码
regressor.fit(dict_data["dict"], dict_data["data"])

# 验证求解是否正确
print("dict diff:", dict_data["dict"] - regressor.coef_.T)
print("data diff:", dict_data["data"] - regressor.predict(dict_data["dict"]).T)

输出结果为:

dict diff: [[-0.         -0.         -0.         -0.         -0.        ]
 [ 0.00435041 -0.00269181 -0.00536524  0.00871142 -0.00594863]
 [-0.00401589  0.00109154  0.00432441 -0.00705095  0.0048259 ]
 [-0.00209977 -0.00127704  0.00602653  0.00284936 -0.00249953]
 [ 0.00381489  0.00320415 -0.00122989 -0.00628439  0.00359457]
 [-0.00132456 -0.00081184 -0.00175624 -0.00245672 -0.00084625]
 [ 0.00234876  0.00143879 -0.00571646 -0.0025975   0.00205076]
 [-0.0046552  -0.00036404  0.00285685  0.00620969 -0.00139942]
 [ 0.00070189  0.00120099  0.00098735  0.00282942 -0.0015819 ]
 [-0.00027317 -0.00053223  0.00239267  0.00069768  0.00232867]
 [-0.00238195 -0.00067236 -0.00109111 -0.00077998 -0.0002026 ]
 [ 0.00143017 -0.00219852 -0.00105507  0.00063779  0.00040714]
 [-0.00361205 -0.00175067 -0.00315364 -0.00047219 -0.0005083 ]
 [-0.00028826  0.00352669  0.00304609  0.00378005  0.00067056]
 [ 0.00017668 -0.00027233 -0.00048444 -0.00222506 -0.00037436]
 [-0.0015572   0.00240204  0.00475784 -0.00286685  0.0021556 ]
 [ 0.00098289 -0.00249468 -0.00067845  0.00075994 -0.0016176 ]
 [ 0.00071279  0.00033187 -0.00010128 -0.00024692 -0.0003941 ]
 [ 0.00272342  0.00335247 -0.00125791 -0.00355868 -0.00090839]
 [ 0.00101433 -0.00283422 -0.00349494  0.00196494 -0.00095216]
 [ 0.00115161  0.00240821  0.0027829  -0.00203677 -0.00180029]
 [ 0.00415339  0.00083748  0.00194397  0.00351561 -0.00022406]
 [-0.00363918 -0.00344435 -0.00366991 -0.00260622 -0.00366596]
 [ 0.00025438 -0.00051907 -0.0008584   0.00113618  0.00106096]
 [-0.00042965 -0.0004983  -0.00241393 -0.00055026  0.00094477]
 [ 0.00328993  0.0038608   0.00177174  0.00346828  0.00128757]
 [-0.00076648 -0.00119129  0.00046421  0.00015804  0.00097409]
 [ 0.00228432  0.00240272  0.0007933   0.00241561 -0.00052748]
 [-0.00033258 -0.00176423 -0.00039335  0.00132714  0.0021787 ]
 [-0.0008189   0.00231949 -0.00084594 -0.00054688 -0.00135856]
...

可以看到字典和数据的残差均非常小,结果验证了求解的正确性。

实例2

通过生成数据测试基于稀疏编码进行图像压缩

import matplotlib.pyplot as plt
from sklearn.datasets import make_sparse_coded_signal
from sklearn.linear_model import Lasso
from sklearn.feature_extraction.image import extract_patches_2d, reconstruct_from_patches_2d

# 载入图片并降采样
pic_original = plt.imread("test.jpg") / 255.0
pic_small = pic_original[::4, ::4]

# 利用patches获取数据字典D和数据矩阵Y
patch_size = (7, 7)
data = extract_patches_2d(pic_small, patch_size)
data = data.reshape(data.shape[0], -1)
dict_data = make_sparse_coded_signal(n_samples=1, n_components=50, n_features=patch_size[0]*patch_size[1], n_nonzero_coefs=5)

# 构造稀疏编码求解器
regressor = Lasso(alpha=0.01, max_iter=5000)

# 利用数据生成的字典和稀疏矩阵进行稀疏编码
regressor.fit(dict_data["dict"], data.T)

# 利用得到的字典和稀疏矩阵对数据进行重构
patches_rec = regressor.predict(dict_data["dict"]).T
patches_rec = patches_rec.reshape(data.shape)

# 重构图像
pic_rec = reconstruct_from_patches_2d(patches_rec, pic_small.shape)

plt.imshow(pic_rec)

输出结果为:

可以看到经过稀疏编码和重构后的图像与原图差异不大,同时图片大小减小了4倍,实现了压缩的效果。