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

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

新規登録して質問してみよう
ただいま回答率
85.48%
CPU

CPUは、コンピュータの中心となる処理装置(プロセッサ)で中央処理装置とも呼ばれています。プログラム演算や数値計算、その他の演算ユニットをコントロール。スマホやPCによって内蔵されているCPUは異なりますが、処理性能が早いほど良いとされています。

並列処理

複数の計算が同時に実行される手法

機械学習

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

Python

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

Q&A

解決済

1回答

4995閲覧

CPU制限の解除方法

tictak00

総合スコア10

CPU

CPUは、コンピュータの中心となる処理装置(プロセッサ)で中央処理装置とも呼ばれています。プログラム演算や数値計算、その他の演算ユニットをコントロール。スマホやPCによって内蔵されているCPUは異なりますが、処理性能が早いほど良いとされています。

並列処理

複数の計算が同時に実行される手法

機械学習

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

Python

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

0グッド

0クリップ

投稿2020/05/04 07:01

編集2020/05/04 08:30

前提・実現したいこと

pythonにて機械学習を行なっています。
計算処理が遅いため、処理速度を向上させたいです。
自分なりに試行錯誤したものの、原因がわからず、、、
ご回答いただけますでしょうか。

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

計算時間が多くかかっている箇所はsklearnモジュールを用いたKNNの処理でした。
処理時にはn_jobs = -1としているため、使用可能なCPUは全て使用しているつもりでしたが、
計算実行時にcpuを確認したところ、あまりCPUが稼働していない状況であることがわかりました。
このアイドル状態のCPUを使用できれば処理速度が向上すると言う認識です。

イメージ説明
イメージ説明

該当のソースコード

python

1from sklearn.neighbors import KNeighborsClassifier as KNN 2from sklearn import metrics 3 4def use_knn_single(X, Y, pred_X): 5 model = KNN(n_neighbors=30, weights='distance', algorithm='auto', leaf_size=30, n_jobs=-1) 6 model.fit(X.values, Y.values) 7 8 result_pred = model.predict(pred_X.values)[0] 9 10 return result_pred

試したこと

KNNのn_jobs = 1と設定したのち、
該当処理をmultiprocessingモジュールで外部から制御したものの結果は変わらず。

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

OS:macOS Catalina
CPU:3.2 GHz 6コア 12スレッド
メモリ:16 GB
python:3.7.5

学習データサイズ:1600 rows ×40 coulumns(最大)
学習データの型:pandas[float64/object/int64]
(目的変数の型はint64)
目的変数のクラス数:6
テストデータのサイズ:1 row

※上記関数は処理の中で複数回呼び出しています
(可能な限り最新の情報を用いて予測したいため)。
加えて使用するカラムのリストを変更しつつ(最大:40、最小:5)呼び出しているので、合わせてかなりの回数で上記関数を呼び出しています。

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

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

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

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

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

meg_

2020/05/04 07:09

メモリの使用状況はどうですか?
tictak00

2020/05/04 07:19

アクションありがとうございます。 説明に追記しましたが、まだ余裕があるように見受けられます。
meg_

2020/05/04 07:31

メモリ使用率98%くらいでしょうか?(余裕はありませんね) 学習中はメモリが不足している瞬間もあるかもしれませんね。 他のアプリケーションを終了して実行すると速くなりませんか?
tictak00

2020/05/04 07:47 編集

ハードウェアの知識がなく申し訳です。 メモリの使用率は使用済み+キャッシュされたファイルで見るべきでしたか。。。他のアプリケーションを終了しても結果は変わらずでした。 また、改めて実行中のメモリ増加量を確認しましたが、学習データのレコード件数もそこまで多くないため500 MBほどの上昇でした。
meg_

2020/05/04 07:56

データ量が少ない(計算量が少ない)場合に使用するコア数を増やしすぎるととオーバーヘッド分かえって遅くなることがあるらしいです。n_jobsに適当な値を指定してみてはどうでしょうか?
tictak00

2020/05/04 08:01

n_jobs=1としても結果は変わらずでした。 また、不可思議なことに、 n_jobs=1とした場合は1スレッドのみ使用する設定だと思うのですが、 CPUを監視したところ、何故か2スレッド使用されていました。 こちら、pythonでCPU使用率を指定する際に別途設定などいりましたでしょうか。
hayataka2049

2020/05/04 08:10

データのshapeを教えて下さい。
hayataka2049

2020/05/04 08:14

あとできれば型と目的変数のクラス数くらいはわかるといいかもしれません。こちらで再現できるのが一番いいのですが、データを貼れない場合もあるので問題ない範囲でできるだけいろいろ教えて下さい。
tictak00

2020/05/04 08:15

hayatakaさま、 アクションありがとうございます。 学習データのshapeは約1600 rows ×40 columnsになります。 カラム数が多すぎますでしょうか。。。
hayataka2049

2020/05/04 08:17

(10^3, 10^2)程度であればほぼ瞬殺のはずです。テストデータのサイズはどれくらいですか? あるいは、この関数を複数回呼び出していたりしますか?
tictak00

2020/05/04 08:26

以下の追加情報になります。 また、申し訳ないですが、諸事情でデータは貼れません。 型:float64/object/int64(目的変数の型はint64) 目的変数のクラス数:6 テストデータのサイズは1 rowになります。 上記関数は処理の中で複数回呼び出しています (可能な限り最新の情報を用いて予測したいため)。 加えて使用するカラムのリストを変更しつつ(最大:40、最小:5)呼び出しているので、合わせてかなりの回数で上記関数を呼び出しています。
hayataka2049

2020/05/04 08:27 編集

その通りの記述でいいので質問本文に追記しておいてください。回答しますが、対応する記述が質問にないと困るので……
tictak00

2020/05/04 08:36

補足事項に追記いたしました。 引き続きよろしくお願いいたします。
guest

回答1

0

ベストアンサー

状況からして、一回の処理自体にはほとんど時間はかからないはずです。関数を一回処理するのにかかる時間を測って見ると良いと思います。

問題はこの関数を複数回呼び出していることです。KNeighborsClassifier内部の学習・予測はマルチコアを活かして並列に効率よく行われますが、並列化が効くのはその部分だけです。並列化が効かないPythonレイヤの処理もありますし、分類器モデル内部でも初期化など並列性の低い部分があります。

一度に大量のデータを流し込んで学習・予測させれば並列性の低い部分がボトルネックになることは避けられますが、今回のような使い方では並列性の低い部分が足を引っ張り、スピードの出ようがありません。

また、マルチプロセス並列化してもオーバーヘッドを考えるとかなり無理があるかと思います。個々の処理が小さければオーバーヘッドの方が足を引っ張ります。むしろ非Pythonレイヤで走るCPU待ちの処理が多いので、スレッド並列が効くかもしれません(スレッド間でデータが整合的かどうか等、注意するべきことは多いですが)。

ロジックを見直せるならそれが一番いいです。

追記

スレッド並列化のテスト。

python

1import time 2import numpy as np 3from concurrent.futures import ThreadPoolExecutor 4from sklearn.neighbors import KNeighborsClassifier 5 6X = np.random.normal(size=(16*10*3, 4*10**1)) 7y = np.random.normal(size=(16*10*3, )) > 0 8 9def f(): 10 model = KNeighborsClassifier(n_neighbors=30, weights='distance', algorithm='auto', leaf_size=30, n_jobs=-1) 11 model.fit(X, y) 12 model.predict(X[0:1]) 13 14t1 = time.time() 15for _ in range(10**2): 16 f() 17t2 = time.time() 18print(t2 - t1) # 11.042834997177124 19 20t1 = time.time() 21with ThreadPoolExecutor() as executor: 22 res = [executor.submit(f) for _ in range(10**2)] 23 for f in res: 24 f.result() 25t2 = time.time() 26print(t2 - t1) # 0.8094661235809326 27

やっぱり待ち時間が長いので、スレッド並列は一つの答えかも。複数同時に回せるタスクがあるならですが。

投稿2020/05/04 08:40

編集2020/05/04 10:03
hayataka2049

総合スコア30933

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

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

tictak00

2020/05/04 08:55

ご回答ありがとうございます。 改めて、ご指摘いただきこれ以上該当箇所が早くならないこと、CPU使用率が上がらないことなどに納得がいきました。 一度、ロジックを見直してみます。 非常に助かりました。
hayataka2049

2020/05/04 10:03

ちょっとだけ追記しておきました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問