【エクセルで学習】ロジスティック回帰分析の仕組み

AI


ロジスティック回帰は、統計や機械学習で頻繁に用いられる二値分類の手法ですが、「数学的な理論が難しい」と悩む方も多いのではないでしょうか。

本記事では、ロジスティック回帰の仕組みをExcelの計算と対応させて理解することを目的に、確率的勾配降下法(SGD: Stochastic Gradient Descent)を用いたロジスティック回帰の手計算方法 を解説します。

実際の計算が入った Excelファイルを次のリンクからダウンロードできますので、記事を読みながらExcelシートを触って理解を深めてください。

📂 Excelファイルのダウンロードはこちら↓


📌 この記事でわかること

この記事の内容

✅ ロジスティック回帰の基本的な仕組み
✅ アイリスデータを用いて、ロジスティック回帰を解説
✅ 確率的勾配降下法(SGD)によるパラメータ最適化の流れ
✅ Excelを使ったロジスティック回帰の実装方法(関数・計算式付き)


本記事はロジスティック回帰の仕組みを理解することを目的としているため、Excelの ソルバー機能 については説明していません。実務でソルバーを使うのは良い選択肢ですが、本記事では理解を深めるために手計算の方法だけを記載しています。

ロジスティック回帰の概要

まずはロジスティック回帰の基本的な仕組みを解説し、「数式だけでなく、Excelで計算するとどうなるのか?」 を意識しながら進めていきます。

ロジスティック回帰の目的

ロジスティック回帰は、二値分類問題を解く際に用いられる分析手法のモデル です。
例えば、「この花は セトナ (Setosa:アヤメの一種) か?」という分類問題では、入力されたデータからSetosaである確率を計算します。

ロジスティック回帰の数学的なモデル

ロジスティック回帰では、入力データベクトル xとパラメータベクトル θ(theta) を使って、あるクラスに属する確率 \(P(y=1 \mid \bf{x}) = f_θ(\bf{x}) \) を次のように計算します。

\[\begin{aligned} f_θ(\bf{x})
&= sigmoid(\bf{θ}\cdot\bf{x}) \\
&= \frac{1}{1+exp(-\bf{θ}\cdot\bf{x})} \\
&= \frac{1}{1+exp(-θ_0-θ_1x_1-θ_2x_2)}
\end{aligned} \]

  • \(\bf{x}\)は、入力データベクトルです。後述の例題に合わせて\({\bf{x}} =({1},{x_1},{x_2} ) \) とします。
  • \(\bf{θ}\)は、パラメータのベクトルです。後述の例題に合わせて\({\bf{θ}} =({θ_0},{θ_1},{θ_2} ) \) とします。
  • \(P(y=1 \mid \bf{x})\) は、確率(probability)を表します。カッコの中を縦棒[|]で区切って、\(\bf{x}\)を与えられた時にy=1 となる条件付き確率を表します。

この数式は シグモイド関数 [=1/(1+exp(−z)) ]を使っており、入力値を0~1の確率に変換する役割を果たします。シグモイド関数をグラフにすると下図の形になります。

モデル構造図は次の通りです。

ニューラルネットワークの説明では構造図を良く見ますので、ロジスティック回帰でも構造図を表現してみます。
ロジスティック回帰は入力層と出力層の2階層になっています。ロジスティック回帰のモデルを学習する際は、目的変数を定義してパラメータθを更新する工程となります。
ロジスティック回帰を使った推論フェーズでは、目的関数は使う事はなく、入力層・出力層だけで計算が完結します。

グラフはGoogle検索窓で「1/(1+exp(−x))」で検索して作りました。Google検索はちょっとしたグラフを作る時に便利です。


ロジスティック回帰で使うデータの準備

ここでは、 Excelを使ってロジスティック回帰の前準備として、ロジスティック回帰モデルの訓練および推定を行う為のデータを用意します。

※本記事の最初にデータを含めたExcelシートをダウンロードできるリンクを用意しています。このファイルを使うなら、データ出力作業は実施する必要はありません。

今回使用するデータセット(アイリスデータ)

今回は、フィッシャーのアイリスデータセットを使い、がく片長 (Sepal Length) と がく片幅 (Sepal Width) をもとに「アイリスの種類がSetosaかどうか」を判定するモデル を作成します。

アイリス(あやめ)

アイリスデータの特徴量は、次の4つの項目からなっています。

  • がく片の長さ(cm): Sepal Length
  • がく片の幅(cm): Sepal Width
  • 花弁の長さ(cm): Petal Length
  • 花弁の幅(cm): Petal Width

アイリスデータの目的変数(ラベル)の中には、次の3種類のいずれかの値が入っています。

  • setosa(セトーサ)
  • versicolor(ヴァーシカラー)
  • virginica(ヴァージニカ)

アイリスの場合は、花弁(はなびら)よりもがくが大きいのが特徴です。花弁・がくの形状は、論文「The Species Problem in Iris」(1936年)の次図をご覧ください。

3種類のアイリスの花びら/がく片のスケッチ(論文「The Species Problem in Iris」より出典)

アイリスデータセット(「あやめ」の形状データ)は、「花びら(petal)/がく片(sepal)の長さと幅(cm)」という4つの特徴量と、あやめの種類である「setosa/versicolor/virginica」という3つのラベルで構成される表形式データセットです。データ件数は150件しかありませんが、システムの実装方法の解説などでよく使われるデータセットです。

本記事で使用する説明変数・目的変数

本記事ではロジスティック回帰の説明を行う都合上、二値分類になるので、目的変数のラベルは「1:Setosaか, 0:それ以外か」のフラグに変換して使います。説明変数も簡単のために2つだけ使用します。

  • 今回使う説明変数(特徴量):
    • x1: がく片長 (Sepal Length)
    • x2: がく片幅 (Sepal Width)
  • 今回使う目的変数(ラベル):
    • y: 1 (Setosa), 0 (それ以外)

アイリスデータの取得

アイリスデータは様々な方法で取得可能ですが、今回はPythonライブラリのscikit-learnから取得する方法を紹介します。

お手元のPython環境や、下の記事で紹介をしていますGoogle Colaboratory等の環境で、スクリプトを実行してください。

まずPython環境にskアイリスデータセットのDESCR (description) を見てみます。

!pip install scikit-learn #scikit-learn インストールされていない場合は実行
from sklearn.datasets import load_iris
iris = load_iris()
print(iris.DESCR)

結果は次の通りです。

Iris plants dataset
--------------------

**Data Set Characteristics:**

:Number of Instances: 150 (50 in each of three classes)
:Number of Attributes: 4 numeric, predictive attributes and the class
:Attribute Information:
    - sepal length in cm
    - sepal width in cm
    - petal length in cm
    - petal width in cm
    - class:
            - Iris-Setosa
            - Iris-Versicolour
            - Iris-Virginica

:Summary Statistics:

============== ==== ==== ======= ===== ====================
                Min  Max   Mean    SD   Class Correlation
============== ==== ==== ======= ===== ====================
sepal length:   4.3  7.9   5.84   0.83    0.7826
sepal width:    2.0  4.4   3.05   0.43   -0.4194
petal length:   1.0  6.9   3.76   1.76    0.9490  (high!)
petal width:    0.1  2.5   1.20   0.76    0.9565  (high!)
============== ==== ==== ======= ===== ====================
・・・(以下略)

インスタンスが150件、特徴量4件、クラス(アイネスの種類)が3種である事がわかります。

次にアイネスデータを出力します。

# ヘッダー(クラス、Setosaflag、特徴量の名前)を表示
print("class\tSetosaflag\t" + "\t".join(iris.feature_names))

# 各データをタブで区切り、クラス、Setosaflag、特徴量の順に表示
for i in range(len(iris.data)):
    row = iris.data[i]
    class_name = iris.target_names[iris.target[i]]  # クラス名を取得
    setosa = 1 if class_name == "setosa" else 0  # Setosaflag (1 or 0)
    print(f"{class_name}\t{setosa}\t" + "\t".join(map(str, row)))
  

アイリスデータだけでなく、後で使いやすいように目的変数となるSetosaかどうかのフラグ列を追加しています。結果画面には次のようにアイリスデータが150行出力されます。今回は件数が少ないので、画面上でコピーしてExcelに張り付けましょう。

class	Setosaflag	sepal length (cm)	sepal width (cm)	petal length (cm)	petal width (cm)
setosa	1	5.1	3.5	1.4	0.2
setosa	1	4.9	3.0	1.4	0.2
setosa	1	4.7	3.2	1.3	0.2
setosa	1	4.6	3.1	1.5	0.2
setosa	1	5.0	3.6	1.4	0.2
setosa	1	5.4	3.9	1.7	0.4
・・・

Colaboratoryで実行した結果をコピーしてExcelに貼り付ける場合は、通常の貼り付けですとExcelの1セルにまとまって張り付いてしまいますので、Excelのセル上で右クリックして「形式を選択して貼り付け」メニューを実行して、「テキスト」形式を選択して張り付けてください。

今回ロジスティック回帰訓練用にこのデータを使用しますが、訓練時は同一値の目的変数(Setosaflag)がまとまっていると、学習がうまく進みません。訓練データはランダムにシャッフルされる事により、確率的に局所解にはまりにくくなりますので、Excel上でランダムに並び替えましょう。
まず、Excelにアイリスデータを張り付け後、G列にランダム値を入れる関数(=RAND())を入れて、全行コピーします。

そしてG列でソートします。すると目的変数(Setosaflag)がいい感じにばらけて150行が並ぶ事になり、この順番で学習を進めれば、学習は効率的におこなわれます。


確率的勾配降下法(SGD)によるパラメータ最適化の説明

ここでは数学的な理論を解説します。この理論をExcel上の計算と対応させることで、より直感的に理解できるようになります。

確率的勾配降下法(SGD)の概要

ロジスティック回帰モデルの式は上でも示した通りです。
\[\begin{aligned} f_θ(\bf{x})
&= \frac{1}{1+exp(-θ_0-θ_1x_1-θ_2x_2)}
\end{aligned} \]
アイリスの分類判定の精度を高めるために適切なパラメータ θ を見つける必要があります。今回が最適なパラメータ θ を求めるために、
確率的勾配降下法(SGD: Stochastic Gradient Descent)というアルゴリズム使用します。

確率的勾配降下法(SGD: Stochastic Gradient Descent)は、機械学習の分野でよく用いられる最適化アルゴリズムの一つです。
なおSDGs( Sustainable Development Goals )とは何ら関係はありません。

最適化アルゴリズムとは?

機械学習では、モデルが与えられたデータに対してどれくらい適合しているかを評価するための損失関数を最小化することを目標とします。この損失関数を最小化するパラメータを求めるために、最適化アルゴリズムが用いられます。主に次の種類があります。

  • 最急降下法(勾配降下法) :すべての訓練データを使用して、損失関数が小さくなる方向にパラメータを更新していくアルゴリズムです。最急降下法とも勾配降下法とも呼びます。
  • 確率的勾配降下法:勾配降下法の一種ですが、損失関数の勾配を計算する際に、すべてのデータではなく1件だけを使用します。ランダムに選ばれた一部のデータ(ミニバッチ)を使用するミニバッチ勾配降下法を指す事もあります。
  • ミニバッチ勾配降下法:最急降下法と確率的勾配降下法の中間に当たります。複数の訓練データをランダムに選び、勾配計算とパラメータの更新する処理を繰り返します。一般によく用いられています。
なぜ確率的勾配降下法を使うのか?
  • 計算効率: 大規模なデータセットの場合、すべてのデータを使って損失関数の勾配を計算すると、計算量が膨大になってしまいます。確率的勾配降下法では、一部のデータのみを使用するため、計算量を大幅に削減できます。
  • 局所最適解からの脱出: 勾配降下法では、局所最適解に陥ってしまう可能性があります。確率的勾配降下法では、勾配の計算にノイズが含まれるため、局所最適解から脱出しやすくなります。

SGDによるパラメータ更新の仕組み

勾配降下法(GD)と確率的勾配降下法(SGD)のパラメータ更新の式がどのようなものか、先にお見せします。

勾配降下法(GD)のパラメータ更新式
\[ \theta_j := \theta_j + \alpha \sum_i (y_i – f_\theta({\bf{x}}_i)) x_{ij} \]

  • jは特徴量の番号。アイリスの例ではjには1:がく片長, 2:がく片幅、および、0:ロジスティック回帰の切片用の番号も加えて、合計3種類が入る。
  • iは学習用データの行番号。アイリスデータは150行しかないが、モデル学習用に100行を使う場合、iには1~100が入る。
  • α(学習率)は、どの程度パラメータを更新するかを決める値。0.00001~1を使う事が多い。
  • \(y_i\) はi番目のデータの実際のクラス(0または1)。アイリスの例ではクラスは 1:Setosa, 0 :それ以外の2種類。
  • \(f_\theta \) はi番目のデータの予測確率。アイ留守の例ではSetosaである予測確率。
  • \( \bf{x}_i \)はi番目のデータの特徴量ベクトル。
  • \(x_{ij} \)はi番目のデータのj番目の特徴量。

勾配降下法(GD)は、シグマ(Σ)で訓練データ全てを使ってパラメータθを更新しています。
これを少し改造して、今回Excelシートでも使う確率的勾配降下法(SGD)に変えてみましょう。

確率的勾配降下法(GD)のパラメータ更新式
\[ \theta_j := \theta_j + \alpha (y_k – f_\theta({\bf{x}}_k)) x_{kj} \]

  • kは、ランダムに選ばれた訓練データのインデックス。

確率的勾配降下法(SGD)は、訓練データ1件だけを使ってパラメータを更新しています。つまり勾配降下法と確率的勾配降下法の違いは、まとめて更新するか細かく更新するかの違いだけです。
この計算をExcelのセルに関数として入力し、反復処理することで最適なパラメータを求めます。

では、上記のパラメータ更新式をどのように算出したのか、導出方法を示します。

目的関数 L(θ) の尤度

上では更新式を示しましたが、更新式を導出する為には、まず目的関数(=損失関数・誤差関数)を定義します。損失関数はモデルがどれくらいデータに適合しているかを表す指標です。

目的関数には、類似する言葉が沢山存在しますので、ここで整理しておきます。


■目的関数(Objective function)
目的関数は、最適化対象となる関数の総称であり、損失関数、誤差関数、コスト関数、評価関数などを包括する概念。

■損失関数(Loss function)
よく使われる関数記号: L(y, ŷ )
損失関数は、モデルが出した予測値(ŷ)と実際の正解値(y)とのズレ(誤差)を定量化 する関数であり、機械学習の学習過程で最適化される関数である。
代表的な損失関数:
回帰問題: 平均二乗誤差(MSE)、平均絶対誤差(MAE)
分類問題: 交差エントロピー損失(Binary Cross-Entropy Loss)
ロバスト回帰: ハブ損失(Huber Loss)

■誤差関数(Error function)
よく使われる関数記号: E(y, ŷ)
誤差関数(Error function)は、機械学習の文脈では 損失関数(Loss function)と同義に扱われる。一方、統計学における誤差関数は、ガウス誤差関数(erf関数)を指す事が多い。

■コスト関数(Cost function)
よく使われる関数記号: C(y, ŷ,θ)
コスト関数は損失関数と同様に扱われる事もあるが、損失関数に対して正則化項を加えたものを指す場合もある。損失関数を L(y, ŷ) として、正則化項を λ R(θ) とした場合、一般的なコスト関数の形は次のように表される:
C(y, ŷ, θ) = L(y, ŷ) + λ R(θ)
R(θ) は 正則化項(例: L1正則化 ||θ||_1 や L2正則化 ||θ||_2^2)
λ は正則化の強さを制御するハイパーパラメータ

■評価関数(Evaluation function)
よく使われる関数記号: E(y, ŷ)
評価関数は、学習が完了したモデルの性能を測るための指標であり、学習時に最適化する目的関数(損失関数やコスト関数)と同じ関数を使う事も、異なる関数を使う事もある。
代表的な評価関数には次のものがある
回帰問題:
平均二乗誤差(MSE): E(y, ŷ) = (1/m) Σ (y_i – ŷ_i)^2
平均絶対誤差(MAE): E(y, ŷ) = (1/m) Σ |y_i – ŷ_i|
決定係数(R²): E(y, ŷ) = 1 – Σ (y_i – ŷ_i)^2 / Σ (y_i – ȳ)^2
分類問題:
正確率(Accuracy)
適合率(Precision)、再現率(Recall)、F1スコア など

※上記の全ての関数において、関数を表す記号として「J」が使われる事があります。Judgment(判断)の頭文字が由来と思われます。

※上記の関数を表現する記号は、具体的に使う関数の種類によっても変わる事があります。例えば、評価関数はEと表現される事が多いのですが、関数の実態が交差エントロピー損失(Cross-Entropy Loss)だった場合は、Cと表現する事もあります。関数を表す記号は決まっているわけではありませんので、資料・教科書によって表現が変わる点はご注意ください。

ロジスティック回帰では、目的関数として尤度関数(ゆうどかんすう)を使います。
尤度関数は、モデルが与えられたときに観測された結果が起こる確率をすべて掛け合わせたものです。つまり、観測されたデータがどれくらい尤もらしい(もっともらしい)かを表します。
目的関数である尤度(Likelihood):L(θ)の式は次の通りです。

\[ L(θ)=\prod_i P(y_i=1 | x_i)^{y_i} * P(y_i=0 | x_i)^{(1-y_i)} \]

  • ∏ は、総積記号です。ギリシャ文字のパイπの大文字です。総和記号∑のかけ算バージョンです。
  • yi​ は、i番目のデータの正解ラベル(0または1)です。
  • 尤度関数を最大化するパラメータθ が、最も尤もらしいパラメータであると考えられます(最尤推定法)。
  • 各データ (xi​,yi​) に対して、yi​=1 の場合は P(yi​=1∣xi​) が、 yi​=0 の場合は P(yi​=0∣xi​) が尤度に寄与します。Pの0乗は1になる為です。
  • 全てのデータの尤度の積が、全体の尤度となります。

私たちは、パラメータθを決めてロジスティック回帰モデルは完成させたいので、これから行うべき事は、この尤度関数L(θ)の値を最大化するθを探す事です。

L(θ)最大化の意味

Lは、先の式からわかるように、確率Pの掛け算です。よってLを最大化するとは、y=1(setosa)の時にモデルが「このxの値ならsetosaの確率は100%!」と答えられて、y=0(setosa以外)の時にモデルが「このxの値ならsetosa以外である確率は100%!」と答えられる、そんな精度が高いθを探し出し、精度が高いロジスティック回帰モデルを目指すという事です。
しかしこれは理想であり、実際は「xの値はsetosaともversicolorともとれるから、setosaの確率60%」なんて事もあります。L(θ)を最大化すると言えども限界はあり、L(θ)を理論的最大値の1(100%×100%×…=1)にするのは現実世界では不可能です。
それでも与えられたアイリスの訓練用データを使い、できる限り高い確率でsetosaかsetosa以外かを答えられるθを探し出しましょう、というのが「L(θ)を最大化する」の意味なのです。

logL(θ)をθで偏微分する

L(θ)を最大化するθがわかれば、精度の良いロジスティック回帰モデルができあがる、という事はわかりました。
では、L(θ)が最大にするθは、どのように求めればよいでしょうか?
そうです、最大化・最小化と言えば微分ですね!
高校数学の微分の授業を思い出してください。ある数式を微分して傾きが0になる点こそが、その数式が最大化・最小化する点です。

今回の問題でも、Lが最大化する点のθを求める為にLを微分するのですが、微分の計算を簡単にするために、まずは対数を両辺につけます。

\[ \begin{aligned} \log L(\theta)
&= \log \prod_i \left( P(y_i=1 \mid x_i)^{\,y_i} \cdot P(y_i=0 \mid x_i)^{\,1-y_i} \right) \\
&= \sum_i \left( \log P(y_i=1 \mid x_i)^{\,y_i} + \log P(y_i=0 \mid x_i)^{\,1-y_i} \right) \\
&= \sum_i \left( y_i \log P(y_i=1 \mid x_i) + (1-y_i) \log P(y_i=0 \mid x_i) \right) \\
&= \sum_i \left( y_i \log P(y_i=1 \mid x_i) + (1-y_i) \log \Bigl(1-P(y_i=1 \mid x_i)\Bigr) \right) \\
&= \sum_i \left( y_i \log f_\theta(x_i) + (1-y_i) \log \Bigl(1-f_\theta(x_i)\Bigr) \right) \end{aligned} \]

次にlogL(θ)を最大化するにはどの程度θを更新すればよいのか算出する為、θで偏微分します。

\[ \begin{aligned} \frac{\partial \log L}{\partial \theta_j}
&= \frac{\partial \log L}{\partial f_\theta} \cdot \frac{\partial f_\theta}{\partial (\theta \cdot x)} \cdot \frac{\partial (\theta \cdot x)}{\partial \theta_j} \\
&= \sum_i \left( \frac{y_i}{f_\theta(x_i)} + \frac{1-y_i}{1-f_\theta(x_i)}(-1) \right) \cdot \frac{\partial f_\theta(x_i)}{\partial (\theta \cdot x_i)} \cdot \frac{\partial (\theta \cdot x_i)}{\partial \theta_j} \\
&= \sum_i \left( \frac{y_i}{f_\theta(x_i)} – \frac{1-y_i}{1-f_\theta(x_i)} \right) \cdot \frac{\partial f_\theta(x_i)}{\partial (\theta \cdot x_i)} \cdot \frac{\partial (\theta \cdot x_i)}{\partial \theta_j} \\
&= \sum_i \left( \frac{y_i}{f_\theta(x_i)} – \frac{1-y_i}{1-f_\theta(x_i)} \right) \cdot \frac{\partial \text{sigmoid}(\theta \cdot x_i)}{\partial (\theta \cdot x_i)} \cdot x_{ij} \\ &= \sum_i \left( \frac{y_i}{f_\theta(x_i)} – \frac{1-y_i}{1-f_\theta(x_i)} \right) \cdot f_\theta(x_i) \Bigl(1-f_\theta(x_i)\Bigr) \cdot x_{ij} \\
&= \sum_i \left( y_i \Bigl(1-f_\theta(x_i)\Bigr) – \bigl(1-y_i\bigr) f_\theta(x_i) \right) \cdot x_{ij} \\
&= \sum_i \Bigl( y_i – f_\theta(x_i) \Bigr) \, x_{ij} \end{aligned} \]

上でご覧いただいたとおり、勾配降下法(GD)はパラメータを次の式になります。

\[ \theta_j := \theta_j + \alpha \sum_i (y_i – f_\theta(x_i)) x_{ij} \]

今回は1件ずつ更新する確率的勾配降下法(SGD)でパラメータを更新しますので、結局次の更新式を使います。

\[ \begin{aligned}
&\theta_0 := \theta_0 + \alpha (y_i – f_\theta(x_i)) \\
&\theta_1 := \theta_1 + \alpha (y_i – f_\theta(x_i)) x_{i1} \\
&\theta_2 := \theta_2 + \alpha (y_i – f_\theta(x_i)) x_{i2} \\
\end{aligned} \]

Excelでロジスティック回帰のSGDの実装

Excelシートの左側にアイリス訓練用データを貼り付け、その右側に上で計算した式を入れていきます。具体的な計算式は、本記事の上部に掲載していますExcelシートをダウンロードして、セル内の関数を確認してください。

  1. データをExcelのシートに入力
    • A列: クラスの種類 (Setosa: 1, それ以外: 0)
    • B列: がく片長 (Sepal Length)
    • C列: がく片幅 (Sepal Width)
  2. 予測確率の計算
    • H列で予測確率 fθ(x) を計算。
  3. 目的関数の計算
    • I列でLogL(θ)1件分を、J列で150行の合計であるLogL(θ)を計算。収束の度合いを見る為の列。
  4. パラメータの更新
    • 学習率 αセルL4 に入力。
    • 更新式を D,E,F列 に適用。
  5. 反復処理
    • 各行でθの更新を繰り返す。今回はExcelシートの「アイリスデータ並び替え後」のデータを10回張り付けて1500行分の訓練データ分でθを更新している。
    • この更新が収束したかどうかは、「LogL(θ)1件」の値を150行分足したLogL(θ)の列の収束度合いを見て判断する。

Excelシートが下に行くに従い、LogL(θ)の値が大きくなっています。つまり学習が進んでいるのがわかります。
なお、Exceの各列をクリックして関数を見るとわかりますが、LogL(θ)の列はパラメータの更新には直接的には使われていません。これは、確率的勾配降下法(SGD)のパラメータ更新の計算式の導出途中ではLogL(θ)が使われていましたが、最終的な更新式ではLogL(θ)は使われていない為です。

グラフの決定境界

Excelシートには、ロジスティック回帰のモデルが、アイリスの種類を分類できているかどうか、グラフも表示しています。
グラフには決定境界を線を入れています。決定境界線はSetosaである確率が50%の位置に引いていますが、その計算式は次の通りです。
\[ \begin{align}
\frac{1}{1 + \exp(-\theta_0 – \theta_1 x_1 – \theta_2 x_2)} &= 0.5 \\
1 + \exp(-\theta_0 – \theta_1 x_1 – \theta_2 x_2) &= 2 \\
\log\left(\exp(-\theta_0 – \theta_1 x_1 – \theta_2 x_2)\right) &= \log(1) \\
-\theta_0 – \theta_1 x_1 – \theta_2 x_2 &= 0 …① \\
x_2 &= -\frac{\theta_0 + \theta_1 x_1}{\theta_2}
\end{align} \]

決定境界はモデルの予測確率が50%になる点の集合ですが、これすなわちexp内の線形関数が0となる点の集合という事ですね。(上記式①より)
θ0,θ1,θ2は、Excelシートの計算で決定していますので(Excelシート右上)、これら値を使用して、決定境界線を引いています。

Excelファイルのグラフを見ると、綺麗にSetosaとそれ以外を分離できています。Excelファイル内で行ったSGDによる学習で、ロジスティック回帰のパラメータθが正しく調整できているという事です。

本来は、データセットを訓練用・検収用・テスト用に6割:2割:2割などで分割して、訓練用データ+検収用データでθを決定し、テスト用データで決定境界のグラフの散布図をプロットして評価するべきです。モデルの性能を評価するときに、訓練時と同じデータを使うと、評価結果が甘くなる為です。
今回は、説明を簡単にする為、アイリスデータの全データを使ってモデルの訓練を行い、グラフにも全データをプロットしていますので、ご了承ください。

参考:ロジスティック回帰分析をPythonで実行

先ほどはExcelでロジスティック回帰による分類を実施しました。
似たことをPython環境で実行するなら、次のスクリプトになりますので、参考までに掲載します。

import numpy as np
from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report
import matplotlib.pyplot as plt
import matplotlib as mpl
mpl.rcParams['font.family'] = ['DejaVu Sans'] # colab環境で、Matplotlib のデフォルトのフォントファミリーに「IPAGothic」が含まれない事による警告出力を回避する為。

# 1. アイリスデータセットの読み込み
iris = load_iris()
# 今回は「がく片長 (Sepal Length)」と「がく片幅 (Sepal Width)」の2変量を使用
X = iris.data[:, :2]

# 2. 目的変数の作成
# Setosaなら1、その他なら0に変換
y = (iris.target == 0).astype(int) # [0 0 ..1 1..2 2..]が[True True ..False False..False False..]になりastype(int)で[1 1 ..0 0..0 0..]になる


# 3. 訓練データとテストデータへの分割(指定のロジックそのまま使用)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 4. ロジスティック回帰モデルの作成と学習(指定のロジックそのまま使用)
model = LogisticRegression(max_iter=200)
model.fit(X_train, y_train)

# 5. テストデータでの評価
y_pred = model.predict(X_test)
print("正解率 (Accuracy):", accuracy_score(y_test, y_pred))
print("混同行列 (Confusion Matrix):\n", confusion_matrix(y_test, y_pred))
print("分類レポート (Classification Report):\n", classification_report(y_test, y_pred))

# 6. 決定境界の描画
# 決定境界は、モデルの予測確率が0.5、すなわち線形判別関数が0となる点の集合
# 直線の式: θ0 + θ1*x1 + θ2*x2 = 0  →  x2 = -(θ0 + θ1*x1)/θ2
x1_vals = np.linspace(X[:, 0].min() - 0.5, X[:, 0].max() + 0.5, 200)
x2_vals = -(model.intercept_[0] + model.coef_[0][0] * x1_vals) / model.coef_[0][1]

plt.figure(figsize=(8, 6))
# Setosa (y=1) のデータ点
plt.scatter(X[y == 1, 0], X[y == 1, 1], color='blue', marker='o', label='Setosa')
# Setosa以外 (y=0) のデータ点
plt.scatter(X[y == 0, 0], X[y == 0, 1], color='red', marker='x', label='Non-Setosa')
# 決定境界のプロット
plt.plot(x1_vals, x2_vals, color='green', linewidth=2, label='Decision Boundary (0.5)')
plt.xlabel('Sepal Length (cm)')
plt.ylabel('Sepal Width (cm)')
plt.title('logstic regression Setosa')
plt.legend()
plt.show()

Pythonの実行結果は次の通りです。

正解率 (Accuracy): 1.0
混同行列 (Confusion Matrix):
 [[20  0]
 [ 0 10]]
分類レポート (Classification Report):
               precision    recall  f1-score   support

           0       1.00      1.00      1.00        20
           1       1.00      1.00      1.00        10

    accuracy                           1.00        30
   macro avg       1.00      1.00      1.00        30
weighted avg       1.00      1.00      1.00        30

PythonでもExcelと同様にSetoraとそれ以外が分離ができていますね。
Pythonのライブラリを使うと、簡単に機械学習のモデルを利用する事ができますが、そのアルゴリズムを知る事はできません。アルゴリズムを勉強する為には、一度Excelで動かしてみるが良いでしょう。


まとめ

Excelを使い、確率的勾配降下法を使用して、ロジスティック回帰のパラメーターを求めてみました。Excelを使うと、機械学習の学習過程が見えますので、理解が深まったのではないでしょうか。

本記事のポイント

✅ ロジスティック回帰の数学的な仕組みをExcelで対応させて理解
✅ 確率的勾配降下法(SGD)を用いてパラメータを最適化
✅ 実際にExcelで試せるファイルを添付

Excel学習シリーズはこちら



タイトルとURLをコピーしました