Pythonではじめる機械学習 ―scikit-learnで学ぶ特徴量エンジニアリングと機械学習の基礎

Andreas C. Muller, Sarah Guido

Python機械学習ライブラリ scikit-learn を使って、さまざまな機械学習アルゴリズムの使い方を学ぶ。特徴的なのは、アルゴリズムの詳細には立ち入らず、使い方に重点を置いていること。とはいっても、ライブラリの使い方だけ説明しているということではなく、どういうケースにどのアルゴリズムが適しているかを、実例を交えて詳細に論じている。

モデルの複雑さと過剰適合の関係など、機械学習において基本的な概念もわかりやすく説明している。特徴量の作り方や、パラメータ調整の実際に関しても詳しく述べられている。特に、特殊な扱いが必要なテキスト処理の基礎も示されている。日本語に適用するには、形態素解析など一手間かかるが、これ一冊でゆるい卒論ぐらいまではカバーできそう。scikit-learnも国内ではまだあまり流行っている感じではないが、すごく良くできているので、今後普及するのではないだろうか。

縁あって、翻訳させていただいた。Python機械学習という本はたくさんあるけど、その中でもなかなかの良書かと。よろしければぜひ。

Google Cloud Platformの機械学習系サービス

このページによると、GCP機械学習系サービスは7つ。というか、大物のEngineが1つとAPIが6つ。APIにはAlpha状態のものもある。

Cloud Machine Learning Engine

TensorFlowのマネージド・サービスらしい。つまり、TFで書いたコードを用意すると、学習から運用まで、Google Cloudのなかでできてしまう、ということらしい。ワークフローエンジンとも連動するらしいので、前処理とかもできるのかな?具体的にはどうやって使うのか、というと、CUIとDatalabというのがあるらしい。

Cloud Datalab というのは、いわゆるnotebook。不思議なことにローカルに何かをインストールするようだ。ローカルサーバがノートブックをハンドルし、実際のリクエストはローカルサーバからクラウド側に転送される、という構造なのかな。

API

Cloud Jobs API - private alpha

Google for Jobs の一部。ジョブ検索APIらしい。ちょっと他のものと違っていて汎用のツールではないようだ。

Cloud Natural Language API

自然言語解析。センチメントアナリシス、文中のエンティティの切り出し、タグ付けまでやってくれる。

Cloud Speech API

言語認識サービス。80言語をサポート。テキストが返される。

Cloud Translation API

翻訳サービス。ブラウザベースでも公開されているものと多分同じ。100あまりの言語をサポートしている。そのうち30あまりと英語の間はNeuralネットワークを使っている。その他のペアは既存手法らしい。

Cloud Vision API

画像を認識するAPI。例えば人の顔の写真を入れると、顔の向き、目の位置、鼻の位置などを認識するだけでなく、感情の認識まで行う。 さらに、画像中にテキストがあればその識別も自動的に行う。適当なタグの付与もおこなう。年齢制限に関連するかどうかの判断も行う。 ランボルギーニラカンを見せたらアヴェンタドールの方が上に来た。が、フェラーリとは間違えなかった。

Cloud Video Intelligence API

ビデオに対するタグ付け。カットを自動認識、各カットに対して、画像API同様のタグをつける。

golang のyaml library の使い方

Go 言語にはyaml を入出力するためのライブラリhttp://godoc.org/gopkg.in/yaml.v2:package yaml があり、これを使うとGoの構造体とyamlとの変換が、わりに簡単にできる。

ところが、構造を持たないようなデータを読もうと思うとなんだかうまくいかない。例えばディレクトリ構造を表現した次のYAMLを読むにはどうしたらいいのかわからない。

- index.html
- index2.html
- ja:
  - test1.html
  - test2.html

なんか色々調べていると、yaml.v1の時にはかなりプリミティブなコールバックがあって、それで手間はかかるけど色々出来たっぽい。v2 でライブラリが直接構造体に書き込むようになったので話が面倒になっている印象

Unmarshaler

v2 にも手動でunmarshal する機構があり、type Unmarshaler で表現されている。これは UnmarshalYAMLという関数を定義してあるタイプで、読み込みたい構造体にこの関数を定義しておくと、読み込み時にコールバックしてくれるらしい。

まず、NamedSubTree という型を定義する。これがディレクトリのファイル、もしくはディレクトリを表現する。ディレクトリの時にはSubがnilになる。

type NamedSubtree struct {
	Str string
	Sub [] NamedSubtree
}

でこの型に対してUnmarshalYAMLを定義する。

func (this * NamedSubtree) 
                 UnmarshalYAML(unmarshal func(interface{}) error) error {
	var s string
	e := unmarshal(&s)    // ファイルを仮定して読み出してみる。
	if e == nil {
		this.Str = s
		return nil          // 成功したら終了
	} 
                                  // 失敗したらディレクリだと思ってMapで読む。
	var m map[string]([] NamedSubtree)
	e2 := unmarshal(&m)
	if e2 == nil {
		for k := range m {
			this.Str = k
			this.Sub = m[k]
		}
	} else {
		pp.Print(e2)
                return e2
	}
	return nil
}

すると、こんな感じにして読みだすことができる。

	dat, _ := ioutil.ReadFile("tree.yaml")
	var t [] NamedSubtree
	e := yaml.Unmarshal(dat, &t)

Marshaler

同様にMarshal側もいじることができる。同じようにMarshalYAMLという関数を定義する。

func (this NamedSubtree)	MarshalYAML() (interface{},  error) {
	if this.Sub == nil {   // Subが空ならファイルなので文字列として出力
		return this.Str, nil
	} else {                   // Subが空でないならmapとして出力
		m := make(map[string]([] NamedSubtree))
		m[this.Str] = this.Sub
		return m, nil
	}
}

呼び出し側はこんな感じ。

	out, _ := yaml.Marshal(t)
	fmt.Println(string(out))

所感

本当はLeafとNodeを別の型にしたかったのだけど、どうにもうまくできなかった。古いAPIならできそうなのになあ。。

Cython ―Cとの融合によるPythonの高速化

  • Kurt W. Smith 著

PythonRubyって、一時はキャラがかぶって競合関係にあったような気がするのだけど、今ではWebならRuby、科学技術計算ならPython と別れてしまったような気がする。numpyやscipyなどの数値演算ライブラリを使うと、Pythonで科学技術計算が簡単に書ける。BigData解析やら機械学習なんかも Pythonでやるのが流行っているようだ。

なんでスクリプト言語で科学技術計算ができるのか、かなり不思議だったのだけど、その秘密は Python/C API にある。numpyにしろscipyにしろ数値演算のコア部分は実はC言語で書かれているし、データもC言語の管理する空間に置かれいている。Pythonはライブラリ呼び出しを制御するだけ、という立ち位置なのだ。

Cythonは、このPython-Cエコシステムの一翼を担うシステムである。C言語で書かれたライブラリをラップするコードを半自動で生成してくれる。Pythonコードに変数の型を指定すると効率のよい拡張モジュールにコンパイルしてくれる。実際、numpy やscipyでもCython は使われている。

Cythonでは、Pythonに型を導入した怪しい言語で、C言語とほぼ同じことが記述できる。構造体どころか関数へのポインタを返す関数、みたいなものまで定義できる。Cythonを使うと、C言語Pythonの世界を簡単に行ったり来たりすることができる。C言語レベルのコールバック関数をPythonで書くなんてことまでできるのだ。C言語レベルでmallocしたメモリを特定のPythonオブジェクトに紐づけて、オブジェクトが死んだら開放するようにすることもできる。

さらに驚くべきなのはprangeというコンストラクト。なんと、バックエンドのopenmpを用いて自動並列化するという。。

言語としてのCythonはPython をベースにした独自言語という位置づけになっている。この種の言語でよくあるのは、中途半端な設計と実装のために、動くには動くけど、コーナーケースがありすぎて実際に使ってみるとすごく大変、というものが多いように思うが、Cythonは違う。

アイディアだけで言えば、気の利いた卒論とかにもありそうなネタなのにもかかわらず、凄みさえ感じさせる完成度。おそるべし。

この本はCythonのさまざまな側面を細大漏らさず書いている。著者はCythonのヘビーユーザーで、開発者コミュニティの一員でもある。

C言語のライブラリを多用しているが、C言語ではもうプログラムが書きたくない、なんて人にはCythonがぴったり。一度Cythonでライブラリをラップしてしまえば、Pythonからインタラクティブにライブラリを使うことができる。

実はこの本、縁あって監訳させていただいた。ご興味があればどうかひとつ。

ZooKeeperによる分散システム管理

  • Flavio Junqueira, Benjamin Reed

ApacheHadoopプロジェクトから派生したZooKeeperを紹介した本。頑健な分散協調を容易にしてくれるZooKeeperだが、実際にはかなり落とし穴がボコボコある。落とし穴の避け方を教えてくれるのがこの本。

Zab プロトコルも詳述されていて、とても参考になる。HadoopのYARNやHiveなど、ZooKeeperを利用したシステムは今後増加すると思われる。適切にZooKeeperを設定するには、それなりの理解が必要なのでこの本を読みましょう。

開発者が書いている本なので内容は信頼できる。でも(世間的にはZooKeeperの元ネタになっていると言われる)GoogleのChubbyに全く言及が無いっていうのはどうなんだろう。。あとPaxosとZabの違いについても明記して欲しかったかな。

この本、翻訳をさせていただいた。原書の間違いもいくつか見つけたし、原著者からの修正も入れてあるので、原書よりもちょっといい、はず。こちらで別の間違いを入れ込んでいなければ。というわけでどうかひとつ。

ZooKeeperによる分散システム管理
Flavio Junqueira Benjamin Reed
オライリージャパン
売り上げランキング: 16,251

json-simpleを使いやすく

ちょっとCassandraをいじっている。内部でJSONを使いたくなったので、Cassandraがもともと使っているjson-simpleを使ってみた。

Object o = (new JSONParser()).parse(jsonString);

のように使う。jsonのMapはJSONObjectに、Listは JSONArrayにマップされる。しかしこれでは使うときにいちいちcastしなければならないし、Parseされた構造が期待通りの構造になっているのかをいちいちチェックしなければならない。できればオブジェクトにマップしたい、ということで関数を書いてみた。

関数

第二引数にクラスを渡すと、そのクラスのインスタンスをつくって、そこにJSONをパースした結果を入れる。やっていることは、クラスのフィールド名をリフレクションで取得して、JSONから取り出して突っ込もうとするだけ。型が違ったりすると例外を投げる。

static Object unmarshal(Object obj, Class clazz) 
throws InstantiationException, IllegalAccessException, 
NoSuchFieldException, SecurityException {
  if (clazz == String.class)
    return (String)obj;
  if (clazz == Integer.class)
    return (Integer)obj;
  if (clazz == Long.class)
    return (Long)obj;
  if (clazz == List.class) 
    return (JSONArray)obj;
		
  JSONObject jObj = (JSONObject)obj;
  Object o = clazz.newInstance();
		
  for (Object s: jObj.keySet()) {
    Field f =  clazz.getField((String)s);
    Object inner = unmarshal(jObj.get(s), f.getType());
    f.set(o, inner);
  }
  return o;
}

使い方

こんなJSONをパースすることを考える。

{
  "name": "ExternalProcessUDF", 
  "command" : ["a", "b"], 
  "args" : {
      "saru" : 1 
   }  
}

これを下のようなネスト構造を持つオブジェクトにマップする。

class Inner {
  public Long saru;
}
	
class External {
  public String name;
  public List<String> command;
  public Inner args; 
}

これにはこのようにすればいい。

Object o = (new JSONParser()).parser.parse(json);
External e = (External) unmarshal(o, External.class); 

取り出す手間が省ける、というよりは構造がチェックできるということのほうが大きいかも。

Head First C ―頭とからだで覚えるCの基本

「チャート式技術書」とでもいうべき、半分おちゃらけた感じの技術書シリーズの一冊。 「Head First」は「頭から飛びけむ」ぐらいの意味で、「あまリ考えずにとにかく手を動かせ」というような ニュアンスなのかと思われる。 アメリカには「XXX for Dummies」というシリーズがあって、およそ考えつく すべてのジャンルをカバーしてたりするのだけど、日本にはあんまりこの種の 本はない。なんでだろう。よく考えるとちょっと不思議だ。

このシリーズ随分前からある(2003年にJavaがでている)のにいまごろになって C言語の本が出る(原著も2012年)というのは、 やっぱりおちゃらけたこのシリーズと、どこまで行っても ストイックなC言語の相性が悪いからなんだろうなあ。

はじめてちゃんとまえがきを読んでみたところ、脳の機能的に言って 無味乾燥な書き方だと絶対に覚えられないので、わざとおちゃらけて書いているのであると のこと。なるほど。 実際、技術的にはまったく無駄な内容を考えて書くのはほんとうに大変だろうと思う。 普通の本の3倍ぐらいの手間暇がかかってるんじゃないだろうか。 書ける人もそんなに多くないだろう。実際、原著者はCやUnixプログラミングの専門家 ではなくて、Head Firstシリーズばかり書いている人。

内容的にも結構すごくて、まったくの0から始まって、ポインタ、構造体、共用体などの 言語機能だけでなく、ヘッダファイルを使ったライブラリの分離、 Makefileを使ったビルド、 fork/execを使ったマルチプロセス、dup2を使ったプロセス間通信、 ソケットによるネットワーク通信、pthreadを使ったマルチスレッドまでたどり着いている。 C言語の本と言うよりは、Unix環境でのプログラミング入門みたいになっている。 実際、C言語だけを独立して勉強してもなんの役にも立たないので、 妥当な構成だと思う。 さらに、AudinoでのプログラミングやOpenCVを使っての画像処理、Allegroを用いてのアステロイド ベルトもどき作成までカバーしている。

実は、この本も縁あって監訳させていただいた。 Windows上でのCygwinやMinWGをサポートした関係で、システムコール周りの説明の 歯切れが悪いのが心残りだったりするのだけど、原著からの逸脱を最小限にしつつ 技術的に間違ってはいない内容にした、つもり。 正直、いまどきC言語の本にどのくらいの 需要があるのかわからない気もする。 でも、これまで全然C言語なんか触ったこと無いのに、新年度から 何かの間違いでC言語で開発しなければならなくなってしまった、なんて場合に C言語界隈のパースペクティブ全体を短時間で把握するには、 結構いい本なのではないだろうかと思う。 というわけで、どうかひとつ。

Head First C ―頭とからだで覚えるCの基本
David Griffiths Dawn Griffiths
オライリージャパン
売り上げランキング: 36,770