GINK03 / a_book_of_life

人生の一冊

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

最適な読書体験をしたい

アマゾンなどでレコメンドされる本を上から見ていても読書体験がそんなに良くありません。
本の売り上げランキングなどは、大衆に受ける本がほとんどであり、少々独特なセンスを持つ人たちにはそんなに受けが良くないです。
結果として現状の解決策がSNSや人づてに聞き及ぶぐらいしかないのとジャケ買いなどがせいぜいです
どうあるべきかを考えるとき、仮に他人の本棚を知ることができれば、集合知と機械学習を用いて自分に向いているだろう本をレコメンドさせることができます

会社の技術共有会の小話で話した話

<iframe src="https://onedrive.live.com/embed?cid=ECE5548EEB0F5802&resid=ECE5548EEB0F5802%21115549&authkey=ALWlrWJS0n3WgPM&em=2&wdAr=1.7777777777777777" width="100%" height="400px" frameborder="0">これは、Office Online の機能を利用した、Microsoft Office の埋め込み型のプレゼンテーションです。</iframe>

Matrix Factorization

2000年台のNetflix Prizeからある伝統的な手法で、シンプルで動作が早く、ユーザが多くアイテムの数がとても多いときに有効な手法です。

DeepLearningでも実装できるし、sklearnなどでも関数が用意されています。

コード

[https://github.com/GINK03/a_book_of_life:embed]

自分のクエリとなる特徴量

自分のAmazon Fionaという特定のURLにアクセスると自分の今までKindleで買ってきた本がAjaxでレンダリングされます。
Ajaxにより描画されていて、かつ、とても描画が遅いので普通の方法では自動取得できなく、google-chrome-headlessブラウザ等を利用してJSを実行しながら内容を取得できるようにします。

実行コマンド

$ cd DataCollection
$ EMAIL=*****@gmail.com PASSWORD=***** python3 A001_from_kindle.py 
$ python3 B001_scan_local_html.py
fionaのURLをアクセスするとAjaxでこのように描画される

いろいろな人達の本棚の特徴量

レコメンドを行うには大量のデータが必要になります。
他人の本棚が必要になりますが、https://booklog.jp/ が本棚SNSになっているのでこれを利用します。
(すいません、スクレイピングしないと学習できないので、集めます)
実行コマンド

$ cd DataCollection
$ python3 A001_scrape.py

現在120万ユーザが登録しているらしく、全体の一割程度でいいのでユーザの本棚をサンプルして、本棚に登録されている本を1として、登録されていない本を0とすると、巨大な疎行列を作ることができます。scipyのlil_matrixという疎行列ライブラリを利用して構築すると、400Mbyte程度に収めることができます。

実行コマンド

$ cd MakeBookReadMatrix
$ python3 A001.py
$ python3 B001.py
$ python3 C001.py

学習

一応、Matrix Factorizationにも過学習という概念があるので、2%をtestとして切り出して、ホールドアウトで、レコメンドしたときのMatrixとのMean Square Errorを小さくします。
実行コマンド

$ cd MakeBookReadMatrix
$ python3 D001.py --fit
fit non-negative matrix factorization
(1757, 1133108)
test mse = 0.000107 # <- 今回のデータ・セットではこのくらい

推論

Kindle Fionaから得られた本を、1*BOOK_NUMのMatrixに変形して、学習で作ったモデルに入力すると、各アイテム毎のレコメンドを行った際のウェイトを知ることができます。

実行コマンド

$ python3 D001.py

scores_00.csv というファイルができ、その中にタイトルとウェイトが記されている.

自分の結果

過去に漫画を大量に買っていたのでおおよそ納得の結果
別の絵本が多いユーザでもやってみましたが、絵本が多く上位に出るので想定通りできていることが確認できました。

依存(Ubuntuを想定)

  • google-chrome
$ wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
$ sudo apt install ./google-chrome-stable_current_amd64.deb
  • chrome-driver
$ wget https://chromedriver.storage.googleapis.com/75.0.3770.140/chromedriver_linux64.zip # google-chromeのversionに応じたものを使ってください
$ unzip chromedriver_linux64.zip
$ sudo mv chromedriver /usr/local/bin/
  • requirements.txt
$ pip install -r requirements.txt

再現できないときいは

よく指摘されるので、難しい場合は、私のデータで学習したときのデータからモデルまでの動作が確認できたときのスナップショットがあるので、参考にしてみてください。

まとめ

自分の知識や体験の幅を広げるには、レコメンドでウェイトが付いているが、リコールを高めに見たときに低いウェイトの方に来ている本を読むと世界や価値観の広がりを高めることができているように思います。
商業的にはおそらく高いウェイトの作品をレコメンドするとよいのでしょうが、自分に近すぎるコンテンツということもあり食傷気味であり、Amazonででる本などは興味を惹かれなかったのですが、自分でこのレコメンドエンジンを使う分にはこの制約がなくて良さそうです。

About

人生の一冊


Languages

Language:Python 100.0%