0825
# 머신러닝 모델 (Machine Learning Model)
* 머신러닝 모델은 현재까지의 데이터로 미래의 데이터를 예측하기 위한 모델
* 예측변수(결과를 도출하기 위한 입력데이터)를 통해 타겟변수(결과로 도출된 출력데이터)를 찾아내기 위한 모델
* 예측변수(predictor variables) 예측하는데 활용하는 변수 또는 모델에 입력하는 값
* 타겟변수(target variables) 예측하고자 하는 변수 또는 모델이 출력하는 값
# 의사결정나무 모델 (Decision Model)
* 예/아니오로 2분된 답변을 연속적으로 취득하여 예측하는 모델 (yes/no)
* 구조가 단순하고 이해하기 쉬워 많은 예측 모델의 토대가 됨
* 타겟변수를 가장 잘 분리해 주는 예측변수에 주목하는 모델
(예를 들어 나이,흡연,음주의 예측변수 중 당뇨병(타겟변수)에 가장 영향을 미치는건 흡연)
* 상위노드일수록 타겟변수를 잘 분리해 주는 예측변수를 선택하도록 함
소득 예측 모델 만들기
머신러닝 모델을 통한 소득 예측
# 의사결정나무 모델(지도학습) 만들기 순서 및 방법
1) 전처리
2) 모델 생성
3) 예측 및 성능 평가
# adult데이터 활용
* 미국인의 성별, 인종, 직업, 학력 등 인적 정보 CSV
48,842명, 변수 15개로 구성, 14개 변수는 예측변수, income변수는 타겟변수)
* adult데이터를 예측변수로 활용해 소득을 예측하는 모델 생성
* ML 프로젝트 생성
* assets 폴더 생성
* assets/adult.csv 복사
* pandas, numpy, scikit-learn, matplot 라이브러리 설치
# 크로스 밸리데이션
* 데이터를 분할해 일부는 모델 생성에 사용, 나머지는 성능 평가에 사용
* 트레이닝 세트 : 모델 생성에 사용되는 데이터
* 테스트 세트 : 성능을 평가하는데 사용되는 데이터
* scikit-learn 패키지를 이용해 트레이닝 세트와 테스트 세트로 분할
- test_size : 테스트 세트의 비율
- stratify : 범주 별 비율을 통일할 변수
- random_state : 난수 초기값
* 의사결정나무 노드 해석
1) 노드에 해당하는 관측치 비율 (전체 데이터의 몇 퍼센트가 해당 노드로 분류 되었는지)
2) 타겟 변수의 클래스별 비율 (알파벳 순)
3) 0.5 기준의 우세한 클래스 (타겟 변수의 두 클래스 중 어느쪽이 더 많은지)
4) 분리 기준 (노드 분리의 기준) :
여기서는 원핫인코딩으로 만들어진 기혼(1), 비혼(0) (원핫인코딩 : 특정값이면 1, 아니면 0으로 숫자화)\
value 클래스는 4번인 (기혼.미혼)데이터셋을 각각 23.9% / 76.1%로 나누고 분리합니다.
class=low(or hight) == low클래스는 income에 영향을 미친다고 볼 수 있습니다.
맨 위가 root 노드 , 다음은 브런치, 리프노드입니다.
각각 색이 짙을수록 우세합니다.
어떤 영향이 있을지는 어떻게하냐? 알고리즘이 진행함
1) 데이터 전처리 - 데이터 확인하기
Confusion Matrix( TF,FT, TT, FF) / 빅분기 필기시험
* 정답여부:True/False, 예측방향:Positive/Negative
* 첫번째 열 모델이 2,382명(1,801+582)을high로 예측, 실제 high는 1,801, low는 582
* 두번째 열 모델이 12,270명(1,705+10,565)을 low로 예측, 실제 high는 1,705, low는 10,565
* 정확도(Accuracy, 예측해서 맞춘 비율) : TP+TN / TP+TN+FP+FN
/ 가장 중요함
* 정밀도(Precision, 관심클래스를 예측해서 맞춘 비율) : TP / TP +FP
* 재현율(Recall, 실제데이터에서 관심클래스를 찾아낸 비율) : TP / TP + FN
* F1 Score : 정밀도와 재현율을 함께 반영
실습 파일명 : 0825_01_desiciontree
# decisiontree.py
def p(str):
print(str, '\n')
## 소득 예측 모델 만들기
# 라이브러리
import pandas as pd
import numpy as np
# 데이터 임포트
df = pd.read_csv("../assets/adult.csv")
#df.info()
# 데이터 전처리
# 연소득 5만달러 초과하면 high, 그렇지 않으면 low
df['income'] = np.where(df['income']=='>50K', 'high', 'low')
#p(df['income'].value_counts(normalize=True)) # 범주의 비율
# 타겟변수(=종속변수) 예측에 도움이 안되는 불필요한 변수 제거
df = df.drop(columns="fnlwgt")
# 원핫인코딩(one-hot encoding)을 이용한 문자타입변수를 숫자타입으로 변환
# 원핫인코딩 : 데이터를 모두 1이나 0으로 표시
target = df['income']
df = df.drop(columns='income') # 종속변수 제거
df = pd.get_dummies(df) # 원핫인코딩
df['income'] = target
df.info(max_cols=np.inf) # 변수의 수에 관계없이 모든 변수의 정보 출력
# scikit-learn을 이용하여 트레이닝 세트와 테스트 세트 분리
from sklearn.model_selection import train_test_split
df_train, df_test = train_test_split(
df, # 데이터프레임
test_size=0.3, # 테스트 세트 비율
stratify=df["income"], # 범주별 비율을 통일할 변수
random_state=1234) # 난수 초기값
#p(df_train.shape) # 트레이닝 세트의 행 개수, 변수 개수
#p(df_test.shape) # 테스트 세트의 행 개수, 변수 개수
# 트레이닝 세트와 테스트 세트의 범주별 비율
#p(df_train["income"].value_counts(normalize=True))
#p(df_test["income"].value_counts(normalize=True))
## 의사결정나무 모델 생성
# 라이브러리 임포트
from sklearn import tree
# 의사결정나무분류기 생성
# random_state:랜덤시드값, max_depth:트리의최대깊이
clf = tree.DecisionTreeClassifier(random_state=1234, max_depth=3)
# 예측변수, 타겟변수 추출
train_x = df_train.drop(columns='income') # 예측변수 (전체 15개 변수 중 타겟변수를 제외)
train_y = df_train["income"] # 타겟변수 (예측변수를 통해서 예측하고자 하는 변수)
# 의사결정나무 모델 생성
# fit(X=예측변수, y=타겟변수)
model = clf.fit(X=train_x, y=train_y)
# 모델 시각화
import matplotlib.pyplot as plt
# 그래프 설정
plt.rcParams.update(
{
'figure.dpi': '100', # 그래프 해상도
'figure.figsize': [12, 8] # 그래프 크기
}
)
# 트리그래프
tree.plot_tree(
model, # 모델
feature_names = train_x.columns, # 예측변수명들
class_names = ['high', 'low'], # 타겟변수 클래스 (알파벳 오름차순)
proportion = True, # 비율 표시 여부
filled = True, # 채움 여부
rounded = False, # 노드테두리 둥글게 할지 여부
impurity = False, # 불순도 표시 여부
label = 'root', # 제목 표시 위치
fontsize = 10 # 글자 크기
)
plt.show()
여기서 확인할 수 있는 자료는 root가 가장 큰 수입의 영향이 있고 그 다음은 결혼여부 그다음은 교육기간(학벌)
다음은 나이 등등 으로 의사결정나무가 뻗어나갑니다.
# 아래의 코드는 이어서 작성한 코드임
#comfusion_matrix
# 예측을 위한 예측변수, 타겟변수 추출 / test데이터 사용
test_x = df_test.drop(columns='income') #예측변수
test_y = df_test['income'] #타겟변수
# 모델을 통한 예측
df_test['pred'] = model.predict(test_x)
p(df_test)
#예측 성능 평가
# 컴퓨전매트릭스 라이브러리
from sklearn.metrics import confusion_matrix
# 컴퓨전매트릭스 생성
conf_mat = confusion_matrix(
y_true = df_test['income'], #실제값
y_pred = df_test['pred'], #예측값
labels = ['high', 'low'] #레이블(클래스 배치 순서, 알파벳 오름차순)
)
p(conf_mat)
#컴퓨전매트릭스를 히트맵으로 표시
#그래프설정 되돌리기
#이전에 그래프설정을 초기화해주는 함수
plt.rcdefaults()
#라이브러리설치
from sklearn.metrics import ConfusionMatrixDisplay
p = ConfusionMatrixDisplay(
confusion_matrix= conf_mat, #매트릭스 데이터
display_labels= ('high', 'low'), #타겟변수 클래스명
)
p.plot(cmap='Blues') #컬러맵
plt.show()
이제는 이 값들을 가지고 정확도를 구하는 함수를 작성했습니다.
#성능평가 지표 구하기
#라이브러리
import sklearn.metrics as metrics
# Accuracy : 정확도를 구하는 함수
acc = metrics.accuracy_score(
y_true = df_test['income'], #실제값
y_pred = df_test['pred'], #예측값
)
p(acc)
를 하면 값은0.8439227461953184 가 나오고 즉 84%가 나오게 됩니다.
# Precision : 정밀도
pre = metrics.precision_score(
y_true = df_test['income'], #실제값
y_pred= df_test['pred'], #예측값
pos_label= 'high' # 관심클래스
)
p(pre)
정밀도(클래스별 정확도)는 0.7557700377675199 가 나오고 75.5%로 볼 수 있습니다.
#Recall : 재현율
rec = metrics.recall_score(
y_true = df_test['income'], #실제값
y_pred= df_test['pred'], #예측값
pos_label= 'high' # 관심클래스
)
p(rec)
재현율을 보면 0.5136908157444381 가 나오고 즉 51.3%입니다
# F1 Score
f1 = metrics.f1_score(
y_true = df_test['income'], #실제값
y_pred= df_test['pred'], #예측값
pos_label= 'high' # 관심클래스
)
p(f1)
F1 Score은 0.6116488368143997 가 나오고 즉 61.1%입니다.
F1 Score은 재현율과 정밀도 그 사이로 나옵니다.
0825_02_decisionmodellib
# decisionmodellib.py
## 디씨젼트리 모델 라이브러리
# 라이브러리 로딩
import numpy as np
import pandas as pd
from sklearn.metrics import confusion_matrix, accuracy_score, classification_report
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier, plot_tree
import matplotlib.pyplot as plt
# 데이터셋 로딩 함수
def importdata(filename):
balance_data = pd.read_csv(
filename,
sep=',',
header=None
)
print("데이터셋 길이 : ", len(balance_data))
print("데이터셋 모양 : ", balance_data.shape)
print("데이터셋 (상위 5행) : ", balance_data.head())
return balance_data
#print(importdata(filename))
# 예측변수, 타겟변수 분리 함수
def splitdataset(balance_data):
X = balance_data.values[:, 1:5] # 예측변수
Y = balance_data.values[:, 0] # 타겟변수
X_train, X_test, y_train, y_test = train_test_split(
X, Y, test_size=0.3, random_state=100
)
return X, Y, X_train, X_test, y_train, y_test
# 디씨젼트리분류기 생성 및 학습 함수
def train_using_gini(X_train, X_test, y_train):
clf_gini = DecisionTreeClassifier(
criterion='gini', # 분류기의 종류(분류알고리즘)
random_state=100, # 랜덤시드값
max_depth=3, # 트리 뎁스
min_samples_leaf=5 # leaf노드 최소 개수
)
clf_gini.fit(X_train, y_train)
return clf_gini
# 예측 함수
def prediction(X_test, clf_object):
y_pred = clf_object.predict(X_test)
print("예측값 : ", y_pred)
return y_pred
# 컨퓨젼매트릭스, 정확도, 레포트 출력 함수
def cal_accuracy(y_test, y_pred):
print("컨퓨젼매트릭스 : ", confusion_matrix(y_test, y_pred))
print("정확도 : ", accuracy_score(y_test, y_pred) * 100)
print("레포트 : ", classification_report(y_test, y_pred))
# 디씨젼트리 가시화 함수
def plot_decision_tree(clf_object, feature_names, class_names):
plt.figure(figsize=(15, 10))
plot_tree(
clf_object,
filled=True,
feature_names=feature_names,
class_names=class_names,
rounded=True
)
plt.show()
# 실행
filename = 'https://archive.ics.uci.edu/ml/machine-learning-databases/balance-scale/balance-scale.data'
df = importdata(filename)
X, Y, X_train, X_test, y_train, y_test = splitdataset(df)
clf = train_using_gini(X_train, X_test, y_train)
plot_decision_tree(
clf,
['X1', 'X2', 'X3', 'X4'],
['L', 'B', 'R']
)
이렇게되면 함수는 일회용으로 사용할 가능성이 크기때문에 함수에 있는 상수인자값들을 모두 변환해주었습니다.
나중에 값이 변경되더라도 함수는 사용할 수 있게끔말이죠.
# decisionmodellib.py
## 디씨젼트리 모델 라이브러리
# 라이브러리 로딩
import numpy as np
import pandas as pd
from sklearn.metrics import confusion_matrix, accuracy_score, classification_report
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier, plot_tree
import matplotlib.pyplot as plt
# 데이터셋 로딩 함수
def importdata(filename):
balance_data = pd.read_csv(
filename,
sep=',',
header=None
)
print("데이터셋 길이 : ", len(balance_data))
print("데이터셋 모양 : ", balance_data.shape)
print("데이터셋 (상위 5행) : ", balance_data.head())
return balance_data
# print(importdata(filename))
# 예측변수, 타겟변수 분리 함수
def splitdataset(balance_data, X, Y, test_size, random_state):
X_train, X_test, y_train, y_test = train_test_split(
X, Y, test_size=test_size, random_state=random_state
)
return X, Y, X_train, X_test, y_train, y_test
# 디씨젼트리분류기 생성 및 학습 함수
def train_using(criterion, random_state, md, msl, X_train, X_test, y_train):
clf = DecisionTreeClassifier(
criterion=criterion, # 분류기의 종류(분류알고리즘)
random_state=random_state, # 랜덤시드값
max_depth=md, # 트리 뎁스
min_samples_leaf=msl # leaf노드 최소 개수
)
clf.fit(X_train, y_train)
return clf
# 예측 함수
def prediction(X_test, clf_object):
y_pred = clf_object.predict(X_test)
print("예측값 : ", y_pred)
return y_pred
# 컨퓨젼매트릭스, 정확도, 레포트 출력 함수
def cal_accuracy(y_test, y_pred):
print("컨퓨젼매트릭스 : ", confusion_matrix(y_test, y_pred))
print("정확도 : ", accuracy_score(y_test, y_pred) * 100)
print("레포트 : ", classification_report(y_test, y_pred))
# 디씨젼트리 가시화 함수
def plot_decision_tree(figsize, clf_object, feature_names, class_names):
plt.figure(figsize=figsize)
plot_tree(
clf_object,
filled=True,
feature_names=feature_names,
class_names=class_names,
rounded=True
)
plt.show()
# 실행
filename = 'https://archive.ics.uci.edu/ml/machine-learning-databases/balance-scale/balance-scale.data'
df = importdata(filename)
X = df.values[:, 1:5] # 예측변수
Y = df.values[:, 0] # 타겟변수
X, Y, X_train, X_test, y_train, y_test \
= splitdataset(df, X, Y, 0.3, 1234)
clf = train_using('gini', 1234, 3, 5, X_train, X_test, y_train)
plot_decision_tree(
(15, 10),
clf,
['X1', 'X2', 'X3', 'X4'],
['L', 'B', 'R']
)
최종적으로 컴퓨전매트릭스까지도 함수화를 만들어놓으면 그냥 언제든지 쓸 수 있는 함수로 사용할 수 있습니다.
# decisionmodellib.py
## 디씨젼트리 모델 라이브러리
# 라이브러리 로딩
import numpy as np
import pandas as pd
from sklearn.metrics import confusion_matrix, accuracy_score, classification_report
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier, plot_tree
from sklearn.metrics import ConfusionMatrixDisplay
import matplotlib.pyplot as plt
# 데이터셋 로딩 함수
def importdata(filename):
balance_data = pd.read_csv(
filename,
sep=',',
header=None
)
print("데이터셋 길이 : ", len(balance_data))
print("데이터셋 모양 : ", balance_data.shape)
print("데이터셋 (상위 5행) : ", balance_data.head())
return balance_data
# print(importdata(filename))
# 예측변수, 타겟변수 분리 함수
def splitdataset(balance_data, X, Y, test_size, random_state):
X_train, X_test, y_train, y_test = train_test_split(
X, Y, test_size=test_size, random_state=random_state
)
return X, Y, X_train, X_test, y_train, y_test
# 디씨젼트리분류기 생성 및 학습 함수
def train_using(criterion, random_state, md, msl, X_train, X_test, y_train):
clf = DecisionTreeClassifier(
criterion=criterion, # 분류기의 종류(분류알고리즘)
random_state=random_state, # 랜덤시드값
max_depth=md, # 트리 뎁스
min_samples_leaf=msl # leaf노드 최소 개수
)
clf.fit(X_train, y_train)
return clf
# 예측 함수
def prediction(X_test, clf_object):
y_pred = clf_object.predict(X_test)
print("예측값 : ", y_pred)
return y_pred
# 컨퓨젼매트릭스, 정확도, 레포트 출력 함수
def cal_accuracy(y_test, y_pred):
print("컨퓨젼매트릭스 : ", confusion_matrix(y_test, y_pred))
print("정확도 : ", accuracy_score(y_test, y_pred) * 100)
print("레포트 : ", classification_report(y_test, y_pred))
# 컨퓨젼매트릭스 가시화 함수
def plot_confusion_matrix(conf_mat, dl, cmap):
p = ConfusionMatrixDisplay(
confusion_matrix=conf_mat, # 매트릭스 데이터
display_labels=dl # 타겟변수 클래스명
)
p.plot(cmap=cmap) # 컬러맵
plt.show()
# 디씨젼트리 가시화 함수
def plot_decision_tree(figsize, clf_object, feature_names, class_names):
plt.figure(figsize=figsize)
plot_tree(
clf_object,
filled=True,
feature_names=feature_names,
class_names=class_names,
rounded=True
)
plt.show()
# 실행
filename = 'https://archive.ics.uci.edu/ml/machine-learning-databases/balance-scale/balance-scale.data'
df = importdata(filename)
X = df.values[:, 1:5] # 예측변수
Y = df.values[:, 0] # 타겟변수
X, Y, X_train, X_test, y_train, y_test \
= splitdataset(df, X, Y, 0.3, 1234)
clf = train_using('gini', 1234, 3, 5, X_train, X_test, y_train)
plot_decision_tree(
(15, 10),
clf,
['X1', 'X2', 'X3', 'X4'],
['L', 'B', 'R']
)
순번 | 함수(매소드) | 설명 |
1 | tree.DecisionTreeClassifier(random_state=1234, max_depth=3) | 의사나무결정 분류기 생성(옵션확인) |
2 | 변수.flt(X= ,y= ) | 의사결정나무 모델 생성 변수 (X= 예측변수, y=타겟변수)를 작성 |
'데이터 분석 및 시각화' 카테고리의 다른 글
[ML]K-Means 클러스터링, DBSCAN(밀도기반 클러스터링) (0) | 2024.09.12 |
---|---|
[ML]클러스터링_집값 상관관계 분석해보기 (0) | 2024.09.11 |
[데이터분석]ML_교차검증_타이타닉생존자 데이터셋 (0) | 2024.08.29 |
[데이터분석] ML_linearregression(선형회귀) (0) | 2024.08.23 |
[데이터분석] ML(머신러닝)_basic, 데이터 분리 (0) | 2024.08.21 |