データサイエンスろぐ

データサイエンスを学ぶ大学4年生の学習ブログ

ロジスティック回帰分析を勉強したのでさらにわかりやすく解説した

概要

以前、ロジスティック回帰分析についての記事を執筆した。

dslog.hatenablog.jp

この記事は、かなり付け焼き刃な解説をしており、わかっているようなわかっていないような感じがする。

この記事を執筆した後も引き続き勉強を行い、当時(と言ってもたかだか数日前だが)よりは理解が深まってきたため、アウトプットのために改めて解説をしようと思う。

前回よりもさらにわかりやすい解説、具体的には機械学習に詳しくない高校生や大学1年生などが読んでもわかるような解説をする。

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

ロジスティック回帰分析とは、ある事象が起きるか起きないかということを予想するための分析である。

一般的には、「回帰分析」というと、数値を予想することなのだが、ロジスティック回帰分析は数値予想ではなく、分類問題なので注意が必要だ。

ある事柄が起きるか起きないかということを予想することの例として、天気予報を考えよう。

例1) 明日の降水確率は90%です。

上のような場合、明日の天気が「晴れ」か「雨」かと聞かれたら、多くの人が「雨」と答えるだろう。

では、次の場合はどうだろう?

例2) 明日の降水確率は51%です。

少し迷うだろう。

「降るかもしれないし、降らないかもしれない。傘くらい一応持っていこうか。」

という感じの確率だ。

ここで、「明日の天気はなんですか?晴れか雨かで答えてください。わからないとか曇りとかは無しで!」

と聞かれたら何と答えるだろうか。

おそらく普通の感覚の持ち主ならば「雨」と答えるだろう。

なぜなら、雨が降る確率が50\%を超えているから。

少し冗長な例え話になってしまったが、要するに確率が50\%を超えるならばその事象は起きると予想し、確率が50\%を下回るなら事象は起きないと予想するのが普通の感覚である。

ということは、ある事象が起きる場合、 0.5より大きい値を、ある事象が起きない場合、 0.5より小さい値を返してくれるような関数で0から1の値をとる関数が存在すると嬉しいわけだ。

ここまでのイメージを踏まえて、次項からはさらに詳しく考えていく。

変数が1つの場合を考える

ある事象が起きる確率を考えるときに、まず、何が事象の起きる可能性を左右するのか(これを特徴量という)を考えよう。

dslog.hatenablog.jp

例えば、先ほどの天気予報の例で考えると、特徴量は「雲量」かもしれない。あるいは、「前日の天気」かもしれない。(気象学に詳しくないので間違ってたらごめんなさい)

他の例えで考えると、「ある学生が入学試験にパスするかどうか」を予想するときの特徴量として「勉強時間」や「模擬試験の点数」などを設定するかもしれない。

このように、特徴量はいくつかあるケースの方が多いが、わかりやすさのために特徴量が1つの場合を考えよう。

シグモイド関数

特徴量を x、特徴量から導かれる事象が起きる確率を yとしよう。

ここで、 xがある値を超えると急激に 1に近づき、 xがある値を下回ると急激に 0に近づくような関数を考えたい。

そのような関数(これを活性化関数という)はたくさんあり、最もわかりやすい例としてはステップ関数などが挙げられるが、ロジスティック回帰分析ではシグモイド関数を扱う。

シグモイド関数は次式で表される関数である。

y = \frac{1}{1+ \exp[-(wx)+b]}

グラフにすると次のような形になる。

f:id:DSlog:20200623153944p:plain

なぜシグモイド関数なのか、というのは前回のブログで書いたようにオッズ比ロジット関数など確率にまつわる背景がある。

dslog.hatenablog.jp

さて、上記の式中にはwbという文字が突然出てきたが、これらは定数である。

wのことを重みと言い、bのことをバイアスと言う。

重みとバイアスをどのように設定すれば、入力xに対して、出力yを高精度で返すのかというのを探るのが機械学習の本質である。

(ここで言う高精度とは、現実の結果に非常近いということ)

ではここから、重みとバイアスが出力結果にどのような影響を与えているのかを見ていく。

重みを変化させると

下図は重みwを変化させたときのシグモイド関数の形の変化を表したものである。

f:id:DSlog:20200630212206p:plain

重みwが大きくなるほど、シグモイド関数の変化が急激になり、特徴量xが事象が起きるかどうかに強い影響を与えるということになる。

いや、実際には、結果から逆算して重みwを決めるため、事象が起きるかどうかについて特徴量xが与える影響が強ければ、重みwが大きくなるという言い方の方が正しいだろう。

バイアスを変化させると

下図はバイアスbを変化させたときのシグモイド関数の形の変化を表したものである。

f:id:DSlog:20200630212229p:plain

バイアスが事象の起きるか起こらないかの境目になっていると見ることができる。

おわりに

ロジスティック回帰分析について、機械学習に詳しくない高校生や大学1年生などが読んでもわかるようにということを意識して解説した。

これからデータサイエンスを学び始める方のとっかかりとなれば幸いである。

参考図書

株式会社マイナビ出版から発行されている、中山光樹著の『機械学習・深層学習による自然言語処理入門 scikit-learnとTensorFlowを使った実践プログラミング』という書籍が非常にわかりやすく大変参考になった。

www.amazon.co.jp

機械学習における特徴量の種類や処理についてまとめた

今回は、機械学習における特徴量の種類と主な処理方法をまとめた。

質的変数と量的変数

まず、特徴量には大きく分けて質的変数量的変数がある。

質的変数は質的な変数で、量的変数は量的な変数である。

…これではさすがに説明になっていないので説明しないほうがマシと言われてもしょうがないため、もう少しちゃんと説明する。

質的変数は、例えば、ある画像データが「ネコ」であるとか「イヌ」であるとか(名義尺度という。詳しくは後述)、服のサイズが「S以下」か「M」か「L以上」かとか(順序尺度という。詳しくは後述)、データの性質を表す変数のことである。

一方、量的変数は、例えば、体重が何kgか、速さが時速何kmか、テストの点数が何点か、といった測定可能な変数のことである。

よく定性的とか定量といった言葉を聞くがそのイメージだとわかりやすい。

ただし、質的変数のことを、性的変数と言ってしまうと、「男」か「女」かという変数なのか、はたまたエッチな変数なのか、と要らぬ妄想を膨らませてしまう危険性があるので注意が必要である。

質的変数

さて、質的変数には大きく分けて名義尺度というものと、順序尺度というものがある。

名義尺度

名義尺度は、具体的には、ある画像データが「ネコ」であるとか「イヌ」であるとか、そういうものをイメージするとよい。

後述の順序尺度とは違って、「ネコ」であるか「イヌ」であるかということに順序関係はない。

「私はイヌよりもネコの方が好きだからネコの方が上だよ」

という考え方は名義尺度で考える場合は適用しない。

順序尺度

順序尺度は、服のサイズが「S以下」か「M」か「L以上」かというものをイメージするとよい。

これらには、大きさという点においては明確に順序関係が存在し、

S以下\lt M\lt L以上

という関係が成り立つ。

量的変数

量的変数にも種類があり、間隔尺度と、比例尺度に分けられる。

間隔尺度

間隔尺度は、例えば気温をイメージするとわかりやすい。

気温は摂氏か華氏かによって変わるが、特定の単位をもって表現される。

後述の比例尺度との違いは、0が相対的なものであり、絶対的なものではないという点である。

0℃というのは人間が勝手に水が氷になる温度として設定しただけであり、ゼロという意味はない。あくまで相対的なものである。

比例尺度

比例尺度は、身長や体重といったものをイメージするとよい。

間隔尺度と違い、0に絶対的な意味がある。

特徴量の処理

ここからは、特徴量の主な処理方法をまとめる。

順序尺度

順序尺度はマッピングという手法を用いて処理する。

マッピング

マッピングは、特徴量を数値に対応させる処理である。

数値に対応させることで、コンピュータが処理できるようになるし、数値の大小によって順序関係も考えることができるようになる。

服のサイズを例にして具体的に説明する。

コンピュータに「S」とか「M」とか「L」とか言っても、コンピュータにとってそれらは単なる文字に過ぎないので、例えば「S以下」を0に、「M」を1に、「L以上」を2に、といった具合に数値に対応させる。

こうすることで、コンピュータが処理しやすい形になり、

S以下\lt M\lt L以上

という順序関係も考えることができるようになる。

名義尺度

名義尺度も同様にマッピングを行うのだが、名義尺度には順序関係がない分、違うマッピングの方法がある。

one-hotマッピング

名義尺度には順序関係がない。

そのため、例えば「ネコ」は0、「イヌ」は1、「ゾウ」は2、といったマッピングを行っても、0,1,2の大小関係には意味がない。

ここで、one-hotマッピングというものがある。

言葉で説明するよりも、表を用いて説明するほうがわかりやすいため、以下の表を参照してほしい。

イヌ ネコ ゾウ
ダックスフント 1 0 0
ゴールデンレトリーバー 1 0 0
スコティッシュフォールド 0 1 0
アフリカゾウ 0 0 1
インドゾウ 0 0 1
乃木坂46 欅坂46 日向坂46
齋藤飛鳥 1 0 0
鈴木絢音 1 0 0
菅井友香 0 1 0
加藤史帆 0 0 1
上村ひなの 0 0 1

このように該当するものに関しては1を該当しないものに関しては0を付与するマッピング方法である。

量的特徴量

量的特徴量の処理方法には、2値化丸めといったものがある。

2値化

2値化はある閾値を超えるデータは1,超えないデータは0とみなす処理である。

こうすることで、その後の処理を高速化することができるというメリットがある。

例)乃木坂46の1stシングルから25thシングルまでの選抜入り回数を5回以上か5回未満かによって2値化する。

実際の選抜回数 2値化
齋藤飛鳥 18 1
鈴木絢音 2 0
堀未央奈 17 1
大園桃子 6 1
岩本蓮加 3 0

丸め

実際のデータとしては少数第〇位まで測定されているが、

今回の解析ではそこまでの精度のデータは求めてないよ

という場合に、整数に変換するような処理のことを丸めという。

参考図書

株式会社マイナビ出版から発行されている、中山光樹著の『機械学習・深層学習による自然言語処理入門 scikit-learnとTensorFlowを使った実践プログラミング』という書籍が大変参考になった。

www.amazon.co.jp

ロジスティック回帰分析を勉強したのでわかりやすく解説した

概要

前回のブログでは、ロジスティック回帰分析を用いて乃木坂46の選抜を予想するということを行った。

dslog.hatenablog.jp

実際に手を動かすことで、ロジスティック回帰分析に慣れ親しむことはできた。

しかし、理論的な部分についてはほとんど理解できなかったため、その後、ロジスティック回帰分析の理論的なところを勉強した。

今回の記事では、ロジスティック回帰分析の理論的な部分について学習したことをまとめる。

最後には勉強になった記事をまとめた。

誰のための記事か

この記事が誰のための記事かというと、まずは自分自身のためである。

他人に説明するつもりで言語化することで、理解を深めたい。

また、これからロジスティック回帰分析を初めて学習する方の理解の助けになれば幸いである。

ロジステック回帰分析とは

ロジスティック回帰分析とは何か、一言で表すと、

ある事象が起きる確率を分析すること

である。

ロジスティック回帰分析では、ある事象が起きる確率を

p = \frac{1}{1+ exp[-(b_{1}x_{1}+b_{2}x_{2}+…+b_{n}x_{n})]}

という式で求めようとする。

ここで x_{i} は説明変数であり、b_{i} は偏回帰係数である。

平たく言うと、

偏回帰係数をどのように設定すれば、確率pを正しく求められるかを知りたい

というのがロジスティック回帰分析の気持ちである。

偏回帰係数をどのように設定すると良いかは、最尤法(さいゆうほう)を用いて求める。

シグモイド関数の導出

ロジスティック回帰分析では、ある事象が起きる確率を

p = \frac{1}{1+ \exp[-(b_{1}x_{1}+b_{2}x_{2}+…+b_{n}x_{n})]}

という式で求めようとする、ということだが、なぜこの形になるのだろうか?

上記のpの式について、b_{1}x_{1}+b_{2}x_{2}+…+b_{n}x_{n}z とおいた形をシグモイド関数と言うのだが、この形を導き出すために、

  • オッズ比
  • ロジット関数

が出てくる。

横文字が苦手な方は吐き気がするかもしれないが、全く難しくないので落ち着いて欲しい。

(横文字が苦手な自分は初めて見たとき錯乱しかけた)

オッズ比

オッズ比は、ある事象が起きる確率と起こらない確率の比である。

 オッズ比 = \frac{p}{1-p}

ある事象が起きる確率 p1に近ければ近いほどオッズ比も大きくなり∞に発散する。

(オッズ比と言わずに確率比と言えば良いのにと思うのは自分だけ?)

ロジット関数

なんだか高度な関数な予感がする名前だが、オッズ比に対数をとったものに過ぎない。

 ロジット関数 = \log\frac{p}{1-p}

ロジット関数は 0 から 1 の値をとる。

元々 0 から 1 の値をとる p について、0 から ∞ の値をとるオッズ比を考えて、さらにそれを 0 から 1 の値をとるロジット関数にするのは、なんだか不思議な気がするが、次の節でこの変換の意図(?)が明らかになる。

シグモイド関数

シグモイド関数を導き出すために、ロジット関数を z とおく。

z=\log\frac{p}{1-p}

ここから少しずつ変形を加えていく。

e^{z}=\frac{p}{1-p}

p=\frac{e^{z}}{e^{z}+1}

p=\frac{1}{1+e^{-z}}

これは、最初に言及したシグモイド関数である。

グラフで表すと以下のようになる。

f:id:DSlog:20200623153944p:plain
シグモイド関数

z0 より大きい場合は p0.5 より大きくなるので、事象が起きると予想される。

z0 より小さい場合は p0.5 より小さくなるので、事象は起きないと予想される。

ここで、


y=
\left\{
\begin{array}{}
1( x \geq 0)(事象が起きる) \\
0( x \lt 0)(事象が起きない)
\end{array}
\right.

とする。

このとき、ロジスティック回帰分析の気持ちとしては、いくつかの訓練データを与えたとき、事象が起きる( y=1 )場合、確率 p はできるだけ大きく、事象が起きない( y=0 )場合、確率 p はできるだけ小さく出力されるようなシグモイド関数であって欲しいわけだ。

最尤法を用いた学習

そこで次のような尤度関数を考える。

\prod_{i=1}^{n}p_{i}^{y_{i}}(1-p_{i})^{1-y_{i}}

p_{i} は、データi が事象に当てはまる確率であり、y_{i} は、データi が事象に当てはまるかどうかである。

この尤度関数が大きければ大きいほど、いくつかの訓練データを与えたとき、事象が起きる場合、確率 p はできるだけ大きく、事象が起きない場合、確率 p はできるだけ小さく出力されるようなシグモイド関数であると言える。

そのため、尤度関数 \prod_{i=1}^{n}p_{i}^{y_{i}}(1-p_{i})^{1-y_{i}} が最大になるようなパラメータを見つけることを目標とする。

しかし、このままでは積の形になっており、計算が難しい。

そのため、対数をとって和の形にする。


\log(\prod_{i=1}^{n}p_{i}^{y_{i}}(1-p_{i})^{1-y_{i}})


=\sum_{i=1}^{n}(y_{i}\log p_{i} +(1-y_{i})\log(1-p_{i}))

これを最大にするような z= b_{1}x_{1}+b_{2}x_{2}+…+b_{n}x_{n} を求める。

すなわち、重みやバイアス b_{1},b_{2},…b_{n} を求める。

ただしこれを解析的に求めるのは難しいため、ニュートン法を用いて近似的に求める必要がある。

勉強になった記事

勉強になった記事、わかりやすかった記事の一覧

qiita.com

qiita.com

ai-trend.jp

ai-trend.jp

udemy.benesse.co.jp

乃木坂46選抜をブログとモバメの投稿数から予想するロジスティック回帰モデルを実装した

概要

乃木坂46のメンバーが選抜に入れるかどうかを公式ブログとMobileメールの投稿件数から予想する、ロジスティック回帰分析モデルを実装してみた。

2019年3月から2019年8月のブログ・モバメの投稿件数と24thシングルの選抜結果を訓練データとし、2019年9月から2020年2月のブログ・モバメの投稿件数と25thシングルの選抜結果をテストデータとした。

動機

自然言語処理100本ノックの第6章に「ロジスティック回帰モデルを学習せよ」という問題が出てきた。

51で構築した学習データを用いて,ロジスティック回帰モデルを学習せよ.

出典:自然言語処理100本ノック

お恥ずかしい話だが、ロジスティック回帰分析というものを知らず、

「ロジスティック回帰分析?何それ美味しいの?」

「ロジスティック三色パン??」

という状態だったため、ロジスティック回帰分析について調べた。

調べた結果、

ある事象が起きる確率を複数の変数から予測すること

ということまでは理解できたので、手を動かして実装してみたくなった。

どうせ練習なので、(自分にとって)とっつきやすいテーマを題材にしたいと思い、趣味である乃木坂46をテーマにすることに。

ロジステック回帰分析は、

ある事象が起きるかどうか

を分析するものなので、

乃木坂46に当てはまりそうなものを考えると

あるメンバーが選抜に入れるかどうか

を目的変数として思いついた。

また、説明変数としては、ブログとモバメの投稿件数を選んだ。

理由は以下の2点。

  1. 定量的に測れる変数であること
  2. 全メンバーにとって機会が平等であること

「可愛いさ・美人さ」や「ダンス・歌の上手さ」などは定量的に測るのが難しく、握手券の売り上げは、メンバーによって枠が決まっていて不平等なので、ブログとモバメの投稿件数を説明変数とした。

データの収集方法

モバメ投稿件数

モバメの投稿件数は下記サイトの情報を元に数え上げた。

  • 2019年3月〜2019年8月分

nogiradi.com

  • 2019年9月〜2019年12月分

乃木坂46モバメ集計 - 2019年9月

乃木坂46モバメ集計 - 2019年10月

乃木坂46モバメ集計 - 2019年11月

乃木坂46モバメ集計 - 2019年12月

  • 2020年1月〜2020年3月分

www.casalcatala.org

ブログ投稿件数

ブログの投稿件数はWEBスクレイピングを行ってブログを収集した上で、自力で数え上げた。

スクレイピングに際して、下記の記事を参考にした。

qiita.com

モバメ投稿件数は'mail'、ブログ投稿件数は'blog'、選抜に入ったかどうかは選抜の場合1、非選抜(アンダー)の場合0のダミー変数'x'にした。

訓練データ

name mail blog x
堀未央奈 183 71 1
山崎怜奈 385 59 0
阪口珠美 617 57 0
中田花奈 566 47 0
佐藤楓 634 30 0
梅澤美波 470 23 1
岩本蓮加 356 21 0
寺田蘭世 258 20 0
樋口日奈 120 20 0
中村麗乃 77 17 0
秋元真夏 224 16 1
生田絵梨花 75 15 1
松村沙友理 71 15 1
渡辺みり愛 470 13 0
鈴木絢音 307 13 0
伊藤純奈 100 13 0
吉田綾乃クリスティー 458 12 0
向井葉月 797 11 0
和田まあや 256 11 0
久保史緒里 629 7 1
新内眞衣 167 6 1
大園桃子 72 6 0
高山一実 55 6 1
北野日奈子 100 5 1
伊藤理々杏 78 5 0
山下美月 468 4 1
星野みなみ 38 4 1
与田祐希 144 3 1
齋藤飛鳥 333 2 1

テストデータ

name mail blog x
秋元真夏 215 11 1
生田絵梨花 69 13 1
齋藤飛鳥 385 1 1
高山一実 45 4 1
中田花奈 201 46 1
樋口日奈 115 22 1
星野みなみ 33 5 1
松村沙友理 34 5 1
和田まあや 207 14 1
伊藤純奈 281 10 0
北野日奈子 53 2 1
新内眞衣 178 4 1
鈴木絢音 262 9 0
寺田蘭世 341 19 0
堀未央奈 152 45 1
山崎怜奈 321 41 0
渡辺みり愛 492 7 0
伊藤理々杏 68 8 0
岩本蓮加 471 22 1
梅澤美波 476 27 1
大園桃子 47 5 1
久保史緒里 520 9 1
阪口珠美 512 43 0
佐藤楓 569 28 0
中村麗乃 74 16 0
向井葉月 746 7 0
山下美月 531 6 1
吉田綾乃クリスティー 336 6 0
与田祐希 118 3 1

環境

仮想環境

仮想環境はvirtualenvを用いて作成。

Pythonのバージョンは3.7.3にした。

特に大きな理由はない。

pipでインストールしたもの

pipでインストールしたパッケージは以下の通りである。

  • pandas
  • sklearn
  • jupyter

ソースコード

実装にあたって下記の記事を参考にした。

qiita.com

各種モジュールのインポート

import pandas as pd
import numpy as np
from sklearn import linear_model
import joblib

参考にした記事内では、joblibのインポートが

from sklearn.externals import joblib

となっているが、最近のバージョンのscikit-learnではjoblibはsklearn.externalsにバインドされなくなっているみたいなので注意。

参考: Python - sklearn.externalsのjoblibインポートでエラー|teratail

訓練データの取得

train = pd.read_csv("train.csv", sep=",")
explanatory = train.loc[:, ['blog', 'mail']].values # 説明変数
response = train['x'].values # 目的変数

学習

clf = linear_model.LogisticRegression(random_state=0)
clf.fit(explanatory, response)
LogisticRegression(random_state=0)
regression_coefficient = clf.coef_
segment = clf.intercept_

ロジスティック回帰の学習結果

print("回帰係数:{}".format(regression_coefficient))
print("切片:{}".format(segment))
print("決定係数:{}".format(clf.score(explanatory, response)))

学習結果の検証

test = pd.read_csv("test.csv", sep=",", encoding= "shift_JIS")
x_test = test.loc[:, ['blog', 'mail']].values
predict = clf.predict(x_test)
print("検証結果:{}".format(predict)) # 検証結果を表示

結果

出力結果

ロジスティック回帰の学習結果

回帰係数:[[-0.0023152  -0.02353291]]
切片:[0.85851572]
決定係数:0.6206896551724138

学習結果の検証

検証結果:[1 1 0 1 0 1 1 1 1 0 1 1 1 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 1]

各メンバーの結果

TP(選抜と予想されて実際に選抜)のメンバー

TN(非選抜と予想されて実際に非選抜)のメンバー

FP(選抜と予想されたが実際には非選抜)のメンバー

FN(非選抜と予想されたが実際には選抜)のメンバー

以下の記事を参考にしてロジスティック回帰モデルの評価を行った。

www.salesanalytics.co.jp

正答率

正答率は65.5%となった。

検出率

検出率は61.1%となった。

精度

精度は78.6%となった。

誤検出率

誤検出率は27.3%となった。

考察と所感

やる前から分かってはいたが、ブログとモバメの件数から選抜に入れるかどうかを予想するのは難しそう。 60%を超える正解率と検出率が出るのは、乃木坂46の選抜は大きくメンバーが入れ替わることがなく、メンバー個人のブログやモバメの投稿頻度が大きく変わることもないからだと思われる。 問題設定がおかしいのはさておき、実際に手を動かしたり結果をまとめたりすることで、理解は深まった気がする。

参考

参考にしたサイト一覧

qiita.com

teratail.com

qiita.com

www.salesanalytics.co.jp

www.casalcatala.org

nogiradi.com

乃木坂46モバメ集計 - 2019年9月

乃木坂46モバメ集計 - 2019年10月

乃木坂46モバメ集計 - 2019年11月

乃木坂46モバメ集計 - 2019年12月