機械学習の学習環境を整える ｰ 仮想環境構築とVisualStudioCode設定編

# 環境
<dl>
  <dt>OS</dt>
  <dd>macOS Mojave 10.14.3</dd>
  <dt>言語</dt>
  <dd>Python 3.7.2</dd>
  <dt>エディタ</dt>
  <dd>Visual Studio Code（Pythonプラグインインストール済み）</dd>
</dl>

# 前提条件
Python3はHomebrewで直接インストールしておりpyenvは未導入です。

```shell
brew install python3
python3 --version
Python 3.7.2
which python3
/usr/local/bin/python3
```

# 仮想環境の導入
システムのPython環境にはLinterおよびFormatterのみ導入して、機械学習用ライブラリは仮想環境にインストールします。

```shell
pip3 install flake8
pip3 install yapf
```
## 仮想環境構築に利用するツール候補
### venv
Python3.3から標準で組み込まれている仮想環境ツールです。
公式ツールというだけでメリットな気もしますが、3.3以降でないと利用できない、production･developmentなど環境ごとに導入パッケージを分けることができないなどのデメリットがあります。
※デメリットの後者は少し自信なしです。ツッコミがあればお願いします。
### pipenv
[pypa/pipenv](https://github.com/pypa/pipenv)
仮想環境ツールとpipの機能が統合されたツールで、RubyのbundlerやJavaScriptのnpmに近いイメージで利用できます。venvのrequirements.txtによるパッケージ管理は[問題を抱えるケース](https://www.kennethreitz.org/essays/a-better-pip-workflow)もあるらしく代わりにPipfileとPipfile.lockを用いてパッケージを管理します。パッケージの依存関係についてもvenvより詳細なグラフ表示による確認が可能です。
### Anaconda
データサイエンス向けのPythonパッケージプラットフォームです。仮想環境とパッケージの管理に専用のCondaコマンドを用いてAnaconda専用のリポジトリからパッケージを取得し、他言語のライブラリやユーティリティなども一元的に提供されます。
### docker
docker上に構築した環境に[ptvsd](https://pypi.org/project/ptvsd/)を用いてリモートデバッグする方法ですが、機械学習の学習にあたっては特にメリットを感じなかったので見送りました。DjangoやFlaskでWebアプリを作ってdocker化する、機械学習モデルのデプロイ時に利用するなどであればメリットがあるのかもしれません（正直なところこのあたりはまだ知見が全くありません）。

## pipenvの導入
機械学習の学習だけを手っ取り早くやりたいのであればAnacondaが最適な気もしましたが、アンコントローラブルなところがあまり好みではなく、メリットの手っ取り早さに頼る理由もないので見送りました。またvenvで十分かなという気もしたのですが、せっかくなら他にも応用がききそうなpipenvを、ということで早速導入していきます。

### インストール
Homebrewでインストールします。

```shell
brew install pipenv
```

### 環境変数
デフォルトの設定では仮想環境がプロジェクト配下ではなくシステム領域に作成されるため、シェルの設定ファイルに以下を追記します。

```Shell
export PIPENV_VENV_IN_PROJECT=true
```

## プロジェクトの作成
### プロジェクト専用仮想環境の作成
プロジェクトディレクトリを作成して仮想環境を作成します。
`pipenv --three`が仮想環境の作成コマンドです。オプションを`--two`にするとPython2系の環境が作成されます。任意のバージョンを指定することもでき、pyenvをインストールしていれば指定したバージョンを自動でインストールすることも可能です。プロジェクト配下に仮想環境を作成する設定にしているためプロジェクトディレクトリ以下の.venvディレクトリ内に仮想環境が作成されます。

```shell
mkdir sample_project
cd sample_project
pipenv --three
creating a virtualenv for this project…
Pipfile: /path/to/sample_project/Pipfile
Using /usr/local/bin/python3 (3.7.2) to create virtualenv…
⠼ Creating virtual environment...Using base prefix '/usr/local/Cellar/python/3.7.2_1/Frameworks/Python.framework/Versions/3.7'
New python executable in /path/to/sample_project/.venv/bin/python3.7
Also creating executable in /path/sample_project/.venv/bin/python
Installing setuptools, pip, wheel...
done.
Running virtualenv with interpreter /usr/local/bin/python3

✔ Successfully created virtual environment!
Virtualenv location: /path/to/sample_project/.venv
Creating a Pipfile for this project…
```

Pipfileも作成されています。

```shell
cat Pipfile
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]

[packages]

[requires]
python_version = "3.7"
```

インストール済みパッケージを確認してみます。仮想環境作成直後にインストール済みのパッケージは表示されないようです。

```shell
pipenv graph
(出力なし)
```

ついでなので仮想環境をアクティベートしてパッケージを確認してみます。最小限のパッケージのみ入っているようです。

```shell
pipenv shell
pip list
Package    Version
---------- -------
pip        19.0.2
setuptools 40.8.0
wheel      0.32.3
```

ちなみに仮想環境からは`exit`で抜けることができます。

### パッケージのインストール
試しにscikit-learnをインストールしてみます。

```shell
pipenv install scikit-learn
Installing scikit-learn…
Adding scikit-learn to Pipfile's [packages]…
✔ Installation Succeeded
Pipfile.lock not found, creating…
Locking [dev-packages] dependencies…
Locking [packages] dependencies…
✔ Success!
Updated Pipfile.lock (2f3a8c)!
Installing dependencies from Pipfile.lock (2f3a8c)…
  🐍   ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 3/3 — 00:00:00
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.
```

Pipfile.lockが作成されているのがわかります。
依存関係もみてみましょう。

```shell
pipenv graph
scikit-learn==0.20.2
  - numpy [required: >=1.8.2, installed: 1.16.1]
  - scipy [required: >=0.13.3, installed: 1.2.1]
    - numpy [required: >=1.8.2, installed: 1.16.1]
```

長くなりましたが仮想環境の導入はこれでひとまず完了です。
次にVisual Studio Codeの設定について確認していきます。

# Visual Studio Codeの設定
## LinterおよびFormatterの設定（お好みで）
システムのPython環境にインストールしたflake8とyapfを設定します。settingsを開いて`python lint` `python format`で検索して以下設定します。
<img width="662" alt="スクリーンショット 2019-02-11 13.48.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/250186/f78ab781-2737-a5e5-f0b5-9040137e371e.png">
<img width="662" alt="スクリーンショット 2019-02-11 13.49.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/250186/d3321a1c-8045-01f8-535e-fa3f158e4ade.png">

## 仮想環境ディレクトリの設定
同じくsettingsを開いて`python venv folder`で検索しVenv Foldersに以下設定します。

```config
"python.venvFolders": [".venv"]
```

## プロジェクトを開く
プロジェクトを開く前に適当にpythonファイルを作成しておきましょう。

```shell
touch sample.py
```

プロジェクトを開くと作成した仮想環境のインタプリタが選択されるはずです。
<img width="310" alt="スクリーンショット 2019-02-11 14.02.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/250186/ec78039a-4d8b-0566-79d9-7f71b3a31819.png">

# まとめ
Pipfile.lockからの環境構築手順などは今回の主題ではないので省きましたが、機械学習の学習にあたるための仮想環境構築という意味では必要十分な情報を整理できたかなと思います。あとはJupyter Notebookまわりでしょうか。また次回まとめていきたいと思います。