giantneco’s blog

技術メモ

Go の名前付き返り値

Go の名前付き返り値の扱いでちょっと迷ったのでメモ。

名前付き返り値を使うとローカル変数扱いにされるとはわかっていた。 return文で新しいインスタンスを作って返した場合もちゃんとケアされるか不安だった。 仕様見ても明記されている箇所が見つけられずよくわからんかったし。

で下のようなコードで確認してみると杞憂だったのがわかった。よかったね。 どうもreturn文の時点で名前付き返り値に代入されるようなイメージで良いらしい。

package main

import (
    "errors"
    "fmt"
)

func f1() (err error) {
    return errors.New("hoge")   
}

func f2() (err error) {
    defer func(){
        err = errors.New("huga")
    }()
    return errors.New("hoge")   
}

func f3() (err error) {
    defer func(){
        err = errors.New("huga")
    }()
    err = errors.New("hoge")
    return err
}

func main() {
    fmt.Println("Hello, playground")
    fmt.Printf("f1: %v\n", f1()) // hoge
    fmt.Printf("f2: %v\n", f2()) // huga
    fmt.Printf("f3: %v\n", f3()) // huga
}

Go で後処理が必須になる場合の API

datastore/sql の Rows は Query で取ってきた後に Close() を呼び出さないといけない。これはまあ常識。

で、恥ずかしい話だが、最近自分が書いたコードでこのCloseし忘れをやってしまっていた。

おそらく原因としては Exec から Query に機械的に変換したときにCloseを付けるのを忘れてたのだと思う。自分はこのパターンで何かしらの処理を付け忘れてしまうことが多い。

しかし人が頑張って Close を書くようにするのではヒューマンエラーがいつか出るのは確実だ。 なので、できれば Go でこういう Close し忘れは検知してもらいたい。

残念ながらそういうことをしてくれるツールを見つけられなかったので、問題を解決するのに次のようなAPIを考えてみた。

resource, close, err := something.Open()
defer close()

後処理が必要なリソースを確保する場合には、確保時に終了処理となる関数を返すのがいいのでは?というアイディアだ。 終了処理となる関数をローカル変数に束縛しておけば、これを呼び出さない場合に Go 側で「未使用の変数がある」と検知してくれるはず。 握り潰しそうとした場合もコード上でわかりやすくなるはず。

という感じのことを自作 API ではやろうと思うのだがどうなんだろうか?

こういうことをしているベストプラクティス見つからないので、それほど良さげな解決策ではないのかも。

AtCoder Beginner Contest 151

Contest Result - AtCoder

今回は A から C まで。ランクも下がった。

どちらかというと今回は解けたという話でなく、どうして解けなかったか?という話になる。 普段は競技プログラミングで点が取れなかった話は振り返ってみても役に立たないので書かないが、 今回は教訓を見出したので自戒を込めてブログ記事にしている。

で、

その解けなかったのは D で、与えられた迷路に対して適当な始点と終点を与えて最短パスを最長にする、というような問題だった。

問題サイズは割と小さかったので、総当りで始点を設定して BFS で最も遠い点を出せばいいかと考えた。 ただ実行時間はなるべく短くしたかったので、始点からは次の条件を満たすものを除外することにした。

  • 上下の点が通行可能
  • 左右の点が通行可能

要するに通路のあたるような点は始点終点から外そうとした。 これは割ともっともらしい。最短パスが最長になる始点終点はなにかしら端のほうになりそうだ。

ということで実装をして提出してみたのだが、最後の1ケースだけ WA になるという残念な結果になってしまった。 コンテスト時間中はなにかしら問題文で見落とした箇所があったのかとか、特殊なケースがあったりするのか、など考えていたが、 なんのことはない、上に述べた除外している箇所を外すだけでうまく動いたのだった。

これに気付いた後で、そのケースを考えてみると次のようなものがあった。

 ■■■■■
 ■□□□■
 ■□■□■
 ■□□□■
 ■■□■■
 ■□□□■
 ■□■□■
 ■□□□■
 ■■■■■

このような8の字型の迷路だと、8の上側の通路と下側の通路を指定すると最短経路が最長になる。

なにが悪かったか?

明らかに余計な条件を加えたのがよろしくなかった。

高速化の鉄則として、

まず正しく動くものをつくり、それから最適化する

というのがある。これこそなにより自分が気を付けなければいけなかったことで、競技プログラミングであってもこの鉄則に従わなかったのは申し訳がたたない。

「高速化する」というのは競技プログラミングの上でももっともらしく聞こえるが、まず正解を出すのが最優先だ。 そもそも速くなるケースは限られるという時点で、最も時間がかかるテストケースが投げられてくる競技プログラミングへの解答としては不適切であったし、今回のようにパッと思いつかないようなレアケースに足を引っ張られることもある。

教訓としては、総当りでいくと決めたら変に高速化を目指さない、ということになるか。TLE になってから考えればよいし、焼け石に水的な高速化はおそらく間違いの場合が多い。

PyTorch と自然言語処理

slides.com

2020/01/08 にあった社内の機械学習勉強会での発表資料。 年末から正月中調べていたのであまり休めた気がしない。

画像処理だといまいち乗れなかったので、自然言語処理の方が好きかも。

AtCoder Beginner Contest 145

Contest Result - AtCoder

今回も A から D まで解いた。

ようやく上の方に青が見えてきたがまだまだ遠い。

良かった点

A-D までは継続して解けている。

C は全経路のコストに何かしらの値をかければ良さそうだとわかった(すべての組み合わせなので、どの枝も同じ回数だけ出現するはずである)。

全ての枝のコストが 1 だった場合は、明らかに n! が全経路のコストの和になる。

なのでここから計算すると、全枝のコストの和 x (n-2)!/2 が解答になる。

反省点:

C のケアレスミス

解答に精度の設定がある問題だったが、その設定を忘れていたので、 WA をもらってしまった。

すぐに終わるはずの問題だったが、終了間際になるまで気づかなかった。

入力例 1 で気づいていてもおかしくなかったのだが、急ぐあまり見落としていたようである。

D の組み合わせ数

D は本質的に組み合わせの数 = nCr を計算する問題。

頻出の問題なので、こういうのこそ前もって準備しておくべきなんだろうが、それができていなかった。

ただやり方自体は Qiita の次の記事を見た覚えがあったので、時間内に調べてなんとか間に合わせた。

https://qiita.com/ofutonfuton/items/92b1a6f4a7775f00b6ae

結局時間内に AC は出せたがぎりぎりになってしまい E には進めなかった。

知っていれば簡単に回答できる問題なので、こういうのはしっかり抑えておきたい。

退職記事を書きたかったが書けなかった話

ここ最近 Google の採用プロセスを受けていたのだが、結局パスすることが出来なかった。

退職記事で書けばいいかと思っていたが、会社の現時点での作業からの現実逃避がしたかったのでさっさとまとめる事にした。 会社の人が誰か見ているかもしれないが、ちょっと自暴自棄になっているのでそうなってもまあいいや。

そもそものきっかけとしては LinkedIn 経由で Google のリクルータの人から接触があった。最初はスパムかな?と思っていたのだが、メールアドレスが @google.com になっていたのを確認して本物なの?という事で返信。 もちろんスカウトではなく、こういう風に採用をやっているので受けてみないか?というぐらいの話をこの時はした。

実はこれが 2 月ごろで、その後自分の方でも色々準備したり Google I/O に参加したり英語メール書くのに躊躇したりがあってしばらくコンタクトを取っていなかった。 この期間中にも他の会社の採用面接を受けてみたりもしたのだが、やっぱり Google のが保留になっている状態だとよくないなという事で、失敗するにしてもちゃんと採用プロセスを進めておこうという気になった。 で結局は次のステップに進むのは 8 月ごろになってしまった。

再度リクルータの人に連絡を取って簡単なインタビューを英語でやらしてもらった。この時は内容的にはいい部分はあったが英語頑張ってね、という事で数週間ぐらい英語を見直してから実際の採用プロセスに進んだ。

採用プロセスは次のような感じ:

  1. リモートでのインタビュー
  2. オンサイトインタビュー 1 回目
  3. オンサイトインタビュー 2 回目
  4. 以下進めなかったプロセス

オンサイトインタビューでは必ず 1 回は英語での物を含むらしい。

まずリモートでのインタビューはうまくいった。難易度でいうと、多分 AtCoder でいう C くらい?

で、次のオンサイトインタビューには進めたのだが、そこでコケた。

フィードバックによると、アルゴリズムやデータ構造については問題なさそうだったが、コーディングやコーディング速度があまりよろしくなかったとのこと。

この点で反省点としては、多分実施日を金曜にして、かつ前日まで仕事で使っていた言語でインタビューに臨まなかったのはよくなかったと思う。インタビューの際に Go だか C++ だか Python だかが混じったような物を書いてしまって結構まごついてしまったのがみられたんだとは思う。

本来自分が得意だと思っていた部分でしくじっていたのはかなり残念。 なのだが、振り返ると思い当たる節は結構ある(会社への愚痴になりそうなので具体的な例は避けておく)ので、その点に気づけただけでも儲けものだったと思いたい。

足りてない部分としてやっぱりコーディング量が足りてないというのはあるので、なんとか増やすようにしたいところではある。

またせっかく Google の新社屋でランチをいただく機会だったのに出来なかったのが残念。 オンサイトインタビューの時にインタビュアーの人に聞いたら伝えておけばランチ食べさせてもらえそうだったので、次のオンサイトインタビューに進めるんだったらその時に行っておきたかった。 これから受ける人はオンサイトインタビュー受ける際にランチも食べたい旨を伝えておくといいかと思う。

他の Google の採用プロセスを受けた人も書いていたが、リクルータの人はかなり親切に採用プロセスの説明とか、不足している部分とかを指摘してくれるので非常にありがたかった。

他のよくなかった点としてはかなり時間がかかってしまった事。最初にコンタクトを受けた時に急がなくてもいいと言われたのに甘えたのもあるが、Google の引っ越し時期と重なったのと、インタビューのために午前休とか1日休みとか設定しないといけなかったので、なかなか進まなかった。年度末が近づいてきてしまってキリのいいところでの転職を狙うのが難しくなったのはよろしくない。次があるとしたら早めに終わらせるようにしたい。

次チャレンジする機会があるとしたら1年後か。その時の状況にもよると思うが、またチャレンジするかも。

PyConJP 2019 に参加してきたメモ

pycon.jp

今年も PyConJP に参加してきた。

今年のテーマは「Python New Era」で Python の新時代の話をしようということだったが、 内容的にはやはり機械学習関連の話が多い。

1 日目は機械学習中心。 2 日目はそれ以外のテーマを中心に見ていくことにした。

Why Python is Eating the World

www.youtube.com

1 日目オープニングは最近和訳された「独立プログラマの作者」Cory Althoff さんによる Python がどうして流行っているかと、Python 習得してどのように職歴を積むとよいのか、という話。

発表者は特に数学などの成績が良かったわけでもなく、大学で Java を諦めたくらいだが、 Python を始めたおかげで今では高給をもらって豪邸に住むまでになったとのこと.

Python が世界を席巻している理由として挙げられていたのは以下の 3 つ: 1. 初心者が受け入れやすい 2. 企業からの需要がある 3. 良いコミュニティがある

他にもアメリカのフリーランス事情が垣間見えて面白かった。

Python でフリーランス始める場合に最初にやるおすすめの仕事は Web スクレイピングで、 比較的簡単は作業で高評価をもらってそれを足がかりに実績を積んでいくといよいらしい。 経験したことは LinkedIn に登録してそこからよい職を取るといよいという話だった。

フォローすべき Pythonista として次の人たちが紹介されていた。

  • Mike Grouchy: a founder at Pycoders Weekly
  • Julian Sequeira: a founder of PyBites
  • Mariatta Wijaya: a core python develope
  • Takayuki Shimizukawa: Python author and Sphinx contributor位

また Python 学習におすすめのサイトも紹介されていた。

感想

これから IT 業界に飛び込もうという人にはかなりいいんじゃないかと思える。 またこの言語を学ぶことで得られる恩恵がかなり具体的に・実体験付きで話されているので説得力高い(日本でも同じかどうかは 微妙だが…)。

Python と AutoML

pycon.jp

サイバーエージェントの AI ラボの芝田 将([c_bata https://twitter.com/c_bata])さん Automated Machine Learning in Python

機械学習の自動化の話。 AutoML は Google のサービスでなく、機械学習自動化全般のことを指すみたい。

自動化のレベル分けと AutoML の要素技術

  1. 手書きの予測機、自動化なし
  2. 手書きの特徴量、予測学習を自動化
  3. 手書きのアルゴリズム、特徴量と予測の学習を自動化
  4. 手書きなし、アルゴリズムの指定も含めてすべて自動化

slideslive.com

自動化は 3 つの観点 * ハイパーパラメータ最適化: 少ない試行回数でよりよいハイパーパラメータを得る * 特徴量エンジニアリング: 適切な特徴量を選択する * アルゴリズム選択: 適切な機械学習アルゴリズムを選択する

ハイパーパラメータの最適化

  • ベイズ最適化: Gaussian Process, TPE, SMAC
  • 早期停止: Successive Halving, Hyperband

おすすめライブラリ

  • Optuna: TPE, SuccessiveHalving に対応
  • scikit-optimize: GP に対応

特徴量エンジニアリング

特徴量エンジニアリングはすごく重要で、時間がたくさんかかる。

現在あるライブラリはどれも基本的なものだけ対応(ex, 欠損値保管、次元削減)

  • 特徴量生成
  • 特徴量選択

アルゴリズム選択

機械学習のアルゴリズムはチートシートがあるくらいに煩雑だが、 かといって自動化して嬉しいかどうか議論の余地ある。

機械学習におけるハイパーパラメータ最適化の理論と実践

pycon.jp

こちらも機械学習の自動化の話。

  • ハイパーパラメータ最適化
    • 機械学習にはチューニングすべきハイパーパラメータが多数ある
      • 例) ロジスティック回帰: がくしゅうりつ、正則化係数
    • 最適化の流れ
      1. 初期値を用いて train データに対して学習
      2. 誤差を見てパラメータを調整
          1. の繰り返し
  • Black-box 最適化
    • GP-EI
      • ベイズ最適化
        • HPO で一番人気
      • カテゴリカル変数用のカーネルを準備
      • 探索空間が狭くて多峰性が見込める場合は TPE より有利?
    • TPE
      • 目的関数のモデル化方法が GP-EI と異なり、カテゴリカル変数を直接扱える
      • 高次元で GP-EI より有利
    • CMA-ES
      • 進化計算における最も有力な手法の一つ
      • ハイパーパラメータ最適化への適用例も存在
      • 多変量正規分布から解を生成することで最適化
      • 時間計算量は良くない
  • Gray-box 最適化
    • successive halving
      • 経験的に、中間の評価値は最終評価値と相関がある
      • 各ポイントでの評価値を元に回の候補を絞り込む
      • 途中で見込みがなかったら打ち切り
    • Hyperband
      • 絞り込み方を変えながら successive halving
        • 積極的に絞り込む or もう少しゆっくり絞り込む or 全く絞り込まない or etc のトレードオフを考慮
    • BOHB
    • Population Based Training (PBT)
      • Sequential Search と Random Search のいいとこどり

おすすめソフトウェア

  • Optuna
    • defin-by-run スタイル
    • ログも綺麗で使いやすい
  • BoTorch -> AX
    • from Facdbook
    • adaptive experiment platform
      • HPO より幅広いプラットフォームらしい
      • バンディットアルゴリズムなども提供
  • Ray
    • 強化学習の RLib と相性がいい
    • 分散環境得意

Python による日本語自然言語処理

pycon.jp

nagisa をつかった日本語自然言語処理の話。

  • 自然言語処理のよくある流れ
    • コーパス→ 前処理 →データ →学習→モデル→評価
  • nagisa
    • feature
      • BLSTMs による単語分割と品詞タグ付け
      • pip install nagisa ですぐ使える
      • 単語、品詞推定、“語形変化の処理“ はない
  • BLSTMs = Bidirectional LSTMs
    • 前向き LSTM と後ろ向き LSTM を計算
    • 入力全体の情報を各時間で考慮できる NN
  • nagisa メソッド
    • 実施 nagisa.tagging(text)
    • 単語の抽出 tokens.words
    • 品詞の抽出 tokens.postags
    • ユーザ辞書への追加 new_tagger = nagisa.Tagger(..., single_word_list=[“あたらしい単語”])

Python ウェブアプリケーションのためのプロファイラの実装 by Yusuke Miyazaki

pycon.jp

wsgi のミドルウェアとして実装されたプロファイラの話。

  • wsgi_lineprof
    • line-by-line profiler for web app
    • アーキテクチャ
      1. capture request/response
      2. get infromation on execution
      3. measure exec time per line
    • WSGI middleware
      • wrapper for WSGI app to ad features
      • why
        • HTTP リクエストを撮りたい
        • 既存のアプリケーションに組み込みたい
        • 簡単にオンオフしたい
    • Implementing WSGI Middleware
      • WSGI application
        • ただの Callable
      • WSGI middleware
        • app = Callable を受け取って Callable を返す
    • tracing
      • wsgi perf では PyEval_SetTrace を使う
    • measuring time
      • C 拡張を用意してプラットフォームごとに使い分け
      • 使ったもの
        • POSIX: clock_getitime()
        • masOS: math_absolute_time()

Introduction to FEM Analysis with Python

Python で有限要素法を行う話

Python で切り開くあたらしい農業

TensorFLow の利用例としてきゅうり仕分け機が有名だが、 その開発時の試行錯誤の話などを聞けて興味深かった。

初期バージョンでは仕分けまでをコンベアを使ってやっていたが、きゅうりに傷がつく、結局どこかで人手がいりそう、なども問題があって完全自動化から人間の手助けをする方針に切り替えた。

他やってみてわかったこと:

  • 熟練者のノウハウ継承の可能性
    • ノウハウの継承 (熟練者→ AI → 初心者)
    • 半年ぐらい使っていると、AI の助けがなくてもできるようになる
  • 自動化だけじゃない DL の可能性
    • 障害者も働きやすい環境作り
    • 人間同士のコミュニケーションの支援

Inside a companion robot belm0

pycon.jp

Lovot 内部の並行処理の話。

スピーカーの人はビブリボン!の開発にも携わっていたとのこと。

Lovot は 人間とインタラクションしながら表示を行ったり音をだしたりと、 並行処理の塊で、 GroovX社ではいろいろ工夫して生産性を上げていた。

並行処理で気をつけた点として以下が挙げられていた:

  1. 開発を妨げない
    • 低レイヤを担当しないチームも含めて並行処理で患わせないようにする
  2. 適切な言語を選択する
    • これは Python を使えば解決
  3. 並行処理の導入で不明になるような処理・わからなくなるような処理を出さない
    • とりわけ mutable な状態・副作用とか
  4. プログラム内部を外部から観察・インタラクト可能にする
    • 自家製のヴィジュ荒いぜーションツールを用意した
  5. (たぶんプロダクト or OSS に対する)
  6. Trio の開発者とコンタクトを取り、チームが変更を恐れずとれるようにした

上記の 3. のために、次のような戦略でシンプルな並行処理にする最適化をおこなった:

  • 明確なコンテキストスイッチ/シングル OS スレッド
  • 統合されたキャンセル処理
  • 構造化した並行処理
  • async/await
  • コルーチン

このうち、「統合されたキャンセル処理」と「構造化した並行処理」のために TRIO を採用した。他は Python ネイティブの機能で対応している。また TRIO の採用で並行処理のテストも簡単にできるようになった。

例えば次のようなコードで

async with trio.open_nursery() as nursery:
  await pause(1)
  nursery.start_soon(turn, pi/2)
  nursery.start_soon(play_sound)

turn(pi/2)の処理で例外が起こった場合は、他の子(ここではplay_sound)がキャンセルされ、また親れ例外が伝播するようになっている(統合されたキャンセル処理)。

婚活・恋活領域における Python を使ったマッチング最適化 Morioka Takashi

pycon.jp

婚活のマッチングアプリ開発の話。 ほぼ Python の話でなく、婚活アプリでの苦労話とか。

  • マッチング最適化への道
    • 安定結婚問題
      • -> Gale-Shapley法をベースに開発
      • O(n2) で安定マッチング
    • マッチング手順の改善
      • 全対象→グループごとに並列実行
        • 計算量を制御できるが、マッチング精度の低下・少数派への悪影響がある
    • 環境の改善
      • Cloud Dataflow
      • pros
        • 大規模処理の水平分散を managed サービスに任せられる
          • BiGQuery, CloudStorage, Datastore のサポート
    • A/Bテストの実施
      • 改善のための基盤を準備
        • ユーザをタグ付けし、これを元にスコアリング処理を切り替える
    • 機械学習の適用
      • 機械学習経験者がいないので Google Cloud の AutoML を採用 → そこそこうまくいっているとのこと
      • Pros
        • BigQuery 連携が可能、バッチ予測・オンライン予測という
        • Cons
        • ブラックボックス部がおおい
          • モデルダウンロードできない

When AI meets 3000-year-old Chinese Palmistry Kai Hsu

pycon.jp

手相を機械学習してみた話。

Chinese Palmistry = 手相学になる模様。

機械学習の話としてはかなりベタだった。 健康、恋愛、仕事の 3 つの項目を手のひらの画像で学習していた。 手相学の方が新鮮だったくらい。

メディアが運用すべき持続可能な VTuber をつくる技術 @hirosaji

pycon.jp

Vtuber とタイトルにあるが、音声に関する機械学習の話が中心だった。 1 人の Vtuber の中の人が変わっても問題ないようにするには声質変換処理が良いだろうとのこと。

pytestによるCIレボリューション あべんべん

pycon.jp

pytest と CircleCI の話だった。