筋肉で解決しないために。

日々出会うモノに対する考察をしたり、主に以下のテーマに関して書いています。 データサイエンス/人工知能/AI/機械学習/DeepLearning/Python//数学/統計学/統計処理

新卒配属ガチャに失敗しました

先日、新卒で入社し、約1年6ヶ月務めた某S社を退職しました。
闇属性でパーティー作ってんのに、光属性☆5引いちゃったみたいなそんな感じです。
(2019/01/04追記:某S社と書きましたが、ソフトバンク株式会社です。年も変わったしもういいでしょう。)

勤務時に、この会社ここがダメだなーとか、ここは良かったなとかパラパラと書き留めてましたので、 それらを整理しつつ、あまり表現がキツくならない様に書きたいと思います。

簡単に情報を書くと、
私は理系大学院修士卒(物理系)で、S社の規模は社員数1万人以上の企業です。

また、本エントリにおける意見は、私が関わったごく限られた部署及びその周辺、または伝聞した範囲の話であることを強く意識した上でお読みください。

まずは良かったところから。

前職の良かったところ

ピュアホワイト企業だった

ホワイト企業チェックリスト見たいなものがもしあったなら、前職はその項目全てオールグリーンだったと思います。
純白、ピュアホワイト、白より白い。

簡単に挙げてみると、
・残業が少ない(もちろんバラつきはあるけど基本的に上司から帰っていく、残業代はもちろん完全支給)
・社内飲み会がない(忘年会、異動等があれば歓送迎会はある。年数回程度)
・フレックス勤務を採用しているため数時間程度の融通を効かせやすい雰囲気がある
・有給、半休を取りやすい雰囲気がある
プレミアムフライデーは毎月取得可能
・育休を取得する男性社員が普通にいた
・休みの人や帰宅後の人を頼るのは辞めようという文化が浸透しており、そもそも属人化による単一障害点がきちんと回避されている

何を働きやすいと言うかは人それぞれだと思うけど、
今振り返っても一般的に望まれている要素はほとんど揃っていた様に思います。

人が余ってるくらいじゃないとホワイト企業って実現しないんだなーって理解しました。

一般的/社会的教養が十分な人で満ちていた

一般的/社会的教養と言うわかりやすい様で、明確でない言葉を使ってしまいましたが、
「まぁみんなそれぞれだよね」と言う感覚をきちんと備えていると言いますか、
パワハラとかセクハラとかそんなレベルからは程遠い人たちの集合だったなと感じています。

少し言い換えると、しょーもない人間関係のゴタゴタに巻き込まれることが一度もなかったと言うことです。
心身共に余裕がある人が多い、そんな組織だったのかなと今となっては思います。

私が入社するより以前にそういったやばい人達はきちんと淘汰されたんだろなとも想像できます。

世間の気持ちや生態が少しわかった

就職まではラボにこもってたので、
これまで社会性なく、且つ周りも自分と似たような人に囲まれて生活してきたため、
何も疑いなく自分は一般的な考え方を持っていると思っていたのですが、
企業で働いてみて、どうやら自分は少数派に属するのだということに気づきました。

良い悪いではなく、
帰宅後や土日に勉強してる人は少ないし、
"そこそこやる"の基準(作業時間等)が他の人とすごく差があったし、
好きでも楽しくもないけど、嫌じゃないからこのままで良いと思っている人は多いし、
そもそももっと強くなりたいと思っている人って少ないんだなぁと感じました。

筑波大学の落合先生はよく”追い込め追い込め”と言った発言をされていて、個人的にはとても共感できるんだけど、
そんなことは"自分だけ"が勝手にやるべきで、その基準を他の人にも勧めたら/求めたらいけないんだなと理解しました。
あんなのはやはり一般的ではないんですよ。
もし私が学生起業なんかしてたら、絶対ブラック企業作ってたわ。

こうした事はそもそも知らなくてもいいのでは?という気持ちもあるけれども、
もう知ってしまったし、知ってた方が良いこともあるとも思うので、良かった事に分類しました。

そういう意味で、世間の気持ちや生態が少しわかったと書きました。

なぜ新卒に庶務をやらせるのか答えを見つけたこと

日本企業では鉄板だと思いますが、新卒に庶務をやらせますね。
例えば、社内の郵便配達、会議室の予約/設営、新聞/雑誌の集荷/整理、役職者のシステム操作代行(IT介護)等々あげればキリがありません。

入社直後から、「なんでこんなバイトでも出来ることをやらせるんだろう。」と思ってました。
1年半も大企業にいたので、答えがわかった気がしています。

その答えは、"出来ない人がいるから"だと感じました。
事務処理能力が低い人って年齢問わず、普通にいることを知りました。

そりゃあ上司は、新人に対して、事務能力を試したくなるわな、と。
そこで上司の信頼を得ると、そこから卒業できるという仕組みなわけです。

結構戦いましたけど、
提案は通る可能性があるから提案するのであって、
閉まっていたり、何重にも門があるところで提案するのは時間の無駄だと気づいて、辞めました。

知らない分野が知れたこと

前職では、省庁対応を行っていました。いわゆるロビイングと言われる分野です。
国内の政策決定を自社に不利益なことにならないよう働きかけたり、自社の取り組みを政府にアピールしていくような業務です。

政治的な力や流れ(いわゆる既定路線)は変わりようがないことも体感できましたし、
どのルートで、どのタイミングで働きかけたら軌道修正できることもあるということも学びました。

私も今後新興分野に身を置きますが、こういった分野こそ、法規制 vs XXの様な構図になりがちかと思いますが、
真正面から省庁と対立しても仕方がなく、また省庁には省庁なりの承認ステップがあり、独特のスピード感があります。
こういった素養を理解できたことは今後役に立つだろうと感じています。

また、なかなか経験できる職種でもないと思いますので、良い経験ができたと思います。

前職の悪かったところ

さて、本編始めますか。

業務とのミスマッチ

退職に最も影響したのはやはり本務に関心がわかなかったことです。

前項では、美しめに"経験になりました。"なーんて書きましたが、
正直「つまんねー!」でした。
仕事してて、脳汁が全く出ないんですよね。

省庁対応やロビイングなんて言ったら、聞こえは良い感じはしますが、
結局、パワポエクセルワードです。

"仕事に答えがない"なんて言われますが、
業務特性もありますが、答えがありました。

先日、このような意見もありましたが、同じ気持ちです。

最初から結論が決まっているので、データ分析はいかに結論をでっち上げるかという方向に労力が注がれる。

anond.hatelabo.jp

また先日、友人に「最近1年で1番楽しかった仕事は?」と聞かれ、答えられなかったです。
これは自分にとって衝撃的で、
改めて辞めて正解だったとそこでは感じました。

てか、人事さん、配属権ないのに採用面接時に配属先について言及するのはやめてください。

働き方とのミスマッチ

これもまた前項で述べましたが、ホワイト企業というのは、
プライベートと仕事をきっちり分けるということ(ワークライフバランス)ですが、
結局、私にはそれは馴染めませんでした。

むしろそう二分することで徐々に仕事が自分ごとに思えなくなっていきました。
私にとってそれはストレスであり、
仕事も趣味も勉強も中途半端になっている感覚が抜けず、
QoLを下げている要因であることに気づきました。

世間ではワークライフバランスを目指した働き方改革が盛んですし、
同期等を見ていてもワークライフバランスを重視したい人が多数派だったので、会社を批判するわけではなく、
企業文化と合ってない私が消えるしかないと考えました。

ワークアズライフってやつを目指してみます。

評価最適化していく自分

評価には、闇の力が多分に含まれ、
フィードバックでは当たり障りのない事が言われる。
こうした事実によって、私は評価への関心をなくしました。

すると、以下に労力少なくこなすか、という考え方に陥り、またそこから抜けることが私はできませんでした。
また、そうした自分がとても嫌でした。

そしてこうした発想は、他部署とタスクの投げ合いをしたりすることに発展し、
「なんだかなー」という気持ちでした。

好きな漫画アカギの言葉を借りて表現すると、自分も含め
「なんでもっとみんなスカッと生きねえのかな・・・」という感じです。

f:id:watarumon:20181118201724j:plain

5年後も10年後も憧れなかった

5年後も10年後の自分の姿というのは、
先輩や上司群を見ればおよそ想像できる気がすると思いますが、
やはりそこに憧れが持てなかった。

もちろんこれは嗜好の問題で、"私は"憧れなかったということにすぎません。
人それぞれです。

また、このままずるずると在籍したら絶対後悔するなと思いました。
もちろん転職しても今より良くも悪くもなり得りますが、
後悔することが明らかであれば、その行動を取るしかないだろうという発想です。

後悔は先に立たずということわざがあり、また概ねその通りだとも思いますが、
後悔は先に立つこともあるだろうと、今回ばかりは感じました。

研修がひどい

大人が何百人も関わって経費たくさん使ってのんびりのんびり何をやっているのかという気持ちでした。

指導側は、"研修を行った"という事実を作るという仕事で、
被指導側は、"研修を受けた"という事実を作るという仕事に成り下がってしまっていると感じました。

組織からしたら、持ち出せるスキルのない人材育てて飼い殺したいんだろうなとか勘ぐってしまう。

転職に際して

新卒ガチャではずれを引く可能性はそれなりにあるわけで、
転職活動に当たって、もちろん明言はされてませんが、修士行ってて良かったなぁと私は感じました。
やはり面接では学生時代の研究の話で盛り上がるし、基本的に即辞め人材なんてポテンシャル採用だろうからね。 もし行くか悩む人がいたなら是非行って欲しいなぁと個人的には思います。

  • 転職の思考法

こういった自己啓発系の書籍を紹介するのは、少し恥ずかしいのですが。
以下の文言が刺さりました。

『転職が100%失敗する、唯一の条件』というものがある。それは腹を括るべきタイミングで、覚悟を決めきれなかったときだ

このまま今の会社にいていいのか?と一度でも思ったら読む 転職の思考法

さいごに

今後も同じ会社で働く人をできるだけ傷つけないように書いたつもりです。

まだまだ書きたいことはありそれは、なぜ異動希望ではなく転職なのか、という答えになるんですが、
これ以上は愚痴になってしまうのと、内容が具体的になってしまうので、心に閉まっておこうと思います。
摂取アルコールの量によって適度に身内にオフライン放出して消化しようと思います。

パフォーマンスとはいえこんな若輩者が、早々に会社辞めてもきちんと送別会が開催してもらえ、
「いつでも待ってますので」とか言われると、少し感傷的になりました。
今はただ淡々と誠実に頑張ろうという気持ちです。 ちなみに次は、ベンチャー企業でデータサイエンティストをやりますよ。

あの会社の社食、ビーフカレーが安くて美味しかったな。

しばしニート期間を楽しもうと思います。

PyCon_JP_2018カンファレンス資料まとめ(仮)

twitterで回ってきたものだけとりあえずまとめています。

全く網羅できていないので、今後も見つけ次第追記、整理します。

twitterで情報いただけると助かります。 [9/24追記:他サイトを追記]

twitter.com

他サイト

他の方がまとめられたページになります。 参考にどうぞ。

qiita.com

day1

github.com

day2

LT

プレゼンテーション入門2_色を増やすのやめよう

f:id:watarumon:20180915180531p:plain:w800

こんにちは、ワタルです。

プレゼンテーション入門2です。

入門1はこちらからどうぞ。

watarumon.hatenablog.com

このエントリの目的

今回は、プレゼンテーションの内容についてではなく、
知ってるだけで資料が美しくになるよ、という部分について解説してみます。

また、それらを反映させたテンプレートも頒布しますのでぜひ使ってみてください。

資料作りで最も重要なこと

まずはじめに、資料デザインで最も重要なことは、
"聴者にストレスを与えないこと", "聴者がデザインに気が取られない様にすること"だと考えています。

ストレスとは、例えばこんなことだと思います。

  1. 位置がバラバラとずれ、気になる。

  2. 資料が人と被って見えない。

  3. 色使いが激しい。

見てるだけで気が散るようなスライドはやめていきましょう。

ガイド機能で使用領域を決めてしまう

まずはじめに、スライドの領域について解説します。

私はスライドをこのようにガイドで区切っています。

f:id:watarumon:20180915135917p:plain:w500

まず、赤色の部分、ここは禁断の領域としています。

単純に、読みにくいからです。特に下部は聴者の頭と被ることがよくあります

さらに、このようにガイドを設定しておくと、
PowerPointには、[描画オブジェクトをグリッド線に合わせる]という機能がデフォルトだと有効なので、
画像や文字が微妙にズレているといったことが起こりにくくなります。

スライド毎に、見出しの位置がズレている資料を目にすることが往々にしてありますが、それを簡単に防ぐことが出来ます。

色使いについて

次に色使いについて。

基本的に黒、赤、青の3色で充分です。
私は、プラスイメージの文字には青マイナスイメージの言葉には赤で使い分けています。

ちなみに、パワーポイントデフォルトの色は少し強いので、
黒は、R:G:B=77:77:77
青は、R:G:B=0:113:188
赤は、R:G:B=255:80:80がおすすめです。

比較図はこちらです。

f:id:watarumon:20180915173730p:plain:w500

右側の方が柔らかい印象を感じられますね。

ちなみに、下記にて配布しているテンプレートでは、このように設定済みです。

f:id:watarumon:20180915182752p:plain:w300

濃淡の活用

とはいえ、色の数が足りないと感じた時は、濃淡を活用すると良いです。
具体例として、駅でよく見かける案内図を見てください。

f:id:watarumon:20180915173840j:plain:w500

センスの悪い人は、行き先を赤行かない方向を黒などの配色にしそうなところですが、
この例から行き先を黒行かない方向をグレーにした方がよほどシンプルでわかりやすいことが実感できます。

このように色が足りないと感じた時は、色の違いではなく、色の濃淡で表現できないかを考えて見ると良いと思います。

このビールのCMも同じ原理だと言えます。

f:id:watarumon:20180915174326p:plain:w500

強調したいときに色を付ける発想だけでなく、強調したくない部分の印象を薄くすることで、目立たせることをここでは覚えてもらいたいです。

文字の大きさについて

次に、文字の大きさについて、
これは20以上32以下の間と覚えておけば充分です。

これ以上小さい字は読めないし、そもそも読む気にならない。 大きい字は稚拙な印象を持たれがち、ということが理由です。

TIPS

最後に、覚えておくと便利そうな事を箇条書きにしておきます。

  • .potmファイルは、”Office のカスタム テンプレート”に保存しておくと、新規作成→個人用から いつでもこのマスタで新規作成ができるようになる。(下記の配布ファイル)

  • クイックアクセスツールバーに「テキストボックス作成」「最背面へ移動」「最前面へ移動」を追加しておくと便利。

  • ショートカット「Alt + H → G → A →C or M」 : 左右揃え or 上下揃え。を覚えておくと便利。

テンプレート配布

最後に、私が資料作成の時に使っている自作のテンプレートを置いておきます。

ご自由にどうぞ。

https://drive.google.com/file/d/14UyxLHEcremongA61tkrQxO3gYkxFyb-/view?usp=sharing

使い方やリンク先がおかしいことになっている等あれば、twitterから連絡頂けると嬉しいです。

twitter.com

このエントリは終わりでーす。

np.whereとdf.whereの違い

f:id:watarumon:20180904173907j:plain
図1 2匹の羊

当たり前ですが、
numpyのndarray.where()
pandasのDataFrame.where()は引数が異なる。

この前、混乱したのでまとめておきたいと思います。

ndarray.where()

まずは、numpy、ndarrayから。

import numpy as np
nd = np.arange(10)
nd

>>>
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
#where

np.where(nd < 5,0,1)

>>>
array([0, 0, 0, 0, 0, 1, 1, 1, 1, 1])

条件式がTrueなら、第2引数。 Falseなら第3引数が返っていることがわかります。

DataFrame.where()

次に、pandas、Dataframeについて。

import pandas as pd
dfw = pd.DataFrame(np.arange(10))
dfw

>>>
   0
0  0
1  1
2  2
3  3
4  4
5  5
6  6
7  7
8  8
9  9
#where

dfw.where(df[0] < 5,0)

>>>

   0
0  0
1  1
2  2
3  3
4  4
5  0
6  0
7  0
8  0
9  0

条件式がTrueなら、それ自身が返っています。 Falseなら第2引数が返っていることがわかります。

ちなみに、条件式がTrueのときに、第2引数を返したいなら、 DataFrame.mask()を使います。

DataFrame.mask()

dfm = pd.DataFrame(np.arange(10))
dfm.mask(df[0] < 5,0)

>>>

   0
0  0
1  0
2  0
3  0
4  0
5  5
6  6
7  7
8  8
9  9

条件式がTrueなら、第2引数。 Falseならそれ自身が返っていることがわかります。

まとめ

ndarray.where(条件式, 2, 3) 条件式がTrueなら、第2引数。 Falseなら第3引数。

DataFrame.where(条件式, 2) 条件式がTrueなら、それ自身。 Falseなら第2引数。

DataFrame.mask(条件式, 2) 条件式がTrueなら、第2引数。 Falseならそれ自身。

以上です!

プレゼン入門1_プレゼンを作り始める前に

f:id:watarumon:20180809230139p:plain

こんにちは、ワタルです。

読むだけでプレゼンが上手くなるプレゼン入門講座をはじめることにしました。

はじめに

実は私、学生時代から学会発表などでプレゼン発表する機会が多く、その経験からビジネスプレゼン大会(1000人規模)で優勝したことがあったりして、人前でプレゼンすることに苦手意識があまりなく、むしろ得意だと思っているところで。

そのため自分自身のための言語化や整理も兼ねて、どんな風に考えてプレゼン作っているかをまとめてみようかなと思います。

少しでも皆さんのプレゼンに貢献できたら嬉しいです。
ちなみにcoconalaでプレゼン資料添削もやってるので、良かったらお仕事ください。
エントリの最後にリンク載せておきます。

プレゼン入門シリーズの構成

今の所、このプレゼン入門シリーズは全10回くらいを想定しています。

第1,2回目 作り始める前にすること

第3,4回目 図の作り方、色の使い方等、デザインについて

第5,6回目 おすすめPower Pointショートカットについて

第7,8回目 細々としたテクニック

第9,10回目 話し方、立ち振る舞い、発表練習について

この様な内容を各2エントリくらいずつかなと思っています。
もちろん書き進める中で変わることはあるかもしれません。

それでは、よろしくお願いします。

このエントリの目的

このエントリでは、私が"資料を作り始める前に必ず行うべき"だと考えていることについてまとめています。

プレゼンをしなければいけない状況になった時、なんとなく資料を作り始めるのは絶対に無しです。 時間ばかりかかって、何を伝えたいのかわからないモノが出来上がります。

私はこうして出来上がった資料は、他人の時間も奪うので"不法投棄された悪臭を放つゴミ"だと考えています。
やめましょう、不法投棄は。

さらに、そういう適当に資料を作る人に限って発表練習すらせずに出てくるから、
発表もまとまってなかったりして、さらに世界の生産性を下げることになります。

少し言い過ぎましたが、
そう言った状況を避けるために、"資料を作り始める前に必ず行うべき"ことを知っていただくことが、このエントリの目的です。


漫画「SLAM DUNK」で例えている部分が多くあります。
読んでいない方にとってわかりにくかったらすみません。
SLAM DUNK」はおもしろいので読んでおいた方が良いと思います。

対象者・目的・内容・順序を考える

その"資料を作り始める前に必ずすべきこと"とは、対象者・目的・内容・順序を考えると言うことです。
ひとつずついきます。

f:id:watarumon:20180809121529p:plain

対象者を考える

まずは、対象者を考えるということについて。

対象者とは、言い換えると、そのプレゼンの受け手、聴者のことです。

対象者を考えるということは、
聴くのは、誰で、どんな状況でそのプレゼンを行うのかを考えるということにほかなりません。

例えば以下の様なことを考えます。
大人数?少人数?
場所は広い?狭い?
資料を配ってのプレゼン?投影?
年齢は?役職は?性格は?
思考や知識のレベルは?などです。

極端なことを言うと、
小学生に専門用語を使っても伝わらないと言うこと、大学教授に基礎から話しても冗長になるだけということ。
この様なことです。

漫画「SLAM DUNK」で例える

漫画「SLAM DUNK」で例えると、海南大付属高校との試合において、
赤木は、マネージャーの彩子に対し、「いいからテーピングだ!」と発言する印象的なシーンがあります。

一般的な人に「いいからテーピングだ!」と言っても、
「テーピングってなに?」「テーピングって何かの検査のこと?」「もう試合には出ないって意味なのかな。。」
などとわけのわからないことになりそうですが、

「テーピングとはどんなものか。」「どんな効果があるか」を理解しているマネージャーの彩子に対しては、
「いいからテーピングだ!」という最小限の言葉で、相手に行動まで促させることに成功しています。

対象者を考えることは、全く時間を要しませんが、
少なくともこの様なことを回避することができるというメリットがあります。

さらに次の目的を考えるときに非常に役に立ちます。

まとめです。

f:id:watarumon:20180809121549p:plain

目的を考える

次は、目的を考えるということについて。

目的を言い換えると、
そのプレゼンを受けた相手に、プレゼン終了後にどんな行動をしてほしいか、ということになります。

つまり、誰に、何を、どうしてほしいのか。ということです。
具体的を書くと、

  • セミナーに来たお客さんに、この商品を、購入してほしい。

  • 山田部長に、この企画を、承認してほしい。

  • 学生に、この講義を、理解してほしい。

  • マネージャーの彩子に、テーピングを、してほしい。

稚拙な例になってしまいましたが、このような感じです。

そして、この様にプレゼン資料に入れてしまいましょう。
プレゼン冒頭で宣言することをお勧めします。

f:id:watarumon:20180809122008p:plain

これをしっかり明言するだけで、もう迷いません。
登壇者と聴者は、伝え/伝えられようとする共同体の様になります。

その行動に必要な情報を説明すればいいし、聴者は行動に必要な部分だけ聞けば良くなり、話が格段に伝わりやすくなります。

プレゼンは、登壇者が伝えたいことを説明して、聴者が登壇者の意図を想像する様な連想ゲームではありません。
始めから答えを言うべきです。

まとめです。

f:id:watarumon:20180809122036p:plain

内容を考える

次は、内容を考えるということ。 ここまで話してきた通り、プレゼンの目的は、プレゼン終了後にどんな行動をしてほしいか、に尽きます。

必然的に、内容は、
対象者が行動するために必要な情報になります。
私は、以下の項目について埋める形で考えています。

目的概要理由まとめ

  • 目的とは、プレゼン終了後にどんな行動をしてほしいか

  • 概要とは、その企画概要

  • 理由とは、その企画の詳細やメリデメ

  • まとめとは、目的や概要のまとめになります。

漫画「SLAM DUNK」で例える

プレゼンを漫画「SLAM DUNK」における「いいからテーピングだ!」で例えると、

目的:
マネージャーの彩子に、テーピングを、してほしい。

概要:
テーピングによる治療箇所の詳細、テーピング材の詳細、締め切り日時

理由:
①テーピングで固めないとプレーできない現状

②自分がプレーすることによるメリット
(→牧 紳一の脅威について)

③自分がプレーすることによるデメリット
(→自身の骨が折れてもいい、歩けなくなってもいいと考えているため、デメリットは無視できる)

まとめ:
理由の一覧+「いいからテーピングだ!」

この様な感じでしょうか。
まとめます。

f:id:watarumon:20180809123259p:plain

順序を考える

最後に順序についてです。

プレゼンにおける順序は2種類あります。
結論を先に置くか、後に置くかです。

多くの場合で結論を先にすべきだと思いますが、長めの講演などでは結論を後に置いた方が効果的な場合もあります。

メリデメをまとめておきます。

f:id:watarumon:20180809223038p:plain

漫画「SLAM DUNK」で例える

結論を先に置く場合:
「いいからテーピングだ!」 → なぜなら...

結論を後に置く場合:
「皆さんは私がこの試合に懸ける気持ちをご存知でしょうか?」 → 「1年生の時からずっと全国制覇を...」 → 「いいからテーピングだ!」

この様になります。

まとめ

最後に、このエントリをまとめておきます。

f:id:watarumon:20180809224029p:plain

第1回目は以上です。

次回もよろしくお願いします。

coconalaでプレゼン資料添削もやってるので、良かったらお仕事くださいね!

coconala.com

決定木とランダムフォレスト分類/回帰の実装と可視化

こんにちは、ワタルです。

はじめに

このエントリでは、サンプルデータを作成し、そのデータを持って決定木とランダムフォレストの実装と可視化をしてみます。

決定木分類をとてもかんたんに説明すると、 ある条件に対してYes or No のように分けて決めていくことでそのサンプルを分類する方法です。

また、ランダムフォレスト(Random forests)は、アンサンブル学習法と呼ばれる学習法の一つです。 アンサンブル学習法とは、いくつかの分類器を集めて構成する学習法のことを指します。 決定木を集めたアンサンブル学習法なので、ランダムフォレストと呼ばれるわけです。

より詳しい説明はこちらを参考にして見てください。 画像もこちらから引用しています。

Enchanted Random Forest – Towards Data Science

f:id:watarumon:20180717171310p:plain

また、コードはこちらを参考にさせていただいております。

Lec86_決定木とランダムフォレスト

それでは実際にコードを書いていきます。

目的とタスク設定

なにごとも、目的とタスクの整理は重要です。

サンプルデータの作成をタスク1 とします。

次に、決定木のみの実装とその可視化をタスク2とします。

次に、ランダムフォレストによる多クラス分類の実装とその可視化をタスク3とします。

最後に、ランダムフォレストによる回帰の実装とその可視化をタスク4とします。

さて、タスク1から始めます。

おまじない

%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn

タスク1

まずはサンプルデータを生成します。

#make_blobsをimportします
from sklearn.datasets import make_blobs

#500の要素
#4つの中心、つまり4つのグループを作る
#再現性のためにrandom_stateを指定
#cluster_stdはばらつき具合
X, y = make_blobs(n_samples=500, centers=4,
                  random_state=7, cluster_std=2.4)

#生成したデータのプロット
plt.figure(figsize=(10,10))
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='jet')
#引数cとcmapは色のため、sはプロット点の大きさ指定です

>>>

f:id:watarumon:20180717172518p:plain

このサンプルデータに対して、分類を実装していきます。

タスク2

次に決定木分類を実装し、可視化します

#決定木分類のインポート
from sklearn.tree import DecisionTreeClassifier

#決定木の可視化
def visualize_tree(classifier, X, y, boundaries=True,xlim=None, ylim=None):

    # fitを使ったモデルの構築
    classifier.fit(X, y)
    
    #軸を自動調整
    if xlim is None:
        xlim = (X[:, 0].min() - 0.1, X[:, 0].max() + 0.1)
    if ylim is None:
        ylim = (X[:, 1].min() - 0.1, X[:, 1].max() + 0.1)

    x_min, x_max = xlim
    y_min, y_max = ylim
    
    
    #meshgridをつくります。
    xx, yy = np.meshgrid(np.linspace(x_min, x_max, 100),
                         np.linspace(y_min, y_max, 100))
    
    #分類器の予測をZとして保存
    Z = classifier.predict(np.c_[xx.ravel(), yy.ravel()])
    #np.ravel関数は配列の一次元化、np.c_は配列の結合を行っています

    #meshgridを使って、整形します。
    Z = Z.reshape(xx.shape)
    
    #分類ごとに色を付けます。
    plt.figure(figsize=(10,10))
    plt.pcolormesh(xx, yy, Z, alpha=0.2, cmap='jet')
    #xx,yyの座標について、Zで色分けをしています。alphaは色の薄さです
    
    #訓練データのオーバープロット
    plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='jet')
    
    plt.xlim(x_min, x_max)
    plt.ylim(y_min, y_max)        
    
    #境界線をプロットする関数をつくります
    def plot_boundaries(i, xlim, ylim):
        if i < 0:
            return

        tree = classifier.tree_
        
        #境界を描画
        if tree.feature[i] == 0:
            plt.plot([tree.threshold[i], tree.threshold[i]], ylim, '-k')
            plot_boundaries(tree.children_left[i],
                            [xlim[0], tree.threshold[i]], ylim)
            plot_boundaries(tree.children_right[i],
                            [tree.threshold[i], xlim[1]], ylim)
        
        elif tree.feature[i] == 1:
            plt.plot(xlim, [tree.threshold[i], tree.threshold[i]], '-k')
            plot_boundaries(tree.children_left[i], xlim,
                            [ylim[0], tree.threshold[i]])
            plot_boundaries(tree.children_right[i], xlim,
                            [tree.threshold[i], ylim[1]])
    
    if boundaries:
        plot_boundaries(0, plt.xlim(), plt.ylim())
#インスタンスを作り、上記のvisualize_tree関数内のモデルに代入します
clf = DecisionTreeClassifier(max_depth=2,random_state=0)
visualize_tree(clf,X,y)

>>>

f:id:watarumon:20180717171435p:plain

垂直が①番目、水平が②番目の順に、決定木分類がされていることがわかります。

深さ2の分類では水色のプロットが全く上手く分類できていないことも見て取れます。

もっと深くして試してみます。

#深さ4にしてみます
clf = DecisionTreeClassifier(max_depth=4,random_state=0)

visualize_tree(clf,X,y)

f:id:watarumon:20180717171448p:plain

#深さ10にしてみます。
clf = DecisionTreeClassifier(max_depth=10,random_state=0)

visualize_tree(clf,X,y)

f:id:watarumon:20180717171501p:plain

だいぶごちゃごちゃしてしまいました。 感覚的に見ても、上手く分類できていないプロットはいくつかあり、過学習を起こしてそうな個所も見受けられます。

そこで、アンサンブル学習法である、ランダムフォレストを試してみます。

ランダムフォレストは、学習データの一部をランダムに選んで、決定木を作るという行動を繰り返す手法です。

タスク3

#ランダムフォレスト分類をインポートします
from sklearn.ensemble import RandomForestClassifier

clf = RandomForestClassifier(n_estimators=100,random_state=0)
#n_estimatorsは、作る木の数です。

# 境界線を書かないようにします。
visualize_tree(clf,X,y,boundaries=False)

f:id:watarumon:20180717171517p:plain

水色の左側のプロットでは、過学習が起きている様な分類結果が見て取れますが、 決定木分類よりは高い精度であることが見て取れます。

最後に、ランダムフォレスト回帰を実装してみます。

タスク4

線形回帰では、回帰曲線を描くのが困難なサンプルデータを作成し、ランダムフォレスト回帰を実装してみます。

まずは2種類のsin波とランダム関数から生成したノイズからなるダミーデータを生成します。

#ランダムフォレスト回帰をインポートします
from sklearn.ensemble import RandomForestRegressor

x = 10 * np.random.rand(100)

def sin_model(x, sigma=0.2):   
    noise = sigma * np.random.randn(len(x))
    return np.sin(5 * x) + np.sin(0.5 * x) + noise

y = sin_model(x)

# Plotします。
plt.figure(figsize=(16,8))
plt.errorbar(x, y, 0.1, fmt='o')
#Xを用意します。
xfit = np.linspace(0, 10, 1000)

#回帰モデルを用意します。
rfr = RandomForestRegressor(100)

#モデルを学習させます。
rfr.fit(x[:, None], y)

#予測値を計算します。
yfit = rfr.predict(xfit[:, None])

#回帰の目指している実際の曲線を描くための値をつくります
ytrue = sin_model(xfit, 0)

#Plotします
plt.figure(figsize=(16,8))

plt.errorbar(x, y, 0.1, fmt='o')

plt.plot(xfit, yfit, '-r');
plt.plot(xfit, ytrue, '-b', alpha=0.5);

>>>

f:id:watarumon:20180717171536p:plain

青が実際の値で、赤が予測値になります。

線形回帰では、ただ、山なりな曲線しか描けなそうなデータに対して、ランダムフォレスト回帰は有効な方法であることを確かめることができました。

さいごに

今回は、サンプルデータを作成し、そのデータに対して決定木分類の実装と可視化、ランダムフォレスト分類と回帰の実装と可視化を行いました。

また、ランダムフォレスト回帰では、線形回帰では、回帰曲線を描くのが困難そうデータに対して、有効な方法であることを確認出来ました。

お疲れ様でした!

それじゃー、また。

ナイーブベイズ分類をIrisデータセットへの実装

こんにちは、ワタルです。

はじめに

このエントリでは、機械学習のサンプルデータとしてよく用いられるIrisのデータに対して、ナイーブベイズ分類を実装してみます。 サンプルデータは、Iris(アヤメ)という植物のデータで、3種類のアヤメについて、それぞれ50サンプルのデータに4つの特徴量が含まれています。

ナイーブベイズ分類をとてもかんたんに表現すると、それぞれの分類先に属する確率を計算し、確率が最も大きいクラスにそのサンプルを分類します。

数字は適当ですが、このようなイメージです。 例えば、Aさんがどのクラスに属するが分類してみたいとします。

Aさんが、クラス1に属する確率は70%、クラス2に属する確率は30%、クラス3に属する確率は50%と求めることが出来た時、Aさんはクラス1に属すると出力されます。

数学的な理解は、こちらのページがおすすめです。

第10回 ベイズ確率:機械学習 はじめよう|gihyo.jp … 技術評論社

それでは、実際に実装してみます。

おまじない

import pandas as pd
from pandas import Series,DataFrame

import matplotlib.pyplot as plt
import seaborn as sns

#Gaussian Naive Bayes のためのコード
from sklearn import datasets
from sklearn import metrics
from sklearn.naive_bayes import GaussianNB

Irisデータセットのインポート

from sklearn import datasets

iris = datasets.load_iris()
X = iris.data
Y = iris.target

データセットの分割

#データを、テスト用とトレーニング用に分けます。

from sklearn.cross_validation import train_test_split
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, random_state=0)

ナイーブベイズ分類にて学習

#インスタンスの作成
model = GaussianNB()

#訓練データで学習
model.fit(X_train,Y_train)

>>>
GaussianNB(priors=None)

予測精度の確認

#分割しておいたテストデータを用いて、精度を確認します
predicted = model.predict(X_test)
expected = Y_test

print(metrics.accuracy_score(expected, predicted))

>>>
1.0

おぉ、1.0になりました。 ついでにお試しとして、データセットの分割具合を変えて、精度スコアを可視化してみましょう。

精度スコアの可視化

predict_score = []

#テストデータを10%から90%まで変化させて、そのスコアを出力します
for size in np.arange(0.1, 1,0.1): 
    X_train, X_test, Y_train, Y_test = train_test_split(X, Y, random_state=0,test_size = size)
    model = GaussianNB()
    model.fit(X_train,Y_train)
    predicted = model.predict(X_test)
    expected = Y_test
    predict_score.append(metrics.accuracy_score(expected, predicted))
X_test_size = np.arange(0.1, 1,0.1)
df_score = DataFrame(predict_score,columns=['predict_score'],index=X_test_size)
df_score

>>>
    predict_score
0.1    0.933333
0.2    0.966667
0.3    1.000000
0.4    0.933333
0.5    0.946667
0.6    0.944444
0.7    0.933962
0.8    0.933333
0.9    0.948148
#プロットします
plt.plot(X_test_size,predict_score,color = 'b')
plt.ylim(0.92,1.01)
plt.xlabel("test_size")
plt.ylabel("predict_score")
plt.xticks( np.arange(0.0, 1.0, 0.1) )
plt.hlines([1], 0, 1, linestyles="dashed")

plt.show()

>>>

f:id:watarumon:20180713152426p:plain

訓練データは多ければ多いほどよいわけではないことを体験することができましたね。

さいごに

今回は、機械学習のサンプルデータとしてよく用いられるIrisのデータに対して、ナイーブベイズ分類を実装し、テストデータの分け方によって精度が変わる事を確認してみました。

お疲れ様でした!

それじゃー、また。