Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.
Avatar for kaise kaise
March 30, 2025

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

線形回帰の知識を前提とし,ロジスティック回帰を実装できるまでの理論,数学,実装方法をまとめた.

Avatar for kaise

kaise

March 30, 2025
Tweet

More Decks by kaise

Other Decks in Programming

Transcript

  1. 目次 • はじめに • ロジスティック回帰とは • 前提知識 • ロジスティック回帰の気持ち •

    ロジスティック回帰の理論 • 実装 • 付録 2024/12/13 3 はじめに
  2. 前提知識 線 形 回 帰 の 実 装 では,重回帰だとどうなるのか. それは単回帰をひたすら足すような式になる.

    これを,内積を使って整理すると以下のようになる. この資料では, 𝒘𝑇𝒙をよく使う. 詳しくは線形回帰の実装 2024/12/13 7 はじめに ො 𝑦 = 𝑤0 𝑥0 +𝑤1 𝑥1 +𝑤2 𝑥2 + ⋯ + 𝑤𝑚 𝑥𝑚 ※ 𝑥0 =1 ො 𝑦 = ෍ 𝑖=0 𝑚 𝑤𝑖 𝑥𝑖 = 𝒘𝑇𝒙
  3. 目次 • はじめに • ロジスティック回帰の気持ち • 線形回帰の対象のデータ • ロジスティック回帰の対象のデータ •

    シグモイド関数に線形回帰を適用 • パラメータの最適化 • ロジスティック回帰の理論 • 実装 • 付録 2024/12/13 10 ロジスティック回帰の気持ち
  4. 目次 • はじめに • ロジスティック回帰の気持ち • ロジスティック回帰の理論 • 線形回帰を確認 •

    シグモイド関数に線形回帰を適用 • パラメータの最適化 • 尤度とは • 最尤法 • ニュートン法 • シグモイド関数の微分 • 実装 • 付録 2024/12/13 18 ロジスティック回帰の理論
  5. 線形回帰を確認 まず,ロジスティック回帰の基盤となる,線形回帰の式を用意する. ※ 今回はバイアス項なしで実装するので,暗黙的に𝒘𝑇𝒙 = 𝑤1 𝑥1+𝑤2 𝑥2 + ⋯

    + 𝑤𝑚 𝑥𝑚 となっている. m:次元数 x∈ ℝ𝑚:説明変数 y∈ ℝ:目的変数 w∈ ℝ𝑚:パラメータ 2024/12/13 20 ロジスティック回帰の理論 ො 𝑦 = 𝒘𝑇𝒙
  6. パラメータの最適化 表にするとこう では,この二つは違うのか? →背景にある気持ちは同じ.どちらも「尤度を最大にしたい」という背景がある. だから本当はこう 線形回帰は尤度を最大化する過程で 二乗和誤差が出てきただけ. 尤度を次のスライドで説明する. 2024/12/13 23

    ロジスティック回帰の理論 モデル 最適度合いの関数 方針 線形回帰 二乗和誤差 最小化 ロジスティック回帰 尤度 最大化 モデル 最適度合いの関数 方針 線形回帰 尤度 最大化 ロジスティック回帰 尤度 最大化
  7. 最尤法(コイン投げの例) 問:10回コインを投げた結果,表が6回,裏が4回でた. このコインの表が出る確率𝜃を求めよ. 尤度𝐿 𝜃 表が出ることを「成功した」と解釈する. n:試行回数 𝜃:パラメータ(表が出る確率) K𝑖 ∈

    {0, 1}:成功フラグ,成功(表)=1,失敗(裏)=0 (ベルヌーイ分布の確率質量関数そのものを当てはめている.) 2024/12/13 28 ロジスティック回帰の理論 𝐿 𝜃 = ෑ 𝑖=1 𝑛 𝜃𝐾𝑖(1 − 𝜃)1−𝐾𝑖
  8. 最尤法(コイン投げの例) 問:10回コインを投げた結果,表が6回,裏が4回でた. このコインの表が出る確率𝜃を求めよ. 各試行について分解してみる. 10回の試行をまとめると以下のようになる. 𝑘:成功数(表が出た回数) 2024/12/13 29 ロジスティック回帰の理論 𝐾1

    = 表 , 𝐾2 = 表 , 𝐾3 = 表 , 𝐾4 = 表 , 𝐾5 = 表 , 𝐾6 = 表 , 𝐾7 = 表 , 裏, 𝐾8 = 裏, 𝐾9 = 裏, 𝐾10 = 裏 𝐿 𝜃 = 𝜃 × 𝜃 × 𝜃 × 𝜃 × 𝜃 × 𝜃 × 1 − 𝜃 × 1 − 𝜃 × 1 − 𝜃 × (1 − 𝜃) 𝐿 𝜃 = 𝜃𝑘 1 − 𝜃 𝑛−𝑘 = 𝜃6 (1 − 𝜃)4
  9. 最尤法(ロジスティック回帰) 負の対数尤度をとる.(負の対数尤度を取り最小化問題とすることで,損失関数として捉えるため.) 損失関数はよく𝐸 𝒘 とおくので,それにならう. あとは, 𝐸 𝒘 を微分して= 0になる𝒘を求めれば良い.

    つまり,∇𝐸 𝒘 = 0を解けば良いということになる.(ベクトルの微分は∇と書く.) しかしこれは解析的に解けない.(方程式の変形だけで解けないということ.ちなみにコイン投げは解析的に解けた.) よって,数値的に解く.(※解析的に解けない問題を,近似的に解を求める方法で解くということ.) 具体的には,(今回は)ニュートン法という方法で解く. 2024/12/13 35 ロジスティック回帰の理論 𝐸 𝒘 = −log𝐿 𝒘 = − σ 𝑖=1 𝑛 (𝑦𝑖 log𝜎 𝒘𝑇𝒙𝒊 + 1 − 𝑦𝑖 log 1 − 𝜎 𝒘𝑇𝒙𝒊 )
  10. 目次 … • パラメータの最適化 • 尤度とは • 最尤法 • ニュートン法

    • ニュートン法とは • 𝑥 − 1 2でのニュートン法 • ロジスティック回帰でのニュートン法 • シグモイド関数の微分 • 勾配:∇𝐸 𝒘 • ヘッセ行列:𝐻 … 2024/12/13 37 ロジスティック回帰の理論
  11. 𝑥 − 1 2でのニュートン法 最尤法をコイン投げで説明したように,ニュートン法でも,ロジスティック回帰以外の例 を用いて体験してもらう. 𝑥 − 1 2

    = 0を数値的に解いてニュートン法を体験する. ニュートン法の式, 𝑥𝑛𝑒𝑤 = 𝑥𝑜𝑙𝑑 − 𝑓(𝑥𝑜𝑙𝑑) 𝑓′(𝑥𝑜𝑙𝑑) に 𝑥 − 1 2を代入する. これで準備は完了. あとは適当な初期値(𝑥の値)を決めて,更新していくだけ. 適当に初期値𝑥=6から始める. 2024/12/13 40 ロジスティック回帰の理論 𝑥𝑛𝑒𝑤 = 𝑥𝑜𝑙𝑑 − 𝑥𝑜𝑙𝑑 − 1 2 2𝑥𝑜𝑙𝑑
  12. 𝑥 − 1 2でのニュートン法 解を得ることができた.実際に𝑥 = 1と,答えもあっている. これがニュートン法. 数値を代入すると こんな感じ

    誤差は許容. 2024/12/13 41 ロジスティック回帰の理論 1. 𝑥𝑛𝑒𝑤 = 𝑥𝑜𝑙𝑑 − 𝑥𝑜𝑙𝑑−1 2 2𝑥𝑜𝑙𝑑 2. 3.92 = 6 − 6−1 2 2×6 3. 2.83 = 3.92 − 3.92−1 2 2×3.92 ⋮ 4. 1.104 = 1.1099 − 1.1099−1 2 2×1.1099 5. 1.099 = 1.104 − 1.104−1 2 2×1.104 ⋮
  13. ロジスティック回帰でのニュートン法 ニュートン法のイメージがつかめたところで, ロジスティック回帰の場合は.ニュートン法の更新式に何を代入すれば良いかをみていく. ニュートン法は𝑓(𝑥)=0を解くアルゴリズムであり,𝑓(𝑥)を代入することで解く. 今回の場合,それは∇𝐸 𝒘 である. ∇𝐸 𝒘 を目的関数として代入する.代入した結果,出来上がった更新式が以下.

    ∇𝐸 𝒘 を微分したものは, 𝐸 𝒘 の二階微分なのでヘッセ行列𝐻で表すことができる. 2024/12/13 42 ロジスティック回帰の理論 𝒘𝑛𝑒𝑤 = 𝒘𝑜𝑙𝑑 − ∇𝐸 𝒘𝑜𝑙𝑑 ∇𝐸 𝒘𝑜𝑙𝑑 ′ =𝒘𝑜𝑙𝑑 − ∇𝐸 𝒘𝑜𝑙𝑑 𝐻 = 𝒘𝑜𝑙𝑑 − 𝐻−1∇𝐸 𝒘𝑜𝑙𝑑
  14. ロジスティック回帰でのニュートン法 シグモイド関数の微分を求める. シグモイド関数:𝜎 𝑥 = 1 1+𝑒−𝑥 = 1 +

    𝑒−𝑥 −1 𝑡 = (1 + 𝑒−𝑥)とする. 𝑑 𝑑𝑥 𝜎 𝑥 = 𝑑 𝑑𝑡 𝑡−1 𝑑𝑡 𝑑𝑥 𝑡 = −𝑡−2 𝑑𝑡 𝑑𝑥 1 + 𝑒−𝑥 −1 = − 1 + 𝑒−𝑥 −2 ⋅ −𝑒−𝑥 = 𝑒−𝑥 1+𝑒−𝑥 2 = 𝑒−𝑥 1+𝑒−𝑥 1 1+𝑒−𝑥 = (1+𝑒−𝑥 1+𝑒−𝑥 − 1 1+𝑒−𝑥 ) 1 1+𝑒−𝑥 = (1 − 𝜎 𝑥 )𝜎 𝑥 2024/12/13 44 ロジスティック回帰の理論
  15. ロジスティック回帰でのニュートン法 勾配:∇𝐸(𝒘)を求める. ∇𝐸 𝒘 = − ෍ 𝑖=1 𝑛 𝑦𝑖

    ∇ log𝜎 𝒘𝑇𝒙𝒊 + (1 − 𝑦𝑖 ∇ log 1 − 𝜎 𝒘𝑇𝒙𝒊 ] 対数の微分より = − ෍ 𝑖=1 𝑛 [𝑦𝑖 1 𝜎 𝒘𝑇𝒙𝒊 ∇𝜎 𝒘𝑇𝒙𝒊 + (1 − 𝑦𝑖 ) 1 1 − 𝜎 𝒘𝑇𝒙𝒊 ∇(1 − 𝜎 𝒘𝑇𝒙𝒊 )] シグモイド関数の微分より = − ෍ 𝑖=1 𝑛 𝑦𝑖 1 − 𝜎 𝒘𝑇𝒙𝒊 𝒙𝑖 + (1 − 𝑦𝑖 (−𝜎 𝒘𝑇𝒙𝒊 )𝒙𝑖 ] = − ෍ 𝑖=1 𝑛 [𝑦𝑖 − 𝑦𝑖 𝜎 𝒘𝑇𝒙𝒊 − 𝜎 𝒘𝑇𝒙𝒊 + 𝑦𝑖 𝜎 𝒘𝑇𝒙𝒊 ]𝒙𝑖 = − ෍ 𝑖=1 𝑛 𝑦𝑖 − 𝜎 𝒘𝑇𝒙𝒊 𝒙𝑖 = ෍ 𝑖=1 𝑛 (𝜎 𝒘𝑇𝒙𝒊 − 𝑦𝑖 )𝒙𝑖 2024/12/13 45 ロジスティック回帰の理論
  16. ロジスティック回帰でのニュートン法 𝜎 𝒘𝑇𝒙𝒊 =ො 𝑦𝑖 なのでො 𝑦𝑖 − 𝑦𝑖 と表すことができる.

    ො 𝑦𝑖 − 𝑦𝑖 はスカラーで,𝒙𝑖 は𝑚次元の列ベクトルである. したがって, σ𝑖=1 𝑛 (ො 𝑦𝑖 − 𝑦𝑖 )𝒙𝑖 は, ((予測された確率) – (実際の確率)) × 説明変数 を全てのデータについての和をとるという意味になっている. ※(実際の確率)は,クラス1であるか否かなので,0.0か1.0のどちらか. 2024/12/13 46 ロジスティック回帰の理論
  17. ロジスティック回帰でのニュートン法 行列を使用すると, σ𝑖=1 𝑛 (ො 𝑦𝑖 − 𝑦𝑖 )𝒙𝑖 のΣを外すことができる.

    ෍ 𝑖=1 𝑛 ( ො 𝑦𝑖 − 𝑦𝑖 )𝒙𝑖 = ො 𝑦1 − 𝑦1 𝑥11 + ො 𝑦2 − 𝑦2 𝑥21 + ⋯ + ො 𝑦𝑛 − 𝑦𝑛 𝑥𝑛1 ො 𝑦1 − 𝑦1 𝑥12 + ො 𝑦2 − 𝑦2 𝑥22 + ⋯ + ො 𝑦𝑛 − 𝑦𝑛 𝑥𝑛2 ⋮ ො 𝑦1 − 𝑦1 𝑥1𝑚 + ො 𝑦2 − 𝑦2 𝑥2𝑚 + ⋯ + ො 𝑦𝑛 − 𝑦𝑛 𝑥𝑛𝑚 これを行列でまとめると,以下になる. ∇𝐸 𝒘 = 𝑋𝑇(ෝ 𝒚 − 𝒚) これで∇𝐸 𝒘 が求められた. 2024/12/13 47 ロジスティック回帰の理論
  18. ロジスティック回帰でのニュートン法 ヘッセ行列:𝐻を求める. ヘッセ行列とは,関数の二階偏微分をまとめた行列である. n次元の変数で,関数を二階偏微分してまとめる. ヘッセ行列: 𝐻 = 𝜕2𝑓 𝜕𝑥1 2

    𝜕2𝑓 𝜕𝑥1 𝜕𝑥2 ⋯ 𝜕2𝑓 𝜕𝑥1 𝜕𝑥𝑛 𝜕2𝑓 𝜕𝑥2 𝜕𝑥1 𝜕2𝑓 𝜕𝑥2 2 ⋯ 𝜕2𝑓 𝜕𝑥2 𝜕𝑥𝑛 ⋮ ⋮ ⋱ ⋮ 𝜕2𝑓 𝜕𝑥𝑛 𝜕𝑥1 𝜕2𝑓 𝜕𝑥𝑛 𝜕𝑥2 ⋯ 𝜕2𝑓 𝜕𝑥𝑛 2 今回これは使わずに, ∇ 𝐸 𝒘 を偏微分して導出するのでスルーしていい. 2024/12/13 48 ロジスティック回帰の理論
  19. ロジスティック回帰でのニュートン法 ロジスティック回帰におけるヘッセ行列を導出する. (∇ 𝐸 𝒘 を偏微分するので,𝐸 𝒘 の二階微分として,∇2𝐸 𝒘 ともかける.)

    ∇𝐸 𝒘 = 𝑋𝑇(ෝ 𝒚 − 𝒚)なので, 𝐻 = ∇2𝐸 𝒘 = 𝜕 𝜕𝒘 𝐸 𝒘 = 𝜕 𝜕𝒘 {𝑋𝑇(ෝ 𝒚 − 𝒚)} = 𝜕 𝜕𝒘 (𝑋𝑇ෝ 𝒚 − 𝑋𝑇𝒚) 𝑋𝑇𝒚は𝒘に関係ないので, 𝜕 𝜕𝒘 (−𝑋T𝒚) =0になる. したがって, = 𝜕 𝜕𝒘 𝑋𝑇ෝ 𝒚 2024/12/13 49 ロジスティック回帰の理論
  20. ロジスティック回帰でのニュートン法 問題は 𝜕 𝜕𝒘 𝑋𝑇ෝ 𝒚のみとなった. 連鎖律より, 𝜕 𝜕𝒘 𝑋𝑇ෝ

    𝒚 = 𝜕 𝜕ෝ 𝒚 𝑋𝑇ෝ 𝒚 𝜕ෝ 𝒚 𝜕𝒘 𝜕 𝜕ෝ 𝒚 𝑋𝑇ෝ 𝒚と, 𝜕ෝ 𝒚 𝜕𝒘 に分けて計算できるようになった.(順番に求めればいい.) 注意したいのは,どちらもベクトルをベクトルで微分する形になっていること. 𝑋𝑇ෝ 𝒚 ∈ ℝ𝑚 ෝ 𝒚 ∈ ℝ𝑛 𝒘 ∈ ℝ𝑚 ベクトルをベクトルで微分すると行列になる. 2024/12/13 50 ロジスティック回帰の理論
  21. ロジスティック回帰でのニュートン法 ベクトルをベクトルで微分すると行列になる. これを,ヤコビ行列と言う. ヤコビ行列をしっかり定義する. 𝒂 ∈ ℝ𝑚 𝒃 ∈ ℝ𝑛

    とする. 𝜕𝒂 𝜕𝒃 = 𝜕𝑎1 𝜕𝑏1 𝜕𝑎1 𝜕𝑏2 ⋯ 𝜕𝑎1 𝜕𝑏𝑛 𝜕𝑎2 𝜕𝑏1 𝜕𝑎2 𝜕𝑏2 ⋯ 𝜕𝑎2 𝜕𝑏𝑛 ⋮ ⋮ ⋱ ⋮ 𝜕𝑎𝑚 𝜕𝑏1 𝜕𝑎𝑚 𝜕𝑏2 ⋯ 𝜕𝑎𝑚 𝜕𝑏𝑛 𝜕𝒂 𝜕𝒃 ∈ ℝm×𝑛とする. この定義から, 𝜕 𝜕ෝ 𝒚 𝑋𝑇ෝ 𝒚 ∈ ℝm×𝑛, 𝜕ෝ 𝒚 𝜕𝒘 ∈ ℝ𝑛×mになることがわかる. 2024/12/13 51 ロジスティック回帰の理論
  22. ロジスティック回帰でのニュートン法 𝜕 𝜕ෝ 𝒚 𝑋𝑇ෝ 𝒚と𝜕ෝ 𝒚 𝜕𝒘 を計算していく. 𝜕

    𝜕ෝ 𝒚 𝑋𝑇ෝ 𝒚を計算する. 𝜕 𝜕ෝ 𝒚 𝑋𝑇ෝ 𝒚 = 𝜕 𝜕ෝ 𝒚 𝑋11 𝑋21 ⋯ 𝑋𝑛1 𝑋12 𝑋22 ⋯ 𝑋𝑛2 ⋮ ⋮ ⋱ ⋮ 𝑋1𝑚 𝑋2𝑚 ⋯ 𝑋𝑛𝑚 ො 𝑦1 ො 𝑦2 ⋮ ො 𝑦𝑛 行列とベクトルの積を計算. = 𝜕 𝜕ෝ 𝒚 𝑋11 ො 𝑦1 + 𝑋21 ො 𝑦2 + ⋯ + 𝑋𝑛1 ො 𝑦𝑛 𝑋12 ො 𝑦1 + 𝑋22 ො 𝑦2 + ⋯ + 𝑋𝑛2 ො 𝑦𝑛 ⋮ 𝑋1𝑚 ො 𝑦1 + 𝑋2𝑚 ො 𝑦2 + ⋯ + 𝑋𝑛𝑚 ො 𝑦𝑛 2024/12/13 52 ロジスティック回帰の理論
  23. ロジスティック回帰でのニュートン法 さっきのをシグマでまとめる. = 𝜕 𝜕ෝ 𝒚 ෍ 𝑖=1 𝑛 𝑋𝑖1

    ො 𝑦𝑖 ෍ 𝑖=1 𝑛 𝑋𝑖2 ො 𝑦𝑖 ⋮ ෍ 𝑖=1 𝑛 𝑋𝑖𝑚 ො 𝑦𝑖 偏微分する.(ヤコビ行列の定義から以下のような行列になる.) = 𝜕 σ𝑖=1 𝑛 𝑋𝑖1 ො 𝑦𝑖 𝜕 ො 𝑦1 𝜕 σ𝑖=1 𝑛 𝑋𝑖1 ො 𝑦𝑖 𝜕 ො 𝑦2 ⋯ 𝜕 σ𝑖=1 𝑛 𝑋𝑖1 ො 𝑦𝑖 𝜕 ො 𝑦𝑛 𝜕 σ𝑖=1 𝑛 𝑋𝑖2 ො 𝑦𝑖 𝜕 ො 𝑦1 𝜕 σ𝑖=1 𝑛 𝑋𝑖2 ො 𝑦𝑖 𝜕 ො 𝑦2 ⋯ 𝜕 σ𝑖=1 𝑛 𝑋𝑖2 ො 𝑦𝑖 𝜕 ො 𝑦𝑛 ⋮ ⋮ ⋱ ⋮ 𝜕 σ𝑖=1 𝑛 𝑋𝑖𝑚 ො 𝑦𝑖 𝜕 ො 𝑦1 𝜕 σ𝑖=1 𝑛 𝑋𝑖𝑚 ො 𝑦𝑖 𝜕 ො 𝑦2 ⋯ 𝜕 σ𝑖=1 𝑛 𝑋𝑖𝑚 ො 𝑦𝑖 𝜕 ො 𝑦𝑛 2024/12/13 53 ロジスティック回帰の理論
  24. ロジスティック回帰でのニュートン法 𝜕 σ𝑖=1 𝑛 𝑋𝑖1 ො 𝑦𝑖 𝜕 ො 𝑦1

    𝜕 σ𝑖=1 𝑛 𝑋𝑖1 ො 𝑦𝑖 𝜕 ො 𝑦2 ⋯ 𝜕 σ𝑖=1 𝑛 𝑋𝑖1 ො 𝑦𝑖 𝜕 ො 𝑦𝑛 𝜕 σ𝑖=1 𝑛 𝑋𝑖2 ො 𝑦𝑖 𝜕 ො 𝑦1 𝜕 σ𝑖=1 𝑛 𝑋𝑖2 ො 𝑦𝑖 𝜕 ො 𝑦2 ⋯ 𝜕 σ𝑖=1 𝑛 𝑋𝑖2 ො 𝑦𝑖 𝜕 ො 𝑦𝑛 ⋮ ⋮ ⋱ ⋮ 𝜕 σ𝑖=1 𝑛 𝑋𝑖𝑚 ො 𝑦𝑖 𝜕 ො 𝑦1 𝜕 σ𝑖=1 𝑛 𝑋𝑖𝑚 ො 𝑦𝑖 𝜕 ො 𝑦2 ⋯ 𝜕 σ𝑖=1 𝑛 𝑋𝑖𝑚 ො 𝑦𝑖 𝜕 ො 𝑦𝑛 の一行一列目だけ計算してみる. 他の要素についても同様の計算をすれば求められる. 𝜕 σ𝑖=1 𝑛 𝑋𝑖1 ො 𝑦𝑖 𝜕ො 𝑦1 = 𝜕 𝜕ො 𝑦1 ෍ 𝑖=1 𝑛 𝑋𝑖1 ො 𝑦𝑖 = 𝜕 𝜕 ො 𝑦1 𝑋11 ො 𝑦1 + 𝑋21 ො 𝑦2 + ⋯ + 𝑋𝑛1 ො 𝑦𝑛 = 𝜕 𝜕 ො 𝑦1 𝑋11 ො 𝑦1 + 𝜕 𝜕 ො 𝑦1 𝑋21 ො 𝑦2 + ⋯ + 𝜕 𝜕 ො 𝑦1 𝑋𝑛1 ො 𝑦𝑛 = 𝑋11 + 0 + ⋯ + 0 = 𝑋11 2024/12/13 54 ロジスティック回帰の理論
  25. ロジスティック回帰でのニュートン法 全部の要素について計算すると,最終的に以下のようになる. 𝜕 σ𝑖=1 𝑛 𝑋𝑖1 ො 𝑦𝑖 𝜕ො 𝑦1

    𝜕 σ𝑖=1 𝑛 𝑋𝑖1 ො 𝑦𝑖 𝜕ො 𝑦2 ⋯ 𝜕 σ𝑖=1 𝑛 𝑋𝑖1 ො 𝑦𝑖 𝜕ො 𝑦𝑛 𝜕 σ𝑖=1 𝑛 𝑋𝑖2 ො 𝑦𝑖 𝜕ො 𝑦1 𝜕 σ𝑖=1 𝑛 𝑋𝑖2 ො 𝑦𝑖 𝜕ො 𝑦2 ⋯ 𝜕 σ𝑖=1 𝑛 𝑋𝑖2 ො 𝑦𝑖 𝜕ො 𝑦𝑛 ⋮ ⋮ ⋱ ⋮ 𝜕 σ𝑖=1 𝑛 𝑋𝑖𝑚 ො 𝑦𝑖 𝜕ො 𝑦1 𝜕 σ𝑖=1 𝑛 𝑋𝑖𝑚 ො 𝑦𝑖 𝜕ො 𝑦2 ⋯ 𝜕 σ𝑖=1 𝑛 𝑋𝑖𝑚 ො 𝑦𝑖 𝜕ො 𝑦𝑛 = 𝑋11 𝑋21 ⋯ 𝑋𝑛1 𝑋12 𝑋22 ⋯ 𝑋𝑛2 ⋮ ⋮ ⋱ ⋮ 𝑋1𝑚 𝑋2𝑚 ⋯ 𝑋𝑛𝑚 = 𝑋𝑇 つまり 𝜕 𝜕ෝ 𝒚 𝑋𝑇ෝ 𝒚= 𝑋𝑇 2024/12/13 55 ロジスティック回帰の理論
  26. ロジスティック回帰でのニュートン法 𝜕ෝ 𝒚 𝜕𝒘 を計算する. これは,一旦ヤコビ行列を展開したほうがわかりやすいと思うので,展開する. 𝜕ෝ 𝒚 𝜕𝒘 =

    𝜕ො 𝑦1 𝜕𝑤1 𝜕ො 𝑦1 𝜕𝑤2 ⋯ 𝜕ො 𝑦1 𝜕𝑤𝑚 𝜕ො 𝑦2 𝜕𝑤1 𝜕ො 𝑦2 𝜕𝑤2 ⋯ 𝜕ො 𝑦2 𝜕𝑤𝑚 ⋮ ⋮ ⋱ ⋮ 𝜕ො 𝑦𝑛 𝜕𝑤1 𝜕ො 𝑦𝑛 𝜕𝑤2 ⋯ 𝜕ො 𝑦𝑛 𝜕𝑤𝑚 2024/12/13 56 ロジスティック回帰の理論
  27. ロジスティック回帰でのニュートン法 𝜕 ො 𝑦1 𝜕𝑤1 𝜕 ො 𝑦1 𝜕𝑤2 ⋯

    𝜕 ො 𝑦1 𝜕𝑤𝑚 𝜕 ො 𝑦2 𝜕𝑤1 𝜕 ො 𝑦2 𝜕𝑤2 ⋯ 𝜕 ො 𝑦2 𝜕𝑤𝑚 ⋮ ⋮ ⋱ ⋮ 𝜕 ො 𝑦𝑛 𝜕𝑤1 𝜕 ො 𝑦𝑛 𝜕𝑤2 ⋯ 𝜕 ො 𝑦𝑛 𝜕𝑤𝑚 の一行一列目だけ計算してみる. ො 𝑦1 = 𝜎(𝒘𝑇𝒙𝟏 ) 𝒙𝟏 = 𝑋11 𝑋12 ⋮ 𝑋1𝑚 = 𝑥11 𝑥12 ⋮ 𝑥1𝑚 ※この大文字小文字に特に意味はない. シグモイド関数の微分:(1 − 𝜎 𝑥 )𝜎 𝑥 から 2024/12/13 57 ロジスティック回帰の理論 𝜕ො 𝑦1 𝜕𝑤1 = 𝜕 𝜕𝑤1 𝜎 𝒘𝑇𝒙𝟏 = 𝜕 𝜕𝑤1 𝜎(𝑤1 𝑥11+𝑤2 𝑥12 + ⋯ + 𝑤𝑚 𝑥1𝑚 ) 𝜎の中の微分は𝑤1 の係数が出てくるので, = 𝜎 𝒘𝑇𝒙𝟏 1 − 𝜎 𝒘𝑇𝒙𝟏 𝑥11 = ො 𝑦1 (1 − ො 𝑦1 )𝑋11
  28. ロジスティック回帰でのニュートン法 全部の要素について計算すると,最終的に以下のようになる. 𝜕ො 𝑦1 𝜕𝑤1 𝜕ො 𝑦1 𝜕𝑤2 ⋯ 𝜕ො

    𝑦1 𝜕𝑤𝑚 𝜕ො 𝑦2 𝜕𝑤1 𝜕ො 𝑦2 𝜕𝑤2 ⋯ 𝜕ො 𝑦2 𝜕𝑤𝑚 ⋮ ⋮ ⋱ ⋮ 𝜕ො 𝑦𝑛 𝜕𝑤1 𝜕ො 𝑦𝑛 𝜕𝑤2 ⋯ 𝜕ො 𝑦𝑛 𝜕𝑤𝑚 = ො 𝑦1 (1 − ො 𝑦1 )𝑋11 ො 𝑦1 (1 − ො 𝑦1 )𝑋12 ⋯ ො 𝑦1 (1 − ො 𝑦1 )𝑋1𝑚 ො 𝑦2 (1 − ො 𝑦2 )𝑋21 ො 𝑦2 (1 − ො 𝑦2 )𝑋22 ⋯ ො 𝑦2 (1 − ො 𝑦2 )𝑋2𝑚 ⋮ ⋮ ⋱ ⋮ ො 𝑦𝑛 (1 − ො 𝑦𝑛 )𝑋𝑛1 ො 𝑦𝑛 (1 − ො 𝑦𝑛 )𝑋𝑛2 ⋯ ො 𝑦𝑛 (1 − ො 𝑦𝑛 )𝑋𝑛𝑚 実は,これはො 𝑦1 (1 − ො 𝑦1 ), ො 𝑦2 (1 − ො 𝑦2 ),…, ො 𝑦𝑛 (1 − ො 𝑦𝑛 )を対角成分にもつ対角行列と, 𝑋に分解できる. 2024/12/13 58 ロジスティック回帰の理論
  29. ロジスティック回帰でのニュートン法 分解して整理すると以下のようになる. = ො 𝑦1 1 − ො 𝑦1 0

    ො 𝑦2 1 − ො 𝑦2 ⋱ 0 ො 𝑦𝑛 1 − ො 𝑦𝑛 𝑋11 𝑋12 ⋯ 𝑋1𝑚 𝑋21 𝑋22 ⋯ 𝑋2𝑚 ⋮ ⋮ ⋱ ⋮ 𝑋𝑛1 𝑋𝑛2 ⋯ 𝑋𝑛𝑚 対角行列を𝑅と置くと. = 𝑅𝑋 つまり, 𝜕ෝ 𝒚 𝜕𝒘 = 𝑅𝑋 𝜕 𝜕ෝ 𝒚 𝑋𝑇ෝ 𝒚= 𝑋𝑇, 𝜕ෝ 𝒚 𝜕𝒘 = 𝑅𝑋 なので, 𝐻 = ∇2𝐸 𝒘 = 𝜕 𝜕𝒘 𝑋𝑇ෝ 𝒚 = 𝜕 𝜕ෝ 𝒚 𝑋𝑇ෝ 𝒚 𝜕ෝ 𝒚 𝜕𝒘 = 𝑋𝑇𝑅𝑋 𝐻 = 𝑋𝑇𝑅𝑋 これで𝐻が求められた. 2024/12/13 59 ロジスティック回帰の理論
  30. ロジスティック回帰でのニュートン法 ∇𝐸 𝒘 と𝐻が求められたので,更新式に代入する. - 更新式 :𝒘𝑛𝑒𝑤 = 𝒘𝑜𝑙𝑑 −

    𝐻−1∇𝐸 𝒘𝑜𝑙𝑑 - ∇𝐸 𝒘 = 𝑋𝑇(ෝ 𝒚 − 𝒚) - 𝐻 = 𝑋𝑇𝑅𝑋 以下の式変形は「逆行列を作る」「単位行列を作る」「結合法則」しか利用していないので補足はしない. 𝒘𝑛𝑒𝑤 = 𝒘𝑜𝑙𝑑 − 𝐻−1∇𝐸 𝒘𝑜𝑙𝑑 = 𝒘𝑜𝑙𝑑 − 𝑋𝑇𝑅𝑋 −1𝑋𝑇 ෝ 𝒚 − 𝒚 = (𝑋𝑇𝑅𝑋)−1𝑋𝑇𝑅𝑋𝒘𝑜𝑙𝑑 − 𝑋𝑅𝑋𝑇 −1𝑋𝑇𝑅𝑅−1 ෝ 𝒚 − 𝒚 = 𝑋𝑇𝑅𝑋 −1(𝑋𝑇𝑅)[𝑋𝒘𝑜𝑙𝑑 − 𝑅−1 ෝ 𝒚 − 𝒚 ] これがパラメータの更新式. これを元にパラメータを更新していくことで最適なパラメータが得られる. ※ 実装にあたっては,2行目の式で十分.4行目の形はIRLSというものと関係があるらしい. 2024/12/13 60 ロジスティック回帰の理論
  31. ライブラリのインポート コピペして使おう. import time import random import pandas as pd

    import numpy as np from sklearn.datasets import make_classification from sklearn.linear_model import LogisticRegression import matplotlib.pyplot as plt import matplotlib.patches as patches 2024/12/13 62 実装
  32. サンプルデータ 以下のコードで,図のようなサンプルデータを作成する.これを分類する. N = 1000 #データの数 d = 2 #

    次元数 K = 2 # クラス数 X, y = make_classification( n_samples=N, n_features=d, n_informative=1, n_redundant=0, n_clusters_per_class=1, n_classes=K, random_state=20 ) plt.scatter(X[:, 0], X[:, 1], marker="o", c=y, s=25) plt.show() 2024/12/13 63 実装
  33. テンプレート tol : 停止基準の許容範囲. 更新後のパラメータと更新前のパラメータの 差がtol以下であれば更新を停止する. max_iter : 最大の更新回数. コードの書き方次第で更新回数を少なく抑え

    られる. …を埋めて実装してみよう. 2024/12/13 64 実装 class LogisticRegression(): def __init__(self, tol: float=0.0001, max_iter: int=100): self.tol = tol self.max_iter = max_iter @staticmethod def _sigmoid(...): # クラス内部で使う関数なので,アンダースコアをつける # シグモイド関数を実装する. return ... def fit(self, x, y): # 学習部分 ... def predict(self, x): # 予測部分 return ...
  34. 期待の出力 左のように使って,右のcoef_と大体同じような出力が得られればOK パラメータはwで,一方のクラスに属する確率はpredict_probaでおく. (できてても,たまにうまくいかなかったりするので何回か実行すると良い.今回の実装は不安定だから) 素直に実装すると,実行時間はデータ数1000で,大体3秒くらいになる. 2024/12/13 65 実装 model =

    LogisticRegression( tol=0.0001, max_iter=100 ) start = time.time() model.fit(X,y) end = time.time() time_diff = end - start print('実行時間',time_diff) print("coef_",model.w) pred = model.predict(X) print("更新回数", model.iter) 実行時間 0.027270793914794922 coef_ [3.62964534 0.07741521] 更新回数 7
  35. 実装に必要な材料 シグモイド関数: 𝜎 𝑥 = 1 1 + 𝑒−𝑥 ここの𝑥は,説明変数が入るわけではないの

    で注意.ただ変数として置いているだけ. 2024/12/13 66 実装 モデル: ො 𝑦 = 𝜎(𝒘𝑇𝒙) しかし, データ一つに対しての場合なので… 実際は行列にした𝑋と𝒘の内積を使う. ෝ 𝒚 = 𝜎(𝑋𝒘) 全データに対しての予測値ということ. 𝑛: データ数 𝑚: 次元数 𝒙 ∈ ℝ𝑚:説明変数 𝑋 ∈ ℝ𝑛×𝑚:説明変数(全てのデータ) 𝑦 ∈ ℝ:目的変数 𝐲 ∈ ℝ𝑛:目的変数(全てのデータ) 𝒘 ∈ ℝ𝑚:パラメータ
  36. 実装に必要な材料 学習 - パラメータや,必要な変数の初期化 - パラメータの初期化.(ランダムでOK) - 対角行列の初期化.(単位行列を作成して初期化すると良い.) - ∇𝐸

    𝒘 = 0を表すのに,更新後のパラメータと更新前のパラメータとの差を利用する. その差が限りなく0に近くなっていれば収束判定,その基準はtol=0.0001で与えている. 収束判定のために,更新後のパラメータと更新前のパラメータとの差を格納するリストを初期化する. ここはnp.infで初期化すると良い.(絶対0にしたくないから.) リストと,tolを比べて,リストの要素全てがtolの値を下回ったら収束とすれば良い. - イテレーション数を初期化する.更新するごとに,+1をして更新回数を計測する. 2024/12/13 67 実装
  37. 実装に必要な材料 学習 - 更新式を回し,最適なパラメータを求める 𝒘𝑛𝑒𝑤 = 𝒘𝑜𝑙𝑑 − 𝑋𝑇𝑅𝑋 −1𝑋𝑇

    ෝ 𝒚 − 𝒚 𝑅 = ො 𝑦1 1 − ො 𝑦1 ො 𝑦2 1 − ො 𝑦2 ⋱ ො 𝑦𝑛 1 − ො 𝑦𝑛 ෝ 𝒚 = 𝜎(𝑋𝒘) 2024/12/13 68 実装
  38. 実装に必要な材料 学習 - 以下の3つを更新する - 更新後のパラメータと更新前のパラメータとの差のリスト - イテレーション数(更新回数) - パラメータ

    に戻って繰り返す. 収束判定は, - 更新後のパラメータと更新前のパラメータとの差のリストの全要素がtolを下回っている. or - イテレーション数(更新回数が),max_iterに達する. 2024/12/13 69 実装
  39. 追加課題 - 逆行列を明示的に求めるのは安定性と早さに欠ける. - 𝒘 = 𝐴−1𝑏ではなくて,𝐴𝒘 = 𝑏を解くと考える. -

    対角行列を扱うのは時間がかかる. - 実はベクトルで代用できる. 右が,対角行列を求めるパターン 左が,対角行列を使わず,ベクトルを使用するパターン これをロジスティック回帰に組み込むようにしてみよう. 2024/12/13 72 実装
  40. ヒント ヒント1: あくまで二値に分類するのは予測時なので, ෝ 𝒚は学習中は確率の値がそのまま使用される. ヒント2: (更新後のパラメータと,更新前のパラメータとの差)とtolを比較する. そのために, - (更新後のパラメータと,更新前のパラメータとの差)が格納されるリスト.

    - tolが格納されるリスト この二つのリストを比較するようにする.要はリストのサイズを合わせて,対応するリストの要素同士で比較すれば良い.tolより低くなっ ていたら収束. ヒント3: 対角行列は,初期化した単位行列に対し,代入していけば良い. それ以外のやり方もあるけど. ヒント4: whileのbreakの条件は, (iterがmax_iterより小さい) & (更新後のパラメータと,更新前のパラメータとの差のリストの全要素がtol以上) これがFalseになったらbreakするようにすれば良い.(てかこれをそのままコードに起こせばできる.) 2024/12/13 73 実装
  41. 答え class LogisticRegression(): def __init__(self, tol: float=0.0001, max_iter: int=100): self.tol

    = tol self.max_iter = max_iter @staticmethod def _sigmoid(Xw): return 1 / (1 + np.exp(-Xw)) 2024/12/13 74 実装 停止基準の許容範囲(tol). 更新後のパラメータと更新前のパラメータの 差がtol以下であれば更新を停止する. 最大の更新回数(max_iter). これらを初期化する. シグモイド関数は数式をそのまま書くだけ. 𝜎 𝑥 = 1 1 + 𝑒−𝑥 関数名の前に_がついているのは,ユーザーがこ の関数を呼び出して使うことを想定していない ため. @staticmethodは,静的メソッドに変換するため のデコレータである. シグモイド関数は,クラス内で使い回す関数な ので,numpyのメソッドのように使いたい思い があってこのように定義している.
  42. 答え def fit(self, x, y): self.w = np.random.randn(x.shape[1]) tol_vec =

    np.full(x.shape[1],self.tol) diff = np.full(x.shape[1], np.inf) self.iter = 0 while np.any(diff > tol_vec) and (self.iter < self.max_iter): y_hat = self._sigmoid(x @ self.w) R = np.diag(y_hat * (1 - y_hat)) w_new = self.w - (np.linalg.pinv((x.T @ R) @ x) @ x.T @ (y_hat - y)) diff = w_new - self.w self.iter += 1 self.w = w_new 2024/12/13 75 実装 重み(w),停止基準のベクトル (tol_vec),重みの差分を保存する ためのベクトル(diff),更新回数 (iter)を初期化する. while文の条件は, 重みの差分が停止基準を下回る か,更新回数が最大更新回数を超 える. に設定する. 予測値を算出する.(y_hat) 対角行列を作る.(R) 更新式をそのまま書く. 𝒘𝑛𝑒𝑤 = 𝒘𝑜𝑙𝑑 − 𝑋𝑇𝑅𝑋 −1𝑋𝑇 ෝ 𝒚 − 𝒚 最後にdiff,iter,w を更新する.
  43. 答え def predict(self, x): y_hat_Xw = np.dot(x, self.w) y_pred =

    self._sigmoid(y_hat_Xw) for _ in range(x.shape[0]): if y_pred[_] > 0.5: y_pred[_] = 1 elif y_pred[_] < 0.5: y_pred[_] = 0 return y_pred 2024/12/13 76 実装 予測値を算出する.(y_pred)この時点では確率. ここから0と1に分類する. 算出した予測値に対し,確率0.5より上であればクラス1に, 下であればクラス0に分類する.
  44. 追加課題の答え def fit(self, x, y): self.w = np.random.randn(x.shape[1]) tol_vec =

    np.full(x.shape[1],self.tol) diff = np.full(x.shape[1], np.inf) self.iter = 0 while np.any(diff > tol_vec) and (self.iter < self.max_iter): y_hat = self._sigmoid(x @ self.w) R = np.diag(y_hat * (1 - y_hat)) # w_new = self.w - (np.linalg.pinv((x.T @ R) @ x) @ x.T @ (y_hat - y)) w_new = self.w - (np.linalg.solve(((x.T @ R) @ x), x.T @ (y_hat - y))) diff = w_new - self.w self.iter += 1 self.w = w_new 2024/12/13 77 実装 方程式を解く.という解釈で 実装すると,np.linalg.solveと いうメソッドを使って,明示 的に擬似逆行列を使わずに実 装できる. (実際にはsolveメソッドが臨 機応変に対応してくれるだ け.)
  45. 追加課題の答え def fit(self, x, y): self.w = np.random.randn(x.shape[1]) tol_vec =

    np.full(x.shape[1],self.tol) diff = np.full(x.shape[1], np.inf) self.iter = 0 while np.any(diff > tol_vec) and (self.iter < self.max_iter): y_hat = self._sigmoid(x @ self.w) # R = np.diag(y_hat * (1 - y_hat)) r = y_hat * (1 - y_hat) # w_new = self.w - (np.linalg.solve(((x.T @ R) @ x), x.T @ (y_hat - y))) w_new = self.w - (np.linalg.solve(((x.T * r) @ x), x.T @ (y_hat - y))) diff = w_new - self.w self.iter += 1 self.w = w_new 2024/12/13 78 実装 対角行列をベクトルで代用す ると,行列演算が一個減るの で,大幅に実行時間を削減で きる. その代わり安定性に欠ける. (気がする.)
  46. 参考 • 加藤公一, 機械学習のエッセンス, SBクリエイティブ, (出版:2018/9/21) • C.M. ビショップ (著),

    元田 浩 (監訳), 栗田 多喜夫 (監訳), 樋口 知之 (監訳), 松本 裕治 (監訳), 村田 昇 (監訳), パターン認識と機械学習 上, 丸善出版, (出版:2012/01/20) • からっぽのしょこ, 4.3.2-3:ロジスティック回帰の導出【PRMLのノート】, (参照:2025/3/29) • 高校数学の美しい物語, ヤコビ行列,ヤコビアンの定義と極座標の例, (参照:2025/3/29) • ウィキペディア, ヤコビ行列, (参照2025/3/29) • AnchorBlues(Yu Umegaki), 「ベクトルで微分・行列で微分」公式まとめ, (参照:2025/3/29) • 高校数学の美しい物語, ベクトルの微分, (参照2025/3/29) 2024/12/13 79 実装