2017年に読んだWeb記事たち

先日Pocketからこんなメールが届いた

f:id:fuyumi3:20171223132623p:plain

私の情報収集術 - ふゆみけ〜おかわり〜 で昔書いたようにWebの記事はすべてPocketに集約させて読むようにしているのだが、いつの間にか Top 1% readers のヘビーユーザーになっていたらしい。

せっかくなのでどのくらい読んだのか調べたかったのだが公式で記事数カウントしてくれる機能はない模様(単語数カウントはあるようだがおそらく日本語に対応してない)。

なのでAPI叩いて取得してみた。

Pocket: Developer API

めんどくさいのでコードは貼らない。結果だけ

https://gist.github.com/who-you-me/8c23f9066d3a59f5d16ade457570b931

総数

12/23現在で1712記事。1日換算すると4.8記事。思ったより多かった

サイト別

5以上のやつだけ

ドメイン 記事数 サイト名
portal.nifty.com 303 デイリーポータルZ
trafficnews.jp 277 乗りものニュース
kabumatome.doorblog.jp 196 市況かぶ全力2階建
blog.livedoor.jp/vitaminw 125 スポーツ見るもの語る者~フモフモコラム
honz.jp 77 HONZ - 読みたい本が、きっと見つかる!
mag.japaaan.com 69 Japaaan - 日本文化と”今”をつなぐウェブマガジン
dhanow.ldblog.jp 66 八鬮不動産
reki.hatenablog.com 52 歴ログ -世界史専門ブログ-
delete-all.hatenablog.com 52 Everything you've ever Dreamed
massneko.hatenablog.com 45 墳丘からの眺め
academist-cf.com 42 academist Journal – 未来のノーベル賞はここにある! イチオシ研究発掘メディア
pmazzarino.blog.fc2.com 31 反社会学講座ブログ
next49.hatenadiary.jp 16 発声練習
miurayoshitaka.hatenablog.com 15 弁護士三浦義隆のブログ
toyokeizai.net 14 東洋経済オンライン
shouyutechou.hatenablog.com 13 醤油手帖
headlines.yahoo.co.jp 12 Yahoo!ニュース
vitaminw.seesaa.net 12 フモフモコラムプレミアム
ameblo.jp/redond 11 picture of player
r.gnavi.co.jp 11 ぐるなび みんなのごはん
www.another-tokyo.com 11 東京別視点ガイド
news.yahoo.co.jp 10 Yahoo!ニュース
healthpolicyhealthecon.com 10 医療政策学×医療経済学
japan.zdnet.com 9 ZDNet Japan
magazine-k.jp 9 マガジン航[kɔː]
tamukai.blog.velc.jp 7 ヴェルク - IT起業の記録
www.buzzfeed.com 7 BuzzFeed
postd.cc 7 POSTD
news.denfaminicogamer.jp 6 電ファミニコゲーマー
speakerdeck.com 5 Speaker Deck
srdk.rakuten.jp 5 それどこ
fujinumayasuki.hatenablog.com 5 藤沼康樹事務所(仮)for Health Care Professional Education
nlab.itmedia.co.jp 5 ねとらぼ - ITmedia

2017年上半期に読んだ本たち

上半期と言いながら7月に読んだのも含まれている気はする。

全部で19冊。これに加えて統計検定準1級の勉強もがっつりやってたので読書家とか勉強家とか言う前にこんな時間あるってことはお前真面目に仕事やってたのかと疑うべき。

時系列順じゃなくてカテゴリ別にまとめます。

分析・技術書

ディープラーニング嫌い芸人を続けるのはいいが知らずにケチつけるのはよくないということで読んだ。

そのままPythonで写経しても今更つまらないのでScalaで書いたりもした。

github.com

前半はいいんだが後半は「ロジックだいたいこんな感じだよ! コードはGitHubに書いてあるから読んでみてね!」で全然ゼロから作ってない。看板に偽りあり。

岩波データサイエンス Vol.3

岩波データサイエンス Vol.3

因果推論は楽しい。オーソドックスな回帰手法や確率についてある程度深く知っていないと理解できないことが多く理解できると優越感が得られる(統計の知識をマウンティングの手段にするのはやめましょう)。

統計的因果探索 (機械学習プロフェッショナルシリーズ)

統計的因果探索 (機械学習プロフェッショナルシリーズ)

データだけから因果を明らかにしようという野心的なアプローチ。実データでいろいろ試してみたい。

詳解 Apache Spark

詳解 Apache Spark

大量データを分析するならやっぱSparkだよねという話。実務で使う機会にはまだ恵まれていない。

社会学

社会学 (New Liberal Arts Selection)

社会学 (New Liberal Arts Selection)

社会学修士号を持っているはずだが理論を疎かにしていたせいでほとんど忘れてたので復習。日本の社会学者が書いてるので内容が日本社会に即しててギデンズのやつより読みやすい。

数理社会学入門 (数理社会学シリーズ)

数理社会学入門 (数理社会学シリーズ)

数理社会学の理論と方法 (数理社会学シリーズ)

数理社会学の理論と方法 (数理社会学シリーズ)

社会現象を数理モデルで説明しようとする社会学の(なかでもマイナーな)一分野。合理的選択理論や社会的選択理論やゲーム理論やネットワーク分析を駆使しまくる。

最近数理社会学やりたい欲が高まっているが「やっぱ生活水準落としたくねえなー」と悟ったのでまた大学院に行くことは当分なさそう。

デザイン

ノンデザイナーズ・デザインブック [第4版]

ノンデザイナーズ・デザインブック [第4版]

いい分析にはいい可視化が欠かせないよね。というかむしろ高度な分析しなくてもただデータを可視化するだけで価値が生み出せる余地ってまだたくさんあるよねということでデザイン系の本を読んだりしている。

「デザイン」というとセンスが云々という話になりがちだが実はかなりの部分は再現可能な原則から成り立ってるので理詰めで到達できるところまでは到達したい。

これを読むとプレゼン資料が綺麗になる。実例はこちら

たのしい インフォグラフィック入門

たのしい インフォグラフィック入門

たのしい(コメントが尽きてきた)

ビジネス書

製品開発の知識 (日経文庫)

製品開発の知識 (日経文庫)

最近開発組織のマネジャーを始めたんだが「どんなにいい開発チームを作ったところで組織全体の戦略とマネジメントがちゃんとしてないといいもの作れないよね」という壁に早くもぶつかったのでプロダクトマネジメント系の本を読み始めてる。

戦略とはつまるところ厳しい外部環境と限られたリソースの中でどこにリソースを重点的に注ぐか(逆にどこには注がないか)を決定することで中途半端にあれもやるこれもやるが一番よくない。

人文・社会

コンテナ物語―世界を変えたのは「箱」の発明だった

コンテナ物語―世界を変えたのは「箱」の発明だった

規格化大事という話と、機械化によって人の仕事が奪われるとか昔からよくあってコンテナの場合は労働組合がすっげえ抵抗して経営者と交渉して妥結してコンテナ化による利益を経営者と労働者でそれなりに分け合ったんだけど、昨今のAIブームで仕事が奪われる系の議論には組合とか全く出てこなくて労働者は搾取されるだけなんだろうな感があるのはなんでだろう。グローバリゼーションによって国際的な競争が激化したからでしょうねとかそんなことを(この本には全く書いてなく勝手に)思った。

応仁の乱 - 戦国時代を生んだ大乱 (中公新書)

応仁の乱 - 戦国時代を生んだ大乱 (中公新書)

冷静な語り口で事実をかなり整理して淡々と述べているがそれでもさっぱり分からないので応仁の乱がとにかくカオスだったということがよく分かる。

「その日暮らし」の人類学 もう一つの資本主義経済 (光文社新書)

「その日暮らし」の人類学 もう一つの資本主義経済 (光文社新書)

文明社会の我々からは不合理で不完全で「遅れてる」ように見える「未開」地域の人たちの暮らしぶりは実はすごく体系的で合理的であることを明らかにし、その事実から逆に我々文明社会様を相対化するのが文化人類学の仕事だとしたらこの本はまさにそれ。

でも私はその日暮しはしたくないです。生活水準落としたくないです(本日二度目)。

さっきのが空間の次元ならこっちは時間の次元。昔はひどいし今もひどい。いつだってひどい。

で、まさに空間と時間の結節点に存在するのがこの本。辺境地域と室町時代の日本が似ていてむしろ現代日本社会のほうが異常なんじゃないかと思えてくる。

応仁の乱もそうだが今ひそかに室町時代ブームが来てるのは今の時代がカオスだという認識からか。となるとそろそろ織田信長が出てくるのか。

知っておきたい「酒」の世界史 (角川ソフィア文庫)

知っておきたい「酒」の世界史 (角川ソフィア文庫)

お酒が好きなんです。

小説

泣き虫弱虫諸葛孔明〈第1部〉 (文春文庫)

泣き虫弱虫諸葛孔明〈第1部〉 (文春文庫)

泣き虫弱虫諸葛孔明〈第2部〉 (文春文庫)

泣き虫弱虫諸葛孔明〈第2部〉 (文春文庫)

天才・酒見賢一がその才能を遺憾なく発揮して好き放題やってると評判の『泣き虫弱虫諸葛孔明』がついに完結した&第四部が文庫化されたとの報を受け、三部まで読んだの結構前なので四部買う前に読み返してる。

てか今年ぜんぜん小説読んでないな俺。

Pythonでの可視化をおさらいするために読んだもの

matplotlibの使い方とかちょっと時間が経つとすぐ忘れるので復習しました。あとデータ可視化ならSeabornが便利らしいのでそっちも入門しました。

Pythonによるデータ分析入門』の8章を読んで写経

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

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

matplotlib単体の使い方+Pandasとの連携についてざっくり知ることができます。

matplotlib公式チュートリアルを読んで写経&galleryからいくつかピックアップして写経

↑を読んだ後だからまあいいかもと思いつつ一応公式のチュートリアルをおさらい。

http://matplotlib.org/2.0.0/users/pyplot_tutorial.html

でもって、galleryの「Statistical plots」のなかからピックアップして(明らかにほぼ被ってるやつが複数あったりするので)写経

http://matplotlib.org/2.0.0/gallery.html#statistics

Seabornのチュートリアルを読んで写経

matplotlibは便利だけどちょっと低レイヤーすぎてデータ分析の過程でやるboilerplateな可視化を繰り返しやるのにはまどろっこしいところがある。

のでデータ分析の可視化に特化したラッパーであるところのSeabornをやってみましょう。

http://seaborn.pydata.org/tutorial.html

チュートリアルがすごい充実していて、単なるAPIの解説じゃなくて可視化の勉強になる内容なのでみんな読んでみたらいいと思います。

とりあえずここまでやった。bokehってどうなのとかmpld3使ったらカッコよさそうとかあるけどひとまずこのくらいで十分かな。

『ゼロから作るDeep Learning』を読み終わった

読み終わりました。「Scalaで実装する」を目標として掲げていましたが結論から言うと5章までしか実装していません。理由は以下の通り。

途中まで実装したコードはこちら

github.com

上のツイートにもある通り、5章までは丹念に解説しながらニューラルネットが実装されていきますが、6章からはほぼ読み物と化します。

とはいえ5章までちゃんと手動かして基礎をつかめばそれ以降の内容は特に自分で実装する必要はないかなと思うので(そもそも大多数の人は実際にDeepLearningやるなら自前で実装せずにライブラリ使うので十分)この構成はバランス取れているのかなと思います。

「DeepLearningちゃんと知っておきたいけど端から見ると不毛なライブラリ覇権争いみたいなのには巻き込まれたくない。勝ち組決まってから乗り出したいけどその前に基礎は知っておきたい」みたいな人には向いてる本なんじゃないでしょうか(適当)。

現状DeepLearningをこれ以上掘り下げる気はあまりないので次は可視化強化月間です。matplotlibとseabornをちゃんとやります。

『ゼロから作るDeep Learning』をScalaで実装する(その3) - ニューラルネットワークとその学習

前回から2週間以上経ちました(そして年をまたいだ)がサボっていたわけではありません。

4章まで終わりました。規模大きくなってきたのでここにコード貼ることはしません。以下をご覧ください。

github.com

以下雑感

  • MNISTデータセットのロードでハマる
  • numpyでは「n次元ベクトル」と「nx1行列」の違いを意識することはほとんどないが、Scala(というかBreeze)では当然異なる型になるのでいろいろ厄介
    • とはいえ静的型付け言語なんだから当然
    • 暗黙の型変換とかを使えばうまくできそうだが、難しいので断念
    • 一貫してDenseMatrixを使う方針で
  • 4章では愚直に勾配降下法で学習しているが、numpyより実装速度が遅い
    • たぶん非効率な実装になってるんだろう。が、チューニングする気は特にない

今後は特にここに書くこともなさそうなので、全部読み終わって総括するまではたぶんこのシリーズは更新しないです。

『ゼロから作るDeep Learning』をScalaで実装する(その2) - パーセプトロン

前回の続き

who-you-me.hatenablog.com

ANDゲート、NANDゲート、ORゲート、XORゲートをパーセプトロンで実装します。

// Perceptron.scala
import breeze.linalg._

object Perceptron {
  private def gate(w: DenseVector[Double], b: Double)
                  (x1: Double, x2: Double): Double = {
    assert(w.size == 2)
    val x = DenseVector(x1, x2)
    if ((w dot x) + b <= 0) 0.0
    else 1.0
  }

  val AND = gate(DenseVector(0.5, 0.5), -0.7)_
  val NAND = gate(DenseVector(-0.5, -0.5), 0.7)_
  val OR = gate(DenseVector(0.5, 0.5), -0.2)_

  def XOR(x1: Double, x2: Double): Double = {
    val s1 = NAND(x1, x2)
    val s2 = OR(x1, x2)
    AND(s1, s2)
  }
}

コードの重複を避けたかったので、ANDNANDORについては共通のカリー化された関数gateを用意し、それに部分適用する形で実装してみました。

GitHubにも上げた。

github.com

ここまでは簡単。次はニューラルネットでたぶんここからが本番。

『ゼロから作るDeep Learning』をScalaで実装する(その1) - Breezeで行列演算

Deep Learningを業務でがっつり使うことは(少なくとも当分は)ないんだけど、さすがに知らないでいろいろ語るのはマズいので、巷で良書と評判の『ゼロから作るDeep Learning』をやろうと思います。

とはいえ今更Pythonでやるのもつまらないので、せっかくだから新しく覚える言語でやろう、ということでScalaで書くことに。

本書の目標とするところは、ゼロからディープラーニングを実装することでした。そのため、外部のライブラリは極力使用しないというのが方針ですが、次の2つのライブラリは例外として用いることにします。ひとつはNumpy、もうひとつはMatplotlibというライブラリです。 (p.2-3)

Scalaで可視化やるつもりはないのでmatplotlibのところは飛ばせばいいんですが、numpy相当の行列演算をスクラッチで書くのはつらいのでScalaの行列演算(以外もあるけど)ライブラリであるところのBreezeを使うことにします。

以下、1章のnumpyの部分をBreezeで書き直します。

1.5.0 インストール

とりあえずREPLを使います。REPLで外部ライブラリ使うにはこうすればいいらしい。

$ sbt
set libraryDependencies += "org.scalanlp" % "breeze_2.11" % "0.12"
set resolvers += "Sonatype Releases" at "https://oss.sonatype.org/content/repositories/releases/"
set scalaVersion := "2.11.6"
console

https://github.com/scalanlp/breeze/wiki#fast-installation

1.5.1 インポート

scala> import breeze.linalg._

1.5.2 配列(ベクトル)の生成

scala> val x = DenseVector(1.0, 2.0, 3.0)
scala> println(x)
DenseVector(1.0, 2.0, 3.0)

わざわざDenseと明示してるってことはSparseもあるに違いない。

1.5.3 算術演算

scala> val x = DenseVector(1.0, 2.0, 3.0)
scala> val y = DenseVector(2.0, 4.0, 6.0)
scala> x + y
res30: breeze.linalg.DenseVector[Double] = DenseVector(3.0, 6.0, 9.0)
scala> x - y
res31: breeze.linalg.DenseVector[Double] = DenseVector(-1.0, -2.0, -3.0)
scala> x :* y
res32: breeze.linalg.DenseVector[Double] = DenseVector(2.0, 8.0, 18.0)
scala> x :/ y
res33: breeze.linalg.DenseVector[Double] = DenseVector(0.5, 0.5, 0.5)
scala> x / 2.0
res34: breeze.linalg.DenseVector[Double] = DenseVector(0.5, 1.0, 1.5)

要素ごとの操作については演算子を変えてますね(:*:/)。そもそもベクトル同士の(内積ではない)積とか商とかってなんやねんって話なのでこういう方針は好き。

1.5.4 N次元配列

scala> val A = DenseMatrix((1, 2), (3, 4))
scala> println(A)
1  2  
3  4  
scala> (A.rows, A.cols)  // A.shapeがやりたい
res40: (Int, Int) = (2,2)
scala> A.getClass  // A.dtypeがやりたい
res41: Class[_ <: breeze.linalg.DenseMatrix[Int]] = class breeze.linalg.DenseMatrix$mcI$sp

numpyのA.shapeA.dtypeに直接相当するメソッドはない模様。

scala> val B = DenseMatrix((3, 0), (0, 6))
scala> A + B
res42: breeze.linalg.DenseMatrix[Int] =
4  2
3  10
scala> A :* B
res44: breeze.linalg.DenseMatrix[Int] =
3  0
0  24

numpyのA * B(要素ごとの積)に相当するのはA :* Bということに注意。

A * Bすると普通に行列同士の積(numpyでいうところのA.dot(B))になりnumpyよりこっちの方が明らかに正しいだろ感。

scala> println(A)
1  2  
3  4  
scala> A * 10
res46: breeze.linalg.DenseMatrix[Int] =
10  20
30  40

1.5.5 ブロードキャスト

scala> val A = DenseMatrix((1, 2), (3, 4))
scala> val B = DenseVector(10, 20)
scala> A(*, ::) :* B
res49: breeze.linalg.DenseMatrix[Int] =
10  40
30  80

Breezeではブロードキャストは暗黙には行われません。「行方向のブロードキャストである」ことを明示するためにA(*, ::)とします。

他にも、BはMatrixじゃなくてVectorとして定義する必要があったり、最終的にはベクトルとベクトルの要素ごとの積になるので:*にする必要があったりといろいろ注意が必要。

1.5.6 要素へのアクセス

scala> val X = DenseMatrix((51, 55), (14, 19), (0, 4))
scala> println(X)
51  55  
14  19  
0   4   
scala> X(0)
<console>:12: error: could not find implicit value for parameter canSlice: breeze.linalg.support.CanSlice[breeze.linalg.DenseMatrix[Int],Int,Result]
              X(0)
               ^
scala> X(0, ::)
res58: breeze.linalg.Transpose[breeze.linalg.DenseVector[Int]] = Transpose(DenseVector(51, 55))
scala> X(0, 1)
res59: Int = 55

X(0)はできない模様。

scala> for (row <- X) println(row)
<console>:12: error: value foreach is not a member of breeze.linalg.DenseMatrix[Int]
              for (row <- X) println(row)
                          ^
scala> for (i <- 0 until X.rows) println(X(i, ::))
Transpose(DenseVector(51, 55))
Transpose(DenseVector(14, 19))
Transpose(DenseVector(0, 4))

Breezeではベクトルはすべて縦ベクトルなので横ベクトルはTranspose(DenseVector(51, 55))のように表現される。

scala> val X1 = X.toDenseVector
scala> println(X1)
DenseVector(51, 14, 0, 55, 19, 4)
scala> val X1 = X.t.toDenseVector
scala> println(X1)
DenseVector(51, 55, 14, 19, 0, 4)
scala> X1(0, 2, 4).toDenseVector  // X1(0, 2, 4)の返り値はbreeze.linalg.SliceVector型
res11: breeze.linalg.DenseVector[Int] = DenseVector(51, 14, 0)

toDenseVectorでは列方向にベクトル化される。なのでnumpyと同じように行方向でやりたかったらX.tで転置しておけばよい。

scala> DenseVector(X1.toArray.filter(_ > 15))
res23: breeze.linalg.DenseVector[Int] = DenseVector(51, 55, 19)

Booleanを使った要素の抜き出しはできなそう。なので一回Arrayにしてfilterして(何故かDenseVectorにはfilterメソッドがない)またDenseVectorに戻せばよい(これが効率のいいやり方かどうかは知らない)。

以上。次はこれを使ってパーセプトロンを実装する。