python環境が壊れた(おそらくcondaとpipの競合が原因)

pythonの処理系が壊れて、動かなくなってしまった。何をやったらどう壊れたのかは以下に詳述する。

(色々いじったあとの最終的な)環境

PS C:\> anaconda --version
anaconda-script.py Command line client (version 1.6.0)
PS C:\> conda --version
conda 4.5.11
PS C:\> python --version
Python 3.6.7 :: Anaconda, Inc.

OSは windows 7 64bit。

注意事項

正確な経緯を記録していないので、以下の記述には不正確な部分があると思います。
また最終的に環境が破壊されたことに注意してください(つまり、このページに書いてあることを実行しても、問題が解決するとは限りません)

shapをインストールした→scikit-learnのインポートに失敗

前の記事でSHAP valueについての解説を書いた。

linus-mk.hatenablog.com

せっかくなら、簡単なデータを入力して実際に試してみようと思って、以下のコマンドを実行してshapのライブラリをインストールした。

conda install -c conda-forge shap

これが全ての元凶であるとは知る由もなかった。
そして試しにプログラムを動かそうとすると、なんだか挙動がおかしい。scikit-learnが動かない。

import sklearn と書くと

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

というエラーが出るようになってしまった。

condaのupdateに失敗

この現象は上記のscikit-learn失敗と関係があるのか無いのか不明。
condaでライブラリをインストールしようとすると
「"conda update -n base conda"を実行してcondaをアップデートしろ」という旨の警告が出るんだけど、
そのコマンドを実際に実行してもcondaはアップデートされず、同じ警告が出続けるという謎の現象が起きた。警告文は以下の通り。

Please update conda by running
$ conda update -n base conda

検索して見つけた、https://github.com/conda/conda/issues/6591 などのページには

conda update -n base -c defaults conda

を実行すればOKと書いてあるけど、実際にはこのコマンドを打っても状況は変わらなかった。

conda update --all →jupyter起動失敗

conda update --allを実行して、全てのライブラリが更新されたというメッセージが表示された、と思う。
しかしその後からjupyter notebookが起動しなくなった。起動しても以下のエラーメッセージが表示される。

AttributeError: type object 'IOLoop' has no attribute 'initialized'  

エラーメッセージで検索して以下のページを発見。
怖いものなんてない!!: Jupyter Notebookを起動するとAttributeError: type object 'IOLoop' has no attribute 'initialized'とエラーが出る
AttributeError: type object ‘IOLoop’ has no attribute ‘initialized’の解決 – LilPacy.info

pyzmqとtornadoのバージョンが競合しているらしいので、
tornadoのアンインストール・再インストール(バージョンを4系にする)か、pyzmqのアップグレードか、どちらかかなと思った。
簡単な方のpyzmqのアップグレードからやってみることにした。

pyzmqアップデート

conda upgrade pyzmq
pyzmq:     16.0.2-py36_0     --> 17.1.2-py36hfa6e2cd_0

これでも動かなかったので、tornadoのアンインストール・再インストール。

tornadoアンインストール・再度インストール→jupyter kernel再起動

再インストールまでやってみたが、jupyterの調子が相変わらずおかしい。
何らかのライブラリをimportするコードを書いて実行すると、下記のメッセージがブラウザ上に出て、kernelが再起動する。

Kernel Restarting
The kernel appears to have died. It will restart automatically.

ここまで色々やってきて、これはもう直る見込みがないのではと諦めた。
(最初の環境はこの時点でのものである)

原因はcondaとpipの競合っぽい

いろいろ調べたけど、Anacoda内のパッケージ管理ツールであるcondaと、python標準のパッケージ管理ツールであるpipを混ぜて使うと
ライブラリの依存関係がおかしくなって危険らしい。
condaは独自の仕組みでパッケージをインストールするので、pipとは互換性が無いのだ。

この辺を参照。
condaとpip:混ぜるな危険 - onoz000’s blog
wheelのありがたさとAnacondaへの要望 - YAMAGUCHI::weblog
【python】scikit-learnのImportErrorが出たのでAnacondaを再インストールした(泣く) - 僕の世界観を変えてみる

既に構築済みの自分のconda環境でpipとcondaの衝突があるか確かめたい場合は、conda listを実行する。同じパッケージがpip経由とconda経由で入っている場合重複して表示される。何かがおかしくなっている可能性が高い。

condaとpip:混ぜるな危険 - onoz000’s blog

と書いてある。 実際にconda listを実行してみると、確かに同じパッケージがpipとcondaで二重に入っていた。
conda listを実行した出力は200行以上になったので、一部を抜き出して書いておく。pipと書いてあるもの、pipとcondaでダブっているものだけを下記に記載する。

# packages in environment at D:\Code\Anaconda3:
#
# Name                    Version                   Build  Channel
awscli                    1.11.158                  <pip>
botocore                  1.7.16                    <pip>
chainer                   4.1.0                     <pip>
easydict                  1.7                       <pip>
filelock                  3.0.4                     <pip>
jmespath                  0.9.3                     <pip>
mock                      2.0.0                     <pip>
numpy                     1.15.3           py36ha559c80_0  
numpy                     1.14.5                    <pip>
numpy-base                1.15.3           py36h8128ebf_0  
pbr                       4.0.0                     <pip>
protobuf                  3.6.0            py36he025d50_0  
protobuf                  3.6.0                     <pip>
rsa                       3.4.2                     <pip>
s3transfer                0.1.11                    <pip>
setuptools                39.2.0                    <pip>
setuptools                40.4.3                   py36_0  
six                       1.11.0                   py36_1  
six                       1.11.0                    <pip>

おそらく、chainerは公式ドキュメントを見てうっかりpipで入れたんだろうと思う。あとはよく覚えていない。numpyは二重に入ってしまっているようだ。

Anacondaをアンインストールした

環境を再構築するために、まずはAnacondaをアンインストールすることにした。
Anacondaは低品質のWeb記事が出回っているっていう話も見かけたし、ちゃんと公式ドキュメントを見て作業するか」と思い、公式ドキュメントの以下のページを参考にした。
Uninstalling Anaconda — Anaconda 2.0 documentation

とはいえ、作業自体は単純なものだ。
コントロールパネルを開いて「プログラムと機能」に進む。
Python 3.6.0 (Anaconda3 4.3.1 64-bit)を選択してアンインストールを実行した。
膨大なライブラリ群を全て削除する必要があるので、アンインストール完了まで10分程度の時間がかかった。

Anacondaは止めて……とは言え、この辺のページを見ていたら、パッケージの管理ツールって色々な種類があるらしい。
Pythonの環境管理ツール良し悪し - Zopfcode
Pythonの仮想環境構築(2017年版) pyenvとpyenv-virtualenvとvirtualenvとvirtualenvwrapperとpyvenvとvenv - Qiita
pyenvが必要かどうかフローチャート - Qiita
Pythonの環境構築を自分なりに整理してみる – Aki Ariga – Medium

  • virtualenv
  • venv
  • pyenv
  • pipenv
  • pyenv-virtualenv
  • virtualenvwapper
  • pyvenv

おいおい。種類ありすぎだよ。慣れてない人には難しすぎるわ!
でも単純に機械学習の勉強をするだけなら、環境を隔離して新たに作らなくても、ベースになる環境にnumpyとかmatplotlibとかを直接入れていけばいい気がする。
ちょっとどうするか考えよう……