2022/06/30

メモ:競プロ用に使っているVSCode Remote WSL の tasks.json と launch.json

VSCodeは、remote WSL で WSLに繋ぐ。
workspaceは WSL の中の、/home/myname/atcoder/ 。
tasks.json と launch.json はさらにその中の .vscode/ の中。

tasks.json
デバッグ用の実行形式は a.dbg

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "build",
            "type": "shell",
            "command": "/usr/bin/g++",
            "args": [
                "-std=gnu++17",
                "-g",
               "-O0",
                "-o",
                "${workspaceFolder}/a.dbg",
                "${file}",
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "options":{
            },
            "problemMatcher": ["$gcc"],
            "presentation": {
                "close": false,
                "echo": true,
                "reveal": "silent",
                "focus": true,
                "panel": "shared",
                "showReuseMessage": true,
                "clear": false
            }
        }
    ]
}


launch.json
[F5]で、上で作った a.dbg に、in.txt を標準入力で入れる。
in.txt に sample をコピペして [F5] を押せば、そのままサンプル実行できる。

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "remote WSL gdb",
            "type": "cppdbg",
            "request": "launch",
            "program": "a.dbg",
            "args": [
                "<",
                "in.txt"
            ],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}/",
            "environment": [],
            "externalConsole": true,
            "pipeTransport": {
                "pipeCwd": "/",
                "pipeProgram": "bash",
                "pipeArgs": ["-c"],
                "debuggerPath": "/usr/bin/gdb"
            },
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
        }
    ]
}

2022/06/10

Notebookで分析とVS Codeで開発をリモートで同時に行う話

 GCP の Vertex AI Workbench はクラウドでデータ分析をする環境として非常に便利です。AI関連の分析はもちろん、単なる jupyter notebook として、python や R で notebook ベースでの分析作業環境を簡単に構築できます。

一方、分析は分析だけで終わる場合もありますが、その結果を使って、また、分析自体をパッケージ化して、なんらかのツールを開発することがしばしばあります。もしくは、notebook で使うモジュールを分析と同時に開発するというケースもあります。ところが、分析と開発を同時にやりたいと思ったとき、jupyter notebook だけでは開発環境がちょっと弱い。

そのようなニーズに対応するためかどうかはわかりませんが、Vertex AI Workbench には jupyter notebook ではなく、Theia IDE を UI として使うメニューも(現状は Experimental ですが)あります。しかし・・・Theia より、VS Code を使いたい・・・。見た目はほぼ同じなので、Theia に慣れればいいだけなのですが、なんとも言われぬもっさり感に、いや、VS Code の快活な動きに慣れてしまった後では、どうしても Theia よりは VS Code で、と思ってしまいます。


ならば、クラウドのノートブックインスタンスに、VS Code の remote SSH で繋げばいいじゃないか!と思ってやってみたらあっさり繋がりましたので、その備忘メモです。


まず、Vertex AI Workbench のノートブックインスタンスは適当に作って立ち上げておきます。


ローカル側ではVS Code を用意し、また、ssh でノートブックインスタンスに接続するので、SSH の設定が一通り必要になります。

まず、SSHの鍵ペアを用意します。無ければ生成して、しかるべき場所に置きます。ローカルが Windows ですと、VS Code は(たぶん)Power Shell の SSH を使って接続しようとするので、C:/user/(name)/.ssh に置くことになると思います。

で、作成した公開鍵を上で立ち上げたノートブックインスタンスに登録します。登録は、Vertex AI Workbench のコンソールからではなく、Compute Engine の設定画面から行います。コンソールのVMインスタンスから当該のインスタンスの設定を「編集」、SSH認証鍵のところで「項目を追加」から公開鍵を記入します。

このとき、公開鍵の最後にくっついているコメントがそのままユーザー名になるので、必要ならばこれを jupyter にしておきます。これは、プロジェクトベースでノートブックインスタンスを立ち上げると、利用するユーザーは Google Account の個人ではなく、Jupyter Notebook のサービスアカウントになっているからです。その名前が jupyter さんなので、ここで登録する SSH公開鍵の名前も jupyter さんにしておきます。

なお、プロジェクトによってはセキュリティの都合上 Compute Engine のインスタンスへの直接 SSH アクセスを禁止していることがありますが、その場合は諦めましょう。管理者が設定したセキュリティ要件には従ってください。


さて、SSH公開鍵をノートブックインスタンスに設置したら、ローカルから SSH 接続ができるかどうかを試します。ローカルの SSHクライアントを適切に選び、接続テストをします。

接続ができたら、config ファイルを作成します。VS Code はその config の Host を見て接続するので、ここに必要な事項を書いておきます。例えば、

Host mynotebookinstance

HostName xxx.xxx.xxx.xxx

User jupyter

IdentityFile ~/.ssh/id_rsa

など。

ここで注意なのが、HostName です。ここにIPアドレスを記入するのですが、Vertex AI Workbench で立ち上げたインスタンスの外部IPはエフェメラルなので、変化する可能性があります。固定IPを契約する、もしくは何らかのホスト名をつけるというのがよいのですが、それができない場合は毎回 IP アドレスを確認し、この HostName を修正する必要があります。但し、セキュリティ的にはそういう運用はあまりよくなさそうですので、心配な方は IT 部門に相談しましょう。


ここまできたら、あとは VS Code の remote-ssh で接続するだけです。VS Code の remote-ssh 拡張は、WSL で VS Code を使っていればおなじみのプラグインなので、入っていればそれでOK。無ければインストールします。

その後、左下の「リモートウィンドウを開きます」から Connect to Host を選ぶと、先ほど config に設定した Host が出てくるので、それを選択します。SSH鍵のパスフレーズを入力し、最初はリモートインスタンスのタイプを尋ねられるので、Linux を選択したら、VS Code からノートブックインスタンスに繋がるはず。左ペインにリモートのディレクトリが見えればOKです。


リモート開発環境の設定、例えば launch.json や settings.json などを適宜実施すれば、めでたく、jupyter notebook をブラウザで開きつつ、VS Code でリモート開発ができる環境が作れました。



最後にセキュリティについて。

そもそも、なぜわざわざクラウドでこういうことをやりたいのかというと、一番の理由は「ローカルに分析の痕跡を残したくない」からです。データ分析の仕事は秘密のデータをたくさん扱うので、データのセキュリティのことを考えると、最も安全なのは、「データをクラウドから出さない」ことです。GCP にはプロジェクトという枠組みがあって、プロジェクトの中にあるものは、プロジェクトの外からは見えなくなっています。Google Account を使ってプロジェクトの中に入ることで、初めてデータやコードなどのリソースに触ることができ、プロジェクトから出ればそれらとしっかり遮断される、そういう環境が理想的です。

そして、Vertex AI Workbench のサービスが開始されて以降、ようやくその理想に近づいてきました。(その以前から別の名前で同様のサービスがあったのですが、最初は非常に使いにくかった。)また一歩、「クラウドから出さないデータ分析」の理想に近づきました。

ただ、それでもまだ完璧ではないのは、Theia のもっさり感と、代替手段である VS Code の快活さです。正直、Vertex AI の Theia での開発はまだちょっと無理です。非常に重い。Theia 自体もさることながら、ブラウザベースでのコミュニケーションであること、また、おそらくコンソールの通信をツールがうまく橋渡ししておらず、タイピングのレイテンシがかなりのストレスになります。

そこで、理想は理想としてありつつも、現実的な路線として、VS Code によるリモート開発が選択肢として上がってきます。SSHで繋ぐので、リモート環境にあるコードやデータをローカルにダウンロードしようと思えば可能です。しかしそのためには scp などを意図的に使う必要がある、つまり、無意識にデータが漏洩することはありません。それ以外では、普通にVS Code でリモート開発しているだけなら、ローカルには(キャッシュを除き)痕跡は残りません。リモートを切断すればローカルには何もありません。

唯一の懸念点は、ローカルに置いてある SSH鍵を使えば、ノートブックインスタンスにアクセスできてしまう点です。この鍵は Google Account を経由せずにプロジェクトの中に入れるので、注意が必要です。しかしその一方で、あくまでも GCP のサービスアカウントの一つですから、その権限を正しく設定しておくことで、リスクを低減することが可能です。また、ノートブックインスタンスは IPアドレスが常に変化するので、万が一この設定が盗難されてしまったとしても、Google Account 無しに IPアドレスを突き止めることは不可能です。さらには、SSH鍵に正しくパスフレーズを設定しておくことで、リスクは限りなくゼロに近づけることができます。

ということで、これらのセキュリティ要件をちゃんと考えた上で、VS Code でのリモート開発は便利で効率的、という話でした。

2022/06/08

マイナンバーカードを使って「商業登記電子証明書」を取得した話

「商業登記電子証明書」は会社の代表個人のマイナンバーカードを使うとすべてオンラインで取得できるとのことで、やってみました経過の備忘録です。次回、27ヶ月後に思い出せるように。

【作業順】

基本的には商業登記のサイトに載っている手順書の通りに実施すればOKだけれど、ちょっと不親切なところがあったので、自分用のメモが次。

  1. 商業登記電子認証ソフトをインストールし、申請用データを作成した。
    • 作成するファイル
      • SHINSEI
      • 鍵ペア
      • 発行申請書・委任状ファイル(紙申請用なので使わない)

  2. 申請用総合ソフトをインストールし、申請書を作成した。
    • まずは送信前の準備で、電子署名の手前まで作業を進める。

  3. 電子署名をして申請
    • マイナンバーカードをICカードリーダーに挿した状態で、申請用総合ソフトの「ツール」->「ICカード切替」で使用するICカードライブラリを登録する。
      • その前にマイナンバーカードを公的個人認証として使えるようにしておくことが必要(後述)
    • 申請書を右クリックし、署名付与
      • マイナンバーの署名用パスワードを入力。
    • これで申請ができるので、申請する。

  4. しばらく経つと受理と費用納付の連絡が来るので、費用を納付する。
    • 「納付」を押すと、ペイジー納付のウェブサイトに飛ぶので、インターネットバンキング等を使って納付する。
    • ブラウザが開き、そのままインターネットバンキングのページに飛ぶのだけれど、もし別のブラウザや別のマシンを使って納付したいときはどうすればいいんだろう?

  5. またしばらく経つと、申請用総合ソフトでステータスが「納付済み」、「手続終了」に変化する。手続き終了になったら、「お知らせ」欄に出力されるシリアル番号を控えておく。

  6. 商業登記電子認証ソフトにて、「電子証明書の取得」を実行
    • 申請用総合ソフトで控えたシリアル番号と、2で作成した鍵ペアファイルを使い、また、電子証明書パスワードを設定して、商業登記電子証明書をダウンロードする。
以上。

これで、自分が代表を務める会社の商業登記電子証明書を、自分のマイナンバーカードを使って、すべてオンラインで取得することができました。


【公的個人認証ソフトについて】

JPKIのサイトからJPKI公的個人認証の利用者クライアントソフトをダウンロード、インストールしておく必要があります。なお、ツール群の中にはjavaのインストールを要求するようなものがあるのですが、今回は不要です。(javaとか絶対インストールしたくない・・・。)

また、ICカードリーダーを接続しておきます。

ところで、たいていのICカードリーダーは、パソコンに接続すると自動的に汎用ドライバがインストールされて使えるようになるのですけれど、自分の環境ではこのドライバはNGでした。ちゃんとメーカーのサイトから専用ドライバをダウンロードし、インストールしておかないと、JPKI利用者ソフトが無言で落ちます。例えばパスワードを入力してマイナンバーカード情報を読み取ろうとした時など。メーカーから正しいドライバをインストールするとその現象は治りました。

落ちる前になんらかのメッセージくらい出してほしかったという思いはあります。

正しく設定されていると、パスワードを使ってカードの情報を読み取ることができます。


【必要なソフトウェア】

結局、3つのソフトウェアをPCにインストールすることになりました。
  • 商業登記電子認証ソフト
  • 申請用総合ソフト
  • JPKI利用者クライアントソフト群
昨今はほとんどのツールがウェブアプリ化されているので、PCにソフトウェアをインスト-ルするということが減りました。インストール画面でのセキュリティ警告も「はい」を押すしかありません。利用するPCも(消耗品として)どんどん入れ替わりますし、ローカルに何かをインストールすると環境を汚して、他の大事なツールが動かなくなったりするので、正直あまりローカルにインストールしたくないです。27ヶ月後はウェブアプリ化されているといいと思います。

2022/02/11

Lenovo Thinkpad X1 Nano で、"FMP Capsule Update Fail"

Lenovo Thinkpad X1 Nano (Windows 11) にて、Firmware Update の指示が出たのでアップデートしたところ、いつまで経っても終わらない。よくよく画面を見てみると、

"FMP Capsule Update Fail"

と表示されて止まっている。あぁ、これは一大事だな・・・

ググると、同様の症状で困っている人多数。電池が無くなるまで待てば戻るという書き込みを見つけたので、ダメ元で強制終了してみようと思ったのだが、電源ボタン長押しするも受け付けない。

なにかあるだろうと思って機器を見回すと、背面に小さい穴があったので、これはリセットボタンだろうと思って押してみたところ、うまくリセットされました。

怖い怖い……。


なお、この通り対処して元に戻らなかったとしても一切責任は負いませんので、あしからず。Lenovoに言ってください。

2021/12/16

データサイエンティストが競プロを始めるメリット

 はじめに

 この記事は、「競技プログラミングを始めたばかりの人に伝えたいこと Advent Calendar 2021」12/16回です。

 お題は、「競プロを始めたときにこんなことが知りたかった、と思うこと」ということで、ここでは特に、データサイエンティストが競プロを始めたらこんなイイコトあるかもよ、的なことを書いてみようと思います。

そもそもデータサイエンティストと競プロ

「データサイエンティスト」で思いつくデータサイエンティスト像は結構多岐にわたって、人によってイメージが違います。いわゆる昔ながらのデータ分析、データ解析の人、データアナリストと呼ばれるような人から、ビッグデータをぶん回しているデータエンジニアリングに近い人、また、機械学習こそがデータサイエンス!という人など、様々。また、分析するだけにとどまらず、その結果を用いた社会実装、例えば最適化計算などオペレーションズリサーチ系にもっていく人や、マーケティング、意思決定、組織論といったビジネスアプリケーション系にもっていく人など、使い方も様々です。

で、自分の周りを見回してみると、意外にデータサイエンティストと競プロerがかぶっていない印象を持っています。ていうか、データサイエンティストにおける競プロer率が非常に少なくみえる!

機械学習系、OR系はそこそこ親和性高くて、競プロerの上位陣(の社会人)にはそういった企業の皆さんが沢山いらっしゃる。一方で、ではデータサイエンティストがみんなそうかというと多分そうじゃなくて、一部のマニアックな人の趣味と思われているんではないかな、と。競プロからみるとデータサイエンティストとして有名企業で働いている人は沢山いて、そういう企業のデータサイエンティストは強者ばかりに見えますけれど、企業で働くデータサイエンティストを分母にするとそこそこレアなのでは?もちろん、そこに目を付けた企業さんは競プロ的スキルセットを持っている人を積極的に採用していると思いますが、一般的な認知はそこまでじゃないんじゃないか。

 かくいう私も、データ分析で飯を食ってはや20年以上になりますが、競プロを始めたのは2年前、ちょうどコロナでずっとこもりっきりになったときにAtcoderを見つけて遊び始めました。ただ、OR系の仕事によく携わることがあったのと、出身が数学なので、入口のハードルはそんなに高くなかったろうと思います。

データサイエンスで競プロが活きる場所

データサイエンスで競プロ的スキルが活きた経験は、私個人としてはたくさんあります。整数計画の組み合わせ爆発をどうやって回避するか、ループが何十個もあるネットワークの中からどうやって旨い経路を見つけ出すか、何億行ある過去ログからどうやってアトリビューションパスを効率的に作るか、などなど。計算機を1週間回しっぱなしにしたり、数十台並列で回したりすることも多かったので、リアルを定式化すると競プロの問題になりそうなものがたくさんありました。いや、競プロと言うよりは、「アルゴリズム」と「計算パフォーマンス」の課題です。数千行のサンプルデータでは簡単に計算できるのに、それが数百万行になった途端にうんともすんとも言わなくなる。果たしてそれが30分かかるのか、一晩で返ってくるのか、それとも数万年かかるのか。それが「わからない」では結果が出ませんから、どうやって実現可能な時間で返ってくる問題に仕立て上げるかを考えなければなりません。ただ、それはそういう仕事、高度計算機利用的な業務を私が得意としていたからで、 普通のデータ分析はローカルコンピューターでExcelやRを使ってポンと出るものが多かったです。

しかし、時代が変わってきました。

次では、具体的にデータサイエンスにおいて競プロが活きる場面を拾ってみます。

データの前処理

昔ながらのデータ分析では、データはせいぜい数千~数万。旧Excelで扱える範囲がだいたい限界でした。(当然、当時からテラバイトぶん回していた猛者はいますが、当時はレアケース。)

しかし、2000年代になって急激にデータ量が増えてきました。ビッグデータという言葉が流行り始めたのは2003年頃です。それからはや20年、ほとんど全てのデータサイエンティストは、当たり前のようにビッグデータを取り扱わなければならない局面にいます。すると、こういう分析課題のためにこういうデータを作りたいというスクリプトが、数万行のサンプルでは一瞬で計算が終わるのに、数百万行のデータを入れた瞬間固まってしまう。私も何度もありました。

ここで、もしそれがアルゴリズムで解決できる課題であった場合、知っているか知らないかでは課題解決できる可能性が大きく変わってきます。もし知らなくても、経験値の高いデータサイエンティストなら別の方法(例えばなんらかの仮説を入れてデータを小さくしてしまうなど)で回避することもできると思いますが、アルゴリズムの見直しでも解決できるならば選択肢は多い方がいい。

データ分析課題は、それを解決できるデータが作れた時点で既に解決しています。逆に言えば、解決するだけの情報が無い、もしくは解決に足りる整理がされていないデータをいくらこねくり回しても、「garbage in, garbage out」です。データサイエンティストは課題を解決できる仮説づくり=それを表現するデータ作りが勝負ですから、そのデータ作りが計算時間の壁によって阻まれているとき、どのように乗り越えるかが試されています。アルゴリズムで解決できることに気がつけば、仮説を完全な形で表現できるかもしれません。逆に知らなければ、不本意な仮説でお茶を濁さなければならなくなるかもしれません。

なお、近年はデータエンジニアが前処理業務を受け持ってくれることも増えてきましたので、「アルゴリズムと計算パフォーマンスに詳しいデータエンジニアがいる」という選択肢もあることを付け加えておきます。しかしそうだとしても、どういう仮説の下にどういうデータを作るかはデータサイエンティストとデータエンジニアが協力して当たらなければならないので、知らないよりは知っていた方が何倍も作業を効率化できます。

分析

データができてしまえば、分析の行為自体は既存のソフトウェアに任せることが多いです。昨今は本当にツールの進化が止まらないので、まっさらから書くことはほぼありません。レアなケースとして、分析手法自体がまだ研究段階だったり、アプリケーションが特殊すぎて自分たちで作るしかないという場合は、計算アルゴリズムから作ることもあると思います。

最適化、機械学習

分析をツールに任せるのと同じように、最適化もほとんどの場合はツールに頼ります。機械学習などの学習アルゴリズムも広い意味で最適化と思ってよいです。これらも最近は本当に優秀なツールが安価に手に入るようになってきたので、ありがたいことです。ただ、最適化はカスタマイズされた制約の影響が大きいので、たまに自分で書いたり、もしくはツールを組み合わせたりなどして、うまく使ってやる必要があったりします。そんなとき、アルゴリズムや計算パフォーマンスのことを知っておくと、自分が取れる選択肢が増えて、イイコトがたくさんあります。

最適化を自分で実装する場合。最適化ということは、なにか原型となるモデルなり数式なりがあって、それをもっともうまい具合に調整する作業になります。調整とはつまり、ある探索空間の中から一つ「最適」なポイントを探し出すことですから、探索アルゴリズムがその中心になります。競プロのビギナー問題あたりでは二分探索の問題が頻出しますが、それのオバケが最適化の問題になっています。

ニュートン法のようなベーシックな方法を使う場合から、極大極小が様々に入り乱れた非線形な場の中でいかにして最大値を見つけるか、パーティクルフィルタやカルマンフィルタなど、また、ベイジアンにしてMCMCを使うとか、どんな方法であってもその裏には必ずアルゴリズムの課題が隠れていて、それをフェーズによって使い分ける必要があります。全く何の知識も無いところにいきなり「○○法」を持ち込んでも、それを実装するのに時間が掛かっていては本末転倒ですから、最初は適当な全探索をぶつけてみたりもします。 さらには、その探索方法選択自体を機械学習によって自動的に使い分けるようなこともあるかもしれません。

それらすべて、どのように効率的なアルゴリズムを組むかにかかっているので、裏で考えているのは、問題をどのように定式化して、どのように実装すると、時間内に思うような探索ができるか、ということで、これはまったく競プロ、特にヒューリスティック系のコンテストで考えていることと同じです。但し、制限時間は競プロと比べてたっぷりあるので、多少のムダがあってもなんとかなります。

二つ目はツールを使う際です。ツールを使うのだからあとはお任せでいいじゃん、ではありません。ツールは最大公約数的な使い方を想定して作ってあることが多いので、それから外れる使い方をしようとしたときに思わぬ落とし穴に嵌まることがあります。そのとき、これはツールの問題なのか、データの問題なのか、計算パフォーマンスの問題なのか、それらの問題点を想像し、解決の糸口にたどり着くために、競プロの知識や経験が活きます。経験したことのないことは想像できませんから、競プロで毎回出題される問題に苦労して経験値を積み重ねておくことは、この想像可能性に大きく影響してきます。

実際、あるライブラリの挙動がめちゃめちゃ遅いとき、もしかしたら?と思ってデータの持たせ方変えてみたところ一瞬で計算が終わった、ということがありました。また、世界的に名のあるソルバーを使ってもどうしても現実的な時間で答えを出せないのに、別のあるローカルソルバーを使ったら一瞬で準最適解までたどり着いたということもありました。ツールには向き不向きがあって、一番よく想定されている問題に一番適した計算方法になっています。ツールの解説書だったり、ツールを構成する元論文だったり、場合によってはツールの挙動を様々なテストデータで試したりして、ツールがどのように動いているのかをイメージし、課題をそれにフィットするようにうまく合わせてあげたりすると爆速になったりしますが、その想像力の元ネタとして競プロでの経験値は非常に役立ちます。 

最適化の課題設定と定式化に必要なスキルはデータサイエンスだけでなく、また一方でアルゴリズムや計算パフォーマンスだけでもありません。そのほかにも、ビジネス経験や、様々なデータを見たり扱ったりした経験も活きます。ある種の総合芸ですので、経験値があればあるほど効果的、効率的な最適化ができます。

競プロ以外にあったらいいスキル

さて、ここまではデータサイエンティストにとって、競プロ的なスキル、つまりアルゴリズムと計算パフォーマンスがどう活きるかを見てきたのですが、データサイエンスは総合芸ですから、競プロではあまり出てこないけれど重要なスキルがあります。それをご紹介します。  

コンピューターの仕組み

これは競プロの延長線上にあると言ってもいいかもしれません。 必ずしも競プロで考慮することではないですが、上位陣はおそらく意識していると思いますし、情報オリンピックレベルの皆さんはおそらくコンピューターサイエンスの授業で習っていると思います。トランジスタ、IC/LSIがどうやって動いているかとか、CPUが周りのデバイスとどう通信しているか、命令のスケジューリング、など。

また、ソフトウェアの面からも、C++やPythonがメモリをどう使っているか、コンパイラの果たす役割、最適化のされ方など。たまに競プロでも、巨大なメモリをアサインする際に「どちら側でまわすか」が議論されていたりしますが、メモリとキャッシュをどう使うと効果的か、という話です。そこまでカリカリにチューニングしなくても、例えばメモリのスワップが入ると劇的に遅くなるとか、ツールがメモリをこうやって使っているからメモリが足りなくなるとか、コンピューターやOS、ソフトウェアがどのような仕組みで動いているかを知っていると、改善の選択肢が増えます。

あとは最近だと、GPUなどアーキテクチャの異なるプロセッサをどう使いこなすかという課題もここに入るかもしれません。

並列計算

計算パフォーマンス改善のもう一つの手段として、並列計算が挙げられます。アルゴリズムによる改善は場合によっては劇的ですが、並列計算の改善はせいぜい線形、悪ければもっとサチります。それでも、100日かかる計算を100台並列で動かして1日で終えたり、30分かかるクエリが1000並列3秒で返ってきたりと、並列計算はパフォーマンス改善の手段として、ある種の問題にとっては確実に計算時間を短縮し、現実的な時間に計算を終えるための選択肢です。

このとき重要なのは、その問題は並列計算可能か?ということを見極めること、もしくは、問題を変形して、並列計算ができるような形にすることです。並列計算の中でも最も単純な分散計算(計算どうしがデータのやりとりをせず、個別の小さい問題を組み合わせるだけで解決する、つまり協調計算でない)問題にできれば、CPU数に対してほぼ線形に計算時間を短縮することができます。つまり、10台使えば計算時間は1/10に、1000台使えば1/1000になります。MapReduceなどもそれ系ですね。

MCMCのように一つ前の計算結果を参照する定式化をしてしまうと、一つの系列をそれ以上分散させることができません。複数系列を同時計算することはできますが。一つの系列に長時間かかるようであれば、例えばモンテカルロのように完全分散化してしまった方がいい場合もあるかもしれません。もちろん、様々な方法が論文等でも提案されていますから、それらを理解するためにも、並列計算の知識はあった方がいいです。

競プロには並列計算の話はほぼ出てこないのですが、「問題をどう定式化すると現実的なリソースで解けるようになるか」を考えるところは思考方針として非常に似ています。

クラウド利用

上に書いた全てのことを、現代ではクラウド無しに実行することは非常に困難です。100台の並列計算をしたいと思ったとき、クラウドではボタンをいくつか押せば直ちに100台のマシンを調達することができ、それが動き始めますが、これをオンプレでやろうとすると半年はかかります。このデータを分析したい、それには100並列で1週間かかる計算が必要、となってから機器を購入して、データセンターを予約して、納入されたマシンを接続して、OSをインストールして・・・気が遠くなります。

データも、いまはローカルにダウンロードすることすら困難な量のものがクラウドならけっこう簡単にやりとりできます。 HDDにダウンロードするのに一日、運搬に一日、コンピューターに入れるのに一日、なんてことは(うまくデータの流れを作れば)ほぼありません。

データベースは2012年に Google の Big Query が世界を変えました。少なくともデータサイエンス、データエンジニアリングにとっては、もはやそれ以前には戻れない画期的なサービスです。もちろんそれまでも、限られた人たちだけが使えるすごいサービスはあったかもしれませんが、一般向けに、誰でも使える巨大なデータベースサービスが、驚きの価格で提供されたことが革命的でした。

これからのデータサイエンスは、クラウドをどう使っていくかということと切り離せなくなってきています。

どのようなスキルセットを持つか

と、データサイエンティストはあれもこれも全部必要!という話になってしまいましたが、実はこれらすべて、ほどほどでいいです。

全てに精通している人は・・・もちろんいないわけではないですが、めちゃめちゃレアです。そしてデータサイエンスは属人的なワークなので、そのレアな人が全ての仕事をかっさらっていくことは不可能です。いきおい、できる人が、できることに、できる範囲で取り組むことになります。 

仕事は中ボス攻略

ドラクエを想像するとわかりやすいと思います。中ボスを倒すのがミッションで、そこに至る過程に様々な障壁があります。あるときは魔法で、あるときは剣で、あるときはアイテムで攻略しなければなりません。そこで自分のステイタスを見てみると、沢山のアビリティが並んでいるのですが、その中に「競プロの部屋」でトレーニングできる「アルゴリズム」と「計算パフォーマンス」があります。もちろん、「数学」や「統計学」もありますし、「ビジネス」(はもっと細分化されていますが)や「システムエンジニアリング」、「クラウド」などもあります。

データサイエンスは総合芸ですから、それら全てのスキルをどのような配分で持っているか、と、あたる中ボスの特性とを見比べて、どうやって攻めるか、もしくは他の人に託すかを考えます。そしてその中ボスは、沢山います。世の中に様々なビジネス課題があって、それらがデータを抱えて待っているので、仕事は今のところなくなる気配はありません。しかし、自分がどういうスキルセットをもっているか、この先どのようにそれを伸ばしていくかということと、将来攻略する中ボスとは相関します。簡単に倒せる中ボスは早晩枯渇しますし、人数の多いスキルセットで倒しやすい中ボスも競争が激しくなるでしょう。

単品勝負の人はけっこう多いです。多くのアビリティの中で一つだけSやSSを持っている人が結構いるのは、大学教育がそうなっているからです。一つ一つのアビリティではSSの人は少ないのですが、アビリティがたくさんあるので「一つだけSS」の人が多くなります。他方、攻略する相手、ほとんどの中ボス攻略には複数のスキルが必要です。一つのアビリティだけで攻略できる中ボスはほとんどいません。ではどうするかというと、一人で複数のアビリティが強い人が攻略するか、チームで攻略するかになります。

自分の特色の作り方

さて、ここで面白いのは、攻略する中ボスにどのスキルセットが必要なのかが、事前には分かりにくいことです。SS単品の人が仮に当たってみても、攻略の糸口は見つかりません。SS周辺はわかるのですが、他のアビリティが低ければ、相手の強さを見積もれないからです。ではSSを沢山集めたチームを作ろう、と言っても、相手の攻略方法を見つけるPOCの段階でドリームチームを動かすのはコスト的にも時間的にも非常に難しい。

ですから、総合芸であるデータサイエンスの「現場」では、SSを一つも持っていなくとも、多くのアビリティでA持ちとか、複数個Sを持っていて残りはBなどという人の方が仕事を回しやすい。そういう人が中ボスの攻略方法にあたりをつけて、自分ひとりでできればちゃっちゃと片付けますし、自分のスキルや時間が足りないなぁと思えばSSの人を連れてくればいい。中ボス攻略のプロジェクトマネジメントができます。

データサイエンティストの方ならばおそらく、数学や統計学のアビリティはA以上だと思います。また、既に現場で活躍していらっしゃる方なら、その分野のビジネスにはかなり精通していらっしゃるので、それもA以上だと思います。そこにもうひとつ、アルゴリズムと計算パフォーマンスでAを持てば、攻略できる中ボスの範囲がぐっと広がります。私の体感として、データサイエンスで必要とされるアルゴリズムおよび計算パフォーマンスのAはAtcoderの緑~水色、Sは青くらいだと思います。実際、私が水色の真ん中くらいを行ったり来たりしているのですが、データ分析の実務で使うにはそのくらいあれば大抵のことができます。

そして冒頭にも申しましたが、データサイエンティストを分母として見回したとき、「アルゴリズム」と「計算パフォーマンス」でA以上の人はかなり少ない印象です。コンピューターサイエンスからデータサイエンスに入ってきた人たちはもともとSやSSを持ってくるのであまり見えないかもしれませんが、何度も言うように総合芸ですから、いろんな入口の人がいて、様々な仕事をしていて、その中でこの二つのアビリティが強い人はなかなかに少ない。そして、ビッグデータとクラウドの時代になって急激に重要性が増している。ということは、「アルゴリズム」と「計算パフォーマンス」のアビリティを「競プロの部屋」で修行して、AやSレベルに上げられれば、できる仕事の幅が広がり、アウトプットの質も高まり、世の中から必要とされるデータサイエンティストにまた一歩近づけるということになります。

 おわりに

 ということで、データサイエンティストが競プロ始めるとこんなにいいことがたくさんあるよ、ということを書きました。

実際に私が2年前から始めてみて、その経験値が具体的な仕事の課題解決に結びついたことが何度もあります。それまでもある程度の知識はあったので、やればそれなりにできると思っていましたが、皮算用のフェーズと具体的に自分がやってみたフェーズとでは想像できる広さとスピードが全く違いました。

いきなりコンテストは・・・と躊躇するなら競プロの典型例題を集めた「典型90」にチャレンジするのもいいですし、それはハードルが高いと思う人は、「アルゴ式」という入門編サイトも最近立ち上がりました。統計における統計検定がフリーで開催されていると思えば良いです。(そうか、統計でもそういうサイトを作ったら面白いかも・・・)あとは、自分が門を開くかどうかだけです。具体的な入門方法は他の方が本カレンダーで沢山解説頂いているので、そちらにお任せします。

最後に。実はこの話を書いている途中で、「あれ?もしかしてこれを書いてしまうと、自分の競合相手を育ててしまうことになるのでは?」と、ちょっと思いました(笑)。自分が統計×数学×計算の領域で飯を食っているので、同じスキルセットの人が増えてしまうと競争相手が増えてしまう・・・。でも、いやまてと。新しい人の流入が無くなってしまったジャンルは早晩潰れます。データサイエンスの世界が常に勢いがあって、スリリングで、活気に溢れるコミュニティである方がいい。その中で、自分が後進に脅かされはぁはぁ息を切らして追い抜かされる方が絶対に面白い。競プロの世界で、自分の子供と同じかそれより若い人たちにまったく敵わない、瞬間過ぎて背中も見えないくらいぶち抜かれて真っ白になるのを毎週経験していたら、未来はもっと面白いなって思えますよね。

 

2021/11/22

【メモ】石川真一郎さんの講演会

昨晩、麻布学園内イベントで石川真一郎さんの講演会がありまして、それについて思ったことのメモです。

NFTとデジタルコンテンツとの関係。 

コンテンツは多くの人に視聴してもらうことが価値。ただ、一方で違法コピーのように拡散が制作者側に無関係に行われてしまうと、制作を続けられないという負の側面がある。

NFTはその関係性をひっくり返す、という話。コンテンツに対する何らかの権利を発行、販売して、それを発信側にフィードバックする。一方で、コンテンツのコピーは自由に流通する。
その根底にあるのは、「モノに感じる価値は人それぞれ異なる」という視点。貨幣という一つの軸に収るものではない、一物一価ではないという考え方。 

価値を感じる人が、その価値に応じた対価を支払い、制作者を支える。
そこまでは事前にある程度勉強してわかっていたのだけれど、とはいえまだモヤッとすることが残っていて。結局、フリーライドする人ばかりになってしまって、コンテンツ制作は生業にはならないのではないか、と。 

お金を支払うに値しないと思っている人にコンテンツが消費されることはOKなのか。今まで違法サイトでこっそり見ていた人が、堂々とフリーライドするだけじゃないか。
と思っていたけど、実は違っていた。

ここからは私の解釈。
コンテンツのフリーライダーは、実はフリーライダーではない。有限の時間しか持たない人間にとって、「時間」は価値があり、それを支払っている。
但し、その単価は人によって異なる。コンテンツをタダで消費する人にとって、貨幣として対価は支払っていないのだけれど、「時間」は支払っている。時間を支払って、コンテンツのミームを吸収し、また拡散する。

人によっては、それが自分の時間を支払ってもなお支払いきれない価値を感じていれば、それを対価として支払う。他方、(動画など)時間を掛けるだけの価値がないと思えば、倍速視聴などで節約する。
しかし、いずれにしてもその人が感じる価値の分だけ、何かを支払っている。 

最近、youtubeなどで、スパチャをよく見る。100人いれば2,3人は飛ばす。スパチャを飛ばす人、時間を使い拡散する人、吸収だけする人、時短で見る人。
これは善意とか施しとか、そういう世界じゃなくて、自分の価値判断に従う世界。誰かに決められた価格ではなく、自分の価値基準を持つ。

これから世界の中心になる世代にとっては、これが当たり前の世界になっていくんじゃないか。

そして、誰が何にどれだけ支払ったかが可視化され、それがその人のステータスになり、発言力になり、人格になる。
そういう世界を、氏は見ているのかなと思いました。

なお、石川氏は Short shorts Film Festival でも講演をなさっているので、こちらも非常に面白かったです。より詳しく、コンテンツとNFTとの関係についてお話頂いています。

https://www.youtube.com/watch?v=I550Znb2Ec0


2021/10/16

R / Colaboratory: 時間のかかるパッケージインストールを何度もしたくないとき

 Colaboratory はサーバーレスで python や R のデータ分析ができる便利なサービスですが、サーバーレスならではの悩みとして、パッケージのインストールが面倒です。毎回使い始めるときにはまっさらのサーバーに戻ってしまうので、特殊なパッケージをインストールして使おうとすると、まずインストールに数分~十数分かかってしまいます。

 そこで、Colaboratory で R を使う際、高速パッケージインストール方法がないかと探したところ、「Google ColabでRパッケージの再インストールを爆速にする」が見つかりまして、参考にさせていただきました。ただ、ちょっと迷ったところとか、自分に合うようにカスタマイズしたところがあるので、それを備忘録がてら残しておこうと思います。

 

方法の概要は、 

  • Colaboratoryもなんらかの仮想(Linux?)サーバーで動いている。
    • 毎回立ち上げ時には初期状態のイメージから開始されるので、前回そこにインストールしたパッケージは消え去っている。
  • Rのパッケージのインストールは、CRANからなんらかのローカルディレクトリに展開されている。
  • ということは、そのディレクトリをそのままコピーして持っておけばいいのでは?
    •  ディレクトリを tar.gz してダウンロードしておき、使うときに展開する方法
    • ディレクトリを毎回マウントして使う方法
    • etc...

ということで今回は、パッケージをカレントディレクトリにインストールし、それを圧縮、ダウンロードして保存しておく方法を試します。

なお、この保存と復元はあくまでもパッケージインストールの途中経過であって、それ以外の目的では無いことをお断りしておきます。


【ライブラリをインストールして一時保存】

まず通常と同じようにライブラリをインストールします。その際、インストール先を指定しておくことで、後からそれだけ持ち出すことが楽になるようにしておきます。

 Rのkernelを指定したノートブックにて、

QCAのところは、インストールしたいライブラリにしてください。これは、

  1. dir.create で、current dir に library という名前のディレクトリを作成する
  2. .libPaths で、そのディレクトリを lib のインストール先に指定する
  3. ライブラリをインストールする

すると、「Installing package into 'content/library'」とアナウンスされ、無事上で作ったディレクトリにインストールされていることがわかります。 

なお、/content/ は Colab がスタートするディレクトリです。/home/hoge ではないんですね。

この段階は、CRANからパッケージをダウンロードし、依存関係のあるパッケージなども自動的に考えてインストールするので、結構時間がかかります。

 正常に実行されたら、試しにインストールしたライブラリを導入してみると、

 

 

無事、使えるようになっていました。

 では、これをパックして保存します。先ほど、パッケージは /content/library/ へインストールしたので、これをそのまま tar.gz に固めます。


 左ペインのファイルマネージャに「 library.tgz 」が見えるので、これをダウンロードし、一時保存しておきます。

 

【一時保存したライブラリを復元してインストール】

ColabであたらしいRのノートブックを立ち上げると、当然ですが、library ディレクトリは存在しません。そこで、先ほど一時保存したlibrary.tgz をアップロードします。


 

 掴んで落とすだけです。

 次に、このファイルは tgz で圧縮されているので、解凍します。

 

 エラーで終了してしまったときのために intern = TRUE を付けています。これがぶじ完了すると、ファイルマネージャに library のディレクトリが出現します。

これで、ライブラリのインストールが終わったときの状態が再現されたので、.libPath でパスを指定すれば使えるようになります。

library.tgz が手元にある状態からスタートすれば、アップロードに多少時間が掛かるくらいで、あとは数秒で終わります。

 

【その他】 

一番最初のリンク先の方法では、library.tgz を google drive において、そこから google to google でダウンロードして使う方法が示されていました。ローカルに置きたくない場合はそれが便利かもしれません。

一方、この方法では library.tgz は時が止まった状態で保存されているので、長期にわたって使うことは困難です。なぜなら、依存関係含め様々なパッケージがアップデートされるので、そんな中に library.tgz だけ時が止まっているのはあまりよろしくないからです。ですので、あくまでも短い期間に何度もインストールする時間をちょっと短縮したい、という目的で使うのがいいと思います。

特に、本格的に notebook を分析用として使いたい場合は、使うパッケージも増えますし、データや関連資料なども大きく、また計算時間や分析期間も長くなりますから、colab のような揮発性のインスタンスではなくて、Vertex AI(旧 AI Platform)の JupyterLab のような有料サービスを使うのがよいです。