LoginSignup
4
2

More than 3 years have passed since last update.

JuliaとJupyter NotebookでScikitLearnがうまく使えない問題

Last updated at Posted at 2019-07-25

経緯

WEB+DB PRESS vol.111のJulia特集の内容をMac(MacOS Mojava 10.14.5)で試した際に発生したエラーの対応方法になります。

  • Julia: 1.1.1

実行内容

Jupyter-notebookで以下のJuliaのコマンドを実行

]add RDatasets
using RDatasets
iris = dataset("datasets", "iris")
]add ScikitLearn
;pip3 install scikit-learn
using ScikitLearn.CrossValidation: train_test_split
X = Matrix(iris[:, 1:4])
y = string.(iris.Species)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3);
  • RDatasets の iris データセットを利用
  • ScikitLearn の train_test_split を実行してデータセットを分割する

発生したエラー

This ScikitLearn.jl functionality (sklearn.model_selection) requires installing the Python scikit-learn library. See instructions on https://github.com/cstjean/ScikitLearn.jl

Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] importpy(::String) at /Users/taketoiseki/.julia/packages/ScikitLearn/bo2Pt/src/Skcore.jl:28
 [3] #train_test_split#93(::Base.Iterators.Pairs{Symbol,Float64,Tuple{Symbol},NamedTuple{(:test_size,),Tuple{Float64}}}, ::Function, ::Array{Float64,2}, ::Vararg{Any,N} where N) at /Users/taketoiseki/.julia/packages/ScikitLearn/bo2Pt/src/cross_validation.jl:664
 [4] (::getfield(ScikitLearn.Skcore, Symbol("#kw##train_test_split")))(::NamedTuple{(:test_size,),Tuple{Float64}}, ::typeof(train_test_split), ::Array{Float64,2}, ::Vararg{Any,N} where N) at ./none:0
 [5] top-level scope at In[2]:4
  • 「Python の scikit-learn をインストールしろ」とのこと
  • ;pip3 install scikit-learnでインストールできてるはずなのに…

原因と解決方法

原因

  • JuliaはConda.jlが内部的にインストールしたPythonを利用する。
  • 私の環境では元々インストールしていたPython3がある。
  • 結果、pip3は元々インストールしていたPython3の方にモジュールをインストールする。

解決方法

Julia の REPL にて以下を実行する

julia> ENV["PYTHON"]="/usr/local/bin/python3";
(v1.1) pkg> build PyCall
julia> using IJulia
julia > notebook()
  • 環境変数で Julia で利用する Python のパスを指定する。
  • 内部的に呼ばれるPyCallをビルドしなおす。
  • Jupyter-notebook を再起動する。

原因判明までの流れ

まずはエラー発生箇所のコードを読む

function importpy(name::AbstractString)
    try
        return pyimport(name)
    catch e
        if isa(e, PyCall.PyError)
            error("This ScikitLearn.jl functionality ($name) requires installing the Python scikit-learn library. See instructions on https://github.com/cstjean/ScikitLearn.jl")
        else
            rethrow()
        end
    end
end

どうやらpyimportした結果、エラーが起きているらしい。

REPLからpyimportを読んでみる

julia> using PyCall
julia> pyimport("scikit-learn")

上記コマンドを実行したところ、以下のエラーが出てきました。

ERROR: PyError (PyImport_ImportModule

The Python package scikit-learn could not be found by pyimport. Usually this means
that you did not install scikit-learn in the Python version being used by PyCall.

PyCall is currently configured to use the Julia-specific Python distribution
installed by the Conda.jl package.  To install the scikit-learn module, you can
use `pyimport_conda("scikit-learn", PKG)`, where PKG is the Anaconda
package the contains the module scikit-learn, or alternatively you can use the
Conda package directly (via `using Conda` followed by `Conda.add` etcetera).

Alternatively, if you want to use a different Python distribution on your
system, such as a system-wide Python (as opposed to the Julia-specific Python),
you can re-configure PyCall with that Python.   As explained in the PyCall
documentation, set ENV["PYTHON"] to the path/name of the python executable
you want to use, run Pkg.build("PyCall"), and re-launch Julia.

) <class 'ModuleNotFoundError'>
ModuleNotFoundError("No module named 'scikit-learn'")

Stacktrace:
 [1] pyimport(::String) at /Users/taketoiseki/.julia/packages/PyCall/ttONZ/src/PyCall.jl:544
 [2] top-level scope at none:0

すごく親切に原因が書かれてますね。

Python3のパスを確認

% which python3
/usr/local/bin/python3

Python3で scikit-learn がインストール済みであることの確認

-> % pip3 show scikit-learn
Name: scikit-learn
Version: 0.21.2
Summary: A set of python modules for machine learning and data mining
Home-page: http://scikit-learn.org
Author: None
Author-email: None
License: new BSD
Location: /usr/local/lib/python3.7/site-packages
Requires: scipy, joblib, numpy
Required-by:

きちんとインストールされてそうなので、環境変数に渡して再度動かしてみる

using ScikitLearn.CrossValidation: train_test_split
X = Matrix(iris[:, 1:4])
y = string.(iris.Species)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3);
X_train

きちんとX_trainが定義できました。

105×4 Array{Float64,2}:
 6.1  2.6  5.6  1.4
 5.6  3.0  4.1  1.3
 6.0  3.0  4.8  1.8
 5.1  3.5  1.4  0.3
 7.7  2.6  6.9  2.3
 6.1  2.8  4.7  1.2
 6.3  2.7  4.9  1.8
 6.2  3.4  5.4  2.3
 4.8  3.4  1.9  0.2
 7.7  2.8  6.7  2.0
 4.8  3.0  1.4  0.3
 5.7  2.9  4.2  1.3
 6.2  2.9  4.3  1.3
 ⋮                 
 6.5  3.2  5.1  2.0
 6.9  3.1  5.4  2.1
 4.4  3.0  1.3  0.2
 4.4  2.9  1.4  0.2
 5.1  3.5  1.4  0.2
 5.7  2.5  5.0  2.0
 6.8  3.0  5.5  2.1
 6.9  3.2  5.7  2.3
 5.3  3.7  1.5  0.2
 6.4  3.2  5.3  2.3
 5.4  3.9  1.3  0.4
 6.1  3.0  4.9  1.8

感想

Pythonは環境づくりに罠が多いイメージがあるんじゃー

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2