プログラマ向けニュースキュレーションサービスを作ってみた話

## はじめに
2015年度新卒でドワンゴに入社しました@ytanakaといいます。普段はAndroidアプリ開発を主に担当していますが、大学院時代は[増井俊之](http://www.pitecan.com/Index/)先生のもとでユーザインタフェースと情報推薦システムの研究をしていました。

ドワンゴに入社後、それまでの研究を活かしプログラマ向けのニュースキュレーションサービス[Menthas(メンタス)](http://menthas.com/)を個人開発しました。今回はせっかくの機会なので、開発の経緯と概要そして仕組みについて述べたいと思います。

### 追記： 続編を書きました
こちらの記事は以前のバージョンの内容になります。現行のMenthasの仕組み・構成は以下にまとめています。
[約3年かけてプログラマ向けニュース推薦アプリを作り直した話](https://qiita.com/ytanaka/items/6cfad69a4c000c05be40)

## 背景
さて、この記事をご覧になっているのはプログラマの方が多いと思いますが皆さん普段どうやって情報収集をしていますか？

自分の見聞きする限りではTwitterやはてなブックマークを主軸に情報収集している人が多いように思います。もしくはRSSリーダーやHackerNewsあたりを活用している方もいるようです。
また、近年ではSmartNewsやGunosyといったニュースキュレーションアプリも台頭してきています。そちらで日々ニュースを閲覧しているひとも多いでしょう。

しかしTwitterやRSSリーダーの場合、自分で情報源となるユーザやサイトを選別しないといけないため、どうしても自分の興味の範疇でしか情報を収集することができません。そうなるとどうしても得られる情報に偏りが出てしまい視野が狭まってしまうことに繋がります。
このような情報のタコツボ化問題は「フィルターバブル」と呼ばれ近年話題となっています。

それに対してはてなブックマークのようなソーシャルブックマークの場合、Twitterなどと異なり自分の興味外の記事を読むことができますが、ソーシャルブックマークの性質上どうしても誰もが読めるようなニュースが上位に来ることが増えてしまい、専門性の高い記事が埋もれてしまうという問題があります。
この点ではSmartNewsやGunosyも対象ユーザがプログラマ向けというわけではないので同様の問題があるといえます。

このような問題を踏まえると、プログラマにとって理想的なニュースキュレーションアプリとは以下のような特徴を満たすものということになるでしょう。

1. 様々なカテゴリを網羅している
2. 専門性の高い記事も読むことができる

とはいえ自分の知る限りではこのような要件を満たすニュースアプリは存在しないように思えました。
無いなら作ってしまえば良いのでは？と考え、プログラマ向けニュースキュレーションサービスである[Menthas](http://menthas.com/)を作成しました。

ちなみにMenthasの由来は薄荷(mentha)とHackerを掛けたところから来ています。

## 概要
Menthasはこちらから使用することできます [http://menthas.com/](http://menthas.com/)

![https://gyazo.com/2dd78a631e2ce53dec8872ab204cf083.png](https://gyazo.com/2dd78a631e2ce53dec8872ab204cf083.png)

### 使い方
トップページは2カラム表示になっており左側に某Slack風のニュースカテゴリ一覧が、右側にはニュースがタイル状に並びます。スクロールは無限スクロール対応で、読みたいニュースをさくさく探すことが可能になっています。

### 特徴
Menthasの特徴として、各ニュースカテゴリごとにキュレーターと呼ばれる専門性の高いユーザをアルゴリズムによって選抜していることがあげられます。
そして選出されたキュレーターが集めたニュースを合議制フィルタリングを通してユーザに配信するという仕組みになっています。

図式すると以下のようなイメージです。
![https://gyazo.com/82cc2ae72db20040c88011e9dfccb4d7](https://gyazo.com/82cc2ae72db20040c88011e9dfccb4d7.png)


今回ははてなブックマークを最大限に活用させていただきました。はてなブックマーカーから後述するアルゴリズムによってキュレーターを選出し、彼らがブックマークした記事をMenthasのニュースソースとしています。

## 仕組みとアルゴリズム解説

### ニュースカテゴリを定義する
ニュースと一口にいってもスポーツや政治経済、芸能関係といったように様々なジャンルやカテゴリがあり得ます。Menthasではプログラマにとって役立つニュースを幅広いジャンルから提供したいという狙いがあります。
しかしプログラマ向けのニュースアプリを作成したい場合どのような切り口でニュースカテゴリを定義すれば良いのでしょうか。

少し考えても様々なジャンルが想定できます。クライアントサイドではJavaScriptやAndroidとiOSといったようなアプリ開発、サーバーサイドではJavaやPHPというプログラミング言語単位でカテゴリをつくっても良さそうですし、インフラやデザインというカテゴリもあり得そうです。

このようなカテゴリを人手で作るとどうしても偏りや抜けが出来てしまいそうなので、アルゴリズムに任せることにしました。

### タグクラスタリング
今回ははてなブックマークのITカテゴリで使われているタグをクラスタリングすることでプログラマの大まかな興味傾向を把握します。はてなブックマークのホッテントリ約１年分を収集後各記事に付けられたタグをカウントしていき上位300件を抽出しました。

そしてタグ同士の共起頻度を算出してタグクラスタリングが可能なようにベクトル化などの処理を行った後、Googleが開発した軽量クラスタリングツールである[bayon](https://code.google.com/p/bayon/)を使って実際にkmeansでクラスタリング(k=20)を行いました。

bayonについてはこちらのブログ記事がとてもわかりやすいです。

- [軽量データクラスタリングツールbayon](http://alpha.mixi.co.jp/entry/2009/10714/)

### クラスタリングの結果
以下は得られたタグクラスタの一例です。

![https://gyazo.com/ad8a42cae3754aced4d5b24093342b16](https://gyazo.com/ad8a42cae3754aced4d5b24093342b16.png)

なんとなくそれっぽい結果が得られていると思います。他にもデータベース関連のタグや開発環境関連のタグが集まったクラスタなど、全部で20のクラスタが出来ました。その後得られたクラスタに対してそれぞれ自分でラベル付けし、それらをニュースカテゴリとして定義することにしました。

## キュレーターの選出法

### そもそも優秀なキュレーターとは？
ここからはいよいよこのシステムのキモであるキュレーター選別アルゴリズムの話です。

さて、そもそも優秀なキュレーターとはどのような人物を指すのでしょうか。
Menthasでは以下のような性質を持つ人物を優秀なキュレーターと定義します。

1. 話題になる前に価値を見抜く
2. 先見の明がある
3. トレンドを作る

これらは一見突拍子もないように思えますが、JavaScript界隈を例にとると、界隈をリードする人々(例えばazuさんやmizchiさんのような方々)はまだ話題になっていないコンテンツを提供したり、その界隈のトレンドを左右するような影響力をもっているとはいえないでしょうか。このようなあるジャンルや界隈で影響力を持つ人たちをキュレーターと考えたい。

しかし、どのようにしてこのようなキュレーターと呼べるようなひとを発見すれば良いのでしょうか。そこで今回考案したのが「わしが育てた係数」(以下わし育係数)です。

### わしが育てた係数

![http://livedoor.blogimg.jp/retire2k/imgs/e/0/e0517778.png](http://livedoor.blogimg.jp/retire2k/imgs/e/0/e0517778.png)

わしが育てた係数とは、わしが育てた度が高いユーザを選出するためのScoreです。
なんでこんなネーミングにしたかというと「わしが育てた」と、価値のあるものにいち早く目をつけるという、上記の優秀なキュレーターの性質って似ていると思いませんか？

今回ははてなブックマークを対象にしているので、将来ブクマ数が伸びるような記事をいち早くブックマークするひとに対して重みを付けます。つまりこのエントリは「わしが育てた」といえるようなひとを探し出そうというのがわし育係数の狙いです。

さて、わし育係数は以下のような関数で定義されます。

<img width="595" alt="スクリーンショット 2015-12-10 1.21.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/51540/7c3ce84e-f8ce-0d1a-b4ed-385135bff50d.png">

ここは数式が絡むので少し抽象的になってしまいますが、例えば200はてブ付いた記事に対してScoreを割り当てると

![https://gyazo.com/dcc237b1dab2d6470190156abfe8cc6a](https://gyazo.com/dcc237b1dab2d6470190156abfe8cc6a.png)

というような感じになります。
一番最初にブックマークしたひとは200pt、10番目にブックマークしたひとは約125ptというようにブックマークの順位で減衰していき、100番目にブックマークしたひとはほとんどscoreを得られません。
初期の頃にブクマしたひとのScoreが高くなるように関数を調整しているのが特徴です。


これを過去１年分のITカテゴリのホッテントリを対象にしてユーザランキングを作ります。そこで得られたユーザの上位20人をMenthasではキュレーターとしています。ただ、わし育係数がまだナイーブなこともあり、ブックマーカーにどんな記事もブックマークするユーザがまぎれている場合があったので得られたユーザを全て人力でチェックを行っています。

### 結果
すべてのカテゴリのキュレーターリストを表示すると莫大になってしまうのでJavaScriptカテゴリのわし育係数Top20位をここでは紹介します。

```
mizchi
kkeisuke
efcl
makotot-riceball 
atm_09_td
yosuke_furukawa
TokyoIncidents
yfnt
dai_yamashita
hohoho_ho2005
clavier
komlow
sh19e
ishiduca
sasaplus1
nakajmg
heavenshell
toshi_itoujp
Jxck
rrreeeyyy
```

なかなかそれらしい方々のリストだと思うのですがいかがでしょうか。
とはいえこれらは半年前に算出したものであり、興味の移り変わりもあるので今はJavaScriptについてキュレートしていない方もいるかもしれません。

## 合議制フィルタリング
実際にユーザが閲覧するニュースは、前述したアルゴリズムで得られたキュレーターから収集したニュースから、以下のような形でフィルタリングして通過したものを配信しています。

1. キュレーターが対象記事ブックマークすると一票
2. 対象記事のタイトルと要約にカテゴリ分けで使ったタグが入っていれば二票
3. 合計四票以上のものを通過させる(Topに出ているものは五票以上)

合議制を取っている理由は、キュレーターがブックマークした記事をすべて配信するとキュレーターの専門外のジャンルのニュースが配信されてしまうという結果になったためです。
合議制にすることでその分野に関連するニュースを効率良く配信することが可能になりました。

## 実装
実装については特にこれといって特筆するべきこともないので簡単に構成だけ。プログラミング言語はCoffeeScript,サーバーサイドはNode.jsとMongoDB,Redis,クライアントはReactとFluxxorを使っています。

詳細が気になる方はgithubの方をみてみて下さい。
[https://github.com/ytanaka-/menthas](https://github.com/ytanaka-/menthas)


半年前に作ったときは色々と最先端のものを使ってたつもりだったんですが、時の流れは早いですね。ES6対応やReactのバージョンアップもお正月あたりに出来ればといいなと思っています。

ちなみにニュースソースははてなブックマークのAPIとRSSを使っています。
CrawlerはNode.jsのジョブキューライブラリのKueを使い、できるだけCrawl先のサーバーに負担がかからないような実装を心がけています。


## まとめと今後の課題

今回はプログラマ向けニュースキュレーションサービスMenthasについて紹介を兼ねて解説させて頂きました。

さて、はてなのニュース推薦アプリといえば[伊藤直也](https://twitter.com/naoya_ito)さんのHBFavが有名だと思います。
[HBFavというはてなブックマークiPhoneアプリを作りました](http://d.hatena.ne.jp/naoya/20111111/1320965898)

個人的には僕も伊藤直也さんと同じくニュースはひとが取捨選択することに価値があると思っています。というのも機械学習ではニュースのカテゴリ分けはできても、ニュースそれ自体の面白さや価値はまだ計測できないと思うからです。はてなブックマークやTwitterで情報収集するひとが多いのもニュースの鮮度と質においては機械よりもひとが勝っていることの証左なのではないでしょうか。

しかし、ひとがニュースのフィルタリングをするとなると今度は誰にフィルタを委譲するかという課題が残ります。Menthasではこの「誰がキュレーターとなるか」をアルゴリズムに選択を委譲することで、公平かつ精度の高いニュースキュレーションを目指しています。
まだ選抜のアルゴリズムはナイーブなところも多く、スマートフォン対応などたくさんの改善点はありますが、今後もプログラマにとって使いやすいニュースアプリを開発していけたらと思っています。


ちなみにRSSもあります。
http://menthas.com/javascript/rss
のように各カテゴリ/rssで取得することができますので良かったらご利用ください。