機械学習−PCA利用(1)


◾PCA eigenface

  • Olivettiデータ
  • AT&Tとケンブリッジ大学の共同研究データ
  • は、顔認識
  • に用いることができる.
  • 特定人物のデータ(10枚)のみをPCA練習として使用
  • from sklearn.datasets import fetch_olivetti_faces
    
    faces_all = fetch_olivetti_faces()

    -データの選択

    K = 20
    faces = faces_all.images[faces_all.target == K]
    
    faces

    import matplotlib.pyplot as plt
    
    N = 2
    M = 5
    fig = plt.figure(figsize=(10, 5))
    plt.subplots_adjust(top = 1, bottom=0, hspace=0, wspace=0.05)
    for n in range(N*M):
        ax = fig.add_subplot(N, M, n+1)
        ax.imshow(faces[n], cmap=plt.cm.bone)
        ax.grid(False)
        ax.xaxis.set_ticks([])
        ax.yaxis.set_ticks([])
    plt.suptitle("Olivetti")
    plt.tight_layout()
    plt.show()


    -PCA分析(2つの主成分を選択)

    from sklearn.decomposition import PCA
    
    pca = PCA(n_components=2)
    
    X = faces_all.data[faces_all.target==K]
    W = pca.fit_transform(X)
    
    X_inv = pca.inverse_transform(W)
    描画
  • 結果
  • import matplotlib.pyplot as plt
    def draw_faces(faces, N, M, title='', inv = False):
        fig = plt.figure(figsize=(10, 5))
        plt.subplots_adjust(top = 1, bottom=0, hspace=0, wspace=0.05)
        for n in range(N*M):
            ax = fig.add_subplot(N, M, n+1)
            if inv == False:
                ax.imshow(faces[n], cmap=plt.cm.bone)
            else:
                ax.imshow(faces[n].reshape(64, 64), cmap=plt.cm.bone)
            ax.grid(False)
            ax.xaxis.set_ticks([])
            ax.yaxis.set_ticks([])
        plt.suptitle(title)
        plt.tight_layout()
        plt.show()
    draw_faces(X_inv, 2, 5, 'PCA result', True)


    -原点と2つのフィーチャー面

  • 10枚の写真、下図3枚で表現できます.
  • face_mean = pca.mean_.reshape(64, 64)
    face_p1 = pca.components_[0].reshape(64, 64)
    face_p2 = pca.components_[1].reshape(64, 64)
    
    plt.figure(figsize=(12, 7))
    plt.subplot(131)
    plt.imshow(face_mean, cmap=plt.cm.bone)
    plt.grid(False); plt.xticks([]); plt.yticks([]); plt.title('mean')
    plt.subplot(132)
    plt.imshow(face_p1, cmap=plt.cm.bone)
    plt.grid(False); plt.xticks([]); plt.yticks([]); plt.title('face_p1')
    plt.subplot(133)
    plt.imshow(face_p2, cmap=plt.cm.bone)
    plt.grid(False); plt.xticks([]); plt.yticks([]); plt.title('face_p2')
    plt.show()


    -ウェイト選択

    import numpy as np
    
    N = 2
    M = 5
    w = np.linspace(-5, 10, N*M)
    w


    -最初の成分変化

    fig = plt.figure(figsize=(10, 5))
    plt.subplots_adjust(top=1, bottom=0, hspace=0, wspace=0.05)
    
    for n in range(N*M):
        ax = fig.add_subplot(N, M, n+1)
        ax.imshow(face_mean + w[n] * face_p1, cmap=plt.cm.bone)
        plt.grid(False); plt.xticks([]); plt.yticks([]); 
        plt.title('Weight :' + str(round(w[n])))
    
    plt.tight_layout()
    plt.show()


    -2番目の成分変化

    fig = plt.figure(figsize=(10, 5))
    plt.subplots_adjust(top=1, bottom=0, hspace=0, wspace=0.05)
    
    for n in range(N*M):
        ax = fig.add_subplot(N, M, n+1)
        ax.imshow(face_mean + w[n] * face_p2, cmap=plt.cm.bone)
        plt.grid(False); plt.xticks([]); plt.yticks([]); 
        plt.title('Weight :' + str(round(w[n])))
    
    plt.tight_layout()
    plt.show()


    -2つの成分を表す

    nx, ny = (5, 5)
    
    x = np.linspace(-5, 8, nx)
    y = np.linspace(-5, 8, ny)
    w1, w2 = np.meshgrid(x, y)
    w1, w2

  • 形状
  • を調整する.
    w1.shape

    w1 = w1.reshape(-1, )
    w2 = w2.reshape(-1, )
    w1.shape

  • 再合成
  • fig = plt.figure(figsize=(12, 10))
    plt.subplots_adjust(top=1, bottom=0, hspace=0, wspace=0.05)
    
    N = 5
    M = 5
    
    for n in range(N*M):
        ax = fig.add_subplot(N, M, n+1)
        ax.imshow(face_mean + w1[n] * face_p1 + w2[n] * face_p2, cmap=plt.cm.bone)
        plt.grid(False); plt.xticks([]); plt.yticks([]); 
        plt.title('Weight :' + str(round(w1[n], 1)) + ', ' + str(round(w2[n], 1)))
    
    plt.show()