Python

scikit-learn環境の作成(Windows編)

scikit-learnはPythonの機械学習ライブラリで、簡単に機械学習を試せるので便利です。しかし、scikit-learnはNumPyやSciPyなど複数の外部パッケージに依存しているため、利用している環境によってはエラーが発生する場合があります。(特にWindows環境)

2018/12/29時点でのscikit-learnの問題点

2018/12/29時点でscikit-learnの最新バージョンは「0.20.2」ですが、「scikit-learn 0.20.2」が依存するパッケージの中に「mkl 2019.1」が含まれています。この組み合わせは、Mac上では問題ないのですが、Windows上ではmkl_intel_thread.dllに関するエラーが発生して動作しません。(将来のバージョンアップで解決されるとは思いますが…)

mklのバージョンも2018.0.2、2018.0.3、2019.0、2019.1…と複数存在しますが、Windows版のscikit-learnとの組み合わせで動作する最上位バージョンは「2018.0.2」になります。それ以降の「2018.0.3、2019.0、2019.1」では正しく動作しません。

2018/12/30追記(手順③の追加)

改めてscikit-learnの最新バージョンで仮想環境を作成すると、パッケージ導入時にmklに関するサイズ不一致の警告(SafetyError)は表示されるものの、mkl 2019.1との組み合わせてもscikit-learnが利用できるようになっていました。動作していなかったときの仮想環境は残っていないので動くようになった詳細な原因は不明(何かパッケージが更新された?)ですが、最新の導入方法③として以下に手順を追加しておきます。

Anaconda 2018.12にはデフォルトで「scikit-learn 0.20.1」と「mkl 2019.1」が含まれていますが、この組み合わせではWindows上で正しく動作しません。よって、以下に示す方法でscikit-learn用の環境を作成する必要があります。

Windows上でscikit-learnを利用するには、以下のどちらかの方法でscikit-learnの環境を作成する必要があります。

  1. Windows上でも正しく動作する古いscikit-learnを使う
    少し古いscikit-learnを利用する事になりますが、正式な依存関係に基づいたパッケージ構成を使用するので、動作保証の観点では安心できます。
  2. 最新のscikit-learnを使い、問題のあるmklだけを強制的に入れ替える
    最新のscikit-learnを利用できますが、定義されている依存関係を無視してmklだけを入れ替えるので、動作保証はありません。自己責任の下で試すことになります。
  3. 推奨:最新のscikit-learnを使って環境を構築する(2018/12/30追記)
    パッケージインストール時にmklに関するサイズ不一致の警告は表示されますが、最新パッケージの組み合わせて正しく動作するようになりました。今後は特別なことが無い限り、この③の手順でscikit-learnの環境作成を推奨します。

それぞれの導入方法について以下にまとめておきます。
どちらにもメリット/デメリットがあるので、目的に応じて使い分けてください。
→2018/12/30以降は、③の方法を推奨します。

 

対象環境

scikit-learnを導入したときの環境は以下の通りです。AnacondaやPythonのバージョンが少し違っていたとしても、condaでscikit-learn専用の仮想環境を構築するので問題無いと思います。

  • Windows 10 Pro (64bit)
  • Anaconda 2018.12 Python 3.7 version (64bit)

安易に conda update --all で全パッケージをアップデートしてしまうと、パッケージのバージョンが変わって環境を壊してしまう可能性があります。パッケージ間の依存関係はバージョンを含めて管理されているので大抵は大丈夫なのですが、依存設定にミスがあったりすると動かなくなってしまいます。そのため、全パッケージを無条件でアップデート…のような作業は避けた方が無難です。

 

①古いscikit-learnを利用する方法

この方法では「古いバージョンのscikit-learn 0.19.1」を導入します。
依存関係の影響で、利用するPythonや各パッケージも古いバージョンになりますが、組み合わせ上問題の無い「mkl 2018.0.2」が使用されることになるため、Windows上でも問題無く動作するようになります。

Anacondaのコマンドプロンプトを使って、以下の手順でscikit-learn用の仮想環境を作成します。利用するpython、mkl、scikit-learnのバージョンを指定する点がポイントになります。

> conda create -n sklearn python=3.6.7 mkl=2018.0.2 scikit-learn=0.19.1

 

これでscikit-learnを使うための最低限の仮想環境が作成できました。
導入されるパッケージは以下のようになります。

> conda activate sklearn
> conda list
# packages in environment at C:\Users\Kurozumi\Anaconda3\envs\sklearn:
#
# Name                    Version                   Build  Channel
blas                      1.0                         mkl
certifi                   2018.11.29               py36_0
icc_rt                    2019.0.0             h0cc432a_1
intel-openmp              2019.1                      144
mkl                       2018.0.2                      1
mkl_fft                   1.0.1            py36h452e1ab_0
mkl_random                1.0.1            py36h9258bd6_0
numpy                     1.14.3           py36h9fa60d3_1
numpy-base                1.14.3           py36h555522e_1
pip                       18.1                     py36_0
python                    3.6.7                h9f7ef89_2
scikit-learn              0.19.1           py36h53aea1b_0
scipy                     1.1.0            py36h672f292_0
setuptools                40.6.3                   py36_0
sqlite                    3.26.0               he774522_0
vc                        14.1                 h0510ff6_4
vs2015_runtime            14.15.26706          h3a45250_0
wheel                     0.32.3                   py36_0
wincertstore              0.2              py36h7fe50ca_0

 

②mklだけを入れ替える方法

最新のscikit-learn(0.20.2)を利用したい場合、パッケージの依存関係を無視してmklを強制的に「2018.0.2」のバージョンに差し替えます。正しく動作する保証は無いので自己責任になりますが、軽く試した感じでは正しく動作しています。

> conda create -n sklearn python=3.7 scikit-learn=0.20.2
> conda activate sklearn
> conda install -f --no-deps mkl=2018.0.2

 

これで、mklのバージョンだけが「2018.0.2」に差し替わりました。
導入されるパッケージは以下のようになります。

> conda activate sklearn
> conda list
# packages in environment at C:\Users\Kurozumi\Anaconda3\envs\test:
#
# Name                    Version                   Build  Channel
blas                      1.0                         mkl
ca-certificates           2018.03.07                    0
certifi                   2018.11.29               py37_0
icc_rt                    2019.0.0             h0cc432a_1
intel-openmp              2019.1                      144
mkl                       2018.0.2                      1
mkl_fft                   1.0.6            py37h6288b17_0
mkl_random                1.0.2            py37h343c172_0
numpy                     1.15.4           py37h19fb1c0_0
numpy-base                1.15.4           py37hc3f5095_0
openssl                   1.1.1a               he774522_0
pip                       18.1                     py37_0
python                    3.7.1                h8c8aaf0_6
scikit-learn              0.20.2           py37h343c172_0
scipy                     1.1.0            py37h29ff71c_2
setuptools                40.6.3                   py37_0
sqlite                    3.26.0               he774522_0
vc                        14.1                 h0510ff6_4
vs2015_runtime            14.15.26706          h3a45250_0
wheel                     0.32.3                   py37_0
wincertstore              0.2                      py37_0

 

③最新のセットを利用する方法(2018/12/30追加)

今まで最新バージョンを導入するとmkl_intel_thread.dllに関するエラーで動作していませんでしたが、2018/12/30時点で最新のパッケージを利用すると正しく動作することが確認できました。

> conda create -n sklearn python=3.7 scikit-learn=0.20.2

 

パッケージ導入の際にmklに関するサイズ不一致の警告(SafetyError)が表示されますが、問題無く動作するようです。
導入されるパッケージは以下のようになります。

> conda activate sklearn
> conda list
# packages in environment at C:\Users\Kurozumi\Anaconda3\envs\sklearn:
#
# Name                    Version                   Build  Channel
blas                      1.0                         mkl
ca-certificates           2018.03.07                    0
certifi                   2018.11.29               py37_0
icc_rt                    2019.0.0             h0cc432a_1
intel-openmp              2019.1                      144
mkl                       2019.1                      144
mkl_fft                   1.0.6            py37h6288b17_0
mkl_random                1.0.2            py37h343c172_0
numpy                     1.15.4           py37h19fb1c0_0
numpy-base                1.15.4           py37hc3f5095_0
openssl                   1.1.1a               he774522_0
pip                       18.1                     py37_0
python                    3.7.1                h8c8aaf0_6
scikit-learn              0.20.2           py37h343c172_0
scipy                     1.1.0            py37h29ff71c_2
setuptools                40.6.3                   py37_0
sqlite                    3.26.0               he774522_0
vc                        14.1                 h0510ff6_4
vs2015_runtime            14.15.26706          h3a45250_0
wheel                     0.32.3                   py37_0
wincertstore              0.2                      py37_0

 

 

mkl_intel_thread.dllのエラー対応

scikit-learnを使ったプログラムを実行すると、mkl_intel_thread.dllに関するエラーが表示される場合があります。原因はさまざまですが、以下の点を確認してみてください。

利用している仮想環境が間違っている

Pythonでは専用の仮想環境を作って開発することが多いため、scikit-learn用に作成した仮想環境に切り替えているか確認してみてください。コマンドラインであればconda activateコマンドで仮想環境を切り替えられます。IDEを利用している場合は、Anaconda3のenvsフォルダ配下に作成された仮想環境フォルダのpython.exeを利用する設定になっているか確認してみてください。

利用するパッケージのバージョンを確認

上記のscikit-learnの導入手順に書いたとおり、scikit-learnで利用可能なmklのバージョンが限られています。特に重要なのが、mklと共に導入されるmkl_intel_thread.dllなので、利用しているmklのバージョンが2018.0.2であることを確認してみてください。

mklのバージョンが2018.0.3や2019.1の場合は以下のようなエラーになります。

序数242がダイナミックライブラリmkl_intel_thread.dllから見つかりませんでした。

 

Windows\System32フォルダのdll確認

正しいバージョンのmklを使っていても、次のようなmkl_intel_thread.dllのエラーが出る場合、C:\Windows\System32フォルダ配下に別バージョンの「mkl_*.dll」が格納されている可能性があります。

プロシージャエントリポイントmkl_blas_dgem2vuがダイナミックライブラリmkl_intel_thread.dllから見つかりませんでした。

 

conda activateで仮想環境を有効にすると、各仮想環境配下のLibrary\binフォルダのパスが優先されるように設定される(かつエラーメッセージでもLibrary\bin配下のdllが利用されているように見える)のですが、なぜかC:\Windows\System32に入っているmkl_intel_thread.dllの方が参照されてしまうようです。

Anacondaのコマンドラインで以下のように where mkl_intel_thread.dll と入力すると参照するdllの一覧が表示されるので、この中にC:\Windows\System32が含まれているかどうかで判断できます。

> where mkl_intel_thread.dll
C:\Users\Kurozumi\Anaconda3\envs\scikit\Library\bin\mkl_intel_thread.dll
C:\Users\Kurozumi\Anaconda3\Library\bin\mkl_intel_thread.dll
C:\Windows\System32\mkl_intel_thread.dll
C:\Program Files\ArrayFire\v3\lib\mkl_intel_thread.dll

 

C:\Windows\System32フォルダ配下に「mkl_*.dll」が含まれていた場合は、それらのファイルを削除することで、各仮想環境のLibrary\bin配下のdllが利用されるようになります。(念のため削除するファイルはバックアップしておくことをおすすめします)