『Python数値計算ノート』ではアフィリエイトプログラムを利用して商品を紹介しています。

ロジスティック関数とロジット

ロジスティック関数

ロジスティック方程式
 \[\frac{dN}{dx}=aN\left( 1-\frac{N}{K}\right)\tag{1}\]
の解である ロジスティック関数 (Logistic function) は、シグモイド関数
 \[f(x)=\frac{1}{1+\exp(-ax)}\quad (a\gt 0)\tag{2}\]
を特別な形として含む、より汎用的な関数です:
 \[N=\frac{K}{1+\exp\left\{-a(x-x_0)\right\}}\tag{3}\]
この定義式において $K=1,\ x_0=0$ とすればシグモイド関数となります。シグモイド関数は(パラメータ $a$ によって)曲線の形しか変えられませんでしたが、ロジスティック関数は $x_0$ によって左右に平行移動させることが可能です。このような柔軟性から、機械学習の分類問題の回帰手法 (最尤推定の記事を参照) としてロジスティック関数が用いられることがあります。
 
次のコードは $a=1,\ K=1$ として、$x_0$ を変化させて少しずつ平行移動させたロジスティック関数をプロットします。

# PYTHON_LOGISTIC

# In[1]

# ライブラリをインポート
import numpy as np
import matplotlib.pyplot as plt

# ロジスティック関数を定義
def logistic(x, a, k, x0):
    y = k / (1 + np.exp(-a * (x - x0)))
    return y

# グラフ描画領域の設定
fig = plt.figure()
ax = fig.add_subplot(111)
ax.grid(linestyle = "--")
ax.set_title("Logistic Function", fontsize = 16)
ax.set_xlim(-8, 10)
ax.set_xlabel("x", fontsize = 16)
ax.set_ylabel("y", fontsize = 16)

# xのデータ
x = np.linspace(-10, 10, 257)

# x0を変えながらロジスティック曲線をプロット
x0 = [0, 2, 4]
for j in range(3):
    y = logistic(x, 1, 1, x0[j])
    ax.plot(x, y, label = "x0 = {}".format(x0[j]))

ax.legend()

Python ロジスティック関数

オッズとロジット

シグモイド関数において、$a=1$ とした関数を標準シグモイド関数とよびます:
 \[y=\frac{1}{1+e^{-x}}\tag{4}\]
標準シグモイド関数の逆関数を ロジット またはロジット関数とよび、$\mathrm{logit}(x)$ で表します:
 \[\mathrm{logit}(x)
=\log\left(\frac{x}{1-x}\right)=\log(x)-\log(1-x)\quad (0\lt x\lt 1)\tag{5}\]
ロジットは主に確率・統計の分野で使用される関数で、普通は変数を $x$ の代わりに $p$ で表します:
 \[\mathrm{logit}(p)=\log\left(\frac{p}{1-p}\right)\quad (0\lt p\lt 1)\tag{6}\]
このとき、$p$ はある事象 $A$ が起こる確率を表します。$p/(1-p)$ はオッズとよばれる値です。
 \[\mathrm{Odds}=\frac{p}{1-p}\tag{7}\]
オッズは事象 $A$ が起こる確率と起こらない確率の比なので、事象 $A$ の起こりやすさの指標となります。オッズは Python でオッズ関数を定義して、グラフの概形を描いてみます。

# PYTHON_ODDS

# In[1]

import numpy as np
import matplotlib.pyplot as plt

# オッズ関数を定義
def odds(p):
    return p / (1 - p)

# データの作成
p = np.linspace(0.01, 0.99, 65)

# 描画領域の設定
fig = plt.figure()
ax = fig.add_subplot(111)
ax.grid()
ax.set_xlim(0, 1)
ax.set_ylim(0, 10)
ax.set_title("Odds", fontsize=16)
ax.set_xlabel("p", fontsize=16)
ax.set_ylabel("Odds(p)", fontsize=16)

# オッズをプロット
ax.plot(p, odds(p), color="blue")

plt.show()

Python Oddsの概形 (グラフ)
オッズは $p=1/2$ のとき $1$ となり、$p$ が $1$ に迫るにつれて急激に値を増加させ、$p\to\ +1$ で $\infty$ となります。
 
ロジットはオッズの 対数 として定義されています。
Matplotlib でロジットの概形を描いてみます。

# PYTHON_LOGIT

# In[1]

# ロジット関数を定義
def logit(p):
    return np.log(odds(p))

# データの作成
p = np.linspace(0.01, 0.99, 65)

# 描画領域の設定
fig = plt.figure()
ax = fig.add_subplot(111)
ax.grid()
ax.set_xlim(0, 1)
ax.set_ylim(-4, 4)
ax.set_title("logit function", fontsize=16)
ax.set_xlabel("p", fontsize=16)
ax.set_ylabel("logit(p)", fontsize=16)

# ロジット関数をプロット
ax.plot(p, logit(p), color="blue")

plt.show()

ロジット関数の概形
オッズは正の値のみをとるのに対し、ロジットは $p\lt 0.5$ で負の値をとる関数です。$p\to -0$ あるいは $p\to +1$ で発散する関数ですが、対数をとっているので、オッズに比べると変化は緩やかです。

 

コメント

  1. HNaito より:

    いくつかサイトを調べてみましたが、ロジスティック関数の定義としては、たとえばWikipediaでは初期値を t=0 で N = N0として、
    N=K/{1+(K/N0-1)exp(-rt)}
    という解が紹介されていました。自分で解いてみても納得できます。この場合は K=1, N0=K/2, r=1のときシグモイド関数になります。(3)式の定義で exp の中に K が入っているのは誤植でしょうか。

    • あとりえこばと より:

      申し訳ありません。おっしゃるように、(3)式は誤りです。微分方程式を解く時に計算ミスをしていたのだと思います。(3) 式および PYTHON_LOGISTIC のコードの一部を修正しておきました。m(_ _)m

  2. あとりえこばと より:

    logisticの由来について調べています

    「ロジクティック」の名称の由来を調べています。というのは、logistic という英単語は「物流」、「記号論理学の」、「兵站の」などの意味がありますが、どれも人口増加モデルや回帰分析とは全く関係なさそうな気がするからです。Wikipedia によると、1958 年にデイヴィッド・コックスという人物が、ロジット関数 (ロジクティック関数の逆関数) を用いる「ロジスティック回帰」の論文を発表したとあります。しかしながら、この人物に関する項目には、なぜ “logistic” という名称を採用したかは書かれていません。ちなみに、今流行りの ChatGPT に尋ねてみると、以下のような返答でした。

    ロジスティック関数の名前の由来は、ラテン語の “logisticus”(輸送に関する)から来ています。この関数は、輸送や流れの理論に関係する分野で、物資の輸送や配布などをモデル化するために使用されていました。その後、統計学や機械学習の分野でも広く使用されるようになり、現在ではシグモイド関数とも呼ばれています。

    … 絶対嘘だと思いました。確かにロジスティクスは物流の流れを最適化する工程管理手法ですが、ロジスティック方程式やロジスティック関数とは全くの別物です。ChatGPT は知らないことを質問されると、知ったかぶりをして平然と嘘を答えるという厄介な性格を持ち合わせているので注意が必要です(機械学習のアルゴリズムの性質上、仕方ない面もありますが)。何はともあれ、”logsitic” の由来について有力な情報がありましたら、コメント欄でお寄せくださると助かります。