読者です 読者をやめる 読者になる 読者になる

Abnormalに生きる

化学の研究者→消防士→ITエンジニア(2016年11月〜)

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

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

そもそもプログラミングに初めて触れたのが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.数学力を高める 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

tensorlfowで株価予測 - Qiita

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

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

以上、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アプリを作っています。また、何かできたらどんどんアウトプットしていきたいと思うので、またよろしくお願いします!

形態素解析エンジンMecabの辞書を更新する(mecab-ipadic-NEologdの導入)

 先日、Rubyで2つの文章間の類似度を計算するモジュールについての記事を書きました。

hirotsuru.hatenablog.com

 形態素解析、すなわち文章を単語に分割することは、文章を解析する上で、最初のステップとなります。この単語分割の際に用いる辞書は、日々生み出される新しい単語に対応するために更新すべきです。今回は、『mecab-ipadic-NEologd』という非常に優れたカスタム辞書を用いると、最近のホットなキーワードにもしっかり対応できるよ、というお話です。

 MeCabには、標準的な辞書として「ipadic」というものが提供されていますが、現在は継続的に更新されていないので、急に流行ったような言葉には対応できません。新しい言葉への対応の一つとして、Wikipedia 日本語版やはてなキーワードなどを取り込み、独自に辞書を定義するということをやっている方もいるみたいですが、少々手間がかかります。そこで、『mecab-ipadic-NEologd』を導入すると、新語への対応に絶大な力を発揮します。

github.com

 mecab-ipadic-NEologdには日本語のREADMEもあるので、インストール方法、使い方については、READMEを見るのがわかりやすいと思います。

 mecab-ipadic-NEologdの優れている点の一つは、その更新頻度です。下のようにかなりの頻度でcommitされています。

f:id:hirotsuru314:20160714130342p:plain

 MeCabの標準辞書を用いて解析した際に、うまく分割できない語や読み仮名の付与ができない語をなるべく追加するようにしてくれているみたいで、本当に助かります。それでは、実際にmecab-ipadic-NEologdを導入することでの変化を見てみましょう。

mecab-ipadic-NEologd導入前

 以下の文章を形態素解析してみます。

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

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

機械 名詞,一般,*,*,*,*,機械,キカイ,キカイ
学習 名詞,サ変接続,*,*,*,*,学習,ガクシュウ,ガクシュー 
と 助詞,格助詞,引用,*,*,*,と,ト,ト
は 助詞,係助詞,*,*,*,*,は,ハ,ワ
、 記号,読点,*,*,*,*,、,、,、
人工 名詞,一般,*,*,*,*,人工,ジンコウ,ジンコー
知能 名詞,一般,*,*,*,*,知能,チノウ,チノー 
における 助詞,格助詞,連語,*,*,*,における,ニオケル,ニオケル
研究 名詞,サ変接続,*,*,*,*,研究,ケンキュウ,ケンキュー
課題 名詞,一般,*,*,*,*,課題,カダイ,カダイ
の 助詞,連体化,*,*,*,*,の,ノ,ノ
一つ 名詞,一般,*,*,*,*,一つ,ヒトツ,ヒトツ
で 助動詞,*,*,*,特殊・ダ,連用形,だ,デ,デ
あり 助動詞,*,*,*,五段・ラ行アル,連用形,ある,アリ,アリ
、 記号,読点,*,*,*,*,、,、,、
様々 名詞,形容動詞語幹,*,*,*,*,様々,サマザマ,サマザマ
な 助動詞,*,*,*,特殊・ダ,体言接続,だ,ナ,ナ
分野 名詞,一般,*,*,*,*,分野,ブンヤ,ブンヤ
へ 助詞,格助詞,一般,*,*,*,へ,ヘ,エ
の 助詞,連体化,*,*,*,*,の,ノ,ノ
応用 名詞,サ変接続,*,*,*,*,応用,オウヨウ,オーヨー
が 助詞,格助詞,一般,*,*,*,が,ガ,ガ
期待 名詞,サ変接続,*,*,*,*,期待,キタイ,キタイ
さ 動詞,自立,*,*,サ変・スル,未然レル接続,する,サ,サ
れる 動詞,接尾,*,*,一段,基本形,れる,レル,レル
。 記号,句点,*,*,*,*,。,。,。
その 連体詞,*,*,*,*,*,その,ソノ,ソノ
一つ 名詞,一般,*,*,*,*,一つ,ヒトツ,ヒトツ
が 助詞,格助詞,一般,*,*,*,が,ガ,ガ
ビッグ 名詞,一般,*,*,*,*,ビッグ,ビッグ,ビッグ
データ 名詞,一般,*,*,*,*,データ,データ,データ 
を 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
用い 動詞,自立,*,*,一段,連用形,用いる,モチイ,モチイ
た 助動詞,*,*,*,特殊・タ,基本形,た,タ,タ
データ 名詞,一般,*,*,*,*,データ,データ,データ
マイニング 名詞,サ変接続,*,*,*,*,マイニング,マイニング,マイニング
で 助動詞,*,*,*,特殊・ダ,連用形,だ,デ,デ
ある 助動詞,*,*,*,五段・ラ行アル,基本形,ある,アル,アル
。 記号,句点,*,*,*,*,。,。,。
EOS

 上を見てわかるように、最近のホットトピックである、「機械学習」「人工知能」「ビッグデータ」「データマイニング」がそれぞれ2つの単語に分割されています。「機械学習」を「機械」と「学習」に分けられると意味が全然変わってきますよね。

mecab-ipadic-NEologd導入後

 mecab-ipadic-NEologdを導入した場合の結果を以下に示します。(コマンドのmecab-ipadic-neologdのパスは個人により異なります)

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

機械学習 名詞,固有名詞,一般,*,*,*,機械学習,キカイガクシュウ,キカイガクシュー 
と 助詞,格助詞,引用,*,*,*,と,ト,ト
は 助詞,係助詞,*,*,*,*,は,ハ,ワ
、 記号,読点,*,*,*,*,、,、,、
人工知能 名詞,固有名詞,一般,*,*,*,人工知能,ジンコウチノウ,ジンコーチノー 
における 助詞,格助詞,連語,*,*,*,における,ニオケル,ニオケル
研究 名詞,サ変接続,*,*,*,*,研究,ケンキュウ,ケンキュー
課題 名詞,一般,*,*,*,*,課題,カダイ,カダイ
の 助詞,連体化,*,*,*,*,の,ノ,ノ
一つ 名詞,一般,*,*,*,*,一つ,ヒトツ,ヒトツ
で 助動詞,*,*,*,特殊・ダ,連用形,だ,デ,デ
あり 助動詞,*,*,*,五段・ラ行アル,連用形,ある,アリ,アリ
、 記号,読点,*,*,*,*,、,、,、
様々 名詞,形容動詞語幹,*,*,*,*,様々,サマザマ,サマザマ
な 助動詞,*,*,*,特殊・ダ,体言接続,だ,ナ,ナ
分野 名詞,一般,*,*,*,*,分野,ブンヤ,ブンヤ
へ 助詞,格助詞,一般,*,*,*,へ,ヘ,エ
の 助詞,連体化,*,*,*,*,の,ノ,ノ
応用 名詞,サ変接続,*,*,*,*,応用,オウヨウ,オーヨー
が 助詞,格助詞,一般,*,*,*,が,ガ,ガ
期待 名詞,サ変接続,*,*,*,*,期待,キタイ,キタイ
さ 動詞,自立,*,*,サ変・スル,未然レル接続,する,サ,サ
れる 動詞,接尾,*,*,一段,基本形,れる,レル,レル
。 記号,句点,*,*,*,*,。,。,。
その 連体詞,*,*,*,*,*,その,ソノ,ソノ
一つ 名詞,一般,*,*,*,*,一つ,ヒトツ,ヒトツ
が 助詞,格助詞,一般,*,*,*,が,ガ,ガ
ビッグデータ 名詞,固有名詞,一般,*,*,*,ビッグデータ,ビッグデータ,ビッグデータ
を 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
用い 動詞,自立,*,*,一段,連用形,用いる,モチイ,モチイ
た 助動詞,*,*,*,特殊・タ,基本形,た,タ,タ
データマイニング 名詞,固有名詞,一般,*,*,*,データマイニング,データマイニング,データマイニング
で 助動詞,*,*,*,特殊・ダ,連用形,だ,デ,デ
ある 助動詞,*,*,*,五段・ラ行アル,基本形,ある,アル,アル
。 記号,句点,*,*,*,*,。,。,。
EOS

 「機械学習」「人工知能」「ビッグデータ」「データマイニング」がそれぞれ一つの言葉として認識されているのがわかると思います。文章の特徴語を抽出する際や特徴ベクトルを生成したい場合には、このようにキーワードをしっかり認識できていることは非常に大事だと思います。

 あとは、mecab-ipadic-NEologdを適宜更新していくだけで、最小限の労力で新語に対応した形態素解析に取り組むことができます。

Rubyで文章間の類似度を計算するモジュールを作ってみた(TF-IDFとCos類似度による推定)

 最近、自然言語処理に興味を持ち始めました。今回は、二つの文章(テキストファイル)の類似度を計算するモジュールを作ってみました。いずれは、これを発展させていって、機械学習とかも組み込んで、Webサイトをユーザの嗜好に応じて推薦してくれるシステムとか作りたいなーって思っています。

今回の目次は以下のような感じです。

目次

なにをやるか

 ニュース記事を3つ取ってきて、その記事同士の関連がどれだけ強いのかを数値化します。比較するニュース記事は以下の三つで、それぞれ「A」「B」「C」とします。

A:自動運転、事故時の法的責任は?テスラの死亡事故問題から考える

B:グーグルが「完全自動運転」にこだわるわけ

C:【ソフトバンク】ノーバン投球の永野「一番中途半端な感じ」オチなしパフォーマンスを反省

タイトルだけ見てもわかるようにAとBは人工知能、自動運転関連の記事であり、Cは野球の記事です。AとBが関連が強く、AとCまたはBとCが関連が弱いような結果がでるものができればよしとします。

つくったもの

 今回書いたコードは下記のリンクから見れます。

github.com

 まだまだリファクタリングの余地ありまくりですが、今回はまず動くことを最優先したので、追い追い改良していきます。

 結果をさきに見てもらいます。(モジュールを使うためには事前にRuby、natto、Mecabのインストールが必要です。)カレントディレクトリに比較したい記事を入れたテキストファイルを置き、コマンドラインで叩くだけです。そうです、この部分は、かなりアナログです。ニュース記事をテキストファイルにコピペしています。

 ゆくゆくは以前の記事に書いたようなスクレイピングを使って、対象のテキストもプログラムから取ってくるようにするつもりです。

hirotsuru.hatenablog.com

コマンドラインで実行すると、値が返ってきます。後ほどまた説明しますが、この値は1に近ければ近いほど類似度が高く、0に近ければ近いほど類似度が低いことを示しています。

AとB 0.618120128908814

AとC 0.0010326528355030487

BとC 0.011337073768295269

結果を見てみると、類似性の傾向としては、望むような結果が出ており、一定の信頼度があるようです。記事の選定の時点でかなり類似性の高いものと、全く関連がないものをチョイスしているため、結果が極端ですが。

採用したアルゴリズム

 アルゴリズムと言えるほど、たいそうなものではないですが、処理の流れとしては、以下の通り。

  1. それぞれの記事からMeCabで単語だけ切り出して記事を単語リストに変換

  2. TF-IDFによる特徴語の抽出と特徴ベクトルの生成

  3. 特徴ベクトル同士のCos類似度を求める。

技術メモ

 「文章の類似性ってどう評価するんだろう?」という疑問が浮かび、いろいろ勉強しながら今回のモジュールを作りました。その作るに至るまでに学んだことを時系列順に説明したいと思います。

文章の類似度計算にはCos類似度

 まず、文章の類似度計算にはCos類似度というのがよく使われていることを知りました。Cos類似度は次の式で定義されています。

f:id:hirotsuru314:20160711104327p:plain

 ここで、aおよびbはベクトルであり、類似性の評価対象のデータです。Cos類似度では、ベクトル空間モデルにおいて、ベクトル同士の成す角の大きさでデータの類似性を評価します。つまり、角度(θ)が小さい場合、ベクトル同士が重なり合うようになるため、ベクトル同士が類似しているということになります。また、角度(θ)がゼロのとき、cosθは1になるため、cosθが1に近いほど、データの類似度が高いということになります。

 ということは、文章をベクトルで表す必要があるということ?そういうことです。

文章をベクトル化する

 文章をベクトル化する方法で、bag of words (BoW)モデルというのがあります。

Bag-of-words model - Wikipedia, the free encyclopedia

 これは、その文章にある単語が何回出現するかをカウントしていく方法です。あるニュース記事で、「プログラミング」という言葉が何回も出てくれば、この記事はIT関連かな?っていうのが予測できそうだと思います。例えば、これを広辞苑に乗っている24万語でカウントしたとします。すると、[5, 1, 0, 3,・・・ ]という具合に出現回数の配列ができます。これが紛れもなくベクトルです。この場合、文書は 24 万次元のベクトル(または空間上の座標)として表されます。

 ということは、文章を単語に分ける必要がありそうです。

文章を単語分割する

 形態素解析という難しそうな言葉がありますが、これは、簡単に言うと文章を品詞単位に分解することです。通常、英語では単語と単語の間をスペースで区切るので単語分割は容易ですが、日本語は助詞などを続けて書くのが通常ですので、話はそんなに単純ではありません。

 ここで、有効なのがオープンソースの日本語の形態素解析エンジンである『Mecab』です。

MeCab: Yet Another Part-of-Speech and Morphological Analyzer

 今回はrubyからMecabを利用するためにnattoというgemを使用しました。nattoは、形態素解析エンジンのMeCabrubyから使うためのインタフェースの役割をします。

 MecabとNattoの導入に関しては以下のリンクが参考になります。

5分でMacにMecabをインストールする方法 | Brainvalley 人工知能と脳科学のアーカイブサイト。

【簡単】RubyとMecabを使うならnattoがおすすめ! | Brainvalley 人工知能と脳科学のアーカイブサイト。

Mecabをインストールすると、下のようにコマンドラインからすぐに利用できます。

$ mecab
今日の天気は晴れのち曇り
今日 名詞,副詞可能,*,*,*,*,今日,キョウ,キョー
の 助詞,連体化,*,*,*,*,の,ノ,ノ
天気 名詞,一般,*,*,*,*,天気,テンキ,テンキ
は 助詞,係助詞,*,*,*,*,は,ハ,ワ
晴れ 名詞,一般,*,*,*,*,晴れ,ハレ,ハレ
のち 名詞,副詞可能,*,*,*,*,のち,ノチ,ノチ
曇り 動詞,自立,*,*,五段・ラ行,連用形,曇る,クモリ,クモリ
EOS

 MeCabには、標準的な辞書として「ipadic」というものが提供されており、これをもとに単語分割します。この単語分割の際にどの辞書を使うかはかなり重要です。その理由は、単語というものは常に新しいものが出てくるため、それに対応するために辞書も更新しないといけないからです。

 また、上の例を見てわかるように「の」や「は」などの助詞は文章の特徴を表さないので、今回は名詞のみをカウントするようにしました。

 ここで、一つ疑問が湧きました。単語をカウントするといっても、「今日」とか「人」のようにどんな文章にもよく出てくるものもあれば、「人工知能」や「プログラミング」のように、特定の分野の文章にしか登場しないような単語もある。これを同じようにカウントすると、うまく文章の特徴を表せないのではないか。

文書内の単語の重み付け: TF-IDFについて

 文書内の単語の重み付けにTF-IDFという手法を使います。TF-IDFでできることは、文書内での単語の重要度を評価して、文章の特徴語を抽出することです。TF-IDFについては、TFとIDFに分けて理解するとわかりやすいです。

tf-idf - Wikipedia

TF

 TFはTerm Frequencyの頭文字をとったもので「文章中にある単語が何回現れたか」のことです。

 計算式は、

  TF = 単語の登場回数 / 文章中の単語の総数

つまり、「ある文章中に、何回も出てくる言葉ほど重要」ということです。

IDF

 Inverse Document Frequencyの頭文字をとったもので、「文章群の中で、ある単語がいくつの文章に現れたか」のことです。

 計算式は、

  IDF = log(文章群中の文章の総数 /その単語が出てくる文章数)

 つまり、単語の珍しさのようなもので、「いろんな文章によく出てくる単語はそんなに重要じゃない」ということです。

 このTFとIDFをかけ合わせたものが、TF-IDFの値となり、ある文章のTF-IDF値の配列が、その文章の特徴ベクトルとなります。

 文章の特徴ベクトルまで求めることができれば、上述のcos類似度の式で、類似度を数値化することができるわけですが、あと一つ困難なポイントがあります。IDFのところで、「文章群」と書きましたが、この文章の集まりをどこから持ってくるかというのがかなり重要です。つまり、TF-IDF法では重要度を分析したい文書だけでなく,その他の関係ないたくさんの文書の集まりが必要となるわけです。

IDFに何を採用するか

 一つの方法として、評価対象のデータと同じ場所から文書を集める方法です。例えば、ニュース記事の類似度を評価したいのであれば、ニュースサイトから5000記事を取ってきて、文書群とし、IDFを算出するというようなやり方です。

 私は今回、Wikipediaから文章を取ってきました。Wikipediaは原則スクレイピングが禁止されているみたいですが、下記のリンクから、文章を全てダウンロードできるようになっています。

Index of /jawiki/

 今回はWikipediaのAbstractを抽出し、データ量が膨大すぎるので、そこからさらに文章数を絞ってDFの算出に使っています。

精度をあげるためにやりたいこと

形態素解析に用いる辞書の検討

 mecab-ipadic-NEologdというものがあることを知りました。 mecab-ipadic-NEologdは、多数のWeb上の言語資源から得た新語を追加することでカスタマイズした MeCab 用のシステム辞書みたいです。その他にも、Wikipediaはてなキーワードなどを導入したりして新語に対応した辞書を作っているみたいです。

GitHub - neologd/mecab-ipadic-neologd: Neologism dictionary based on the language resources on the Web for mecab-ipadic

IDF算出に用いる文書群の検討

 今回は、WikipediaのAbstractを使いましたが、ここの選択が結果に大きく影響を与えることは間違いないので、いろいろ試してみたいと思います。

単語の出現位置

 単語が文章中のどの位置に出現するかということも取り込めたら、精度が上がりそうな気がします。例えば、大事なことは、最後の方に出てくるとか。どんなアルゴリズムで実装できるかはわかりませんが。

今後やること

 まだまだ精度をあげるための工夫は必要ですが、文章の特徴ベクトルが求められるようになったということは、それなりに汎用性があると思います。未知の文章でも、今回の方法で特徴ベクトルを作れば、k-meansなどで実装した分類器にかけて、文章のカテゴライズなどもできるはずです。

   今後は、今回作ったものをベースに、より高度なアルゴリズムの導入とクローラーと併せてWebアプリ化をやっていきます。最終的には、ユーザに応じてどの記事を読んだら勉強になるかを優先順位をつけて推薦してくれるようなシステムを作りたいです。結局はGunosyとかがやっていることと同じですが、それを「学び」に特化した形でやりたいと思っています。