22.10.31.🎗️
머신러닝 기초에 대해 배우는 중.
회귀 평가 지표와 하이퍼파라미터 튜닝의 기초적인 내용들을 다루었다.
오차 절대값의 평균. 가장 직관적인 지표이다.
MSE같은 경우, 오차에 제곱을 시키기 때문에, 절대값 1 이하의 작은 값이나 아주 큰 값 등 이상치에 대해 민감하나, MAE는 상대적으로 이상치에 강건하여 변동성이 큰 지표와 작은 지표를 같이 예측할 시 유용하다.
mae = abs(y_train - y_predict).mean()
# 또는
from sklearn.metrics import mean_absolute_error
mean_absolute_error(y_train, y_predict)
오차가 해당 값의 몇 %나 되는지의 절대값 평균. ((실제값 - 예측값) / 실제값) 의 절대값에 대한 평균이다.
mape = abs((y_train - y_predict) / y_train).mean()
오차 제곱의 평균. 앞에서 언급했듯이 이상치에 민감하다.
MAE와 비교하였을 때엔 미분 가능하다는 차이가 존재한다.
계산 방식이 잔차의 분산이라고 생각할 수 있다.
mse = ((y_train - y_predict) ** 2).mean()
# 또는
from sklearn.metrics import mean_squared_error
mean_squared_error(y_train, y_predict)
오차 제곱의 평균에 루트를 씌운 값. 루트를 씌웠기 때문에, MSE에 비해 오차에 덜 민감하다고 할 수 있다.
MAE는 오차의 절댓값의 평균이기 때문에, 모든 오차에 가중치 없이 그대로가 반영된다고 볼 수 있으나, RMSE는 MSE, 즉 오차를 제곱한 값들을 이용했기 때문에, 큰 오차와 작은 오차에 다른 가중치가 반영되었다고 볼 수 있다.
결론적으로, MAE에 비해서는 오차에 민감하나, MSE에 비해서는 덜 민감하다.
RMSE = np.sqrt(mse)
1 - RSS/TSS
RSS란, 잔차 제곱의 합이다.
TSS란, 데이터의 평균 값과 실제 값의 차이 제곱의 합이다.
R2는 회귀 모델의 설명력을 표현하는 지표로, 1에 가까울수록 높은 성능이다.
from sklearn.metrics import r2_score
r2_score(y_test, y_predict)
결국, 데이터와 모델에 따라 그때그때 필요한 회귀 판단 지표를 선택하거나 직접 제작하여 사용해야 할 것이다.
주요 평가지표들을 한번에 살펴보기 위해 다음 코드를 사용할 수 있다.
from sklearn.metrics import classification_report
print(classification_report(y_test, y_predict_clf))
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=None, train_size=None, random_state=None, shuffle=True, stratify=None)
위 이미지 중, 왼쪽이 grid search를 이용한 것, 오른쪽이 random search를 이용한 것이라고 볼 수 있다. 출처 : 위키백과
GridSearchCV를 통해 하이퍼파라미터 튜닝 후 확인할 수 있는 정보들은 다음과 같다.
사이킷런을 이용한 코드는 다음과 같다.
max_depth = list(range(3,12,2))
max_features = [0.3, 0.5, 0.7, 0.8, 0.9]
parameters = {'max_depth' : max_depth, 'max_features' : max_features}
from sklearn.model_selection import GridSearchCV
clf = GridSearchCV(model, parameters)
clf.fit(X_train, y_train)
clf.best_estimator_
pd.DataFrame(clf.cv_results_).sort_values('rank_test_score')
사이킷 런에서의 사용에 대해서 살펴보자.
코드는 다음과 같다.
from sklearn.model_selection import RandomizedSearchCV
param_distributions = {'max_depth' : np.random.randint(3,20,10), 'max_features' : np.random.uniform(0.5,1,10)}
clfr = RandomizedSearchCV(model, param_distributions= param_distributions, random_state= 42, n_jobs = -1, n_iter = 10, verbose = 3)
clfr.fit(X_train, y_train)
clfr.best_estimator_
clfr.best_params_
clfr.best_score_
pd.DataFrame(clfr.cv_results_).nsmallest(5,'rank_test_score')
param_distributions : dict or list of dicts
Dictionary with parameters names (str) as keys and distributions or lists of parameters to try. Distributions must provide a rvs method for sampling (such as those from scipy.stats.distributions). If a list is given, it is sampled uniformly. If a list of dicts is given, first a dict is sampled uniformly, and then a parameter is sampled using that dict as above.
그러네. 우리는 랜덤하게 추출해낸 값들의 list(array)를 인자로 줬지만, rvs 메소드가 존재하여 sampling 할 수 있는 scipy의 확률 분포를 인자로 줘도 된다고 나와있다. 두 방법 다 가능하다는 것을 알았다!
fig, axes = plt.subplots(nrows = 1, ncols = 2, figsize = (12,4))
sns.countplot(x = y_train, ax = axes[0]).set_title('train')
sns.countplot(x = y_test, ax = axes[1]).set_title('test')
위와 같이 사용할 수 있다!
넘파이에서 제공하는 균등 분포 함수로, 최소값, 최대값, 데이터 개수의 인자를 주면 해당 값을 균등히 나누어 array를 만들어준다.
.agg({'column' : 'func', 'column' : 'func'})와 같이 사용하여 각 컬럼들에 다른 여러 함수를 적용해 줄 수도 있다...!
해당 내용은 멋쟁이사자처럼 AI School 오늘코드 박조은 강사님의 자료를 참고하였으며, 일부 인용하고 있습니다.