はじめに
PyCon JP 2019で「Anaconda環境運用TIPS」という15分のトークをします。
ドキュメントを当たったり、Anacondaの環境で実験したりして得た知見全てを15分のトークに収めることが難しかったので、別途記事にすることにしました。
正確性を重視したいので、誤った記載を見つけた場合は、コメントなどでご指摘いただけるとありがたいです。
##前提
この記事で扱うこと
- Pythonのインストール方法(Anaconda中心)
- AnacondaでPythonをインストールした場合のパッケージ管理方法の特徴
扱わないこと
- パッケージとは
- Anacondaの環境(base環境とは)
- condaコマンドの詳細な使い方(特に環境を分離する方法)
今後の更新や別記事でアップデート予定です。
おことわり
この記事を書く意図は、Anacondaをオススメすることではありません。
自分の中に蓄積されたAnacondaに関係する情報の整理が目的です。
また、書き手はPythonを使った開発でAnacondaを使っているわけではありません。
Pythonを教える中で、Anaconda環境の問題を何件か解決し、この記事に記載した認識に至りました。
(誤りがあるかもしれませんので、お気づきの点はお知らせください)
動作確認環境
- macOS 10.12.6
- conda 4.6.11
一部の検証にDockerイメージも使っています。
Pythonのインストール方法
Pythonには複数のインストール方法があります。
どういった方法があり、それぞれどのくらいの人が使っているかは、例えば、JetBrainsが調査したPython Developers Survey 2018 Resultsがあります(Python Installation and Upgradeという項目1)。
- 1位はOSごとに提供される方法(
apt-get
,yum
,brew
など)で38% - 2位はPython.orgで33%
- 3位がAnacondaで22%
また、2019年4月に「みんなのPython勉強会」で環境構築について話した際に参加者に挙手していただいたところ、AnacondaでPythonをインストールした方が半数で、Python.orgからインストールした方よりも多かったと記憶しています。
というわけで、ここでは、Pythonをインストールする際に、Anacondaという選択肢を選ぶ人が増えていることを確認しました。2
AnacondaでPythonをインストールする際の特徴
では、AnacondaでPythonをインストールした場合、他の方法と何が違うのでしょうか。
大きな特徴は、Pythonをインストールするだけでなく、科学計算に使うパッケージも合わせてインストールする3ということです。
Python.orgやbrew
やapt
でPythonをインストールする場合、科学計算に使うパッケージを別途インストールする必要があります。
科学計算に使うパッケージ(numpy, scipy, pandas)が合わせてインストールされている例を見てみましょう。
AnacondaをインストールしたmacOSのターミナルでPythonを対話モードで起動します。
(base) $ python
Python 3.7.3 (default, Mar 27 2019, 16:54:48)
[Clang 4.0.1 (tags/RELEASE_401/final)] :: Anaconda, Inc. on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy, scipy, pandas
>>>
科学計算のパッケージに関連して、Anacondaでは機械学習のパッケージ(例:tensorflow)もインストールしやすいという特徴があります。
(macOSやLinuxを使った経験では、Python.orgからインストールしたPythonでも環境構築できました。私が未経験のWindowsでは苦労があるのかもしれません)
他の特徴として、Anacondaはクロスプラットフォームであり、Windows・macOS・Linuxいずれでも動作する4という点も挙げられます。
これはbrew
やapt
などOSごとに提供される方法でPythonをインストールする選択肢とは対照的ですね。
conda
コマンド
Anacondaにおけるパッケージ管理はconda
というコマンドで行われます。
AnacondaにおいてはPythonもパッケージとして扱われるため、Pythonのバージョンも管理5できます(脚注4のリンク参照)。
AnacondaでPythonを導入するとbaseという名前の環境ができます。
そこに含まれるパッケージの一覧をconda list
で表示してみましょう。
(base) $ conda list
# Name Version Build Channel
numpy 1.16.2 py37hacdab7b_0
pandas 0.24.2 py37h0a44026_0
python 3.7.3 h359304d_0
scipy 1.2.1 py37h1410ff5_0
200行を超える出力があるため、上では一部を抜粋しました。
AnacondaでPythonをインストールすると、200を超えるパッケージもすぐに使える状態というわけです。
Anacondaを使わずにPythonをインストールした場合、conda
コマンドは使えず、pip
というコマンドでパッケージを管理します。
混乱を招きやすいのですが、pip
コマンドはAnacondaでも使うことができます(この点については理解して使っていただきたいため、詳細を後述します)
conda |
pip |
|
---|---|---|
Anaconda | ◯(オススメしたい) | △(使える) |
Anaconda以外 | ☓(使えない) | ◯(オススメしたい) |
なぜAnacondaが登場したか
Anacondaが登場した背景として、科学計算に用いるパッケージにはバイナリモジュールに依存するものがあり、pip
コマンドでインストールすることが難しい6ことがあったそうです。
このあたりの状況は改善してきている7と認識していますが、科学計算のパッケージのインストールのしにくさという問題により、今後もAnacondaは1つの選択肢として残り続けるのではないかと私自身は考えています。
conda
とpip
の違い
上ではconda
ではPythonのバージョンを管理できるが、pip
ではできないという違いを見ました。
実はこの点よりも重要な違いがあります。
それは、**配布されたパッケージをインストールする際の参照先のサイト(リポジトリ)**が異なるということです。
conda
でもpip
でも、配布されたパッケージ(アーカイブされたファイル)をインターネット経由でダウンロードし、手元の環境にインストールします8。
pip
でパッケージをインストールする場合は、デフォルトでPyPI(Python Package Index)にあるパッケージを参照します。
一方、conda
でパッケージをインストールする場合、デフォルトではAnaconda社が管理するリポジトリ(repo.anaconda.com)を参照します9。
PyPIは開発者に公開されており、誰でもPythonのパッケージを配布するために利用できます。
そのため、大量の多岐に渡るパッケージが集まっています。
一方、Anaconda社のリポジトリは、開発者に公開されているわけではありません。
Anaconda社が管理しているため、PyPIに比べてパッケージはずっと少ないです。
また、PyPIにある最新版が必ずあるとは限りません。
この点への対応として、コミュニティが運営するconda-forgeなどのリポジトリからconda
コマンドでパッケージをインストールする方法が案内されています10。
ここまで、conda
の場合もpip
の場合もパッケージという同じ言葉を使ってきましたが、実はconda
とpip
とでパッケージの形式は異なります11。
conda
とpip
は混ぜられる?
Anacondaは導入がしやすい反面、パッケージのリポジトリという点でやや苦労するという印象を私は持っています。
対応として、conda-forgeを紹介しましたが、conda
コマンドのドキュメントでは、conda-forgeで対応できない場合、pip
を
使うことが案内されています12。
この記載を見て、「condaとpip:混ぜるな危険」という2018年2月のエントリを思い出す方もいるでしょう。
「conda
とpip
を混ぜていいの?」と。
ドキュメントの記載によれば、conda
の4.6以降ではconda
とpip
が混ぜられる13ようです。
しかしながら、環境によっては壊れてしまうこともあるようなので、この記事の初公開の段階では積極的にオススメはしません。
(このあたり登壇当日までに結論を出し、アップデートします)
(前略) conda now understands pip metadata more intelligently.
(注)リンク先には以下の2つが記載されており、ここで紹介しているのは後者の方です。
- experimentalな機能:
.condarc
(conda
の設定ファイルの編集) -
conda
がpip
のメタデータに対応した話
後述の実験結果から、後者の機能はexperimentalの機能とは別に有効になっていると考えています。
(注 終わり)
Dockerイメージcontinuumio/anaconda3のタグ2019.07を用いて実験してみました。
- base環境に入っていないtensorflowのバージョン1.13.1を
conda install tensorflow=1.13.1
でインストール -
pip install -U tensorflow
で最新のバージョン1.14.0にアップデート - 対話モードやJuputer Notebookでtensorflowがimportできることを確認
Dockerイメージを用いた検証では、無事importできました。
しかしながら、macOSにてbaseと同様の環境を作って検証をしたところ、3に失敗する結果となりました。
(「Illegal instruction: 4」と表示されて対話モードが終了します。JuputerではKernelがRestartします)
ドキュメント上はconda
とpip
が混ぜられると記載されていますが、混ぜることで環境を壊さない可能性が絶対にないとは言えないという認識でいます。
そこで、Anacondaを使っている場合のパッケージ管理(暫定版)は
- まずAnaconda社のリポジトリやconda-forgeを検索
- 1で見つからない場合は、リスク承知でPyPIからインストール
という手順になりそうです。
そして、Anaconda社のリポジトリやconda-forgeからインストールしたパッケージのアップデートはconda
コマンドを使うことで、環境を壊すリスクは低減されると考えています。
環境が壊れるリスクを抑える別の方法としては、Anacondaの環境を開発ごとに分離して使うことを私はオススメしたいです。
分離してあれば、ある環境が壊れたとしてもAnaconda自体の再インストールは発生しないと考えています。
Anacondaを使った場合の環境の切り分けについては、PyCon JP当日のトーク(または別の記事で)お伝えします。
-
%の合計が100を超えるので、複数回答と考えています ↩
-
この理由について、JetBrainsの調査は「Pythonを使う他の種類の開発よりもデータサイエンスの人気が増していることを示している」と述べています。また、私の推測ですが、国内では毎月のように機械学習の入門書(やPythonの入門書)が刊行されており、そこでAnacondaが紹介されることが多いという理由もありそうです。後の節で触れますが、インストールする手順が簡単というのは著者にとって魅力なのでしょう。 ↩
-
https://docs.python.org/ja/3/using/windows.html#alternative-bundles ↩
-
https://packaging.python.org/guides/installing-scientific-packages/#the-conda-cross-platform-package-manager ↩
-
Pythonのバージョン管理は後述の
pip
ではできません ↩ -
https://docs.python.org/ja/3/installing/index.html#install-scientific-python-packages ↩
-
numpy 1.10.4やscipy1.0.0以降はメジャーなOS向けにwheelフォーマットでパッケージがリリースされているそうですが、Windowsでは最適化された線形代数演算の性能が出ない可能性があるそうです ref:https://packaging.python.org/guides/installing-scientific-packages/ ↩
-
Distribution Packageの用語説明をもとにしています ↩
-
https://docs.conda.io/projects/conda/en/latest/user-guide/concepts/channels.html (ドキュメント上ではリポジトリのことをチャンネルと呼んでいるようです) ↩
-
ref:
conda
で扱うパッケージ、pip
で扱うパッケージ ↩ -
https://docs.conda.io/projects/conda/en/latest/user-guide/concepts/channels.html#conda-channels ↩
-
https://docs.conda.io/projects/conda/en/latest/user-guide/configuration/pip-interoperability.html ↩