Verwenden Sie ** scikit-learn **, um ** PCA ** in Python auszuführen. Es gibt viele Erklärungen für PCA auf der Welt, daher werde ich es hier nicht erklären, sondern nur erklären, wie man es verwendet.
Die Verwendung ist einfach. n_components ist die Anzahl der Komponenten. Wenn nichts angegeben ist, ist dies die Anzahl der Dimensionen der Daten. Jetzt müssen Sie nur noch die Daten passend übergeben.
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
pca.fit(X)
Details finden Sie hier [http://scikit-learn.org/stable/modules/generated/sklearn.decomposition.PCA.html#sklearn.decomposition.PCA.fit_transform].
Ich habe die Testdaten so erstellt. Es spielt keine Rolle, ob Shuffle getrennt ist oder nicht.
In [10]: x = np.linspace(0.2,1,100)
In [11]: y = 0.8*x + np.random.randn(100)*0.1
In [12]: X = np.vstack([x, y]).T
In [13]: np.random.shuffle(X)
PCA Die PCA sollte wie folgt sein.
In [14]: from sklearn.decomposition import PCA
In [15]: pca = PCA(n_components=2)
In [16]: pca.fit(X)
Out[16]: PCA(copy=True, n_components=2, whiten=False)
** Hauptkomponenten ** befinden sich in components_. Übrigens können Sie die ** Mittelwert ** und ** Kovarianzmatrix ** mit mean_, get_covariance () sehen.
In [17]: print 'components'
...: print pca.components_
...: print 'mean'
...: print pca.mean_
...: print 'covariance'
...: print pca.get_covariance()
...:
components
[[ 0.71487492 0.69925235]
[-0.69925235 0.71487492]]
mean
[ 0.6 0.47190318]
covariance
[[ 0.05441077 0.04603365]
[ 0.04603365 0.0523763 ]]
Berechnen wir nun den ** Mittelwert ** und die ** Kovarianzmatrix ** selbst. Der Durchschnitt ist der Durchschnitt für jede Komponente. Die Kovarianzmatrix ist eine Berechnung der Kovarianz. (Korrekt) Bei der Berechnung der Kovarianz dient Bias = 1 zur Angabe des Nenners der Varianz und Kovarianz. Hier wird 1 angegeben, um durch die Anzahl der Daten zu teilen. Wenn es 0 ist, wird es durch die Anzahl der Daten-1 geteilt. Sie können sehen, dass die Ergebnisse gleich sind.
In [22]: mn = np.mean(X,axis=0)
In [23]: z = X - mn
In [24]: cv = np.cov(z[:,0],z[:,1],bias=1)
In [25]: print 'mean'
...: print mn
...: print 'covariance'
...: print cv
...:
mean
[ 0.6 0.47190318]
covariance
[[ 0.05441077 0.04603365]
[ 0.04603365 0.0523763 ]]
Berechnen Sie als nächstes den ** Eigenwert ** und den ** Eigenvektor ** der ** Kovarianzmatrix **. Der Eigenvektor der Kovarianzmatrix entspricht der Hauptkomponente. Die Eigenwerte und Eigenvektoren werden in numpy.linalg.eig berechnet.
W, v = np.linalg.eig(cv)
print 'eigenvector'
print v
print 'eigenvalue'
print W
eigenvector
[[ 0.71487492 -0.69925235]
[ 0.69925235 0.71487492]]
eigenvalue
[ 0.09943842 0.00734865]
W ist der Eigenwert und v ist der Eigenvektor. Hier ist der Eigenvektor ** Spaltenvektor *. (Vertikal gefüttert) Das heißt, v [:, 0] ist der erste Eigenvektor. Beachten Sie, dass components_ ein ** Zeilenvektor ** ist (nebeneinander). Sie können sehen, dass sie übereinstimmen. ( Manchmal ist die Richtung um 180 Grad umgekehrt.)
Multiplizieren wir die Kovarianzmatrix mit dem Eigenvektor. Da der Eigenvektor und die PCA dieselbe Hauptkomponente haben, entspricht dies der Multiplikation der Kovarianzmatrix mit der Hauptkomponente. Da es sich um einen Eigenvektor handelt, ändert sich die Richtung nicht.
In [28]: print cv.dot(v[:,0].reshape(2,1))
...: print v[:,0]*W[0]
...: print cv.dot(v[:,1].reshape(2,1))
...: print v[:,1]*W[1]
[[ 0.07108603]
[ 0.06953255]]
[ 0.07108603 0.06953255]
[[-0.00513856]
[ 0.00525337]]
[-0.00513856 0.00525337]
Lassen Sie uns den ersten Hauptkomponentenvektor und den zweiten Hauptkomponentenvektor in den Daten anzeigen. Sie können sehen, dass die erste Hauptkomponente in Richtung einer großen Dispersion zeigt.
Projection Lassen Sie uns ** Projektion ** mit den Daten als Hauptkomponente. Die Projektion dient speziell dazu, das innere Produkt der Daten und den Hauptkomponentenvektor zu nehmen.
In [30]: Xd = pca.transform(X)
Wenn Sie tatsächlich das innere Produkt der Daten und den Hauptkomponentenvektor nehmen und überprüfen, können Sie sehen, dass es dasselbe ist.
In [31]: print pca.components_[0]
...: print pca.components_[1]
...: print X[0,:]
...: print z[0,:]
...: print pca.components_[0].dot(z[0,:]), pca.components_[1].dot(z[0,:])
...: print Xd[0,:]
[ 0.71487492 0.69925235]
[-0.69925235 0.71487492]
[ 0.57979798 0.47996242]
[-0.02020202 0.00805924]
-0.00880647453855 0.0198876592146
[-0.00880647 0.01988766]
Wenn Sie die projizierten Daten zeichnen, ist dies wie folgt. Wenn Sie sich die geplottete Form ansehen, sehen Sie, dass der Hauptkomponentenvektor auf die neue Achse gedreht wird.
MNIST Ich habe es mit MNIST-Daten versucht. MNIST sind handgeschriebene Zeichendaten. Die Daten können von hier heruntergeladen werden. Das Format der Daten wird auch hier geschrieben. (* Dieses Mal habe ich mir den Ort zum Lesen der Daten aus dem Beispielcode von Tensorflow ausgeliehen.)
Ich habe die Daten gelesen und 256 Daten mit dem Zeichen '3' verwendet. (Weil es viele gibt, wenn Sie alle verwenden)
PCA hat die Anzahl der Komponenten wie unten gezeigt auf 50 eingestellt. (50 hat keine besondere Bedeutung)
In [36]: from sklearn.decomposition import PCA
In [37]: N = 50
In [38]: pca = PCA(n_components=N)
In [39]: pca.fit(X)
Out[39]: PCA(copy=True, n_components=50, whiten=False)
Das Folgende ist ein Bild der Hauptkomponenten.
Die Projektion führt natürlich zu 50-dimensionalen Daten. Jetzt können Sie die Abmessungen komprimieren.
In [44]: Xd = pca.transform(X)
In [45]: print X.shape
(256, 784)
In [46]: print Xd.shape
(256, 50)
Kehren wir zur ursprünglichen Dimension zurück. Verwenden Sie zum Zurücksetzen inverse_transform.
In [51]: Xe = pca.inverse_transform(Xd)
In [52]: print Xe.shape
(256, 784)
Das Folgende ist ein Vergleich des Originals und des Ergebnisses der Dimensionskomprimierung. Die obere Reihe ist das Original und die untere Reihe ist die komprimierte Abmessung. Da die Anzahl der Dimensionen 50 betrug, ist es schwierig, den Unterschied zu erkennen, aber Sie können sehen, dass er geringfügig unterschiedlich ist.
Das Ergebnis der Einstellung der Anzahl der Dimensionen auf 3 ist wie folgt. Das Ergebnis der Dimensionskomprimierung ist, dass die Anzahl der Dimensionen extrem gering ist, sodass kleine Änderungen nicht ausgedrückt werden können und alle gleich fühlen.
Ich habe den Code eingefügt, den ich unten verwendet habe.
code
import numpy as np
import matplotlib.pyplot as plt
# generate data
x = np.linspace(0.2,1,100)
y = 0.8*x + np.random.randn(100)*0.1
X = np.vstack([x, y]).T
np.random.shuffle(X)
# plot data
fig = plt.figure()
axes = fig.add_subplot(111,aspect='equal')
axes.scatter(X[:,0],X[:,1])
axes.set_xlim([-0.2, 1.4])
axes.set_ylim([-0.2, 1.4])
axes.set_xlabel('x0')
axes.set_ylabel('x1')
axes.vlines(0,-0.2,1.4,linestyles='dashed')
axes.hlines(0,-0.2,1.4,linestyles='dashed')
# PCA
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
pca.fit(X)
# print components and mean
print 'components'
print pca.components_
print 'mean'
print pca.mean_
print 'covariance'
print pca.get_covariance()
mn = np.mean(X,axis=0)
z = X - mn
cv = np.cov(z[:,0],z[:,1],bias=1)
print 'mean'
print mn
print 'covariance'
print cv
W, v = np.linalg.eig(cv)
print 'eigenvector'
print v
print 'eigenvalue'
print W
# covariance matrix x eigenvector
print cv.dot(v[:,0].reshape(2,1))
print v[:,0]*W[0]
print cv.dot(v[:,1].reshape(2,1))
print v[:,1]*W[1]
# display
fig = plt.figure()
axes = fig.add_subplot(111,aspect='equal')
axes.scatter(X[:,0],X[:,1])
axes.set_xlim([-0.2, 1.4])
axes.set_ylim([-0.2, 1.4])
axes.set_xlabel('x0')
axes.set_ylabel('x1')
axes.vlines(0,-0.2,1.4,linestyles='dashed')
axes.hlines(0,-0.2,1.4,linestyles='dashed')
axes.quiver(pca.mean_[0], pca.mean_[1], pca.components_[0,0],pca.components_[0,1], color='red', width=0.01, scale=3)
axes.quiver(pca.mean_[0], pca.mean_[1], pca.components_[1,0],pca.components_[1,1], color='blue', width=0.01, scale=3)
# projection
Xd = pca.transform(X)
print pca.components_[0]
print pca.components_[1]
print X[0,:]
print z[0,:]
print pca.components_[0].dot(z[0,:]), pca.components_[1].dot(z[0,:])
print Xd[0,:]
fig = plt.figure()
axes = fig.add_subplot(111,aspect='equal')
axes.scatter(Xd[:,0],Xd[:,1])
axes.set_xlabel('xd0')
axes.set_ylabel('xd1')
axes.set_xlim([-1.0, 1.0])
axes.set_ylim([-1.,1.0])
axes.vlines(0,-1.0,1.0,linestyles='dashed')
axes.hlines(0,-1.0,1.0,linestyles='dashed')
# MNIST
# generate data
import numpy as np
import matplotlib.pyplot as plt
import gzip
image_filename = './data/mnist/train-images-idx3-ubyte.gz'
label_filename = './data/mnist/train-labels-idx1-ubyte.gz'
def _read32(bytestream):
dt = np.dtype(np.uint32).newbyteorder('>')
return np.frombuffer(bytestream.read(4), dtype=dt)[0]
with gzip.open(image_filename) as bytestream:
magic = _read32(bytestream)
num_images = _read32(bytestream)
rows = _read32(bytestream)
cols = _read32(bytestream)
buf = bytestream.read(rows * cols * num_images)
data = np.frombuffer(buf, dtype=np.uint8)
data = data.reshape(num_images, rows, cols)
with gzip.open(label_filename) as bytestream:
magic = _read32(bytestream)
num_items = _read32(bytestream)
buf = bytestream.read(num_items)
labels = np.frombuffer(buf, dtype=np.uint8)
Xall = data[labels == 3, :, :]
X = Xall[0:256,:,:].reshape(256,28*28)
X = X /255.0
# PCA
from sklearn.decomposition import PCA
N = 3
pca = PCA(n_components=N)
pca.fit(X)
# plot
import matplotlib.pyplot as plt
import matplotlib.cm as cm
cols = 10
rows = int(np.ceil(N/float(cols)))
fig, axes = plt.subplots(ncols=cols, nrows=rows, figsize=(20,10))
for i in range(N):
r = i // cols
c = i % cols
axes[r, c].imshow(pca.components_[i].reshape(28,28),vmin=-0.5,vmax=0.5, cmap = cm.Greys_r)
axes[r, c].set_title('component %d' % i)
axes[r, c].get_xaxis().set_visible(False)
axes[r, c].get_yaxis().set_visible(False)
# projection
Xd = pca.transform(X)
print X.shape
print Xd.shape
# inverse
Xe = pca.inverse_transform(Xd)
print Xe.shape
fig, axes = plt.subplots(ncols=10, nrows=2, figsize=(30,4))
for i in range(10):
axes[0, i].imshow(X[i,:].reshape(28,28),vmin=0.0,vmax=1.0, cmap = cm.Greys_r)
axes[0, i].set_title('original %d' % i)
axes[0, i].get_xaxis().set_visible(False)
axes[0, i].get_yaxis().set_visible(False)
axes[1, i].imshow(Xe[i,:].reshape(28,28),vmin=0.0,vmax=1.0, cmap = cm.Greys_r)
axes[1, i].set_title('dimension reduction %d' % i)
axes[1, i].get_xaxis().set_visible(False)
axes[1, i].get_yaxis().set_visible(False)
Recommended Posts