使用PCA對數據進行降噪(使用手寫數字實例)
(在notebook中)
加載庫並制作虛擬的數據並進行繪制
import numpy as np
import matplotlib.pyplot as plt
X = np.empty((100,2))
X[:,0] = np.random.uniform(0. ,100. , size=100)
X[:,1] = 0.75 * X[:,0] + 3. + np.random.normal(0. ,10. ,size=100)
plt.scatter(X[:,0],X[:,1])
圖像如下
這個數據集展現出來這樣一個結果,但是實際情況是怎么樣的呢,有沒有可能其數據集就是一根直線,其數據的上下抖動其實是因為多種原因導致的噪音
我們使用PCA這種方法將X降維成一維,再恢復成二維的數據,並繪制圖像
from sklearn.decomposition import PCA
pca = PCA(n_components=1)
pca.fit(X)
X_reduction = pca.transform(X)
X_restore = pca.inverse_transform(X_reduction)
plt.scatter(X_restore[:,0],X_restore[:,1])
圖像如下(此時的數據就變成了一條直線)
上面的過程可以理解成將數據的噪音去除了,當然,實際情況下,這不能說是一點噪音都沒有,可以理解成,降低了維度,丟失了信息,同時也去除了部分噪音
我們使用手寫識別的例子來更加直觀的看待這個操作
我們使用手寫數字數據集
from sklearn import datasets
digits = datasets.load_digits()
X = digits.data
y = digits.target
重新創造一個具有噪音的數據集
noisy_digits = X + np.random.normal(0,4,size=X.shape)
為了更加直觀的看到,我們繪制一下這些數字
從樣本中取出100個digits,稱其為example_digits,初始的時候,在noisy_digits中y=0中取十個,然后進行循環從一到十,每一個都再從noisy_digits中取出y=num的十個,將這些樣本和原來的樣本壘在一起
example_digits = noisy_digits[y==0,:][:10]
for num in range(1,10):
X_num = noisy_digits[y==num,:][:10]
example_digits = np.vstack([example_digits,X_num])
這樣就有了含有100個的元素的,每個元素有64位的數據
example_digits.shape
結果如下
繪制代碼:
def plot_digits(data):
fig,axes = plt.subplots(10,10,figsize=(10,10),
subplot_kw={'xticks':[],'yticks':[]},
gridspec_kw=dict(hspace=0.1,wspace=0.1))
for i,ax in enumerate(axes.flat):
ax.imshow(data[i].reshape(8,8),
cmap='binary',interpolation='nearest',
clim=(0,16))
plt.show()
plot_digits(example_digits)
圖像如下
然后我們使用PCA降噪,實例化然后取0.5,進行fit操作
pca = PCA(0.5)
pca.fit(noisy_digits)
結果如下
此時我們的保留數據維度為
pca.n_components_
結果如下
然后對低維返回高維,再進行繪制
components = pca.transform(example_digits)
filtered_digits = pca.inverse_transform(components)
plot_digits(filtered_digits)
圖像如下
簡單使用PCA來對圖像進行降噪就完成了