250x250
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- TensorFlow
- 연결
- Linux
- GridSearchCV
- postgre
- psql
- GPU
- 교차검증
- 복구
- pgadmin
- SQL
- Docker image
- Jupyter
- cpu
- LOG
- sqldeveloper
- 시계열
- jupyternotebook
- psycopg2
- 도커
- oracle
- 도커이미지
- Memory
- 오라클
- docker
- 머신러닝
- 파이썬
- Python
- 쿼리
- 리눅스
Archives
- Today
- Total
areum
[Machine Learning] Random Forest (랜덤포레스트) 본문
728x90
Random Forest
1. 관련 라이브러리 import
import pandas as pd
from pandas import DataFrame
import numpy as np
from time import time
import zipfile #zip파일 해제
# 경고 무시
import warnings
warnings.filterwarnings(action='ignore')
2. zip 파일 해제 & csv파일 불러오기
- encoding 사용하여 한글 깨짐 방지
img=zipfile.ZipFile('zip파일 경로/ 이름')
img.extractall('저장할 경로/ 저장할 이름', pwd=b'비밀번호')
img.close()
# Table
data=pd.read_csv('경로가 다르면 경로 작성/data.csv', sep=',', encoding="cp949")
3. 데이터 형태 확인
- 결측치 확인 및 데이터 형태 확인하는 작업
data.info()
4. 데이터 전처리(값이 특정값인 값만 제거, 컬럼이름 및 값 수정, 원핫인코딩, 제외할 컬럼 제거)
- One-Hot Encoding : 표현하고 싶은 단어의 인덱스에 1의 값을 부여하고, 다른 인덱스에는 0을 부여하는 단어의 벡터 표현 방식.
# count이 2인 값 인덱스 확인 및 제거
count_2=data_raw[data_raw['count']==2].index
data=data_raw.drop(count_2, inplace=False)
# 컬럼 이름 및 값 수정
data=data.rename(columns={'before1':'after1','before1':'after2'})
data=data.replace({'20대' : '20_age','30대' : '30_age'})
# One-Hot encoding (나이 & 성별)
sex_feature=pd.get_dummies(datan['sex'])
data=pd.concat([data,sex_feature],axis=1)
age_feature=pd.get_dummies(data['age'])
data=pd.concat([data,age_feature],axis=1)
# 제외할 column
datathon=datathon.drop(['sex','age'],axis=1)
5. Train, Test set 나누기
- test_size: test데이터의 비율
- random_state: 호출할 때마다 같은 학습/테스트 용 데이터 세트를 생성하기 위해 주어지는 난수 발생 값. train_test_split()는 호출 시 무작위로 데이터를 분리하므로 random_state를 지정하지 않으면 수행할 때마다 다른 학습/테스트 용 데이터를 만들 수 있습니다. 동일한 데이터 세트로 분리하기 위해 random_state를 일정한 숫자 값으로 부여하면 됩니다.
- stratify: 계층적 데이터 추출 옵션(데이터 분포에 맞춰 잘 분활한다 !! 따라서 저는 y에 있는 outcom비율에 맞게 분할되는 것 -outcome 은 0과 1 존재)
X = df.drop(['outcome'], axis=1)
y = df['outcome']
x_train, x_test, y_train, y_test=train_test_split(x, y, test_size=0.3, random_state=42, stratify=y)
# check the shape of X_train and X_test
X_train.shape, X_test.shape
6. 교차검증
- cv함수 : 교차 검증을 하기 위한 함수 생성. 저는 총 5번의 교차 검증을 하기 위해 아래와 같이 cv값을 5로 넣어주었습니다.
# 교차검증
def cv(clf, x_train, y_train):
accuracy=cross_val_score(clf, x_train, y_train, scoring='accuracy', cv=5)
precision=cross_val_score(clf, x_train, y_train, scoring='precision', cv=5)
recall=cross_val_score(clf, x_train, y_train, scoring='recall', cv=5)
f1=cross_val_score(clf, x_train, y_train, scoring='f1', cv=5)
roc_auc=cross_val_score(clf, x_train, y_train, scoring='roc_auc', cv=5)
print("Cross Validation : 5")
print("정확도(Accuracy) - 평균 검증 : ", np.round(np.mean(accuracy), 5)," 교차 검증별 : ", np.round(accuracy, 5))
print("정밀도(Precision) - 평균 검증 : ", np.round(np.mean(precision), 5), " 교차 검증별 : ", np.round(precision, 5))
print("재현율(Recall) - 평균 검증 : ", np.round(np.mean(recall), 5), " 교차 검증별 : ", np.round(recall, 5))
print("F1 score - 평균 검증 : ", np.round(np.mean(f1), 5), " 교차 검증별 : ", np.round(f1, 5))
print("AUC - 평균 검증 : ", np.round(np.mean(roc_auc), 5), " 교차 검증별 : ", np.round(roc_auc, 5),"\n")
7. 모델 정확도 평가
- 정확도, 정밀도, 재현율, F1 score, AUC확인(round사용하여 소수점 5번째 자리 반올림)
from sklearn.metrics import accuracy_score, f1_score, confusion_matrix, precision_score, recall_score, roc_auc_score
# 모델 정확도 평가
def pred_eval(y_test, y_pred, model):
print("Model : ", model)
print('정확도(Accuracy) : ' , round(accuracy_score(y_test, y_pred), 5))
print('정밀도(Precision) : ' , round(precision_score(y_test, y_pred), 5))
print('재현율(Recall) : ' , round(recall_score(y_test, y_pred), 5))
print('F1 score : ' , round(f1_score(y_test, y_pred), 5))
print('AUC : ' , round(roc_auc_score(y_test, y_pred), 5),"\n")
8. RandomForestClassifier 실행
- GridSearchCV하는 과정에서 n_jobs=30으로 정해줌으로써 cpu자원을 3000까지 쓸 수 있도록 제한 하였습니다. (현재 docker container로 작업중이여서 가지고 있는 cpu자원이 80개 한정이라 30정도로 잡아주었고, 일반 컴퓨터에서 실행하시는거면 cpu자원이 제한되어 있기 때문에 확인 후 가지고 있는 cpu자원을 전체 사용하려면 n_jobs=-1로 작성하면 됩니다.)
- verbose=2 로 할당해주면 현재 어디까지 진행되고 있는지 실시간을 출력됩니다.
- cv_results_ : 는 위 파라미터의 경우의 수를 다 뽑아 score점수를 볼 수 있습니다. 경우의 수가 얼마 안되는 경우 print를 사용해서 보면 되지만 저는 경우의 수가 너무 많아 csv파일로 따로 뽑아 확인해 보고, 파라미터 조정을 계속 해주었습니다.
from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestClassifier
# 랜덤포레스트 실행
def rf_best(x_train, y_train, x_test, y_test):
#find best parameter
start=time()
clf = RandomForestClassifier()
params = {'n_estimators' : list(range(50,400,10)),
'max_depth' : list(range(4,20,15)),
'min_samples_leaf' : list(range(4,20,1)),
'min_samples_split' : list(range(2,20,1))}
grid_cv = GridSearchCV(clf, param_grid=params, cv=5, n_jobs=30, verbose=2)
grid_cv.fit(x_train, y_train)
# 보통 best_params만 확인하지만 저는 혹시 모를 상황에 모든 parameter들의 점수를 확인한 후 추출하는 과정을 시행하였습니다.
score_df=pd.DataFrame(grid_cv.cv_results_)
# 양이 너무 많기 때문에 csv로 따로 저장
score_df.to_csv("/save/score_df_rf.csv")
#print(score_df)
best_params = pd.DataFrame.from_records([grid_cv.best_params_])
print(best_params)
print("best parameter(RF) - find best parameter : {} 분\n".format(round((time()-start)/60, 2)))
#input best parameter
start=time()
clf = RandomForestClassifier(n_estimators = int(best_params['n_estimators']),
max_depth = int(best_params['max_depth']),
min_samples_leaf = int(best_params['min_samples_leaf']),
min_samples_split = int(best_params['min_samples_split']))
clf.fit(x_train, y_train)
y_pred=clf.predict(x_test)
feature_importance = clf.feature_importances_
pred_eval(y_test, y_pred, "Random Forest, Best")
print("best parameter(RF) - model fit : {} 분\n".format(round((time()-start)/60, 2)))
return y_pred, feature_importance
9. feature importance확인 및 confusuon matrix확인
import seaborn as sns
import matplotlib.pyplot as plt
# figure 함수
def feature_impo(feature_importance, X_train, model):
feature_imp=np.array(feature_importance)
feature_name=np.array(X_train.columns)
data={"feature_name": feature_name, "feature_importance":feature_imp}
data=pd.DataFrame(data)
data.sort_values(by=['feature_importance'], ascending=False, inplace=True)
plt.figure(figsize=(10,20))
sns.barplot(x=data['feature_importance'], y=data["feature_name"])
plt.title(model+" feature importance")
plt.show()
return
# 위 시각화를 dataframe으로 보는 작업
def feature_impo_df(feature_importance, X_train):
feature_importance = pd.Series(feature_importance, index=X_train.columns)
feature_top = feature_importance.sort_values(ascending=False)[:len(X_train)]
feature = pd.DataFrame(feature_top.reset_index())
feature.columns = ['feature', 'importance']
return feature
#confusion matrix
def confu(y_test, y_pred, model):
result = pd.concat([y_test.loc[:,['OUTCOME']].reset_index(drop=True),pd.DataFrame(y_pred,columns=['예측값'])],axis=1)
cm=pd.DataFrame(confusion_matrix(result['OUTCOME'],result['예측값']))
sns.heatmap(cm, annot=True, fmt='g')
plt.title(model+" Confusion Metrix")
여기까지 RandomForestClassifier 분석을 마치겠습니다.
'Programming > Machine Learning' 카테고리의 다른 글
[ML] K-Means Clustering (K-평균 군집) (0) | 2023.03.17 |
---|---|
[ML] Association Rule Analysis (연관 규칙 분석) (0) | 2023.03.14 |
[시계열 분석] ARIMA를 이용한 기온 예측 (0) | 2023.01.31 |
[Machine Learning] GridSearchCV 하이퍼 파라미터 튜닝 (0) | 2022.12.01 |
[Machine Learning] Multiple_regression (다중 회귀) (0) | 2022.07.19 |