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

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

ただいまの
回答率

90.51%

  • Python

    11753questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

ロジスティック回帰のアルゴリズムのロジックがよく分かりません。。

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 241

korr

score 3

前提・実現したいこと

ロジスティック回帰を用いて、irisの分類を行なっております。

該当のソースコード

# パッケージをインポート
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_classification

# データを取得
iris = datasets.load_iris()
# irisの0列目と2列目を格納
X = iris.data[:, [0, 2]]
# irisのクラスラベルを格納
y = iris.target
# trainデータ、testデータの分割
train_X, test_X, train_y, test_y = train_test_split(X, y, test_size=0.3, random_state=42)

# ロジスティック回帰モデルの構築
model = LogisticRegression()

# train_Xとtrain_yを使ってモデルに学習させる
model.fit(train_X, train_y)

# test_Xに対するモデルの分類予測結果
y_pred = model.predict(test_X)
print(y_pred)


# 可視化の作業
plt.scatter(X[:, 0], X[:, 1], c=y, marker=".",
            cmap=matplotlib.cm.get_cmap(name="cool"), alpha=1.0)

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, 0.02),
                       np.arange(x2_min, x2_max, 0.02))
Z = model.predict(np.array([xx1.ravel(), xx2.ravel()]).T).reshape((xx1.shape))
plt.contourf(xx1, xx2, Z, alpha=0.4,
             cmap=matplotlib.cm.get_cmap(name="Wistia"))
plt.xlim(xx1.min(), xx1.max())
plt.ylim(xx2.min(), xx2.max())
plt.title("classification data using LogisticRegression")
plt.xlabel("Sepal length")
plt.ylabel("Petal length")
plt.grid(True)
plt.show()


このコードの中の可視化する部分の以下のコードのロジックがよく分かりません。

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, 0.02),
                       np.arange(x2_min, x2_max, 0.02))
Z = model.predict(np.array([xx1.ravel(), xx2.ravel()]).T).reshape((xx1.shape))

よろしくお願い致します。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

+2

コードを少し整理しました。

import matplotlib.pyplot as plt
import numpy as np
from sklearn import datasets
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split

# データを取得
iris = datasets.load_iris()
X = iris.data[:, [0, 2]]
Y = iris.target

# 学習データとテストデータに分割する。
X_train, X_test, Y_train, Y_test = train_test_split(
    X, Y, test_size=0.3, random_state=42)

# ロジスティック回帰モデルで学習する。
model = LogisticRegression(solver='lbfgs', multi_class='multinomial')
model.fit(X_train, Y_train)

# テストデータを推論し、精度を出力する。
Y_pred = model.score(X_test, Y_test)
print('test accuracy: {:.2%}'.format(Y_pred))
fig, ax = plt.subplots(figsize=(8, 6))
ax.set_title('classification data using LogisticRegression')
ax.set_xlabel('Sepal length')
ax.set_ylabel('Petal length')

# サンプルを描画する。
ax.scatter(X[:, 0], X[:, 1], c=y, marker='.', cmap='cool')

xlim = ax.get_xlim()
ylim = ax.get_ylim()
X, Y = np.meshgrid(np.linspace(xlim[0], xlim[1], 1000),
                   np.linspace(ylim[0], ylim[1], 1000))

# 推論する。
XY = np.column_stack([X.ravel(), Y.ravel()])
Z = model.predict(XY).reshape(X.shape)

# 等高線を描画する。
ax.contourf(X, Y, Z, alpha=0.4, cmap='Wistia')
plt.show()

このコードの中の可視化する部分の以下のコードのロジックがよく分かりません。

numpy.meshgrid() でサンプルデータが存在する範囲に格子状の点を作成する。つまり、描画範囲を敷き詰めるように点を作成します。(下図の青が作成された点)

イメージ説明

numpy.meshgrid() の仕様

イメージ説明

そして、この各点での推論結果を計算します。
すると、各点の推論したラベルの値 (今回は0, 1, 2) が得られます。
これは以下のような関数とかんがられます。

イメージ説明

この関数の塗りつぶした等高線を contourf() で作成します。

contourf() の使い方

等高線ということは推論したラベルが同じ点は同じ色で塗られるので、結果、分類境界が描画されることとなります。

イメージ説明

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/01/23 01:06

    ご丁寧な解説ありがとうございます!図が大変参考になりイメージとしても理解することができました!

    キャンセル

+2

結果を2次元平面上で可視化しているようですね。

x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1

この2行は可視化する領域を決めるために、0列目と1列目(それぞれ0つめと1つめの特徴量に対応)でそれぞれ最小値と最大値を拾っています。最小・最大より少し広めに取っておけば安心なので、-1と+1があります。

xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, 0.02),
                       np.arange(x2_min, x2_max, 0.02))

これについてはmeshgridとarangeの使い方を理解していないとわからないので、以下の参考リンクなどを御覧ください。

numpy.meshgrid — NumPy v1.15 Manual
numpy.arange — NumPy v1.15 Manual
配列の要素から格子列を生成するnumpy.meshgrid関数の使い方 - DeepAge
連番や等差数列を生成するnumpy.arange関数の使い方 - DeepAge

Z = model.predict(np.array([xx1.ravel(), xx2.ravel()]).T).reshape((xx1.shape))

xx1xx2はそれぞれ2次元配列のようになっていて可視化する平面上の各点の値を表していますが、predictメソッドで予測するためにはそれぞれを一次元配列にして結合した後に転置し、特徴量ベクトルの配列にする必要があります。

予測した後に元のxx1,xx2と同じshapeにするためにreshapeメソッドを使っています。

predictメソッドに渡すまでの操作
>>> import numpy as np
>>> a = [1,2,3]
>>> b = [4,5,6]
>>> aa, bb = np.meshgrid(a, b)
>>> aa
array([[1, 2, 3],
       [1, 2, 3],
       [1, 2, 3]])
>>> bb
array([[4, 4, 4],
       [5, 5, 5],
       [6, 6, 6]])
>>> aa.ravel()
array([1, 2, 3, 1, 2, 3, 1, 2, 3])
>>> bb.ravel()
array([4, 4, 4, 5, 5, 5, 6, 6, 6])
>>> np.array([aa.ravel(), bb.ravel()])
array([[1, 2, 3, 1, 2, 3, 1, 2, 3],
       [4, 4, 4, 5, 5, 5, 6, 6, 6]])
>>> np.array([aa.ravel(), bb.ravel()]).T
array([[1, 4],
       [2, 4],
       [3, 4],
       [1, 5],
       [2, 5],
       [3, 5],
       [1, 6],
       [2, 6],
       [3, 6]])

ここで、predictメソッドの返り値はnp.array([aa.ravel(), bb.ravel()]).Tの行数と同じになり、以下のようにreshapeで変換できます。

>>> np.arange(9) # arangeで代用
array([0, 1, 2, 3, 4, 5, 6, 7, 8])
>>> np.arange(9).reshape(aa.shape)
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/01/23 01:04

    ご丁寧な説明ありがとうございます!単純化すると分かりやすくて大変参考になりました!

    キャンセル

同じタグがついた質問を見る

  • Python

    11753questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。