「今年中にあなたが結婚できる確率は4%です。しかし英会話スクールに入ることで、結婚できる確率が2%上がります。」
「あなたは3年後にリストラされる確率は65%です。しかし今からpythonを学ぶことで、リストラされる確率が30%下がります。」

ロジスティック回帰分析は、分類モデルを作るアルゴリズムです。そして、分類結果の発生確率を予測します。例えば「ガンになる確率 30%」 のような予測ができます。

また、モデルの中身を数式として出力できるので、ディープラーニングのようにブラックボックスになりません。そのため、企業データの分析レポートなどでは、ロジスティック回帰とディープラーニングの2種類の手法で分析して比較するということがよく見られます。

一方、ロジスティック回帰は、線形分離可能なクラスに対してのみ高い性能が発揮されます。非線形の問題はうまく学習できないという重回帰分析と同じ問題を抱えています。

重回帰分析とロジスティック回帰分析

重回帰分析は数値を予測する手法です。ロジスティック回帰分析は、2値分類を予測する手法です。分析対象によって用途が異なります。

重回帰分析:y=ax+b y:数値
ロジスティック回帰分析:loge{y/(1-y)}= ax+b  y:2値(0 or 1など)

(補足)
回帰分析からロジスティック回帰分析を導出可能です。0 から 1 の値を取るシグモイド関数に線形回帰を代入して、対数尤度関数を最小化すれば、ロジスティック回帰の式が出てきます。厳密には、シグモイド関数ではなく正規分布の累積密度関数で導出すべきなのですが、累積密度関数を近似したシグモイド関数を使うときれいに計算できるので、こちらがよく利用されます。

ロジスティック回帰分析をscikit-learnで実装する

重回帰分析はExcelでもできますが、ロジスティック回帰分析は、専用のツールが必要です。そのため、いつものpythonとscikit-learnでモデルを実装してみます。 

データセットは、UCIのBank Marketingを利用しました。この銀行データを使って、顧客が定期預金を申し込む確率を予測します。

参考記事:AIエンジニアが教えるゼロから機械学習の勉強法


①csvファイル読み込み

csvデータを読み込んで、特徴量xと教師ラベル(目的変数)yに分けて格納しました。
csvファイルの右端に教師ラベルがあったので、df.ix[:, -1].valuesで右端列を格納しています。
import numpy as np
import pandas as pd
from sklearn.metrics import confusion_matrix
from sklearn import grid_search
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt

#csvファイルの読み込み
df = pd.read_csv('bank-additional_01.csv')

x = df.ix[:, 0:-1].values
y= df.ix[:, -1].values


②モデルの定義

LogisticRegression()関数の最適なパラメータCについて、グリッドサーチで探索しています。
最も精度の高いパラメータを、clf.best_params_で取得しました。
#ロジスティック回帰の定義
clf = grid_search.GridSearchCV(LogisticRegression(), {'C':[0.1,1,10,20,50,100]})
clf = clf.fit(x, y)

#ベストパラメータのモデル
print clf.best_params_
clf_best = clf.best_estimator_


出力結果
{'C': 1}


③モデルの作成と評価

交差検定と混合行列で、モデルの精度を評価しました。
参考記事:交差検定(クロスバリデーション)など機械学習の評価方法まとめ
#交差検定
score = cross_val_score(clf_best, x, y, cv=5)
print "----クロスバリデーション----"
print score.mean()

y_pre = clf_best.predict(x)
print "---Confusion Matrix---"
print confusion_matrix(y, y_pre)

出力結果
----クロスバリデーション----
0.883495145631
---Confusion Matrix---
[[2705   15]
 [ 341   29]]

④確率モデルの表示

ロジスティック回帰は、モデルを数式で表すことが出来ます。
今回は以下のような結果になりました。
#数式モデル
print "切片:  " + str(clf_best.intercept_)
print "係数:   " + str(clf_best.coef_)

出力結果
切片:  [-4.66328491]
係数:   [[ 0.0122054   0.17699825  0.15220169 -0.00568729 -0.07541696 -0.10128668  0.87517413  1.95041109]]

⑤確率グラフの作成

定期預金の購入確率を、昇順で並べたグラフを作成したくて、少しコードを書きました。横軸は昇順で並べた顧客番号、縦軸は定期預金の購入確率です。

購入期待値の20%のところで点線をひいています。これより上の顧客にアプローチすれば営業がうまくいくかもしれませんね。
#確率の計算
#特徴量ごとに推定値をかけて足し合わせる
ans = 0
for i in range(len(clf_best.coef_[0])):
    ans = ans + x[:, i].dot(clf_best.coef_[0, i])

#足し合わせた結果に切片を足す
ans1 = ans + clf_best.intercept_

#ロジスティック回帰の確率を算出する
ans2 = 1.0/(1+ np.exp(-ans1))

#列を追加する
df['score'] = ans2

#確率が低い人から昇順で並べ替え
#print df.sort_values(by=["score"], ascending=True)

#グラフ作成
X_value = clf_best.decision_function(x)

def sigmoid(x):
    return 1 / (1+np.exp(-x))
    
prop = sigmoid(X_value)
prop2 = np.sort(prop)

#グラフ作成
plt.plot(np.sort(sigmoid(X_value)))
plt.plot([0,3100], [0.2, 0.2],linestyle="--")
plt.ylim(0,1)
plt.show()

出力結果
figure_2

ロジスティック回帰は、有名なアルゴリズムですが、有名には有名になるだけの理由があります。冒頭でも書きましたが、一番の理由は発生確率の構造が分かることです。

確率の構造が分かるというのは結構すごいことで、診断系のWebサービスとか作ったら結構流行るのではないかと思っています。「自転車通勤すると死亡確率が3%とあがります」とか「リンゴを毎日食べると生存確率が10%とあがります」とか個人個人で診断してくれたら面白いですよね。

あとインターネットで、「あなたがこのビタミン材を購入すると、脂肪肝が治ります」とかいう広告打てたらすごいクリックされますよね。Amazonあたりならできそうな気が。。。

ちなみにpythonでWebサービスを作るなら、WebアプリケーションフレームワークはFlaskが断然おススメです。なぜならとても簡単に使えるからです。

さあ明日からいろんな確率を求めてみましょう。僕たちの未来はロジスティック回帰が導いてくれるはずです。