機械学習ライブラリScikit-learn
前回、機械学習ライブラリScikit-learnの手書き数字のデータセットの解説を行いました。
ただ手書き数字のデータセットということで、画像のデータセットだと期待していたのですが、残念ながら数値データになってしまっていました。
ということで今回はその数値データから画像データに変換をしてみたいと思います。
まずはデータの読み込みから。
前回、データを読み込んで中に含まれるデータを色々確認してみたところ、dataとimagesに画像データを数値データに置き換えたデータが含まれていることが分かりました。
ということでdataとimagesから同じデータを引っ張ってきてみましょう。
from sklearn.datasets import load_digits
digits = load_digits()
print(digits.data[0])
print(digits.images[0])
実行結果
[ 0. 0. 5. 13. 9. 1. 0. 0. 0. 0. 13. 15. 10. 15. 5. 0. 0. 3.
15. 2. 0. 11. 8. 0. 0. 4. 12. 0. 0. 8. 8. 0. 0. 5. 8. 0.
0. 9. 8. 0. 0. 4. 11. 0. 1. 12. 7. 0. 0. 2. 14. 5. 10. 12.
0. 0. 0. 0. 6. 13. 10. 0. 0. 0.]
[[ 0. 0. 5. 13. 9. 1. 0. 0.]
[ 0. 0. 13. 15. 10. 15. 5. 0.]
[ 0. 3. 15. 2. 0. 11. 8. 0.]
[ 0. 4. 12. 0. 0. 8. 8. 0.]
[ 0. 5. 8. 0. 0. 9. 8. 0.]
[ 0. 4. 11. 0. 1. 12. 7. 0.]
[ 0. 2. 14. 5. 10. 12. 0. 0.]
[ 0. 0. 6. 13. 10. 0. 0. 0.]]
上がdataの中にある一番最初のデータ。
下がimagesの中にある一番最初のデータ。
同じ数字が並んでいますが、imagesのデータは8個ずつ区切られています。
それぞれが1ピクセル中の色の濃さを示しているので、imagesでは8×8ピクセルが表現されていることになります。
しかしdataのデータではそれが表現されていません。
まずはdataのデータの形式を変えてみましょう。
一次元リストと二次元リストの変換:numpy reshape
先ほどの数値が入ったリスト、dataとimagesのうち、dataでは一つのリスト内に全ての数値が入っています。
[ 0. 0. 5. 13. 9. 1. 0. 0. 0. 0. 13. 15. 10. 15. 5. 0. 0. 3.
15. 2. 0. 11. 8. 0. 0. 4. 12. 0. 0. 8. 8. 0. 0. 5. 8. 0.
0. 9. 8. 0. 0. 4. 11. 0. 1. 12. 7. 0. 0. 2. 14. 5. 10. 12.
0. 0. 0. 0. 6. 13. 10. 0. 0. 0.]
このようなリストを一次元リストと呼びます。
imagesの方はリストの中にさらにリストが含まれていて、その中に数値が入っています。
[[ 0. 0. 5. 13. 9. 1. 0. 0.]
[ 0. 0. 13. 15. 10. 15. 5. 0.]
[ 0. 3. 15. 2. 0. 11. 8. 0.]
[ 0. 4. 12. 0. 0. 8. 8. 0.]
[ 0. 5. 8. 0. 0. 9. 8. 0.]
[ 0. 4. 11. 0. 1. 12. 7. 0.]
[ 0. 2. 14. 5. 10. 12. 0. 0.]
[ 0. 0. 6. 13. 10. 0. 0. 0.]]
もしリストの中にリストがあって、さらにその中にリストが含まれているとか、さらにリストが含まれている、なんて状態だと多次元リストと呼ばれます。
画像データだと二次元リストと一次元リストを行き来することも多々あると思いますので、まずはこの変換方法から解説していきましょう。
まずは一次元リストを二次元リストにするには、numpyのreshapeを使います。
例えばこんな感じです。
import numpy as np
digits.data_reshape = np.reshape(digits.data[0], (4,16))
print(digits.data[0])
print(digits.data_reshape)
実行結果
[ 0. 0. 5. 13. 9. 1. 0. 0. 0. 0. 13. 15. 10. 15. 5. 0. 0. 3.
15. 2. 0. 11. 8. 0. 0. 4. 12. 0. 0. 8. 8. 0. 0. 5. 8. 0.
0. 9. 8. 0. 0. 4. 11. 0. 1. 12. 7. 0. 0. 2. 14. 5. 10. 12.
0. 0. 0. 0. 6. 13. 10. 0. 0. 0.]
[[ 0. 0. 5. 13. 9. 1. 0. 0. 0. 0. 13. 15. 10. 15. 5. 0.]
[ 0. 3. 15. 2. 0. 11. 8. 0. 0. 4. 12. 0. 0. 8. 8. 0.]
[ 0. 5. 8. 0. 0. 9. 8. 0. 0. 4. 11. 0. 1. 12. 7. 0.]
[ 0. 2. 14. 5. 10. 12. 0. 0. 0. 0. 6. 13. 10. 0. 0. 0.]]
つまり「np.reshape(変換したいリスト, (リスト内のリストの数, 最後のリストに含まれる要素数))」ということです。
二次元の形で表現するともうす少し覚えやすくなり、「np.reshape(変換したいリスト, (縦, 横))」となります。
逆に二次元リストを一次元リストにする場合もnumpyのreshapeが使えます。
その場合は先ほどの縦横の数値を「-1」にします。
print(np.reshape(digits.data_reshape, -1))
実行結果
[ 0. 0. 5. 13. 9. 1. 0. 0. 0. 0. 13. 15. 10. 15. 5. 0. 0. 3.
15. 2. 0. 11. 8. 0. 0. 4. 12. 0. 0. 8. 8. 0. 0. 5. 8. 0.
0. 9. 8. 0. 0. 4. 11. 0. 1. 12. 7. 0. 0. 2. 14. 5. 10. 12.
0. 0. 0. 0. 6. 13. 10. 0. 0. 0.]
他にもnumpyにはravelやflattenという一次元化する関数がありますが、今回は割愛します。
二次元リストから画像に変換
次に二次元リストを画像に変換してみましょう。
ちなみにこの例はScikit learnの公式サイトにあったものです。
import matplotlib.pyplot as plt
plt.gray()
plt.matshow(digits.images[0])
plt.show()
実行結果
それぞれの行に関しては、
「plt.gray()」はグレースケールでの表示
「plt.matshow(digits.images[0])」でdigits.images[0]の二次元リストを表示
「plt.show()」で画像を表示
というかんじでしょうか。
今回は公式ウェブサイトを参考にmatshow()を使いましたが、他にも色々と画像を表示する方法はあるようです。
次回はせっかくなのでmatshow()の解説をしてみたいと思います。
というわけで今回はこんな感じで。
コメント