質問するログイン新規登録

Q&A

解決済

1回答

2485閲覧

scipy nnls RuntimeError: too many iterations を解決したいです。

K2T

総合スコア1

Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Webサーバー

Webサーバーとは、HTTPリクエストに応じて、クライアントに情報を提供するシステムです。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Processing

Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。

0グッド

0クリップ

投稿2021/07/08 05:54

編集2021/07/08 06:21

0

0

前提・実現したいこと

Processingからサーバーに値を渡して、Pythonで記述した機械学習のプログラムで計算した後、Processingに値を返すものを作成しています。

それぞれのパーツを書いて、つなげて実行しようとした時にエラーになりました。

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

Traceback (most recent call last): File "/Users/username/miniforge3/envs/myenv/lib/python3.9/site-packages/flask/app.py", line 2070, in wsgi_app response = self.full_dispatch_request() File "/Users/username/miniforge3/envs/myenv/lib/python3.9/site-packages/flask/app.py", line 1515, in full_dispatch_request rv = self.handle_user_exception(e) File "/Users/username/miniforge3/envs/myenv/lib/python3.9/site-packages/flask/app.py", line 1513, in full_dispatch_request rv = self.dispatch_request() File "/Users/username/miniforge3/envs/myenv/lib/python3.9/site-packages/flask/app.py", line 1499, in dispatch_request return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args) File "/Users/username/flask/flask-mini-api/app.py", line 13, in api food_list = calc(food_id_list) File "/Users/username/flask/flask-mini-api/test.py", line 20, in calc abc = pd.DataFrame(nnls(A,B)[0]*100) File "/Users/username/miniforge3/envs/myenv/lib/python3.9/site-packages/scipy/optimize/_nnls.py", line 82, in nnls raise RuntimeError("too many iterations") **RuntimeError: too many iterations**

該当のソースコード

flask_mini

Processing

1import http.requests.*; 2 3String URL = "http://127.0.0.1:3000/api?food_id=130,355,529,630,706,995,1758,1922,1943,1966,2296"; 4 5void setup() { 6 GetRequest get = new GetRequest(URL); 7 get.send(); 8 JSONObject result = parseJSONObject(get.getContent()); 9 println(result); 10} 11 12void draw() { 13}

app.py

Python

1from flask import Flask, request, jsonify 2from test import calc 3 4app = Flask(__name__) 5 6@app.route("/api", methods=["GET"]) 7def api(): 8 req = request.args 9 food_id_param = req.get("food_id") 10 11 food_id_list = food_id_param.split(',') 12 13 food_list = calc(food_id_list) 14 return jsonify({"food": food_list}) 15 16if __name__ == "__main__": 17 app.run(port=3000) 18

test.py

Python

1import pandas as pd 2import numpy as np 3from scipy.optimize import nnls 4 5def calc(food_id_list): 6 df = pd.read_csv('nutrients_data_shaped.csv') 7 data=df[['NO','food','ENERC_KCAL','PROT-','FAT-','CHOAVLDF-','K','CA','MG','P','FE','ZN','CU','VITA_RAE','VITD','TOCPHA','VITK ','THIA','RIBF','NE','VITB6A','VITB12','FOL','PANTAC','VITC','FIB-','NACL_EQ']] 8 9 data2= data[data['NO'].isin(food_id_list)] 10 11 data2matrix=np.delete(data2.to_numpy(),[0,1],1).astype('float').T 12 13 A=data2matrix 14 B=np.array([2650,65,59,384,2500,800,340,1000,7.5,11,0.9,850,8.5,6.0,150,1.4,1.6,15,1.4,2.4,240,5,100,24,5]) 15 16 data2_food_name = pd.DataFrame(data2['food']) 17 18 data2_food_name.reset_index(drop=True, inplace=True) 19 20 abc = pd.DataFrame(nnls(A,B)[0]*100) 21 data2_need_nutrients_amount = pd.concat([data2_food_name, abc], axis=1) 22 data2_need_nutrients_amount = data2_need_nutrients_amount.rename(columns={0:'必要な量(g)'}) 23 24 return_arr = [] 25 for data in data2_need_nutrients_amount.values: 26 return_arr.append({ 27 "food_name": data[0], 28 "weight": data[1] 29 }) 30 return return_arr

試したこと

test.pyのnnlsのところが問題になっていると考え、AとBの要素を減らして実行しましたが、同じ結果になりました。また、nnlsの中身をみて、modeが1にならないといけないのかなと思いましたが、jupyter notebookでは動いています。

nnls.py

Python

1from __future__ import division, print_function, absolute_import 2 3from . import _nnls 4from numpy import asarray_chkfinite, zeros, double 5 6__all__ = ['nnls'] 7 8 9def nnls(A, b): 10 """ 11 Solve ``argmin_x || Ax - b ||_2`` for ``x>=0``. This is a wrapper 12 for a FORTAN non-negative least squares solver. 13 14 Parameters 15 ---------- 16 A : ndarray 17 Matrix ``A`` as shown above. 18 b : ndarray 19 Right-hand side vector. 20 21 Returns 22 ------- 23 x : ndarray 24 Solution vector. 25 rnorm : float 26 The residual, ``|| Ax-b ||_2``. 27 28 Notes 29 ----- 30 The FORTRAN code was published in the book below. The algorithm 31 is an active set method. It solves the KKT (Karush-Kuhn-Tucker) 32 conditions for the non-negative least squares problem. 33 34 References 35 ---------- 36 Lawson C., Hanson R.J., (1987) Solving Least Squares Problems, SIAM 37 38 """ 39 40 A, b = map(asarray_chkfinite, (A, b)) 41 42 if len(A.shape) != 2: 43 raise ValueError("expected matrix") 44 if len(b.shape) != 1: 45 raise ValueError("expected vector") 46 47 m, n = A.shape 48 49 if m != b.shape[0]: 50 raise ValueError("incompatible dimensions") 51 52 w = zeros((n,), dtype=double) 53 zz = zeros((m,), dtype=double) 54 index = zeros((n,), dtype=int) 55 56 x, rnorm, mode = _nnls.nnls(A, m, n, b, w, zz, index) 57 if mode != 1: 58 raise RuntimeError("too many iterations") 59 60 return x, rnorm

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

M1 mac miniforge3
Processing 3.5.4
Python 3.9.1
flask 2.0.1
scipy 1.7.0
numpy 1.21.0
pandas 1.3.0

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

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

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

guest

回答1

0

ベストアンサー

回答がつかないみたいなので、回答じゃないですが、一緒にデバッグな感じで回答を書きます。

Flask側しか知らないのでそちらの観点から。

とりあえずエラーメッセージを見ると、

File "/Users/username/miniforge3/envs/myenv/lib/python3.9/site-packages/scipy/optimize/_nnls.py", line 82, in nnls raise RuntimeError("too many iterations")

とあるので、_nnls.pyの82行目でraise RuntimeError()が発生しているようです。
これを呼び出しているところに問題がないか確認してください。

これについてはjupyter notebookでは動いているということなので、問題無いのかもしれません。
「かもしれない」なので、本当に動くのか確認が必要です。
Web(Flask)から呼び出すのではなく、最後に呼び出されるところをjupyter notebookと同じように実行してみて動くのか確認してみましょう。
jupyter notebookではFlaskは動いていないと思うので、flask_miniからtest.pyを直接呼び出す形で動くか確認してみてください。

これで動いた場合、呼び出し方が悪いのかもしれません。
food_list = calc(food_id_list)ではgetパラメータをsplitしてlistにして渡していますが、デバッガで見ると、渡している値は以下です。

python

1 # food_id_listのデバッグ情報 2 food_id_list = {list: 11} ['130', '355', '529', '630', '706', '995', '1758', '1922', '1943', '1966', '2296'] 3 00 = {str} '130' 4 01 = {str} '355' 5 02 = {str} '529' 6 03 = {str} '630' 7 04 = {str} '706' 8 05 = {str} '995' 9 06 = {str} '1758' 10 07 = {str} '1922' 11 08 = {str} '1943' 12 09 = {str} '1966' 13 10 = {str} '2296' 14 __len__ = {int} 11

list:11は想定の型ですか?
listに含まれる値は全てstr型ですが、想定通りでしょうか?
"も'もついていない数字がカンマで区切られているのでintが欲しかったり、実はfloatが欲しかったりしないでしょうか?
nutrients_data_shaped.csvの中身が分からないので、どういうのが想定されているのか分かりませんが、Webの値の入力が想定と異なるのはありがちなので確認してみてください。

デバッガについて(2021/07/12 09:38追記)

私が使ったのはPyCharm Professionalです。

PyCharm Professionalは有料ですが、無料のPyCharm Communityというのもあります。
以下からDL可能です。

https://www.jetbrains.com/ja-jp/pycharm/

PyCharm入門が以下にありますので参照ください。
https://pleiades.io/help/pycharm/quick-start-guide.html#meet

PyCharmは何もしないと英語でメニュー等が表示されますが、以下手順で日本語に変更できます。

  1. 左上メニューの[file]
  2. Settings(Ctrl + Alt + Sでも可)
  3. plugin
  4. 検索部分で「Japanese」と入力
  5. 表示された Japanese Language Pack をインストール。
  6. PyCharmを再起動

K2Tさんの場合は、以下の手順でデバッグ可能と思います。

  1. 今作成中のプログラムが含まれるディレクトリをPyCharmで開き(ファイル -> 開く)
  2. 【Flaskのデバッグ環境構築】
    右上にある緑右向き三角(再生ボタンみたいなやつ)の左にあるプルダウンメニューから「実行構成の編集」を選択
  3. Flaskの実行構成を作成(名前(N):は[app]とか[flask]とかわかりやすいものに。)
    https://www.nakamuri.info/mw/index.php/PyCharm_CE%E3%81%8B%E3%82%89Flask%E3%82%A2%E3%83%97%E3%83%AA%E3%82%92%E8%B5%B7%E5%8B%95%E3%81%99%E3%82%8B
  4. 再生ボタンみたいなやつの右にある虫マークをクリック

これでFlaskが起動するはずです。
虫ボタンを押すと、下に「デバッグ」ウィンドウが表示され、最終的に以下のような画面が表示されます。

* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit) ⇒これは127.0.0.1とかかも

止めたい行の行番号とコードの間をクリックすると赤い●が追加されますので、実行されればそこで止まります。

他にPythonのプログラムがあれば、似たような手順でデバッグ可能になります。
なお、PyCharmは新規プロジェクト作成時に[venv]というフォルダを勝手に作成します。
python3 -m venv venvと実行した時と同じものです。

下にある「ターミナル」や「Python コンソール」ではこれが勝手に有効になった状態で実行されるので注意してください。
この仮想環境の追加は、「ファイル->設定->プロジェクト:プロジェクト名->Python インタープリター->右上の歯車マークをクリック->追加]から追加可能です。
変更は[Python インタープリター]画面の[Python インタープリター:」右にあるプルダウンメニューから変更してください。

また、実行構成で使用されるPython インタープリターは、「実行構成の編集」画面を表示して右側の「環境->Python インタープリター(P):」から変更してください。

パッケージがない等と表示される場合は、このインタープリター指定が正しく無いなどの問題が考えられます。
使っている仮想環境と正しく把握してインストールしましょう。

投稿2021/07/09 12:50

編集2021/07/12 00:45
FiroProchainezo

総合スコア2455

K2T

2021/07/10 06:11

ご回答ありがとうございます。ご指摘の通り、listの型がstr型で、想定していたint型と異なっていたため、動かなかったようです。 ```Python from flask import Flask, request, jsonify from nnls import calc app = Flask(__name__) @app.route("/api", methods=["GET"]) def api(): req = request.args food_id_param = req.get("food_id") food_id_list_str = food_id_param.split(',') food_id_list = [] for food_id_str in food_id_list_str: food_id_list.append(int(food_id_str)) result = calc(food_id_list) return jsonify({"result": result}) if __name__ == "__main__": app.run() ``` のようにすると動きました。ありがとうございます。 追伸 : "food_list = calc(food_id_list)ではgetパラメータをsplitしてlistにして渡していますが、デバッガで見ると、渡している値は以下です。" とありますが、デバッガはどのように使うのでしょうか。 デバッガが、コンピュータープログラムのバグを探して修正するプログラムで、pdbモジュールというものがあることまでは調べました。読むべき記事のURLなど、教えていただけると幸いです。
FiroProchainezo

2021/07/12 00:46

遅くなりましたが、デバッガについての記述を追加しました。 確認ください。 何か不明点があれば質問してください。
K2T

2021/07/13 02:35

お忙しい中、教えていただきありがとうございます。FiroProchainezoさんの分かりやすい説明のおかげでデバッガ(PyCharm Community)を使うことができました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.29%

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

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

質問する

関連した質問