ta-dadadadaのブログ

忘備録とポエム

mod_wsgi がインストールできない

新しく環境構築してたらよくわからないところでハマったのでメモ。

ハマっていたこと

環境は amazon linux (と言いつつその後 ubuntu でも試して同じ症状で苦しんだのでものによらない)。

pyenv で python3.7 を入れて、その仮想環境上で mod_wsgi を入れようとしていた。

とりあえず apache は不可欠なのでいれる。

sudo yum install httpd httpd-devel

それで、

pyenv global 3.7.1

とかして

pip install mod_wsgi

すると、

 /usr/bin/ld: final link failed: Bad value
    collect2: error: ld returned 1 exit status
    error: command 'gcc' failed with exit status 1

とかいって落ちるわけです。

やったこと

どうも依存パッケージが足りないとかそういうわけでは無いらしく、

qiita.com

こういうことだった。 どうも共有ライブラリというのが pyenv 経由の python のインストールでは(デフォルトでは)できないらしく、 一方 mod_wsgi 側からは共有ライブラリを必要としているのでエラーになっていたようだ。

なので実行したこととしては、一旦 python 消してから、

env PYTHON_CONFIGURE_OPTS="--enable-shared" pyenv install 3.7.1

で入れ直した感じ。

改めて pip install mod_wsgi したら無事通った。

注意書き たぶん良い子は真似してはいけない

共有ライブラリ云々というのを知らなかったのでちょっと調べた。

qiita.com

要するに

  • 複数の python version 使う場合、共有ライブラリ作っちゃうと意図しないバージョンの python が誤作動することがあって危ない
  • ライブラリを参照したい側の設定を変えたほうが無難。今回なら mod_wsgi のビルド時に指定するとか

ということらしい。

よくよく考えると一つの環境内部に複数の mod_wsgi がいる、というのも変な話だしな・・・

いろいろ眺めてると、 mod_wsgi にリンクさせる python も 3 のほうが安定するらしい ただ、ビルドする方法だと mod_wsgi-express みたいな便利そうなツールを別途いれないといけない( pip だと同時に入る)とか、 システム自体に python いれないとなので centos で python3.7系を入れる方法とは?とかいう懸念もあって、ベストプラクティスはよくわからない。

とりあえず「1つの環境に求められる python version は 1 つだけ」と割り切ってエイヤと好きな方法で入れてしまっていい気がするけど、どうだろう? 実際サーバ立てるとしたらあんまり混沌なのは想像したくないし・・・

第3回 Cpaw AI competition 参戦記

これ に参加させていただいたので、日記を残しておく

背景

実は弊社の方で第2回大会のピザ枠でスポンサーさせていただいてて、そのとき見学させていただいて「次は個人で絶対出るぞ!」と決意していた。 イベントが人気すぎて登録したときにはもう補欠枠だったので半分諦めていたが、最終的に繰り上がりで出場が叶った。

環境

会場提供は CyberAgent 様。立派なビルの一室で、もちろん電源も wifi も完備。

作業環境として さくらインターネット 様が提供するリモート環境がすごくて、 cpu は 12core あるわメモリは 96GB あるわで「こんなに使い切れんよ...」と面食らっていた。

問題

今回は3問。前回は4問、第1回は5問だったらしく、だんだん絞られてきている感じ。

3問の内訳は、

  1. finger count: 「手」の画像データが与えられて、「手」のうち立っている指の本数が 1,2,3 のどれかを当てる、というもの
  2. HSI: 航空写真をスペクトル分解したデータが与えられて、航空写真に写っているものが何かを当てる、というもの
  3. tourist spots: 観光地についての説明文+基礎データが与えられて、観光地のカテゴリ(寺とか美術館とか)を当てる、というもの

コンペ開始

リモート環境は さら だったので、とりあえず anaconda + 各種DLのライブラリをインストール。 インストール待ってる間にリモートから rsync するスクリプト書いたりしていた。

今回はサンプルスクリプトが与えられていた。 これが本当の本当にありがたくて、とりあえず実行すると識別率70%くらい余裕で出るというシロモノだった。

とりあえず1本サンプル回してみて「このサンプルは強い」という事実に気づいたので、とりあえず 3問ともまわしてみて submit するという RTA を敢行。 RTA では1位になったので一瞬ランキングの1位になったりしてこの時点でなんかわりと満足していた。

前処理の試行錯誤

ぱっと見 tourist spots は自然言語処理を含む感じでつらそうだな、と思ったんですけど、 前処理部分が品詞分解してつっこむだけのものだったので多少工夫できるかもな、と思ってとりあえず触ってみることにした。

いろいろやった結果品詞を動詞か名詞だけにしぼって突っ込んでみる、というのをやってみた。 実際はそのへんの「効かない」パラメータについては学習器側でいい感じにされてるはずなこともあり、大した変化にはならなかった。

次に触ったのが finger print 。今回の問題の中では一番素直そうな問題だったので触りやすそうかな、という目論見だった。 画像の normalize とかを手探りでやってみつつ、芳しい効果は得られないまま時間が経過していた。

15時後半くらいで「前処理は全くスキルがないから無理やな」という事実に気がついたので、投げ出す。

このあたりでどのサンプルスクリプトも Ridge 回帰を使っていることに気づいて、 「これ全部 RandomForest にしたらめっちゃいい感じになるんじゃね?」という雑な経験則からくるアレに基づいて順次 RandomForest に切り替える作業を始める。 この作戦自体は当たりで、いっとき順位が6位になるくらいまで健闘できた。 また、マシンパワーのおかげで GridSearch が非常に捗ったので、ちょっとずつハイパーパラメータのチューニングをしていた。

pretrain model

「学習済みモデルの convection とかを利用して前処理 -> 特徴量抽出して雑に学習器にぶちこめば素人が下手に触るより格段によいモデルができる」というのを知っていて、 finger count に適用してみるか、と思いついたのが 16時を回った頃。

ふわっと chainer の VGG モデルにつっこんでみる、というのが実装できたのが 16時半くらいのこと。 勝った!と思いながら回り始めてみたところ、 iteration speed から逆算するに競技時間内に学習が終わらない、という事実に気づいて絶望する。

学習済みモデルをもっと軽いものに置き換えられないかとか、 ideep 導入したらめっちゃ早くなるんじゃないかとか試して悪戦苦闘するも、残念ながら速度改善には至らず、この方針は諦めた。 もっと早いうちから思いついてれば間に合ったのになーという程度の見積もりだったので、ここは一番の心残り。

競技終了

最後の1時間くらいはハイパーパラメータのチューイングを回しつつ前処理の試行錯誤をしていた。 残念ながら特にブレイクスルーは得られず。

最終的なランキングは 10 位/30名 といったところだった(執筆時点で最終順位全体は公開されていないので実際はもう少し下の順位かも)。

何も知らない割には参加者平均以上の成績を残せたので、個人的には大変満足でした。

講評とか

問題の解説 + 優勝者のやったこと聞いた感じ、

  • もっとデータ見るべきだった。「効く」ところだけ抽出してぶん投げるだけでももうちょっと改善できた気がする
  • finger count はやっぱり得点源だった。もうちょっとスキルがあって、さらっと CNN 実装できてればよかった(優勝者の識別精度が 97% だったということを聞いて)

懇親会

CyberAgent 様のおしゃれなスペースに移動して🍕。

上位陣の方としゃべれたりして、とてもためになった。 機械学習にわかマンなのでついていけないなーと思いつつ、もうちょっとは勉強しなくちゃなーとかやっぱ kaggle はやっとくか、とか。 twitter 上で一方的にフォローしていた方々と形の上とはいえ面識ができてたいへんうれしかった。

運営の方や学生の方とも話せて、名刺交換までさせていただいて、実りの多い懇親会になったと思う。

感想

初学者的には本当にサンプルスクリプトに助けられた。 正直0スタートだったらデータを読み込んで最も基本的なモデルに渡す、というのをするだけで1日が終わってしまっていたと思う。 おかげで前処理の試行錯誤とか(成果はでなかったけど)、モデルの変更とかの比較的上層レイヤーの改善に集中できた。

自分でも一応「参戦」できたというのが嬉しかったし、とても楽しかった。 次回の開催を楽しみにしています。

isucon8 予選敗退した感想

今更ながら、9/15,16 に開催された isucon8 予選大会に参加し、予選敗退したので、感想を残しておこうと思う。

課題

チケット予約システムをはやくすること。 サンプルとしてぜんぜんイケてないアプリケーションが与えられるので、スケールアップ以外のほとんど全ての手段を使って良いので「いい感じにスピードアップする」ことが課題。

 

事前準備したこと 

  • ある年の過去問やってみた
  • チーム用の git レポジトリを準備
  • チーム用の slack を準備
  • slack に git からのイベント通知がくるよう設定

当日

まずやったこと

スキルセットとして低レイヤー(ミドルウェアとか)のことはあまり知らなかったので、アプリケーションレイヤーで改善点を探そう、というのは個人的な作戦を立てていた。

幸い MySQL は少しだけわかるので、いわゆる n+1 クエリを探しつつ、とりあえずコードを読んだ。言語は普段から触っている python を選択した。 明らかにイケてなさそうなところをいくつか発見したので、中でも n×m×l クエリになりそうな一番やばそうに見えたところのチューニングに照準を合わせることに。 その過程でモデル定義が激ヤバなところを横目にしつつ、いくつか index 追加しながらチューニングに取り組む。

  アプリケーションレイヤーでうまくキャッシュする、ということを考えたあたりで若干躓きながら時間を浪費する。

躓き

 チームメンバーが構成変更やらミドルウェアやらについて触っていてくれたのだけど、 構成変更するとうまく動かないという話がでてきたので、そちらを齧り始める。

  結果的には init 処理の向き先をちゃんと設定してやらないとダメ、という話だったのだけれど、 なかなか原因の特定ができずに昼からの数時間を費やした。

  並行して、 sheet テーブルがヤバすぎるのでなんとかしよう、というところにも取り組んだ。 適当にキャッシュしようとしたところ上手く整合性がとれずにベンチマークがこけつづけて、これにも時間を吸われる。

  その間の雰囲気はわりとお通夜だった。

クエリ改善

 構成変更がなんとかなったのが 16時とかで、そこから改めてクエリチューニングに取り組む。 ある程度改善できたのはほとんど滑り込みの時間だった。

コンテストの終わり

事前喚起されていたので再起動テストもやってみるか、というのを当初は計画していたが残り時間的に全く手がつかず。 コードを眺めていたチームメンバーが意味不明な処理を見つけたりしたのでやっつけで直したりしつつ、コンテストは終わりを告げた。

結果1

最終的に手元のベンチマークではなんとか 10000 ポイントをマーク。 ただこれは最良時の話で、確率的に 5000 から 10000 の間を行き来する、という感じだった。

結果2

最終的に公式発表されたスコアは 5000 ポイントくらいで、 150 位というところだった。 残当だなという感覚と思ったよりいったな、という感覚が同居する総合すると残念な気持ちでコンテストは終わった。

感想戦

うまくいったチームの話を聞くと、モデルがヤバいからモデル自体に手を入れたというのを耳にした。 たしかにそれはやればなんとかなったなという思いがあり、実際やったらスキル的に間に合わなかった気がしつつも、特に後悔しているポイント。  

全体的にはもうちょっとミドルウェアの知識があればスムーズだったなーという感が強い。

  とはいえ終わってみればたいへん楽しかったので、来年に向けて精進したいと思います。

prickathon#4 に参加してきました

概要

参加させていただきました。

prickathon.connpass.com

実は前回(#3)も出ていたんですが、レポ書き出遅れてるうちに出し損ねました。今回こそ。

できたもの

https://pri-story-search.herokuapp.com/

プリティーシリーズの各話を探す API を作りました。

モノ自身は python で flask を使ってできていて、終盤時間が余ったので heroku にデプロイしてみました。 レスポンスは json の漢らしいヤツ。

パラメータは series が必須で、 subtitle やら scenario やらをオプションにして部分一致検索できます。

今考えると series は url に含めるべきな気がしてきたのでそのうち直します。

やったこと

午後から参加したこともあり軽くデータ弄って何かやろう、ということで wikipedia から各話リストをスクレイピングしてくることを思いつきました。 で、はじめは beautiful soup とかでいい感じに web スクレイピングしてこようとしてたんですが、 1時間ほど格闘したものの思う通りの形でできなかった(主に知識不足で、いい感じにテーブルの処理ができなかった)ため、 スクリプトでやることを投げ出してコピペ&スプレッドシートでの温かみのある作業に移行。 一応温かみがあったのは日付の処理くらいで、最低限やったら csv に吐き出して pandas に読み込み、 セル結合のおかげで欠損値になる部分などだけ処理してやって json に加工する、ということをやってました。

search についても極めて原始的な文字列部分一致をかいて、あとは適当に flask で返せるようにした、というのが今回の成果です。

今回は合計してもせいぜい数百行にも満たないデータだったので生の json をソースに含めて読み込んでしまったけれど、 あまり頭のいい検索の実装とは言えない感じがするので、もう少しデータ構造を工夫するなり、 sqlite でいいから DB をバックエンドにしたかった気持ちはあります。

その辺あまりきちんとしなかったおかげで逆にさらっと heroku にデプロイできたとこもあるので、総合的には良い判断だったのかもしれません。

プリッカソンそのものの話

スペースとお菓子とプロジェクターが余るほどあり、 プリティーシリーズの が絶え間なく流れる非常に過ごしやすい環境でした。

途中キンプリとキンプラを同時に摂取する事態に見舞われながら(何も言っているかわからない)、 それにも動じずにコーディングを続ける参加者たちはたいへん訓練された女児だなあと感服する次第です。

プリパラの星の下に集う仲間たちということもあり(?)、 全体的にフロント畑の参加者が多い印象があったんですが、 ブラウザアプリやら画像検出やら画像分類やらゲームやらARやら音楽やら、 成果物については幅広く出揃った感があってとても刺激になりました。

個人だけでなく参加者間でチームになって企画を進められると、 すごく面白いものができそうな期待感に満ちているので、今後もハッカソンを継続していただいて、 そういうことにもチャレンジしていけたらいいなーとわくわくしています。

以下余白

プリッカソン公式ステッカー。なかひこ氏の力作。一晩でやってくれました。 私物にステッカー貼るのって女児ですよね。

懇親のピザを頬張りつつ、ライブと成果発表を同時に眺めるの図。

懇親のピザを頬張りつつ、2つの成果発表が並列処理されそうになるのを眺めるの図。

iphone で Safari が落ちる事象が解決した

はじめに

随分前から、 iphone 6s で Safari を開いてもすぐにアプリが強制終了してしまう、仮に開いたとしても画面上部の検索フィールドをタップしたら落ちてしまう、という不具合に悩んでいた。

iOS は常に最新のものにしていたし、ありがちな Safari 関係の機能をオフにしてみる対処法を試してみたものの効果は全くなし。 apple 純正の端末で apple 純正のアプリがまともに使えないとはどういうことだ、と憤りつつも、普段使っているブラウザは chromeSafari の出番は滅多にないので、諦めていた。

なんだけれど、不意に Safari にしか対応していないページを閲覧する必要に迫られたので、久しぶりに困った。 それ自体は 気合いで 対処したが、今後もアクロバティックな方法を続けていくのは不本意なので、改めて解決法をググって回ることにした。

解決策

こいつだった。

did2memo.net

このSafariが落ちる不具合については、Safariのブックマーク/お気に入りに含まれる「半角カタカナ」のサイト名を修正したら直った、との報告が増えています

半信半疑ながら macSafari を開き、プックマークを確認してみると、太古の昔のブックマークの中に、半角文字が含まれているものがあった( アイドルマスターシンデレラガールズ!)。

エイっとブックマークから削除し、その後も半角カナ文字をシラミ潰して、 iphoneSafari を開いてみると、直っていた。

おわりに

改めて考えてみると、 iOS, MacOS が基本的に半角カナ文字をサポートしていない(入力手段がない)ので、不具合の原因であることもなんとなく頷ける。 Safari の起動時に、サポート外の半角カナ文字が含まれるお気に入り/ブックマークをロードする段階で落ちていたのだろう。

実は Safari を直接起動せずに、他のアプリ( Twitter とか)経由で開いた Safari だと落ちないことは知っていて(「はじめに」で言った「気合いで解決」もこれを利用していて、 Twitter 経由で yahoo -> 検索 -> ... という感じで目的のページまで行った)、おそらく他のアプリ経由(多分 URL 直指定のブラウザ遷移)だとブックマークのロードが挟まらないので落ちなかったんだろうなーと。

今の時代に使う意味もない半角カナとはさよならしましょうね。

feedly + pocket がすごいという話

iphone アプリの話ですが。

feedly と pocket を連携しておくと、 feedly 側で記事を長押しするだけで pocket に保存される。すげえ。

pocket からワンタッチで evernote に保存できると完璧なんだけど。

macOS Sierra に Julia をインストールする

jupyter-notebook のモダンな環境で julia を触ってみたいと思い、 homebrew でのインストールや githubの手順 にあるコマンドラインからのビルドを試してみたが、 どうにもうまくいかなかったので、最終的にうまくいった方法をメモしておく。

  • 参考にさせてもらったもの

qiita.com

環境

macOS Sierra 10.12.6

手順

anaconda をインストールする

jupyter-notebook をなるべく楽に入れるならこいつ。 僕の場合は anaconda3-5.0.1pyenv でインストールした。

julia をインストールする

公式ページ から .dmg ファイルをダウンロードして起動。 Applecations に放り込んでおく。

リンクの作成

julia をコマンドラインから起動したいのでやっておく。 Julia-0.6.app の部分はダウンロードしたバージョンのやつに、シンボリックリンクの場所はお好みの所に。

ln -s /Applications/Julia-0.6.app/Contents/Resources/julia/bin/julia /bin

julia を起動して IJulia パッケージをインストール

ターミナルを起動して、 julia で julia が起動することを確認。 起動したら、julia のプロンプト内で次のコマンドを走らせ、 IJulia パッケージをインストール。

Pkg.add("IJulia")

jupyter-notebook を起動してみる

無事にインストールできたら、引き続き julia プロンプトから notebook を起動してみる。

using IJulia
notebook()

適当なブラウザで jupyter-notebook が開く。 New ボタンから作成できるノートブックに julia がある。

一度正常に作業が完了すれば、通常通り jupyter-notebook から起動しても julia が選べるようになっている。