てくてく目指すデータサイエンティスト Vol.1 -環境構築 編-

f:id:swyn_persol:20200717132633p:plain 

学生時代の研究など自己紹介

はじめまして。今年の4月にデジタルテクノロジー統括部に新卒で入社しました、柳澤といいます。同期の長谷川くんと同様、研修の内容についてこちらで発信させていただくことになりました。『成長日記』というとぶっちゃけ気恥ずかしいですが、ぼちぼちやっていこうと思います。

僕はこの春、学際系の大学院の修士課程を卒業して新卒で社会人になり、大学では「人がどのように"納得感”を得るか」といった内容で研究をしていました。心理学の分野に根差した研究であり、理論の提案と実験の考案が主な領域でした。
理系寄りの研究室の出身であるため機械学習などの知識もないわけではないのですが、イチから勉強し直し、という状態です。それなりに出来るスキルは、Rを用いたある程度のデータ分析や、その読み取り程度です。Pythonはとくに積極的に触った経験もなく、NumPyとPandasから勉強し始め、といったところ。

正直、就活をしている際には「自分にデータサイエンスは無理では」と思い避けていた業界でしたが、様々な人たちの”はたらく”にまつわるデータを扱えることには非常に良い機会と感じ、勉強をしているところです。 

研究の紹介――”メタ認知”

僕の大学時代の研究は、納得感が心理的にどのようなはたらきによって発生するか、をモデル化していました。いわゆる、「ああなるほど!」というやつです。

人がある知識を得たとき、理解が進んでいくことをどのように人はメタ認知し、納得につながっていくか、の考察を続けていました。とくに、このような内容についてはほとんど研究されていなかったため、ゼロベースで論じていたのがつい数ヶ月前のことです。この研究は、メタ認知の分野で重要とされる、モニタリングの概念などを背景として研究を行いました。
モニタリングとは自らの思考や記憶などを客観的に見る活動のことで、「私の発言ってどう思われるかな」「あのとき私はどう感じてたかな」と考えることを指します。
……ということは、僕自身が人を納得させるプロでありメタ認知の達人、のように思えるかもしれませんが、残念ながらそうではありません。全然納得できない話を突然するし、自分がどう見えるかメタ認知することが激しく苦手、といった部類です。
研究者の世界には、研究に進んだ人(とくに、自由にテーマを設定できる分野の人)は、等しく「自らが苦手とする分野を専門とする」という法則があるといいます。完全にそれだ……、という気持ちです(笑) 

企画の趣旨ー振り返りから考えるメタ認知

この連載企画では、自分の考えたことを記録することで「振り返り」の学習を行うことが期待されています。つまり、自分の行動の傾向や性格などを客観的に把握し、次につなげていくということです。ここでお察しいただけたと思いますが、これぞまさにメタ認知、です。そして僕のもの凄くニガテなものです。

とくに今回の記事は、特にかなり拒否反応が出る部分がありました……。苦手を自覚していてもさらに苦手だ!と思うことをやっています。そんなわけで色々キツいのですが、とくに僕の記事に関しては、自分が考えたことや悩んだことを重視して表現していきたいと思います。いろんな意味で、長谷川くんの文章とは別物になることが予想されます。同じ課題をやっているはずですが、全く同じ読み口にはなりませんので、お楽しみください!

与えられた課題の説明

今回の課題は、Udemyで提供されている講座『【世界で18万人が受講】実践Python データサイエンス』を履修し、その内容を受けてkaggleの入門者向けコンペであるtitanicの生存者を予測することです。
環境としてはMac上でAnacondaを用いて、Python3系のJupyter Notebookで勉強していきます。

記事の概要

記念すべき初回となるこの記事では、分析やコンペのために利用した手法やデータ、結果などを書く予定でした。しかし、今回の記事は当初の思惑と違う内容になってしまいました。実際のデータ分析には立ち入らず、環境構築について、それもエラー対処中心に書いていきたいと思います!

本当なら、利用した手法やデータの見方など、そういう話を書ければいいな〜と思いながら作業を進めていたのですが……。

環境構築といえば、初心者にとって最大の難関と呼ばれることもありますが、しっかりハマるとは。正直メチャクチャに間抜けなスタートを切りました!結構落ち込んだりもしたのですが、どうやらこの失敗にも傾向がありそうです。
そこで、今回はこの場を借りて整理して、次につながるような行動指針にしたいなあと思っています。
技術系記事、という点からは微妙によろしくないかと思いますが、もう少しソフトなノウハウの部分を共有することができれば、と思っています。

 

まず今回の問題点は大きく二つ。

  1. うっかりミスが積み重なったこと。
  2. 参照しやすい形で記録を取っていなかったこと。

このうち、2の記録を取らなかったことが非常に大きな問題でした。
なぜなら、1のミスの原因追求の際、どこから手をつけていいか分からなくなったからです。その結果、必要以上に右往左往してしまいました。
また、この後のミスに気づく経緯については、「たしかこうだった気がする……」という推測のもとに書いてある部分が結構あります。これに限らず、細かいエラー処理は無数に行ないました。それらについては省略しています。
記事の最後の部分では、こういったスタンスについても反省の意を書いてみました。

分析手法とパッケージ

さて、Pythonを用いたデータ分析や機械学習では、主にpandasやNumPyを用い、適宜Jupyter Notebook上で可視化を行いながら分析を実施していきます。その際には、Matplotlibなどを用いて、いわゆる棒グラフなどの形で可視化を行います。
これまで、大学ではExcelの可視化とRによる分析を組み合わせながらデータ分析を行っていました。このやり方であれば、ローデータを眺めるだけでも、どのような欠損値があるかわかるため便利でした。しかし今回は、pandasのデータフレームを利用することに慣れるため、様々なパッケージをインストールしていきました。
ここで、インストール方法には、condaとpipの二種類のやり方があります。
Condaとは、anacondaという仮想環境にパッケージをインストールする方法です。

$ conda install ***

などのコマンドで実行されます。
一方で、pipインストールという方法も一般的です。こちらはanacondaの仮想環境を前提とせず、同様にインストールすることができます。
コマンドとしては、condaの部分をそのままpipに変更したものです。とくに、python3系の環境では、pipではなくpip3コマンドを用います。

$ pip3 install ***

たまにcondaでは対応していないパッケージが存在するため、このように代替案としてpipを用いることが一般的です。
ところが僕の環境では、実際にパッケージのインストールを行なっていると、condaがしばしば使えないことに気づきます。
実は、このときから一連の不具合は起き始めていた可能性があります。ここで立ち止まることが出来ていれば、もう少しラクだったのにな、という気持ちも、若干あるような…

titanicのデータ前処理

この調子で進もう、ということで、titanicのデータを前処理するため、いくつかのパッケージをインストールしながら進んでいきます。

サクサクとはいかないものの、「このやり方ならどうか」と試行錯誤しつつ実施。

前処理のために用意されたパッケージなどを使えばもっとラクかな、など、色々と準備しながら実施していきます。ここまでは、それなりに順調でした。

エラー発生

さて、予測モデルの構築に入りました。
ここで、Udemyの講座では機械学習モデルの導入の全てが教えられるわけではありません。とくに、titanicはデータの可視化の例として教材化されており、予測のためのサンプルなどはないため、前処理などは自分で行う必要があります。
したがって、自分で分析したいような手法をインターネット上の記事をQiitaなどで探しながら作業を進めていきました。この手法か、次はあの手法か、などと様々なパッケージをインストールしながら、すすめていきます。
しかし、あるとき、様々な分析手法を試すためにimportを試していると、次のようなエラーが出ました。

DLL load failed: 指定されたモジュールが見つかりません。

Pythonに限らず、これまで経験した環境のいずれにおいても見たことのないエラーに、直感的にヤバイと感じます。やらかしです。
不安になったため少し遡り、先ほどまで実施できていた部分をやり直してみると、こちらもエラーに。エラーがあまりにも多すぎて、どこでなにが起きているのかさっぱりつかめません……。

エラー対処

以降、この記事ではエラーに関する記述が続きます。
うかつなことにちゃんとログを取らずにこれらの対処を進めてしまいました。
今回、記事に起こすにあたっては、仕方ないので断片的な記憶から再構成し、大きなエラー対処に絞って掲載し、考察しています。

まず、いろいろ調べてみると、condaが動かないパターンとして、condaにpathが通っていないパターンがあるとのこと。
pathとは、コンピュータ上のプログラムがどこにあるか、を示す場所のことです。
この場所を指して、普段様々なファイルを実行するものです。


さて、ではpathを通すとはどういうことかというと、アプリケーションが開くべきプログラムの場所を、アプリケーションに指定してあげることです。これはBashなどのシェルスクリプトによる記述によって、制御されています。シェルスクリプトとはコマンド言語のひとつで、プログラムが自動的に読み込む設定ファイルのことです。この設定ファイルのうち、Anacondaのpathを制御しているのは、bash_profileというファイルになります。
したがって、今回はbash_profileを書き換えることによって、Anacondaにcondaを使えるようにしたい、ということになります。
ここではvimというテキストエディタを用いて、bash_profileを書き換えます。

bash_profileはロックされた隠しファイルであり、通常の手順だと書き換えるのに手間がかかるため、このような手段をとるようです。
余談ですが、このvimというアプリケーションは非常に不思議な操作方法のエディタで、ほとんどの操作をキーボード上で扱うことができます。カーソルを動かすのも、矢印のキーを押すのではなく、通常の文字入力をすることで移動することができます。(「左へ移動する:h」や、「上へ移動する:j」など)慣れれば使いやすいということですが、この作業をしている際には意味がわからず、おっかなびっくり編集するだけです。
ここでは、bash_profileに

export PATH=/Users/yanagisawa/opt/anaconda3/bin:$PATH

の記述を付け足すことで、Anacondaへのpathを通しました。

 

混乱

しかし、いざAnacondaを起動してみると、やはりcondaが通りません。
そもそも、condaが通らない場合への対処であって、それ以外のエラーが起きている原因もこれでは説明出来ないことになります。
このままでは他のエラー対処と同様、時間の無駄になるなと思っていたとき、ふと、Anacondaの構成を確認してみようと思い、検索バーからAnacondaを検索しました。

 

f:id:swyn_persol:20200706175134p:plain

に、二匹おる(再現画像)


ここで、ほんの少し残っていた冷静さが消滅した記憶があります。
「……これ、どっちから起動してたんだろう……」
この場合、bash_profileで通したpathが、先ほどまで起動していたAnaconda のものなのかもわかりません。
そうすると、もしやこのAnaconda同士が競合しているのか、という疑惑が起こります。しかし、試行錯誤してみましたが、どうにもわからないことが多く、だんだん途方に暮れ始めました。いくらか悩んだ結果、最終的に、どちらもアンインストールすることに決めました。

ちなみに、なぜ二匹いたのか、という疑問ですが、どうやらインストール時のミスのようでした。
思い返すと、最初のインストールの際に「つぎへ」を連打していたところ、不具合が起きてインストールが失敗し、改めてインストールしたのを覚えています。
最初のインストール場所が、HD直下になっていた記憶があります。(ユーザー直下にインストールできないとの表示も)

f:id:swyn_persol:20200706175258p:plain

通常のインストール画面

このインストールのエラーと今回の事象には直接の関係がなかった、とも考えられますが、異なるPython環境が(同じバージョンとはいえ)共存している状況であれば、遅かれ早かれ不具合も起きると考えられます。今回早めに気づくことができたのは、一種の怪我の功名のようなものと思っておくことにします。

さて、ここでPython環境を綺麗にするのにも、少々手間取りました。本来、Anacondaのアンインストールは、condaコマンドを利用してアンインストールするのが最も良いとされています。
Anacondaなどのアプリケーションを通常のゴミ箱などの手段で削除する場合、バックグラウンドに常に動き続けているファイルを削除することができません。したがって、再インストールした際にまた別の不具合の原因になることが考えられます。
しかし、ここまで盛大に環境が壊れているとなれば、今回は通常通りの削除を行うことに。

その結果、新しくインストールしたAnaconda環境では、これまで通り課題を実施することができるようになりました。
ここでは簡単に書いておりますが、想像以上に右往左往した結果、ようやく再開することが出来ました。
結果だけ見ればものすごく簡単な話で、結局再インストールで解決してしまいましたが、これがずっと使い続けた環境で発生していたらと考えると、かなりうんざりすること間違いなしです。おそらくこれまで使っていたパッケージなどを入れていくだけでもそうとう煩雑な作業になることでしょう。
ものすごく面倒くさかった。なんともエンジンのかからない始まり方をしてしまったのが、僕の成長日記の初回ということになります。

原因は?

さて、では今回の原因はなんだったのかというと、pipとcondaの競合によりPython環境が壊れたことだと思われます。推測でしか語れないのは、アンインストールしたあとであるうえ、記録もろくに残っていないためです。ただし、今回問題複雑にしたのは、なんともいえない二匹のAnacondaです。これがあるために、余計に混乱してしまいました。
問題が発生した直接的な原因は、pipによってインストールしたパッケージが、すでにcondaでインストールされていて、上書きしてしまった、というものと考えられます。
では、この事態を招いた行動がなんだったかといえば、「無秩序に様々なやり方を試し過ぎた」の一言につきます。
インターネット上にある記事をそのままコピペしてそのまま実行する、というマインドだったために、Pythonのコードだけでなくインストールのコマンドまでダブって行なってしまったものと考えられます。
インターネット上の記事を鵜呑みにするのは危険だと言いますが、滅茶苦茶しょぼい失敗から、それを身に染みて理解したのでした。


考察


今回起こった事態を考察しようとすると、複数の点で謎な部分が残りました。
まず、pathが通っていないのでは、という推測をするのは、本来間違いであること。condaによるこの不具合が起きるのは、はじめて使い始めたタイミングなどで発生するものであるはずで、少々奇妙です。
ここで、現在のbash_profileを参照したものが次です。

# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$('/opt/anaconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
eval "$__conda_setup"
else
if [ -f "/opt/anaconda3/etc/profile.d/conda.sh" ]; then
. "/opt/anaconda3/etc/profile.d/conda.sh"
else
export PATH="/opt/anaconda3/bin:$PATH"
fi
fi
unset __conda_setup
# <<< conda initialize <<<

この記述は、どのようなAnacondaに対してもインストールした段階では同一のものが与えられると考えられます。
これらのうち、

export PATH="/opt/anaconda3/bin:$PATH" 

がcondaを利用する際に必要なpathですが、ここが絶対パスではなく相対パスであることが問題の中心だった可能性があります。
絶対パスの場合は、次のように記述します。

export PATH=/Users/yanagisawa/opt/anaconda3/bin:$PATH

つまり、最初期のパッケージインストールの際に抱いた「ときどき使えない」という感想についても、別のAnacondaのbinを参照することがあったから、と考えられます。
……本当か? という気持ちでいっぱいですが、基本的に振り返ることが出来ないため、完全に推測の域を出ません。

結局のところ、二つのAnacondaが共存していた状態は、たしかに、直接的には、環境の破壊に関係していなかったことになります。
しかし、condaがときどき使用不能になることがpipインストールを多用するきっかけになり、それが見事に環境を壊したのだとすれば、やはり遠因では、と感じます。
それどころか、エラーが発生して気が付くより前から、すでに競合を起こしていて、ずっとギリギリの状態でAnacondaを動かしていたのかもしれません。

真相は闇の中ですが……。


教訓:後からトレースできるようにしよう

Why 何が原因だったかわからなくなってしまう!!

今回のエラーは、発生した瞬間には、ものすごく理不尽に感じました。しかし、よくよく思い返せば、強烈にアホなミスを複数やらかすという、嫌な現実が見えてきます。こればかりは、記録に対する意識の低さが引き金になっているため、絶対直す必要があります。
また、原因究明してみよう、と思ったときのハードルがハンパなく高いです。こちらも非常に要注意です。誰かに相談するうえでも当然ですし、今回のように原因を考察する場合にはとんでもなく労力がかかります。手間という面でもそうですし、精神的にも。自分のひどい思考過程に対して活字にするという、非常に負荷の高いメタ認知になりました……。


How 再発防止策を講じましょう。


1.記録


まずはこれにつきます。
エラーが起きた際には、エラーの痕跡をガンガン消してしまいがちでした。これは綺麗な作業環境を維持したいから、だと思われます。
しかし、何が起きたか、を多少煩雑でも記録できるようにしていきたいです。
たとえば、バージョン違いを逐一保存することや、参考にした手法を必ず控えておくことなど、です。


2.自分の中での方法に対する優先順位づけや、特別な場合に対応する際の意識づけ。


今回、もっとも直接的な原因は、pipインストールとcondaインストールの混在にあります。
これが発生した理由は、どっちの手法も使っていい、という認識ゆえです。冷静に考えれば、全く問題なく互換性があるというのは甘い発想でした。
pipとcondaの競合にしろ、調べれば簡単にわかる内容の不具合でした。
こういった情報を事前にある程度仕入れることが必要です。また、手法には自分の中で優先順位をつけることが必要かな、と思います。


締め

まさか初回の記事で分析の話に一切触れられず、トラブルシューティング(しかもググって出てきても使えない類)だけを書いていくことになるとは。
「環境構築は最難関」とみなさんには言ってもらえましたが、なんのことはない、原因追ってみれば普通に全部僕がアホなのが原因では? 心を抉られながら、ようやくtitanicの分析を行うことができました。
次回は分析の要点や手法の比較に絞ってお伝えしていきます。

f:id:swyn_persol:20200717130035p:plain



柳澤 寛光 Hiromitsu Yanagisawa

デジタルテクノロジー統括部 データ&テクノロジー ソリューション部 アナリティクスグループ

※2020年7月現在の情報です。