Fire Engine

消防士→ITエンジニア→研究者

【統計】モデル選択とAIC

 最近、社内で統計モデリングのバイブル本である『データ解析のための統計モデリング入門』の勉強会を行っており、第4章の部分を担当したので、その際の資料をこちらに載せておきます!

www.slideshare.net

 第4章は『GLMのモデル選択ーAICとモデルの予測の良さー』という内容で、ざっと中身を説明すると、統計モデルを構築する際に、どのようにして良いモデルを選択するか、について書かれています。ありがちな間違いとして、手持ちのデータへのあてはまりの良さ(誤差が小さい)を基準としがちですが、それは正しくありません。その理由は主に2つあるとか思います。
 1つ目は、データへのあてはまりの良さはモデルを複雑にすることでいくらでも改善できる点です。これは機械学習などで『過学習』と言われる状態で、たまたま手元に持ち合わせているデータだけに適応しているだけに過ぎないかもしれません。
 2つ目は、そもそも統計モデルを作る目的ってなんだっけ?ということを考えると、手持ちのデータを再現することではなく、真の統計モデルを推定すること、ひいては、データが観測される現象の背後にある「しくみ」の特定です。それらを理解することで、次に得られるデータがどういうものかを予測したいというわけです。そして、この予測の良さを重視するモデル選択基準がAIC(Akaike’s information criterion)です。
 この『データ解析のための統計モデリング入門』という本はよく『みどり本』などと呼ばれており、かなり人気のある本らしいです。私も最近知って読んでいるのですが、かなりわかりやすくて感動してます!何かしらの分析したいデータをお持ちで、それを統計モデルにあてはめてみたいという方はぜひ読んでみてください!

消防士からエンジニアに転職して半年が経ちました

 こんにちは!私事ですが、エンジニアに転職して半年が経ちました!以前は消防士という全く違う世界で仕事をしており、プログラムの経験もほとんどないままエンジニアになりましたが、なんとか普通に仕事ができるようになってきました!
 今回は、私が転職して半年で学んだことや、これからできるようになりたいことなどを書いていきます。今後エンジニアへの転職を考えている人やプログラムを勉強中の方々の参考になればと思います。

転職の話はこちらに書きました↓  blog.tsurubee.tech

目次

今なにをやっているか

 2016年11月に経験ゼロからシステム開発会社に拾っていただきました。私が勤めている会社は主にECサイトの受託開発・保守等を行なっています。私は現在、ECサイトのレコメンドエンジンの開発・保守を行なっています。「これを買った人はこれも買っています」みたいなやつです。また、それに加えてここ数ヶ月は、ECサイトのデータ分析の仕事もしています。
 開発言語は、Pythonを使っており、データ分析の仕事ではSQLをゴリゴリ書いています。また、レコメンドエンジンをやらせてもらったことをきっかけに機械学習に興味を持ち、業務外で自分で学習モデルを組んで、画像認識や文書分類などもやっています。あとは、機械学習をやる上で理論まで理解しようとすると、かなり数学の力が必要だなって実感して、微分積分線形代数・最適化数学なども勉強中です!

経験ゼロから転職してどうだったか

 私がエンジニアになったときのスキルセットは、Rubyが少し書ける、Excelが少し使えるくらいでした。そんな中で、初日からいきなり案件にジョインさせて頂いて、わからないことの連続でした。Linuxサーバーをコマンドラインから操作してみると、「cd ディレクトリ名」で移動して・・むっ、戻れない。。 上の階層への戻り方を知らず、「cd /」でルートに戻ってました。笑
 そんなこんなで周りの方にも迷惑をかける日々でしたが、会社に入る前に独学で本を読みながら勉強しているのとは比較にならないスピードで成長できたと思います。やはり、実際に手を動かして慣れるのが一番だと実感しました。なので、私は、本当にエンジニアになりたいなら「まだスキル全然ないしなー」とか考える前に未経験でも拾ってもらえる会社を探して、実際に現場に飛び込むのが良いと思っています。

半年でできるようになったこと

 この半年でできるようになったことを挙げるとざっとこんな感じです。(それぞれできるといってもレベルは低いですが。。)

プログラム

 プログラムに関しては、現在仕事でPythonを使っていることもあり、Pythonがそこそこ書けるようになりました。むしろ今Python以外、書ける言語がないのでちょっとやばいかもって思ってます。笑
 言語もさることながら、その背後にあるオブジェクト指向についても勉強しました。クラスとかインスタンスとか最低限知識がないとオブジェクト指向型のプログラムを書くとき・読むときにかなり支障がでるので、そこはかなり重要と思います。

数学・統計学

 私は一応理系の大学を出ましたが、久しぶりに数式に触れるとすっかり忘れており、記憶から完全に葬り去られていることに気づきました。。なので数学は一通り勉強しなおしました。やったこととしては、主に微分積分線形代数あたりです。
 また、機械学習の勉強をしていると、「統計的機械学習」とか「ベイズ統計学」といったフレーズが出てきて、ベイズってなに??というレベルだったので一通り勉強しました。本気で統計学をやろうと思うと、かなり数学を使うので、統計学を学ぶには同時並行で数学を学ぶことになるでしょう。

機械学習

 機械学習については主要なアルゴリズムがだいたいわかる程度にはなりました。また、実際にTensorFlowやKerasなどのライブラリを使ってニューラルネットのモデルが組み、文書分類などを行ったりしました。現在、機械学習はライブラリが充実しているので、初学者が実際にモデルを組んでデータを扱うまでの壁はほとんど感じられないと思います。ただ、実際に自分が直面している課題を機械学習を導入することで、解決するところまでいくにはかなり壁があるなーと思いました。現在壁を乗り越えるため、理論をしっかり理解することが必要だと思うので、真剣に勉強中です。

データ分析

 おそらく、ここ半年で一番成長したと思えるのはSQLです。仕事でかなりSQLを書く機会があり、最初はSELECT文とかさえ知らなかった私が、今ではテーブルの結合や集計なども使いこなせるようになり、ときには数百行にまたがるSQL文を書いてデータの集計・分析をし、BIツールで可視化といったことをやっています。
 あと最近は、R言語も使い始めました!もともとPythonが多少書けるのでRは使う気はなかったのですが、データ分析系の本を買うと、サンプルコードがRというケースが多すぎるので、心が折れて使い始めました・・笑  

半年で読んでよかった本

 半年でいろんな本を読みましたが、この本はまじで読んでよかった!っていう本がいくつかありますので紹介したいと思います。

 もはや今更どうこういうレベルではないくらい多くの方に読まれているかと思いますが、ディープラーニング学ぶならまじで最高の1冊です。ただ、幅広い機械学習の分野の中で、良くも悪くもディープラーニングのみに特化した本です。Pythonでライブラリを使わず、ニューラルネットワークを実装するのでかなり力がつくと思います。

ITエンジニアのための機械学習理論入門

ITエンジニアのための機械学習理論入門

 上のオライリーの本ではディープラーニングしか取り扱ってないのと対照的に、この本ではディープラーニング以外の主要なアルゴリズムはだいたい押さえています。ざっと挙げると、最小二乗法、最尤推定法、パーセプトロン、ロジスティック回帰、k平均法、EMアルゴリズムベイズ推定、といった感じです。本書は機械学習の入り口的な本としての位置付けですが、本中のコラムにはけっこうガチな数学の議論をしてます。2章の最小二乗法でいきなり「ヘッセ行列」とか出てきたときは、「まじか!」と思いました。数学が不得意な方はコラム抜きで読んでも、主要アルゴリズムの概論的なものがだいたいわかるかと思います。

プログラミングのための線形代数

プログラミングのための線形代数

 数学系の本を読んで初めておもしろい!と感動を覚えました。本書では冒頭に「行列は写像だ!」と連呼しているのですが、正直最初はなにを言っているんだろう、行列ってあの数字が表みたいに並んだやつよね?って思っていました。しかし今では、行列が写像にしか見えません。笑 行列を見た瞬間、これは5次元から3次元への線形変換だな、とか、これは時計回りに90度回転しているなっとか、行列の見方が一気に変わりました。これ、機械学習ではめちゃくちゃ大事なことです!  同著者が「プログラミングのための確率統計」という本も出していて読みましたが、なんか説明が回りくどく私には合いませんでした。

これなら分かる最適化数学―基礎原理から計算手法まで

これなら分かる最適化数学―基礎原理から計算手法まで

 数学の本でもう一冊読んでよかった本を挙げるなら、この本です。この本を読むことで機械学習の「学習」部分で使う最適化アルゴリズムへの理解が深まります。同著者の「これなら分かる応用数学教室」もかなりいい本でしたが、機械学習をやるなら最適化数学の方が直結するような気がします。

 ベイズってなに?って言う状態から、ベイズってこういうことね!って言う状態までに最短で行くには最適の本です。私はベイズ統計学という名前を聞いたことがない状態で、この本を読み始めましたが、ベイズの考え方はだいたいわかりました。ただ、この本を読んでも、ベイズをつかって何かしよう!というレベルにはいかないです。本当に導入部分を知るための1冊です。  

これからできるようになりたいこと

 これからできるようになりたいことを3つほど挙げましたが、今まさに本気で勉強中です。ここらへんをブログでアウトプットしていきたい・・

機械学習の理論を本気で理解する

 前述しましたが、機械学習をただ使えるのと、理論を理解して使いこなすとの差はすさまじく大きいと思います。機械学習の理論を学ぶのに最適な本は何かと調べているとだいたいこの本にぶち当たります。  

パターン認識と機械学習 上

パターン認識と機械学習 上

 かの有名なPRMLです。(プレモルとか呼ばれてるらしい)
 ただ、ぶっちゃいきなりやるのはかなり無謀だと感じました。なので、いろんな方のブログで、PRML挑戦の前段階で位置付けられている はじめてのパターン認識を勉強中です。
 今年中には、PRMLの方に手を出したい・・。

統計学を使いこなせるようになりたい

 最近、データ分析の仕事をしていると、統計学の大事さを痛感します。統計学を知らないと分析の結果を出しても、その根拠を示せないからです。また、統計学を学ぶ過程で、かなり数学が必要になるので、都度都度、数学も補いながらやると、一石二鳥かなって思ってます。ディープラーニングをやるだけなら、微分線形代数くらいでいけるけど、ここに確率的な議論が入ると、積分もガンガン使うので、理論が飛躍的になるように思います。逆に言うと、非常に習得が難しい統計学をしっかり理解している人材ってあまりいないし、かなり貴重だと思います。なので、このあたりを攻めると他と差別化できそうな気がしてます。
 あと、統計モデリングとかできるようになりたいなって漠然と思い、みどり本を読み始めました。

まだ3章までしか読んでないですが、めちゃくちゃおもしろいです!  

英語が壁にならないようにする

 学生時代には英語をかなりしゃべる環境に身を置いており、そこそこ自信はあったのですが、それから消防士になり5年くらい全くしゃべってなかったので、本当に話せなくなってました。今でも、読むのにはほとんど苦労しないし、聞くのもだいたい何言っているかわかりますが、話すのが全然ダメになっているので、そこをなんとかしたいです。もともと英語を話すために英語を勉強するっていうのは嫌いで、英語はあくまでもツールの一つなので、勉強しないスタンスを貫いてきたのですが、それが障壁になり、チャンスを逃すようになるともったいないので、勉強を始めてみようと思います。
 とは言ったもののなにから始めてよいものか・・悩み中です。

2017年の目標(エンジニアに転職して1年目)

 2016年は私にとって、激動の年でした。何と言っても下記のエントリーにも書きましたが、転職したことが大きな変化の1つです。   blog.tsurubee.tech

そもそもプログラミングに初めて触れたのが2016年の1月でした。なので、まだプログラミング自体始めて1年くらいですが、なんとかかんとか周りの方々に迷惑をかけながらエンジニアとしてのスタートをきることができました。今回は、エンジニア1年目の私の2017年の目標を書きます。

2017年の目標

1.Pythonを使いこなせるようになる

 私はプログラミングを始めて短期間に、RubyPHPPythonと言語を変えたので、これといって得意な言語がありません。周りの人たちを見ていると1つの言語を習得すると、次の言語に移るスピードが速いのは明らかなので、まず、一言語を習得したいと思っています。純粋なPythonももちろんですが、データ分析をやる際に何かとでてくるNumpyやPandasも使いこなせるようになりたいと思います。とりあえず下の2冊をやります。

入門 Python 3

入門 Python 3

Pythonによるデータ分析入門 ―NumPy、pandasを使ったデータ処理

Pythonによるデータ分析入門 ―NumPy、pandasを使ったデータ処理

2.数学力を高める 

 最近機械学習をやり始めたら、数学が必要だなって感じました。機械学習における数学についての話は下記のものが参考になります。

数学を避けてきた社会人プログラマが機械学習の勉強を始める際の最短経路

機械学習の基礎知識としての数学 - learning.ikeay.net

機械学習に必要な高校数学やり直しアドベントカレンダー Advent Calendar 2016 - Qiita

 微分積分線形代数が必要だと思うので、その二つを勉強するってのはもちろんなんですが、そもそもどうやったら素の数学力を高められるのかを追求したい。

3.仕事以外でプロダクトを作る。

 仕事以外でも作りたいものを決めてコードを書いていきたいなーと思います。現時点で作りたいものは以下の二つです。

自然言語処理機械学習を用いた文書推薦システム

 スマートニュースやグノシー的なイメージのものを自分の情報収集のために作りたい。IT関連の情報に特化して収集し、最近の好みを機械学習して、オススメしてくれるようなものが作りたいなーって思っています。
 グノシーみたいなのを作っている方がいたので、参考にしたいです。

機械学習で大事なことをミニGunosyをつくって学んだ╭( ・ㅂ・)و ̑̑

 また、作る過程で、クローラー開発もやりたいなって思います。

Pythonで作るWebクローラ入門 - Speaker Deck

機械学習を使った株やFXのトレードシステム

 トレードシステムを作ることのモチベーションは、お金を生み出したいというよりは、金融データをRNNとかで扱えるようになるとかっこいいし、株とかFXにも興味があるので詳しくなりたいです。 以下のものが参考になりそうです。

tensorlfowで株価予測

pythonと遺伝的アルゴリズムで作るFX自動売買システム その1

アルゴリズムトレードへの誘い

以上、2017年の目標でした!!

消防士からエンジニアに転職した話

 私は2016年10月まで消防士の仕事をしていて、2016年11月からITエンジニアに転職しました。学生時代の専攻も情報系とは全く関係なく、プログラミングに初めて触れたのが2016年の1月からで、勉強を始めて約10ヶ月で転職に至りました。今回は、そんな少し変わった経歴を歩んでいる私が、なぜ消防士を辞めてエンジニアに転職したか、ゼロからプログラミングの勉強を始めて転職するまでの道のりなどを書いていきたいと思います。

目次


自己紹介

 私は化学の研究者→消防士→ITエンジニアと異色の経歴を歩んでいる20代後半の男です。
 学生時代は、大学・大学院で化学を専攻し、博士課程まで進学しました。当時は、海外の学会で英語で研究発表をしたり、海外の学術雑誌に論文を投稿したりと、非常に活発に研究をしていました。知っている人も少ないかもしれないですが、日本学術振興会の特別研究員というものに採択され、文部科学省から給料をいただきながら研究をしていました。
  そんな私は5年ほど前に大学院の博士課程を中退し、2016年10月まで消防士として働いていました。消防士になったきっかけは簡単には書けないくらいいろいろありますが、人の役に立つ仕事がしたいというのと、地方公務員になって地元に残りたいという気持ちがありました。今思えば、当時は自分のことが全然よくわかってなかったし、仕事をするってことがよくわかっていなかったと思います。
 2016年1月からプログラミングの勉強を始めました。始める前、パソコンは化学の研究でWordやExcelを使うくらいで、PHPRubyというプログラミング言語があることさえ知りませんでした。そんな私はプログラミングの勉強を始めて約10ヶ月の2016年11月からITのスタートアップ企業でエンジニアとして働き始めました。現在仕事では、Pythonを使ってECサイトのレコメンドシステムの開発等に従事しており、趣味で機械学習をやっています。

なぜ転職したのか

 私は学生時代から漠然と「人の役に立つ仕事がしたい」と強く思っていて、東日本大震災をきっかけに、自分の体を使って直接的に人を助ける仕事をしようと決意し、消防士の採用試験を受けました。運良く一発で合格することができ、消防士として働き始めました。実際に消防士になってみて、本当にやりがいのある素晴らしい仕事だと感じました。ただ、ある時ふと思いました。『あれ?俺、休みの日のために仕事してないかな?』
 消防士という仕事は基本的に24時間勤務ですが、月の出勤は10日くらいで、すごくフリーな時間が多い仕事です。それで、私は休みの日は外に遊びに行ったり、家でゴロゴロしたり過ごしていて、なんとなく充実感を感じていました。しかし、その充実感は仕事とは全く関係なく、ほぼ休みの日の充実感でした。なんでそうなったかを今考えると、理由は2つあります。1つは消防士といえど、人の役に立ったなーって感じる瞬間はかなり稀であること。それは万が一に備える仕事の特性上、当然のことだと思います。もう1つは自分の力を活かせてないなーって感じていたこと。私は運動はすごく好きですが、特別得意なわけではないし、仕事をしてから、骨折、脱臼、肉離れ、捻挫、腰痛といった様々な怪我に悩まさる日々が続きました。どう考えても、私は身体を使う仕事より頭を使う仕事の方が、好きだし、得意だなって思うようになりました。
 それから何か新しいことを学びたいと思うようになり、前々から興味があったプログラミングを始めてみました。始めはよくわからず、Rubyで簡単なWebアプリを作ったりして遊んでいましたが、やればやるほど興味が湧いてきて、次第にのめり込んでいきました。勉強をしていく中で私の中に新しい考えが生まれました。人の役に立つって何も身体を使って人の命を助けるだけじゃないし、今や、テクノロジーが直接的に人を救う時代がきている。例えば、少し前ですが、血液ガンに侵され、死を覚悟した女性を人工知能「Watson」が救ったの記事のように人の命だってテクノロジーで救うことができるということに感銘を覚えました。そう考え出すと、もう一度自分の好きなこと、得意なことを活かしてゼロから挑戦したいと思い、エンジニアとしての転職を目指し出しました。

消防士という仕事

 消防士は、24時間勤務の2交代または3交代制で仕事をしています。仕事は大きく分けると、消防業務(いわゆる火消し)と救急業務に大別され、勤務中に指令が入ると出動し、災害対応にあたります。出動がないときは、災害を想定した訓練や体力錬成をしています。
 消防士という仕事は、己の体力・技術・知識を駆使して人の命を救うとてもやりがいがあって素晴らしい仕事だと今でも思います。ただ、時代背景として、年々火災件数は減少しており、一方で救急件数は激増しています。(地域にもよります)私は、比較的大きな都市で仕事をしていましたが、実際に火災で燃えているのを見るのは、数ヶ月に1回あるかないかでした。火災がないことはもちろんいいことです。ただ、日々万が一のために備えて、厳しい訓練をし続けるのには、相当な高いモチベーションが必要だと感じました。そして、私は怪我をきっかけにそのモチベーションを保つことが少しずつできなくなりました。
 また、私にとって消防という仕事は閉鎖的な世界に感じました。何が言いたいかというと、消防士として習得する知識・技術は消防士としてしか活かせないということ。日々の鍛錬は消防士としての自分の価値を高めているのであるということ。その点、エンジニアという仕事は、日々の業務で身につけた知識や技術は勤めている会社だけで発揮できるものではない普遍的な力であり、そこを極めていくと、起業したり、フリーランスになったり、海外で仕事をしたりと、その先が無限大に広がる世界のように感じます。どちらがよいというつもりはありませんが、私にとっては先が自由に開けた世界の方がワクワクして仕事ができると思いました。

f:id:hirotsuru314:20161231172841j:plain

仕事の位置付け

 世の中には休みの日のために働くという人も多いと思います。見方によっては仕事は生きるための手段でしかないし、休みのために働くという考え方もありだなって思います。要は、個人個人、人生における仕事の位置付けが違っているんだと思います。私は、社会人としてのキャリアをスタートしたのち、その自分の中での仕事の位置付けというものを模索し、考え始めました。
 私にとっての仕事の位置付けは、あくまでも、家族の次に大切なものです。しかし、私にとっての仕事は、そこに大きな目標があり、ときには家族との楽しい時間を割いてでも、何かを達成するために注力したいと思えるものであってほしい存在でした。

すべての経験をプラスにする

 私のように消防士→ITエンジニアという全然違う分野に方向変換をすると、直接的に何かが活きてくるということはほとんどないかもしれません。それでも私は全ての経験はプラスだと思います。
 他人と接すると、必ず自分は相手の知らないことを知っているし、したことない経験をしていると思います。自分の知らない世界を知っている人は、自分にない視点を持っているし、何より話が新鮮で楽しい。私もこれから消防士という仕事をしていたことをプラスに変えるような生き方をしていきたいと強く思います。すでに、「元消防士です」って言うだけで相手に印象を残せるので、ある意味得しているのかもしれません。笑

転職活動について

 私が今の職場に就職したきっかけは勉強会でした。あとあと入社して職場の人の話を聞くと、勉強会きっかけってけっこう多いみたいです。私は完全素人だったので、自分が勉強会に参加するなんておこがましいなって思ったこともありました。しかし、勇気を出して行ってみると、知識や人とのつながりなど多くのことを得ることができることを実感しました。私は勉強会を探すためにconnpassというサイトを使っています。

connpass.com

 あと最近では、Wantedlyというビジネスに特化したSNSも転職活動に有効だと思います。

www.wantedly.com

 私も実際にWantedlyを通じて、いくつかのスカウトをいただき、何社か面談に行かせていただきました。

ゼロからプログラミングを始めて転職するまでの道のり

勉強したこと

 私が勉強を始めてから転職するまでの10ヶ月にやったことを時系列でざっとまとめてみました。
 まず、プログラミングの勉強するといっても何をしたらいいかがわからなかったので、プログラミング全般のことが書いてある下の本を読みました。

おうちで学べるプログラミングのきほん

おうちで学べるプログラミングのきほん

 世の中にはどんな言語が存在して、何を学べば何ができるようになるかを知りました。すると、どうやらWebサービススマホアプリを作る言語は違うということがわかりました。私はWebサービスを作る方を勉強しようと決めました。
 ドットインストールという無料で様々な言語が学べるサイトがあるということを知りました。私は、興味があるものを一通りやりました。どうやら、Webサービスをつくるには、ブラウザを通してユーザに見える画面を作るフロントエンドと、サーバとのやりとりなど内部的な処理をしているバックエンドがあることを知りました。まず、画面を作ってみたいと思い、HTML・CSSの勉強をしました。

スラスラわかるHTML&CSSのきほん

スラスラわかるHTML&CSSのきほん

 この本では一冊を通して架空のcafeのホームページを作ります。完全ゼロから始めた私でも全くつまずくことなく最後までやりきれました。ある程度ホームページの作り方わかってきたあとに、今の時代ホームページはPCからだけでなくスマホから見られることが多いということを知り、画面サイズに合わせて自在にレイアウトを操る『レスポンシブWebデザイン』という言葉を知りました。

 レスポンシブWebデザインについては上の本で勉強しました。横に並べていた写真を、画面サイズを小さくすると、縦に並ぶようにするといったことができるようになりました。この時点で、ある程度画面が作れるようになったものの、自分にはデザインのセンスがないということを気付かされました。そして、デザインのセンスがなくても簡単に見た目の整ったものが作れるBootstrapというフレームワークがあることを知りました。

Bootstrapファーストガイド―CSS設計の手間を大幅に削減!

Bootstrapファーストガイド―CSS設計の手間を大幅に削減!

 センスのない私でも、見た目の整ったそれらしい画面が比較的高速に作れるようになりました。そろそろ画面づくりは飽きたな、バックエンドの勉強でも始めるか、ということで、国産の言語であるRubyを始めました。併せてRuby on Railsというフレームワークも学びました。

たのしいRuby 第5版

たのしいRuby 第5版

Ruby on Rails 4 アプリケーションプログラミング

Ruby on Rails 4 アプリケーションプログラミング

 このあたりで、簡単な掲示板サイトやTwitterクローンのようなものが作れるようになりました。そしてあとは、自分が作りたいものを決め、ひたすら
 コードを書く→エラーが出る→調べる→最初に戻る(→時々うまくいく→次に進む)というサイクルを繰り返しました。
 調べる際には、Qiitaにだいぶお世話になりました。また、Qiitaでは調べ物だけでなく日頃の情報収集も行なっています。

 qiita.com

 そろそろ、前々から興味があった機械学習でも始めてみようと思いました。機械学習をやるにはPythonという言語がよいということを知りました。

入門 Python 3

入門 Python 3

 PythonにはRubyでいうところのdo〜endのようなブロックを囲う表現がなく、インデントのみで階層構造を表現していることに最初はすごく違和感を覚えました。言語によっていろいろルールがあるんだなっていうことがわかりました。Pythonが少し書けるようになったので、機械学習の本を買いました。

ITエンジニアのための機械学習理論入門

ITエンジニアのための機械学習理論入門

 私にとっては、全然入門じゃなかった。完全に数学やり直さないとダメだなって感じ、高校数学をやり直し始めました。今も微分積分・行列あたりを勉強中です。数学をやり直した後に上の本の素晴らしさにやっと気付けました。数学はとにかく挫折しないことを最優先に考え、マンガで学ぶ系のシリーズからやり始めました。

マンガでわかる微分積分 微積ってなにをしているの?どうして教科書はわかりにくいの? (サイエンス・アイ新書)

マンガでわかる微分積分 微積ってなにをしているの?どうして教科書はわかりにくいの? (サイエンス・アイ新書)

  • 作者: 石山たいら,大上丈彦,メダカカレッジ,森皆ねじ子
  • 出版社/メーカー: SBクリエイティブ
  • 発売日: 2007/12/15
  • メディア: 新書
  • 購入: 29人 クリック: 139回
  • この商品を含むブログ (17件) を見る

数学の知識は必要とはいうものの、早い段階で機械学習で何か作って見たいなって思って、下の本を買いました。

 今までいろんな参考書を読んでいましたが、初めて衝撃を覚えました。こんなにわかりやすい本があるんだと。私のような素人でも機械学習で手書き文字の画像分類ができるようになりました。今は機械学習でもっとおもしろいことができないかなーって思い、tensorflowとかを触ってみてます。この他にもいろいろ勉強しましたが、それはまた別の機会で紹介します。

モチベーションを保つために

 何かを学ぶときってモチベーションを保ち続けるのが大変だし、すごく大事な部分だと思います。私もけっこうモチベーションを見失いかけたときがあったのですが、そんなときにやる気を出した方法の一つとしては、いろんな方々の経験談などの記事を読むことです。 特に私は、誰かのWebアプリ作ってみた系の記事が好きでよく参考にしていました。

ニートが1週間でアイデア共有サービスをつくったときの記録 - kamiのサービス制作ログ

ノンプログラマーが3ヶ月でWebサービスを作ってみた - Qiita

webサービス(webアプリ)を1年独学で個人開発してきた僕の作り方

素人がRuby on Railsを勉強してWEBサービスを作るまで | rokuro Fire

あと、下のビル・ゲイツFacebook創業者のマーク・ザッカーバーグなどが、プログラミングを学ぶ魅力について語っている動画もモチベーションが上がります。英語ですが、日本語字幕で見れます。『天才じゃなくてもプログラミングはできる』というのが印象的でした。

www.youtube.com

今後について

 人はたとえ会社に勤めていようと、自分で事業をしていようと、自分の能力(技術や知識)を売って仕事をしているんだと思います。そう考えるとその商品(能力)がどうやったら売れるか、またどうやったら高く売れるかを真剣に考える必要があると思います。私はまだまだ知識も経験も未熟ですが、これからも自分の価値を高める努力をし続けていきたいと思います。
 ITの分野は非常に広大であるため、私はある程度勉強する対象を絞った方がいいんじゃないかなって思いました。そこで私が選んだキーワードとして、「データサイエンス」「機械学習」「Python」「数学」あたりに力を入れていきたいと思います。
 あと、もともと私がブログを書き始めたのは、プログラミングの勉強を始めて、備忘録的にブログを書くことで、自分の理解も高まると感じたからです。なので、これから自分が学んだことを自分のためにも、見てくれる人のためにもガンガン発信していきたいと思いますので、よろしくお願いします!

【書評】『コンピュータで「脳」がつくれるか』は超わかりやすい人工知能(AI)の入門書だった。

 2016年9月に出版された『コンピュータで「脳」がつくれるか』という本を読みました。すごくよかったので、紹介します!

コンピューターで「脳」がつくれるか

コンピューターで「脳」がつくれるか


 読んだきっかけは、著者の方がはてなブログを書いていて、私はもともとそのブログの読者でした。そのブログの中で、書籍の紹介があったので、気になって購入しました。

コンピューターで「脳」がつくれるか? FAQ編 - Sideswipe

 本書のよかったところは、数式やプログラミングの知識なしで最近の人工知能事情を理解することができる点だと思います。人工知能とか機械学習といったフレーズを聞くと、専門的で敷居が高い気がしますし、実際に人工知能関連の本は決して初心者にもわかりやすいとは言えないと思います。そういう点では、この本は、今までの本とは少し毛色が違っていて、エンジニアではない方にも理解しやすいように書かれています。

 東京大学の松尾豊先生が書いた 人工知能は人間を超えるか (角川EPUB選書) は、2016年のビジネス書大賞にも選ばれ、人工知能の本としては、かなり有名になりましたが、紹介する本は、より内容を噛み砕いており、絵や図を多く使っているため、わかりやすかったです。『コンピュータで「脳」がつくれるか』→『人工知能は人間を超えるのか』の順番で読むと理解が深まると思います。(私は逆の順番でしたが楽しく読めました。)

 本書の中では、まず人工知能を「汎用AI」と「特化型AI」とにはっきり分けています。(これは、強いAIと弱いAIなどとよく言われています。)簡単に言うと汎用AIというのは、ターミネータやドラえもんのように意識を持っていて、人間と同じような知能を持ったものをいい、特化型AIというのは、チェスや囲碁をするなど特定の作業に特化した能力を持つものをいいます。本書は、「脳のしくみ」について、一つの章をさいて説明しており、汎用AIを実現する方法を脳科学の観点から考察している点が非常に面白く、私はそのような話は初めて目にしました。

 また、教師あり学習、教師なし学習、強化学習、ディープラーニングなどについても簡単に解説してあるので、よかったです。最近の人工知能というのは機械が自分で考えているの?人間のように感情を持ったロボットって将来的に実現できるの?とか、そんな素朴な疑問を持っている人は、この本でそこらへんの実情を知ることができるので、オススメです。

 あと、最近YouTubeにある下の講演会の動画を見て、すごく勉強になったので、紹介しておきます。『人工知能は人間を超えるのか』の著者の松尾豊も出ています。タイトルにもあるように、何年後に実現するかわからない夢物語ではなく、ここ数年で実現可能な人工知能を用いた技術について討論されています。

www.youtube.com

あと、私も以前、人工知能についての記事を書いていますので、良ければ読んでください。

hirotsuru.hatenablog.com

はてなブックマークから特徴語を抽出し、ユーザーの興味・関心を分析する。

 以前、文章から特徴語の抽出や特徴ベクトルを生成するモジュールを作りました。

hirotsuru.hatenablog.com

 今回は、これを使って個人のはてなブックマークから特徴語を抽出し、興味・関心を分析できるのかやってみたいと思います。

 はてなブックマークについては、はてなブログを閲覧されている方々には、説明の必要がないかも知れませんが、オンライン上にブックマークを無料で保存できるソーシャルブックマークサービスです。下の画像は私のはてなブックマークのページです。

f:id:hirotsuru314:20160805173705p:plain

 ユーザーは興味がある記事にしかブックマークをしないので、個人のブックマークを解析することで、その人が興味を持っていることを知ることができるんじゃないかと思いました。もし、個人の興味・関心を知ることができれば、一人一人にパーソナライズされたサービスの提供に繋げられるので、非常に有用ではないかと思います。

目次

つくったもの

 コードは以下のリンクから見れます。

github.com

やったことの流れとしては、以下のような感じです。

1.ユーザーがブックマークした記事をRSSから読み込み、取得

2.ブックマークのタイトルを取り出す。(全タイトルをつなげて、一つの文章のように扱う)

3.Mecabで単語分割(名詞のみを抽出)

4.各単語のTF-IDFを算出し、特徴語を抽出

実際に使ってみる

 実際に私のブックマークを使って、分析の結果をお見せします。コマンドラインからプログラムを実行すると、

$ ruby Sample.rb
はてなIDを入力してください。

まず、はてなIDを聞かれますので、入力します。ここで、注意が必要なのが、はてなの「ニックネーム」じゃなく「はてなID」の方です。

f:id:hirotsuru314:20160805171030p:plain

はてなIDを入力すると、以下のような結果が返ってきます。(関心度が高いものから、ランキング形式で5つの特徴語を抽出しています。)

$ ruby Sample.rb
はてなIDを入力してください。hirotsuru314
1:機械学習
2:Ruby
3:Ruby on Rails
4:コード
5:初心者

 私は、「Ruby」や「Rails」、「機械学習」を勉強し、「コード」を書いているプログラミングの「初心者」ですので、かなり私のことをパーソナライズしています。笑

 この結果から、個人のブックマークを使うと、興味関心をパーソナライズできそうです!

技術メモ

RSSフィードから情報を取得する

 RubyRSSフィードを解析し、何かしらの情報を取得するためには、標準ライブラリの「rss」が有効です。Rubyにはnokogiriという非常に優れたスクレイピングのためのライブラリがありますが、情報の取得先がRSSだけであれば、nokogiriを使わずに標準ライブラリで十分です。

library rss (Ruby 2.2.0)

ユーザーのはてなブックマークRSSのURLは以下のようになります。

http://b.hatena.ne.jp/はてなID/rss

ちなみに、ユーザーのはてなブックマークRSSは最新の20件のみしか表示されません。全件を取得するためには、APIを叩けばできますが、 oauth認証が必要であったり、少し面倒なので今回はやりません。

def get_rss
  url = "http://b.hatena.ne.jp/#{$hatena_id}/rss"
  opt = {}
  opt['User-Agent'] = 'Opera/9.80 (Windows NT 5.1; U; ja) Presto/2.7.62 Version/11.01'
  @rss = open(url, opt) do |file|
    RSS::Parser.parse(file.read)
  end
end

上のコードでUser-Agentの部分は、以下の記事を参考にしています。

はてなブックマークの RSS を Ruby で取得していたのですが、こ… - 人力検索はてな

専門用語の対応はmecab-ipadic-NEologd

 以前の記事にも書きましたが、mecab-ipadic-NEologdという非常に優れた辞書があります。

hirotsuru.hatenablog.com

 IT関連の専門用語はこれを導入すれば十分に対応できます。逆にこれを使わないと、「機械学習」が「機械」と「学習」に分けられてしまったりして、うまく特徴語が抽出できません。

 mecab-ipadic-NEologdを使った単語分割のコードは以下のような感じです。ここで、@bookmark_titlesにRSSから取得した20件のブックマークのタイトルをつなげた文章が入っています。

 #Mecabによる形態素解析
  def split_words
    @arr = Array.new
    nm = Natto::MeCab.new('-d /usr/local/lib/mecab/dic/mecab-ipadic-neologd')
    nm.parse(@bookmark_titles) do |n|
      surface = n.surface
      feature = n.feature.split(',')
      #名詞のみを抽出する
      if feature.first == '名詞' && feature.last != '*'
        @arr.push(surface) #テキストを単語分割して配列で返す
      end
    end
  end



TF-IDFによる特徴語抽出

 Mecabによる単語分割までできれば、あとはブックマークのタイトルに登場する単語をカウントして、それぞれの単語のTF-IDFを算出します。

  def calculate_tf
    @tf = Hash.new
    @arr.each do |word|
      if(@tf.key?(word))
        @tf[word] += 1
      else
        @tf[word] = 1
      end
    end
    @tf.each do |key, value|
      @tf[key] = value.to_f/@tf.size
    end
  end

  def calculate_tfidf
    @tfidf = Hash.new
    @tf.each do |key, value|
      if $idf.has_key?(key)
        @tfidf[key] = ($idf[key] * value).round(3)
      end
    end
  end

TF-IDFを算出した後に、その値が大きいものから5つを特徴語として取り出しました。

さいごに

 今回、はてなブックマークからの特徴語抽出をやってみて、一人一人の興味・関心をパーソナライズする一つのアプローチとして、ブックマークを使うのは有効だと思いました。今後は、これをもとにユーザごとにパーソナライズされたサービスを提供するようなWebアプリケーションを作ってみたいと思っています。

Rubyで文章を特徴ベクトルに変換するモジュールを作った。

 最近、自然言語処理関係に興味を持ち、いろいろやっています。今回作ったものは、例えば、人工知能に関する文章をプログラムに渡すと、

{ "人工知能": 3.4, "自動運転": 2.8, "研究": 1.5, ・・・・ }

といったように、文章の特徴を表す単語(以下、特徴語という)を抽出し、その特徴語がどれだけ文章の特徴を表しているかを数値化します。結果は、Rubyにおけるハッシュで返し、特徴語をkey、値をvalueとします。このハッシュが文章の特徴ベクトルになります。

 実はこれ、以前も同じようなことをやっています。

hirotsuru.hatenablog.com

 以前も2つの文章の特徴ベクトルを生成し、ベクトル同士の角度から類似度を推定するというようなことをやっています。しかし、特徴ベクトルを作るのって、まだまだ検討の余地があるなーって思っていたので、またいろいろやってみました。

 また、特徴ベクトルを作るというプロセスは、自然言語処理に関わらず、非常に重要なプロセスです。「情報推薦システム入門:講義スライド」という非常に勉強になるスライドから拝借した画像を以下に示します。

f:id:hirotsuru314:20160724212134p:plain

 この画像からわかるように、文章に限らず、画像や音声など様々なデータをプログラムで処理する際、その特徴を抽出することが必要となります。この際に、データを特徴ベクトルで表すということがよくやられています。特徴ベクトルを作ることができると、それらの類似度の推定やカテゴライズなどもできるようになります。

つくったもの

 コードは下のリンクから見れます。

NLP/Feature_vector at master · hirotsuru314/NLP · GitHub

 私のポートフォリオでも私の経歴や制作物の情報などを載せていますので、よければ見てください。

www.hirotsuru.sakura.ne.jp

なにができるか

 実際に以下の文章をベクトル化したものを見てみましょう。

 機械学習とは、人工知能における研究課題の一つであり、様々な分野への応用が期待される。その一つがビッグデータを用いたデータマイニングである。 』

 この文章を、テキストファイルに格納し、コマンドライン引数でプログラムに渡します。

$ ruby Sample.rb text.txt
{"機械学習"=>0.436, "人工知能"=>0.39, "研究"=>0.236, "課題"=>0.363, 
"一つ"=>0.431, "様々"=>0.279, "分野"=>0.259, "応用"=>0.331, 
"期待"=>0.361, "ビッグデータ"=>0.529, "データマイニング"=>0.465}

 以上のように、結果としてハッシュが返ってきました。コードは以下のような感じです。

$:.unshift File.dirname(__FILE__)
require 'natto'
require "idf_dic"

module TfIdf

  #Mecabによる形態素解析(単語分割)
  def split_words(text)
    @arr = Array.new
    nm = Natto::MeCab.new('-d /usr/local/lib/mecab/dic/mecab-ipadic-neologd')
    nm.parse(text) do |n|
      surface = n.surface
      feature = n.feature.split(',')
      #名詞のみを抽出する
      if feature.first == '名詞' && feature.last != '*'
        @arr.push(surface) #テキストを単語分割して配列で返す
      end
    end
  end

  #TF値を計算
  #配列をkeyが形態素、valueがTF値(Float)のハッシュに変換
  def calculate_tf
    @tf = Hash.new
    @arr.each do |word|
      if(@tf.key?(word))
        @tf[word] += 1
      else
        @tf[word] = 1
      end
    end
    @tf.each do |key, value|
      @tf[key] = value.to_f/@tf.size
    end
  end

  def calculate_tfidf
    @tfidf = Hash.new
    @tf.each do |key, value|
      if $idf.has_key?(key)
        @tfidf[key] = ($idf[key] * value).round(3)
      end
    end
    puts @tfidf
  end
end

 流れとしては、Mecabで単語分割して名詞だけを抽出する、単語の出現回数を数える(TF値)、事前に算出したIDF値と掛け合わせる、結果をハッシュで返すといったことをやっています。

 結果を見てみると、「機械学習」とか「ビッグデータ」とか専門的な言葉は、その文章の特徴となるため、比較的大きな値となり、一方で「研究」とか「分野」といった言葉は、様々文章に出てくる頻出ワードであり、文書の特徴を表さないので、値が小さくなっています。以上の結果から、一定の信頼性をもった文書の『特徴語抽出』と『特徴ベクトル生成』ができたと言えると思います。

技術メモ

形態素解析に用いる辞書を更新する。

 以前の記事にも書きましたが、形態素解析に用いる辞書を更新することはかなり重要です。

hirotsuru.hatenablog.com

 通常は、記事にも書いている『mecab-ipadic-NEologd』を使えば、だいたい対応できると思います。ただし、アニメのタイトルなどのいわゆるオタク用語?のようなものにまで対応しようとすると、独自に辞書を定義する必要があるかもしれません。

・DF-IDFによる単語の重み付け

 DF-IDFについての説明は以前の記事に書いています。

 上の例では、短文を分析したので、それぞれの単語は1回ずつしか登場しないのですが、きちんと特徴を表していそうな単語に大きな値が示されているのは、IDFにより、単語の重み付けができている証拠です。

 IDFの算出には、分析対象となる文章以外に多くの文章群を必要とします。つまり、その単語の希少性(レアさ)を調べるために、その単語が多くの文章に出現するのか、または特定の分野でしか登場しないレアな単語なのかを調べることが単語の重み付けに繋がります。

 私の場合、この文章群にWikipediaのAbstractを用いました。Abstractの中でも100語以上あるものだけを抽出し、IDF辞書として定義しました。私のコードの中の"Making_idf_dic.rb"に文章群を渡すと、IDF辞書をハッシュで返すようになっています。文章群はファイル名"documents.txt"でカレントディレクトリにおき、テキストファイル内は文章間を改行で区切ったものを渡すとIDF辞書が作成できるようにしています。

・IDFを外部ファイルに格納した

 私の場合、IDFはWikipediaの文章から事前に定義しているので、その値は変わることはありません。そのため、このIDF辞書を外部ファイル(idf_dic.dat)に格納しました。これで、自分専用のIDF辞書が完成です。IDF辞書の値は、特徴ベクトルにおける次元に相当するものなので、結果に大きく影響することは間違いありません。またいろいろ検討してみたいと思っています。

終わりに

 最近、やっと少しずつ日本語文章の取り扱い方がわかってきたので、他に手を出さず、最近作ったモジュールを使ってWebアプリを作っています。また、何かできたらどんどんアウトプットしていきたいと思うので、またよろしくお願いします!