質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.96%

決定領域を作成するグラフコードの意味がわかりません

受付中

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 1,312

bouyomisan

score 85

 前提・実現したいこと

決定領域を描写するコードがあるのですがこの意味がわかりません。

 該当のソースコード

以下のものが該当のコードになります。ここでわからないのは2つの配列を meshgrid で変換しているのと、plt.contourf(xx1, xx2, Z, alpha=0.4, cmap=cmap)でグラフに描写しているところです。

こちらのサイトにも等高線を引く時にも meshgrid と countourf の二つを使ってグラフを書いていました。
http://ailaby.com/contour/

なぜこれで決定領域が引けるのかがわかりません。

イメージ説明

from matplotlib.colors import ListedColormap

def plot_decision_regions(X, y, classifier, resolution=0.02):
    # マーカーとカラーマップの準備
    markers = ('s', 'x', 'o', '^', 'v')
    colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan')
    cmap = ListedColormap(colors[:len(np.unique(y))])

    #決定領域のプロット
    x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1

    #グリッドポイントの生成
    xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution),
                           np.arange(x2_min, x2_max, resolution))
  #各特徴量を一次元配列に変換して予測を実行
    Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
    #予想結果を元のグリッドポイントのデータサイズに変換
    Z = Z.reshape(xx1.shape)
    # グリッドポイントの等高線のプロット
    plt.contourf(xx1, xx2, Z, alpha=0.4, cmap=cmap)
    plt.xlim(xx1.min(), xx1.max())
    plt.ylim(xx2.min(), xx2.max())

    # plot class samples
    for idx, cl in enumerate(np.unique(y)):
        plt.scatter(x=X[y == cl, 0], y=X[y == cl, 1],
                    alpha=0.8, c=cmap(idx),
                    edgecolor='black',
                    marker=markers[idx], 
                    label=cl)

 試したこと

 meshgrid

meshgrid(X,Y) メソッドはこちらのサイトによるとマス目を作るそうですがよくわかりませんでした。実際に試して見るとこのようになり、第一引数の配列は横一列にして縦に並べるようになり、第二引数の配列は縦一列に並べて横に並べる形になりました。

X = np.array([[1,2],
              [3,4]])


Y = np.array([[5,6],
              [7,8]])

xx1, xx2 = np.meshgrid(X,Y)

print(xx1)
#
#[[1 2 3 4]
# [1 2 3 4]
# [1 2 3 4]
# [1 2 3 4]]

print(xx2)

#[[5 5 5 5]
# [6 6 6 6]
# [7 7 7 7]
# [8 8 8 8]]

 countour

countour これに関してはなんのことかわかりません。ただ、先ほどのサイトのコードを試してみると1、2引数の配列を元に第三引数のグラフへと代入しているようです。

import numpy as np
import matplotlib.pyplot as plt

n = 100
x = np.linspace(-1, 1, n)
y = np.linspace(-1, 1, n)

X, Y = np.meshgrid(x, y)
Z = np.sqrt(X**2 + Y**2)

#
# meshgrid で作った X と Y、そして高さ Z を contour に渡す
#
plt.contour(X, Y, Z)

plt.gca().set_aspect('equal')
plt.show()

イメージ説明

 補足情報(FW/ツールのバージョンなど)

python機械学習プログラミング p30
github
https://github.com/rasbt/python-machine-learning-book/blob/master/code/ch02/ch02.ipynb

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+3

順番に説明します

2変数関数 f(x,y) がある場合、横軸に x, 縦軸に y を取り
f(x,y) の値を等高線図で表したものが countour()、上記の等高線図を色で塗り分けたものがcountourf()となります。

で、上記の countour() or countourf()ですが、データとして2次元データを渡す必要があります。
例えば

f(x,y) = x + y
という関数があったとして
Xがとる値を
x = [1,2,3,4,5,6,7,8,9]
Yがとる値を
y = [10,20,30,40,50]
とした場合、
f(x,y) がとる値を表にすると

1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
30 31 32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47 48 49
50 51 52 53 54 55 56 57 58 59

となりますので、countour() or countourf()のデータとしては上記の表同様の2次元データを渡すことにより、f(x,y)の値をもとに等高線図を描画することができます。

data = [[11,12,13,14,15,16,17,18,19],
        [21,22,23,24,25,26,27,28,29],
        [31,32,33,34,35,36,37,38,39],
        [41,42,43,44,45,46,47,48,49],
        [51,52,53,54,55,56,57,58,59]]
plt.contourf(data)

ですが実際は上記のように計算結果を常にハードコーディングするわけにはいきませんので、配列サイズに合わせて X値だけ埋めたもの

X = np.array([[1,2,3,4,5,6,7,8,9],
              [1,2,3,4,5,6,7,8,9],
              [1,2,3,4,5,6,7,8,9],
              [1,2,3,4,5,6,7,8,9],
              [1,2,3,4,5,6,7,8,9]])


と Y値だけ埋めたもの

Y = np.array([[10,10,10,10,10,10,10,10,10],
             [20,20,20,20,20,20,20,20,20],
             [30,30,30,30,30,30,30,30,30],
             [40,40,40,40,40,40,40,40,40],
             [50,50,50,50,50,50,50,50,50]])


を予め準備しておき f(x,y) の値を

data = X + Y


のように実際に計算を行うことで、データを作成するのが一般的となります。

・・と、ここまで理解できましたら、あとは簡単で、

一番最初に定義した

x = [1,2,3,4,5,6,7,8,9]
y = [10,20,30,40,50]


の2つの配列から上記で計算に使用する

X = np.array([[1,2,3,4,5,6,7,8,9],
              [1,2,3,4,5,6,7,8,9],
              [1,2,3,4,5,6,7,8,9],
              [1,2,3,4,5,6,7,8,9],
              [1,2,3,4,5,6,7,8,9]])
Y = np.array([[10,10,10,10,10,10,10,10,10],
             [20,20,20,20,20,20,20,20,20],
             [30,30,30,30,30,30,30,30,30],
             [40,40,40,40,40,40,40,40,40],
             [50,50,50,50,50,50,50,50,50]])


のような2次元配列化したX,Yを作成する為の関数がmeshgrid()ということになります。
meshgrid()を使うと上記のコードは

import numpy as np
import matplotlib.pyplot as plt

x = [1,2,3,4,5,6,7,8,9]
y = [10,20,30,40,50]
X,Y = np.meshgrid(x,y)
data = X + Y
plt.contourf(X, Y, data)
plt.show()


となります。

最後になりますが、分類結果の色分けは単にZ(=f(x,y))の値によって countourf()にて色分けしているだけとなります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

与えられた領域からグリッド状にデータ点をサンプルし、全ての点に対して識別器で分類させています。Zが分類結果なのですが、それに基づいてcontourfで色を塗り分けているだけです。

あまり気にせずに進んだほうがいいところだと思いますよ。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.96%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる