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

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

ただいまの
回答率

90.35%

  • Python 3.x

    11171questions

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

Sklearnのexe化

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,737

miyakazu

score 5

 前提・実現したいこと

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

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

Traceback (most recent call last):
  File "SimplePred01.py", line 3, in <module>
    import sklearn
  File "c:\venv\ins\lib\site-packages\PyInstaller\loader\pyimod03_importers.py",
 line 631, in exec_module
    exec(bytecode, module.__dict__)
  File "lib\site-packages\sklearn\__init__.py", line 134, in <module>
  File "c:\venv\ins\lib\site-packages\PyInstaller\loader\pyimod03_importers.py",
 line 631, in exec_module
    exec(bytecode, module.__dict__)
  File "lib\site-packages\sklearn\base.py", line 13, in <module>
  File "c:\venv\ins\lib\site-packages\PyInstaller\loader\pyimod03_importers.py",
 line 631, in exec_module
    exec(bytecode, module.__dict__)
  File "lib\site-packages\sklearn\utils\__init__.py", line 11, in <module>
  File "c:\venv\ins\lib\site-packages\PyInstaller\loader\pyimod03_importers.py",
 line 631, in exec_module
    exec(bytecode, module.__dict__)
  File "lib\site-packages\sklearn\utils\validation.py", line 18, in <module>
  File "c:\venv\ins\lib\site-packages\PyInstaller\loader\pyimod03_importers.py",
 line 631, in exec_module
    exec(bytecode, module.__dict__)
  File "lib\site-packages\sklearn\utils\fixes.py", line 144, in <module>
  File "c:\venv\ins\lib\site-packages\PyInstaller\loader\pyimod03_importers.py",
 line 631, in exec_module
    exec(bytecode, module.__dict__)
  File "lib\site-packages\scipy\sparse\linalg\__init__.py", line 114, in <module
>
  File "c:\venv\ins\lib\site-packages\PyInstaller\loader\pyimod03_importers.py",
 line 631, in exec_module
    exec(bytecode, module.__dict__)
  File "lib\site-packages\scipy\sparse\linalg\isolve\__init__.py", line 6, in <m
odule>
  File "c:\venv\ins\lib\site-packages\PyInstaller\loader\pyimod03_importers.py",
 line 631, in exec_module
    exec(bytecode, module.__dict__)
  File "lib\site-packages\scipy\sparse\linalg\isolve\iterative.py", line 7, in <
module>
  File "c:\venv\ins\lib\site-packages\PyInstaller\loader\pyimod03_importers.py",
 line 714, in load_module
    module = loader.load_module(fullname)
ImportError: DLL load failed: 指定されたモジュールが見つかりません。
[11720] Failed to execute script SimplePred01

 該当のソースコード

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

# -*- mode: python -*-

block_cipher = None

himports = [
    'pandas', 'sklearn']

def get_pandas_path():
    import pandas
    pandas_path = pandas.__path__[0]
    return pandas_path

def get_sklearn_path():
    import sklearn
    sklearn_path = sklearn.__path__[0]
    return sklearn_path

a = Analysis(['SimplePred01.py'],
             pathex=['C:\\Users\\z05464p0\\Python\\F_test02\\make_exe'],
             binaries=[],
             datas=[],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher)

dict_tree = Tree(get_pandas_path(), prefix='pandas', excludes=["*.pyc"])
a.datas += dict_tree
a.binaries = filter(lambda x: 'pandas' not in x[0], a.binaries)


dict_tree = Tree(get_sklearn_path(), prefix='sklearn', excludes=["*.pyc"])
a.datas += dict_tree
a.binaries = filter(lambda x: 'sklearn' not in x[0], a.binaries)

pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          exclude_binaries=True,
          name='SimplePred01',
          debug=False,
          strip=False,
          upx=True,
          console=True )
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               name='SimplePred01')

 試したこと

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

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • キャンセル

  • wakame

    2018/03/16 19:28

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

    キャンセル

  • miyakazu

    2018/03/19 09:22

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

    キャンセル

回答 2

checkベストアンサー

+2

これは恐らく、 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 にリンクできるという寸法です。

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

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

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/23 17:28

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

    キャンセル

  • 2018/03/23 21:36

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

    キャンセル

0

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/19 09:34

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

    キャンセル

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

  • ただいまの回答率 90.35%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • Python 3.x

    11171questions

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