5828


画像処理を行っていて、特徴量抽出に scikit-learn の PCA
を使いましたが、様々な処理を行った後その結果から画像を復元したい（参考（これを`python`でやりたい）：[R prcomp
での主成分分析結果から元データを復元する](http://sinhrks.hatenablog.com/entry/2014/10/19/000929)）。

具体的には以下のようなコードになっています。

[code]

    from sklearn.decomposition import PCA
    from PIL import Image
    import numpy as np
    
    # loading image and convert to gray-scale
    imgAry = np.asarray(Image.open('image.png').convert('L'))
    print imgAry.shape  # (224, 224)
    
    # doing pca decomposition
    pca = PCA(n_components=2)
    pca_res = pca.fit(imgAry).transform(imgAry).T[0]
    print pca_res.shape  # (224,)
    
[/code]

この時、`pca_res`を使って元画像の`array`を得る方法はありますか？

よろしくお願いします。


CC BY-SA 3.0
2015-02-03T04:01:35.797
5822
2015-02-03T12:45:16.107
2015-02-03T07:44:40.117
3313
2713
question
python 画像 pca scikit-learn
scikit-learnを用いて主成分分析 (PCA) した結果から元の画像データを復元したい

[code]

    pca = PCA()
    pca.fit(imgAry) # この処理で内部に計算結果を格納してる模様
    pca_res = pca.transform(imgAry)
    restoredImgAry = pca.inverse_transform(pca_res)
    
[/code]

で`imgAry`を少量の誤差で復元することが可能です。これは元の画像を224列のデータとみなして主成分分析を行い、特に次元数を圧縮していないものになります。

尚、どの程度まで次元を圧縮してよいのかについては計算後

[code]

    pca.explained_variance_ratio_
    
[/code]

で調べることができます。(いわゆる各主成分の`寄与率`に相当します。)  
試しに`n_components=5`などと明示して計算後に

[code]

    sum(pca.explained_variance_ratio_)
    
[/code]

をしてみると、5次元まで次元を削減した場合に、どれくらいの精度でデータを復元できるかがわかると思います。(`累積寄与率`です。これが1に近いほど、生成結果が元のデータの情報量を維持できていることになります。0.5ですと半分のデータが失われています。)

* * *

以下、わかりやすさのため、  
グレースケール画像を用いてどれくらい復元できるかの例と累積寄与率を試しに計算させてみました。

![元画像](https://i.stack.imgur.com/c6bhl.jpg)
元画像(<https://incisors.files.wordpress.com/2008/06/gs.jpg>)  
![第1主成分のみ](https://i.stack.imgur.com/n1dED.png) n_components=1 (0.4879)  
![第2主成分まで](https://i.stack.imgur.com/D1EIS.png) n_components=2 (0.6499)  
![第5主成分まで](https://i.stack.imgur.com/uRgJH.png) n_components=5 (0.8309)  
![第10主成分まで](https://i.stack.imgur.com/B0bFL.png) n_components=10 (0.9117)  
![第50主成分まで](https://i.stack.imgur.com/lRYn6.png) n_components=50 (0.9925)  
![第100主成分まで](https://i.stack.imgur.com/ozVQ9.png) n_components=100 (0.9992)

この例ですと250次元のデータを50次元まで削減してもかなり復元できていることがわかります。  
<https://gist.github.com/3100/067b79489dbf75ab8f8f>

* * *

気になったのは、そもそも画像データの特徴量をこのように単なる1次元配列の集合として分解してから求めて良いのかどうかですが、目的次第な気もします。  
今回の質問の範囲外なので詳しくは立ち入りません。


CC BY-SA 3.0
2015-02-03T05:34:44.523
5828
2015-02-03T12:45:16.107
2015-02-03T12:45:16.107
3313
3313
5822
answer