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

回答編集履歴

2

追記

2020/05/04 10:03

投稿

hayataka2049
hayataka2049

スコア30939

answer CHANGED
@@ -6,4 +6,40 @@
6
6
 
7
7
  また、マルチプロセス並列化してもオーバーヘッドを考えるとかなり無理があるかと思います。個々の処理が小さければオーバーヘッドの方が足を引っ張ります。むしろ非Pythonレイヤで走るCPU待ちの処理が多いので、スレッド並列が効くかもしれません(スレッド間でデータが整合的かどうか等、注意するべきことは多いですが)。
8
8
 
9
- ロジックを見直せるならそれが一番いいです。
9
+ ロジックを見直せるならそれが一番いいです。
10
+
11
+
12
+ # 追記
13
+ スレッド並列化のテスト。
14
+
15
+ ```python
16
+ import time
17
+ import numpy as np
18
+ from concurrent.futures import ThreadPoolExecutor
19
+ from sklearn.neighbors import KNeighborsClassifier
20
+
21
+ X = np.random.normal(size=(16*10*3, 4*10**1))
22
+ y = np.random.normal(size=(16*10*3, )) > 0
23
+
24
+ def f():
25
+ model = KNeighborsClassifier(n_neighbors=30, weights='distance', algorithm='auto', leaf_size=30, n_jobs=-1)
26
+ model.fit(X, y)
27
+ model.predict(X[0:1])
28
+
29
+ t1 = time.time()
30
+ for _ in range(10**2):
31
+ f()
32
+ t2 = time.time()
33
+ print(t2 - t1) # 11.042834997177124
34
+
35
+ t1 = time.time()
36
+ with ThreadPoolExecutor() as executor:
37
+ res = [executor.submit(f) for _ in range(10**2)]
38
+ for f in res:
39
+ f.result()
40
+ t2 = time.time()
41
+ print(t2 - t1) # 0.8094661235809326
42
+
43
+ ```
44
+
45
+ やっぱり待ち時間が長いので、スレッド並列は一つの答えかも。複数同時に回せるタスクがあるならですが。

1

編集

2020/05/04 10:03

投稿

hayataka2049
hayataka2049

スコア30939

answer CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  問題はこの関数を複数回呼び出していることです。`KNeighborsClassifier`の**内部の学習・予測はマルチコアを活かして並列に効率よく行われますが**、並列化が効くのはその部分だけです。並列化が効かないPythonレイヤの処理もありますし、分類器モデル内部でも初期化など並列性の低い部分があります。
4
4
 
5
- 一度に大量のデータを流し込んで学習させれば並列性の低い部分がボトルネックになることは避けられますが、今回のような使い方では並列性の低い部分が足を引っ張り、スピードの出ようがありません。
5
+ 一度に大量のデータを流し込んで学習・予測させれば並列性の低い部分がボトルネックになることは避けられますが、今回のような使い方では並列性の低い部分が足を引っ張り、スピードの出ようがありません。
6
6
 
7
7
  また、マルチプロセス並列化してもオーバーヘッドを考えるとかなり無理があるかと思います。個々の処理が小さければオーバーヘッドの方が足を引っ張ります。むしろ非Pythonレイヤで走るCPU待ちの処理が多いので、スレッド並列が効くかもしれません(スレッド間でデータが整合的かどうか等、注意するべきことは多いですが)。
8
8