【Aidamy】 ディープラーニングで手書き文字を識別してみよう②

前回記事の続き。
Aidamyの手書き文字認識コースをやっていく。
今回はコース3:Matplotlibによるデータの可視化から。

Matplotlibによるデータの可視化

データ可視化のための準備

  • シードの設定
    シードを固定すれば常に同じ乱数列を生成することができる
    np.random.seed(整数)

  • 正規分布に従う乱数
    np.random.randn()

  • 二項分布に従う乱数
    以下は確率0.5で成功する試行を100回行った時の成功数をsize=10000個分求める
    np.random.binomial(100, 0.5, size=10000)

  • リストからランダムに選択
    np.random.choice(list, int)

  • datetime型
    datetime.datetime(年, 月, 日, 時, 分, 秒, ミリ秒)を指定するとdatetime型を返す

  • timedelta型
    datetime.timedelta(日, ..., ミリ秒)で時間の長さを表すtimedelta型を返す
    datetime型との演算が可能

  • 文字列からdatetime型生成
    2018-02-19 16-15-30の様に日時が表されている時、以下のようにdatetime型に変換できる
    datetime.datetime.strptime(s, "%Y-%m-%d %H-%M-%S")

  • 等間隔の数列生成
    np.arange(0, 11, 2)のようにすることで0から10までの偶数列を生成
    np.linspace(0, 10, 5)のようにすることで[0. 2.5 5 7.5 10.]を生成

matplotlibの使い方

import maplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 2*np.pi)
y1 = np.sin(x)
y2 = np.cos(x)

# 画像サイズを4インチ×4インチに設定
plt.figure(figsize=(4, 4))

# x軸、y軸の範囲を指定
plt.xlim([0, 2*np.pi])
plt.ylim([0, 1])

# タイトルを設定
plt.title('TITLE')

# x軸とy軸の名前を設定
plt.xlabel('x-axis')
plt.ylabel('y-axis')

# グリッドを表示
plt.grid(True)

# 目盛りを設定
plt.xticks(目盛りを挿入する位置, 挿入する目盛り)

# x, y1を赤でプロット
plt.plot(x, y1, color='r', label='y=sin(x)')

# x, y2を青でプロット
plt.plot(x, y2, color='b', label='y=cos(x)')

# 上記で設定したラベルに基づいて凡例を表示
plt.legend()

# グラフを表示
plt.show()
  • subplotを用いる場合
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 2*np.pi)
y = np.sin(x)

# Figureオブジェクトを作成
fig = plt.figure(figsize=(9, 6))
# 2×3のレイアウトの2行目2列目にサブプロットオブジェクトを作成
ax =  fig.add_subplot(2, 3, 5)

# subplot周りの余白調整
plt.subplots_adjust(wspace=横間隔を空ける割合, hspace=縦間隔を空ける割合)

# subplotのy軸の表示範囲設定
plt.set_ylim([0, 1])


# subplotのタイトルやx軸、y軸の名前の設定
ax.set_title('TITLE')
ax.set_xlabel('x-axis')
ax.set_ylabel('y-axis')

# subplotにグリッドを表示
ax.grid(True)

# subplot内のグラフの軸に目盛りを設定
ax.set_xticks('挿入位置のリスト')
ax.set_xticklabels('目盛りのリスト')

# データx,yをグラフにプロット
ax.plot(x,y)

# 空白部分をサブプロットで埋める
axi = []
for i in range(6):
    if i == 4:
        continue
    fig.add_subplot(2, 3, i+1)
plt.show()

様々なグラフを作る

import numpy as np
import matplotlib.pyplot as plt

以下、上記のインポートがしてあるとして進めていく。

折れ線グラフ

days = np.arange(1, 11)
weight = np.array([10, 14, 18, 20, 18, 16, 17, 18, 20, 17])

# 表示設定
plt.ylim([0, weight.max()+1])
plt.xlabel("days")
plt.ylabel("weight")

# 赤の円マーカーの青の破線の折れ線グラフをプロット
plt.plot(days, weight, linestyle='--', color='b', marker='o', markerfacecolor='r')

plt.show()

f:id:hanhan39:20180219213129p:plain

棒グラフ

x = [1, 2, 3, 4, 5, 6]
y1 = [12, 41, 32, 36, 21, 17]
y2 = [43, 1, 6, 17, 17, 9]
labels = ["Apple", "Orange", "Banana", "Pineapple", "Kiwifruit", "Strawberry"]

# ラベル付きの棒グラフを作成
plt.bar(x, y1, tick_label=labels)

# bottom(下の余白)にy1を設定することで積み上げ棒グラフに
plt.bar(x, y2, bottom=y1)

# 系統ラベルを設定
plt.legend(("y1", "y2"))
plt.show()

f:id:hanhan39:20180219213623p:plain

ヒストグラム

np.random.seed(0)
data = np.random.randn(10000)

fig = plt.figure(figsize=(15, 5))
ax1 = fig.add_subplot(1, 2, 1)
ax2 = fig.add_subplot(1, 2, 2)

# 正規化されたビン数自動設定のヒストグラム
ax1.hist(data, bins='auto', normed=True)
# 正規化されたビン数100の累積ヒストグラム
ax2.hist(data, bins=100, normed=True, cumulative=True)

plt.show()

f:id:hanhan39:20180219214200p:plain

散布図

np.random.seed(0)
x = np.random.choice(np.arange(100), 100)
y = np.random.choice(np.arange(100), 100)
# x, yと同じサイズのデータを用意する
# zの値に応じてマーカーの大きさや濃さを変化させられる
z = np.random.choice(np.arange(100), 100) 

fig = plt.figure(figsize=(15,5))
ax1 = fig.add_subplot(1, 2, 1)
ax2 = fig.add_subplot(1, 2, 2)

# zの値に応じてマーカーの大きさが変化
ax1.scatter(x, y, s=z)
# zの値に応じて、マーカーの濃さが青系統で変化
sc = ax2.scatter(x, y, c=z, cmap="Blues")
# カラーバーを表示
plt.colorbar(sc)

plt.show()

f:id:hanhan39:20180219215509p:plain

円グラフ

data = [60, 20, 10, 5, 3, 2]
labels = ["Apple", "Orange", "Banana", "Pineapple", "Kiwifruit", "Strawberry"]
explode = [0, 0, 0.1, 0, 0, 0]

fig = plt.figure(figsize=(15,5))
ax1 = fig.add_subplot(1, 2, 1)
ax2 = fig.add_subplot(1, 2, 2)

# axis('equal')がないと楕円になる
ax1.pie(data, labels=labels, explode=explode)
# labels付きのBananaを目立たせた円グラフ
ax2.pie(data, labels=labels, explode=explode)
ax2.axis("equal")
plt.show()

f:id:hanhan39:20180219220051p:plain

3Dグラフ

from mpl_toolkits.mplot3d import Axes3D

以下では上記もインポート済みとする。
格子を作成する際に用いているnp.meshgridについては配列の要素から格子列を生成するnumpy.meshgrid関数の使い方 - DeepAgeが分かりやすかった。

  • 3D描画機能を持ったサブプロット
t = np.linspace(-2*np.pi, 2*np.pi)
X, Y = np.meshgrid(t, t)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)

fig = plt.figure(figsize=(6,6))
ax = fig.add_subplot(1, 1, 1, projection='3d')

# プロットして表示
ax.plot_surface(X, Y, Z)
plt.show()

f:id:hanhan39:20180219224426p:plain

fig = plt.figure(figsize=(5, 5))
ax1 = fig.add_subplot(111, projection="3d")

# x, y, zの位置
xpos = [i for i in range(10)]
ypos = [i for i in range(10)]
zpos = np.zeros(10)
   
# x, y, zの増加量
dx = np.ones(10)
dy = np.ones(10)
dz = [i for i in range(10)]

# 3次元bar
ax1.bar3d(xpos, ypos, zpos, dx, dy, dz)

plt.show()

f:id:hanhan39:20180219225514p:plain

  • 3D散布図
np.random.seed(0)

X = np.random.randn(1000)
Y = np.random.randn(1000)
Z = np.random.randn(1000)

fig = plt.figure(figsize=(6, 6))
ax  = fig.add_subplot(1, 1, 1, projection="3d")

# X,Y,Zを1次元に変換
# 今回のケースだともともと1次元だから必要ない
x = np.ravel(X)
y = np.ravel(Y)
z = np.ravel(Z)

# 3D散布図
ax.scatter3D(x, y, z)

plt.show()

f:id:hanhan39:20180219225926p:plain

  • 3Dグラフへのカラーマップ適用
  • 色が単調な3Dグラフは凹凸が見えにくいことがある
  • zの値についてカラーマップを適用する
# カラーマップを表示するためのライブラリ
from matplotlib import cm

t = np.linspace(-2*np.pi, 2*np.pi)
X, Y = np.meshgrid(t, t)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)

fig = plt.figure(figsize=(6, 6))
ax  = fig.add_subplot(1,1,1, projection="3d")

ax.plot_surface(X, Y, Z, cmap=cm.coolwarm)

plt.show()

f:id:hanhan39:20180219230342p:plain

なんか今までなんとなくでmatplotlib使ってたからここでやれてよかったかも。