2019. 5. 6. 20:43ㆍ분석 Python/Scikit Learn (싸이킷런)
피드백은 항상 좋아합니다.
숙제로 제출해야 하는 게 있어서 만들어 봤습니다.
기본적으로 loop로 해야 하는 구조여서 적어도 모델 만들어지는 것은 multiprocessing으로 하려고 했는데 오히려 느리게 됐다는... 3가지 버전을 보여주려고 합니다.
1. Loop , 2, 잘못된 버전 3. 잘된 버전
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression, Ridge, Lasso, ElasticNet
from sklearn.metrics import mean_squared_error
import pandas as pd
from multiprocessing import Pool
import re
그냥 Loop로 하는 코드
def Loop_Ridge_Lasso_Elastic(lambda_list) :
ridge_train_mse , ridge_test_mse = [] , []
lasso_train_mse , lasso_test_mse = [] , []
elastic_train_mse , elastic_test_mse = [] , []
lasso_coef , ridge_coef , elastic_coef = pd.DataFrame() , pd.DataFrame() , pd.DataFrame()
for i in lambda_list :
ridge = Ridge(alpha=i)
ridge.fit(train_x , train_y )
r_coef = pd.DataFrame(ridge.coef_)
ridge_coef = pd.concat([ridge_coef , r_coef], axis = 0)
train_mse = mean_squared_error(train_y , ridge.predict(train_x) )
test_mse = mean_squared_error(test_y , ridge.predict(test_x) )
ridge_train_mse.append(train_mse)
ridge_test_mse.append(test_mse)
lasso = Lasso(alpha= i)
lasso.fit(train_x , train_y )
l_coef = pd.DataFrame(lasso.coef_).T
lasso_coef = pd.concat([lasso_coef , l_coef], axis = 0)
train_mse = mean_squared_error(train_y , lasso.predict(train_x) )
test_mse = mean_squared_error(test_y , lasso.predict(test_x) )
lasso_train_mse.append(train_mse)
lasso_test_mse.append(test_mse)
ela = ElasticNet(alpha=i)
ela.fit(train_x , train_y )
ela_coef = pd.DataFrame(ela.coef_).T
elastic_coef = pd.concat([elastic_coef , ela_coef], axis = 0)
train_mse = mean_squared_error(train_y , ela.predict(train_x) )
test_mse = mean_squared_error(test_y , ela.predict(test_x) )
elastic_train_mse.append(train_mse)
elastic_test_mse.append(test_mse)
ridge_coef.reset_index(drop= True , inplace= True)
lasso_coef.reset_index(drop= True , inplace= True)
elastic_coef.reset_index(drop= True , inplace= True)
return ridge_train_mse , ridge_test_mse , lasso_train_mse , lasso_test_mse , elastic_train_mse , elastic_test_mse , lasso_coef , ridge_coef , elastic_coef
잘못된 Multiprocessing 버전
def multiprocessing_Ridge_Lasso_Elastic(lambda_list) :
global find_mse
def find_mse(reg) :
reg.fit(train_x, train_y)
coef = reg.coef_
train_mse = mean_squared_error(train_y , reg.predict(train_x) )
test_mse = mean_squared_error(test_y , reg.predict(test_x) )
return train_mse , test_mse , coef
ridge_train_mse , ridge_test_mse = [] , []
lasso_train_mse , lasso_test_mse = [] , []
elastic_train_mse , elastic_test_mse = [] , []
lasso_coef , ridge_coef , elastic_coef = pd.DataFrame() , pd.DataFrame() , pd.DataFrame()
for i in lambda_list :
regressors_list = [Ridge(alpha=i) ,Lasso(alpha= i) ,ElasticNet(alpha=i) ]
if __name__ == '__main__':
with Pool(3) as pool :
output = pool.map(find_mse,regressors_list)
pool.close()
pool.join()
ridge_train_mse.append(output[0][0])
ridge_test_mse.append(output[0][1])
lasso_train_mse.append(output[1][0])
lasso_test_mse.append(output[1][1])
elastic_train_mse.append(output[2][0])
elastic_test_mse.append(output[2][1])
ridge_coef = pd.concat([ridge_coef , pd.DataFrame(output[0][2])], axis = 0)
lasso_coef = pd.concat([lasso_coef , pd.DataFrame(output[1][2]).T], axis = 0)
elastic_coef = pd.concat([elastic_coef , pd.DataFrame(output[2][2]).T], axis = 0)
return ridge_train_mse , ridge_test_mse , lasso_train_mse , lasso_test_mse , elastic_train_mse , elastic_test_mse , lasso_coef , ridge_coef , elastic_coef
잘 된 Multiprocessing
def multiprocessing_Ridge_Lasso_Elastic_v2(lambda_list) :
global concat_data
global find_mse
def find_mse(reg) :
reg.fit(train_x, train_y)
coef = reg.coef_
train_mse = mean_squared_error(train_y , reg.predict(train_x) )
test_mse = mean_squared_error(test_y , reg.predict(test_x) )
return train_mse , test_mse , coef
def concat_data(i) :
Ridge = pd.DataFrame(np.squeeze(np.array(Ridge_list)[:,2][i])).T
Lasso = pd.DataFrame(np.squeeze(np.array(Lasso_list)[:,2][i])).T
Elastic = pd.DataFrame(np.squeeze(np.array(Ela_list)[:,2][i])).T
return Ridge , Lasso , Elastic
regressors_list = []
for i in lambda_list :
for j in [Ridge(alpha=i) ,Lasso(alpha= i) ,ElasticNet(alpha=i) ] :
regressors_list.append(j)
if __name__ == '__main__':
with Pool(10) as pool :
output = pool.map(find_mse,regressors_list)
pool.close()
pool.join()
Ridge_list = output[0::3]
Lasso_list = output[1::3]
Ela_list = output[2::3]
ridge_train_mse , ridge_test_mse = np.array(Ridge_list)[:,0] , np.array(Ridge_list)[:,1]
lasso_train_mse , lasso_test_mse = np.array(Lasso_list)[:,0] , np.array(Lasso_list)[:,1]
elastic_train_mse , elastic_test_mse = np.array(Ela_list)[:,0] , np.array(Ela_list)[:,1]
if __name__ == '__main__':
with Pool(10) as pool :
output = pool.map(concat_data,range(len(lambda_list)))
pool.close()
pool.join()
ridge_coef = pd.DataFrame(np.array(output)[:,0,:])
lasso_coef = pd.DataFrame(np.array(output)[:,1,:])
elastic_coef = pd.DataFrame(np.array(output)[:,2,:])
return ridge_train_mse , ridge_test_mse , lasso_train_mse , lasso_test_mse , elastic_train_mse , elastic_test_mse , ridge_coef , lasso_coef , elastic_coef
multiprocessing_Ridge_Lasso_Elastic_v2(lambda_list)
lambda_list = np.linspace(0.02 , 50.0 , 100)
저 함수들에 이것만 넣어주면 값을 출력해준다.
잘 된 multiprocessing 버전에는 몇가지 알아둬야 하는 게 있는데, 우리가 지금 구해야 하는 것은
100(lambda 경우의 수) x 3(모델 3개) 이걸 구해야 한다. 잘 못된 버전에서는 100개를 구하는데 모델 3개만 Multiprocessing 한 것이라서 느린 것 같다.
1. 그래서 다른 방법 저것을 길게 쭉 나열해서 300 x 1 개로 만들어서 구하는 방식으로 바꾸니 빨라졌다.
> 엄밀하게 속도 비교를 해봐야하지만, 원래 빨리 돌아가는 코드이기도 하고 믿어주시기를...
2. 그리고 한가지 더 주의해야 하는 것은 multiprocessing을 함수로 만들고 싶고 또 그것의 함수를 만들고 싶을 때
nestd 구조로 짜야하는데, 그때 그냥하면 안 되고 global을 사용해줘야 한다!
비교
실제 코드에서는 lambda list 가 100개 였을 때는 그냥 loop가 빠르지만, 숫자를 1000으로 늘리니
multiprocessing 한 것이 더 빠르게 돌아간 것을 확인했다.
잘 못 짠 코드는 1분이 지나도 안돌아가서 그냥... 확인을 포기했다
'분석 Python > Scikit Learn (싸이킷런)' 카테고리의 다른 글
sklearn Pipeline을 이용해 다양한 Regression모델 모델링하기 (0) | 2019.06.15 |
---|---|
sklearn Pipeline을 이용해 다양한 Classification모델들 모델링하기 (0) | 2019.06.15 |
Sklearn SVM + OneVsRestClassifer Gridsearch (0) | 2019.06.15 |
[ Python ] Scikit-Learn, Numeric 표준화 / Category Onehot 하는 Pipeline 및 모델링하는 코드 (0) | 2019.06.15 |
Lasso coordinate Descent 방식으로 최적의 Coef 구하기 (0) | 2019.05.12 |