質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

2回答

2815閲覧

Sklearnのexe化

miyakazu

総合スコア7

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2018/03/15 10:16

編集2018/03/19 00:23

前提・実現したいこと

Python3.6のsklearnを使用して簡単な重回帰分析を行うプログラムをexeで動かしたい。

発生している問題・エラーメッセージ

Python

1Traceback (most recent call last): 2 File "SimplePred01.py", line 3, in <module> 3 import sklearn 4 File "c:\venv\ins\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", 5 line 631, in exec_module 6 exec(bytecode, module.__dict__) 7 File "lib\site-packages\sklearn\__init__.py", line 134, in <module> 8 File "c:\venv\ins\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", 9 line 631, in exec_module 10 exec(bytecode, module.__dict__) 11 File "lib\site-packages\sklearn\base.py", line 13, in <module> 12 File "c:\venv\ins\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", 13 line 631, in exec_module 14 exec(bytecode, module.__dict__) 15 File "lib\site-packages\sklearn\utils\__init__.py", line 11, in <module> 16 File "c:\venv\ins\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", 17 line 631, in exec_module 18 exec(bytecode, module.__dict__) 19 File "lib\site-packages\sklearn\utils\validation.py", line 18, in <module> 20 File "c:\venv\ins\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", 21 line 631, in exec_module 22 exec(bytecode, module.__dict__) 23 File "lib\site-packages\sklearn\utils\fixes.py", line 144, in <module> 24 File "c:\venv\ins\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", 25 line 631, in exec_module 26 exec(bytecode, module.__dict__) 27 File "lib\site-packages\scipy\sparse\linalg\__init__.py", line 114, in <module 28> 29 File "c:\venv\ins\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", 30 line 631, in exec_module 31 exec(bytecode, module.__dict__) 32 File "lib\site-packages\scipy\sparse\linalg\isolve\__init__.py", line 6, in <m 33odule> 34 File "c:\venv\ins\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", 35 line 631, in exec_module 36 exec(bytecode, module.__dict__) 37 File "lib\site-packages\scipy\sparse\linalg\isolve\iterative.py", line 7, in < 38module> 39 File "c:\venv\ins\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", 40 line 714, in load_module 41 module = loader.load_module(fullname) 42ImportError: DLL load failed: 指定されたモジュールが見つかりません。 43[11720] Failed to execute script SimplePred01

該当のソースコード

Pyinstallerでexe化するときに使用したspecファイルの中身。
他ブログ等を参考にして、pandasは読み込んだが、sklearnを読み込んでいないっぽい。

Python

1# -*- mode: python -*- 2 3block_cipher = None 4 5himports = [ 6 'pandas', 'sklearn'] 7 8def get_pandas_path(): 9 import pandas 10 pandas_path = pandas.__path__[0] 11 return pandas_path 12 13def get_sklearn_path(): 14 import sklearn 15 sklearn_path = sklearn.__path__[0] 16 return sklearn_path 17 18a = Analysis(['SimplePred01.py'], 19 pathex=['C:\Users\z05464p0\Python\F_test02\make_exe'], 20 binaries=[], 21 datas=[], 22 hiddenimports=[], 23 hookspath=[], 24 runtime_hooks=[], 25 excludes=[], 26 win_no_prefer_redirects=False, 27 win_private_assemblies=False, 28 cipher=block_cipher) 29 30dict_tree = Tree(get_pandas_path(), prefix='pandas', excludes=["*.pyc"]) 31a.datas += dict_tree 32a.binaries = filter(lambda x: 'pandas' not in x[0], a.binaries) 33 34 35dict_tree = Tree(get_sklearn_path(), prefix='sklearn', excludes=["*.pyc"]) 36a.datas += dict_tree 37a.binaries = filter(lambda x: 'sklearn' not in x[0], a.binaries) 38 39pyz = PYZ(a.pure, a.zipped_data, 40 cipher=block_cipher) 41exe = EXE(pyz, 42 a.scripts, 43 exclude_binaries=True, 44 name='SimplePred01', 45 debug=False, 46 strip=False, 47 upx=True, 48 console=True ) 49coll = COLLECT(exe, 50 a.binaries, 51 a.zipfiles, 52 a.datas, 53 strip=False, 54 upx=True, 55 name='SimplePred01')

試したこと

  1. venv仮想環境で最低限のモジュールでexe化。
  2. .specにhimports = ['pandas', 'sklearn']を追加。
  3. .specにget_pandas_path()などを追加。pandasは読み込まれるようになった。
  4. .specにget_sklearn_path()などを追加。sklearnは読み込まなかった。

補足情報(FW/ツールのバージョンなど)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2018/03/15 10:20

exe化する目的はなんでしょうか?
miyakazu

2018/03/15 23:00

ユーザーの使用環境がWindows7であるためです。
wakame

2018/03/16 10:28

上記を参考にソースコードとエラーコードはで``` ```囲ってもらえますか
miyakazu

2018/03/19 00:22

ご指摘ありがとうございます。Markdownを使用しました。
guest

回答2

0

ベストアンサー

これは恐らく、 PyInstaller の こちらの issue で議論されているもの と同じ問題で、 SciPy のバイナリモジュールが依存している DLL を PyInstaller が適切に組み込めていないがため、実行時の import に失敗している状況と思われます。

SciPy 1.0.0 以降に PyPI で提供されている Windows 版の Wheel では、 FOTRAN 製のライブラリが引き起こす標準 C ライブラリの衝突を回避してビルド済 Wheel を提供するため に、 GFortran で別途ビルドした DLL を scipi/extra-dll というディレクトリに配置し、これを動的に読み込む仕様になっているそうです。このディレクトリには普段パスが通っていませんが、 import scipy とすると scipy/__config__.py (numpyこのへん が生成するファイル) によって、次のようなコードで PATH 環境変数へと自動的に追加されるため、通常の利用時は特に問題なく依存 DLL にリンクできるという寸法です。

python

1import os 2extra_dll_dir = os.path.join(os.path.dirname(__file__), 'extra-dll') 3if os.path.isdir(extra_dll_dir): 4 os.environ["PATH"] += os.pathsep + extra_dll_dir

しかしながら、 PyInstaller はそんなパスは知る由もないため、バイナリモジュールの解析により必要な DLL ファイルの名前は分かっても、それが見つけられず実行ファイルに同梱されていない状況ではないでしょうか。恐らく、 pyinstaller コマンドの実行時、それを意味する "lib not found" WARNING が出ていると思います。

さて、これを解決する方法ですが、実は最初に提示した issue が closed なことからも分かるように、 一週間前に merge された pull-request によって修正されています 。この pull-request にて、 PyInstaller 同梱のフックファイルが最新の scipynumpy に対応したものに更新されていますので、取り敢えずはこれらをダウンロードし、 --additional-hooks-dir で指定したディレクトリに放り込んでおけば動作するのではないでしょうか。もちろん、 PyInstaller 自体を GitHub の最新のものに入れ替えるということも可能です。

あるいは、前述の DLL パス解決の仕組みを参考にすると、 scipyimport さえすればパスが通る わけですから、実は spec ファイルの先頭で適当に import scipy とするだけでも解決すると思われます。個人的には、こちらの方がちょっと面白く、 PyInstaller の analyzer を最大限活用できるので好きですが、まあ、実際には前掲の新しいフックファイルでは、この DLL の問題以外にも新しい hiddenimports モジュールの追加なども行われていますし、何よりきちんと検証の上で公式に提供されているファイルなので、素直にそちらを使うのが宜しいかと思います。

投稿2018/03/22 05:41

argparse

総合スコア1017

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

miyakazu

2018/03/23 08:28

素晴らしい回答ありがとうございます! issueのどのファイルをダウンロードするのかわからないのですが、ご教示いただけないでしょうか?
argparse

2018/03/23 12:36

issue の方はコメントも長いので、最後に記載した pull-request へのリンクを御覧下さい。 3 つタブがあると思いますが、一番右の "Files changed" タブを開くと、当該 pull-request に含まれる `hook-numpy.py` 及び `hook-scipy.py` の修正点がコメント入りで確認できるはずです。これらが必要なファイルなので、それぞれファイル名の右にある "View" ボタンをクリックして表示し、 "Raw" ボタンのリンク等でダウンロードすると良いのでは無いでしょうか。 今回は最新であれば良いので、とりあえずリポジトリをチェックアウトするなり色々ともっと簡便な方法は有るかとは存じますが、それは Git / GitHub の使い方になるので割愛します。自分でバージョン管理するにも便利ですが、こういった OSS を利用する時のトラブル解決にも役に立ちますから、是非使い方を学ばれることをお勧め致します。
guest

0

https://qiita.com/jokitsu2/items/4020ee85056f3a21c11b

このようなことはもう試されましたか?

投稿2018/03/15 10:46

mkgrei

総合スコア8560

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

miyakazu

2018/03/19 00:34

`hiddenimports=[pandas, sklean],`としてみましたが、読み込んでいないようです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問