ㅇ복습
1. R문법과 판다스 비교
2. 머신러닝을 배우기 위해 필요한 문법
3. KNN (이론 : 유클리드 거리 공식, R구현, 파이썬 구현)
4. 나이브베이즈(이론 : 나이브베이즈 확률, R구현, 파이썬 구현)
5. 의사결정트리(이론 : 정보획득량(엔트로피) , R구현, 파이썬 구현)
> 데이터 : 화장품 고객데이터 , 독일은행 데이터, iris 데이터
ㅇ의사결정트리 모델의 불순도 평가방법 3가지
1. 엔트로피(p202)
2. 지니계수
3. 카이제곱 검정
- 파이썬으로 의사결정트리 모델 생성하는 코드
#python
from sklearn.tree import DecisionTreeClassifier
model = DecisionTreeClassifier( criterion='entropy', max_depth=5)
criterion 에 사용할 수 있는 2가지 수학공식
> 엔트로피 (criterion='entropy')
> 지니계수 (criterion='gini')
메뉴얼 : https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html
1. 엔트로피
엔드로피(불순도)가 낮을수록 순도가 높아짐.
2. 지니계수
지니계수가 낮을수록 순도가 높아짐.
49 파이썬으로 의사결정트리 모델 만들기
실험 데이터 : 독버섯 데이터, 독일은행, iris
ㅇ독버섯 데이터를 파이썬으로 이용해서 의사결정 모델 만들기
# 1. 데이터 로드
# 2. 결측치 확인
# 3. 문자 데이터를 숫자로 변경
# 4. 훈련 데이터와 테스트 데이터 분리
# 5. 훈련 데이터 정규화
# 6. 의사결정트리 모델 생성
# 7. 모델 훈련
# 8. 훈련된 모델로 테스트 데이터 예측
# 9. 모델 평가
# 10. 모델 성능 개선
# 1. 데이터 로드
import pandas as pd
mush = pd.read_csv("c:\\data\\mushrooms.csv")
mush.shape #(8124, 23)
mush.head()
type이 label이 되는 정답컬럼
# 2. 결측치 확인
mush.isnull().sum() #결측치 없음 확인
# 3. 문자 데이터를 숫자로 변경(R은 문자데이터 그대로 사용 가능)
mush2 = pd.get_dummies(mush.iloc[:,1:]) # label(type컬럼) 제외하고 데이터 넣어야함
mush2.shape #(8124, 117)
x = mush2 #학습시킬 데이터 구성
y = mush['type'] #정답컬럼 구성
# 4. 훈련 데이터와 테스트 데이터 분리
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.2, random_state = 1)
print(x_train.shape) #(6499, 117)
print(x_test.shape) #(1625, 117)
print(y_train.shape) #(6499,)
print(y_test.shape) #(1625,)
# 5. 훈련 데이터 정규화
# 위에서 0과1로 데이터를 변경했기 때문에 정규화 작업 불필요
# 6. 의사결정트리 모델 생성
from sklearn.tree import DecisionTreeClassifier
model = DecisionTreeClassifier(criterion = 'entropy', max_depth = 5)
정보획득량을 구하는 기준 criterion은 entropy, gini 2가지가 있는데 지금은 entropy를 사용하겠음.
max_depth는 가지의 깊이를 나타냄. 가지의 깊이가 너무 깊으면 훈련 데이터의 정확도는 높은데 테스트 데이터의 정확도가 떨어지는 과대적합 현상이 발생함.
# 7. 모델 훈련
model.fit(x_train, y_train)
# 8. 훈련된 모델로 테스트 데이터 예측
result = model.predict(x_test)
result
# 9. 모델 평가
sum(result == y_test) / len(y_test) * 100 # 100%
from sklearn.metrics import confusion_matrix
a = confusion_matrix(y_test, result)
print(a)
[[820 0]
[ 0 805]] > 정확도 100%
> 나이브 베이즈때는 FN이 1개가 나왔음. 그런데 의사결정트리는 FN이 0이고 정확도도 100%임
문제274. 이번에는 불순도를 계산하는 기준을 entropy말고 gini로 실행하시오.
# 6. 의사결정트리 모델 생성
from sklearn.tree import DecisionTreeClassifier
model_gini = DecisionTreeClassifier(criterion = 'gini', max_depth = 5)
# 7. 모델 훈련
model_gini.fit(x_train, y_train)
# 8. 훈련된 모델로 테스트 데이터 예측
result_gini = model_gini.predict(x_test)
result_gini
# 9. 모델 평가
sum(result_gini == y_test) / len(y_test) * 100 # 99.87692307692308 %
from sklearn.metrics import confusion_matrix
a = confusion_matrix(y_test, result_gini)
print(a)
[[820 0]
[ 2 803]]
> gini는 entropy와 달리 FN이 2로 증가함. 그러면서 정확도도 떨어짐.
> 실험결과 gini는 max_dept를 7 정도 주면 그때부터 정확도 100%의 모델이 나옴.
(cf. max_dept를 지정하지 않으면 기계가 알아서 순수도가 높아질때까지 가지를 치는데 그렇게되면 과대적합이 일어날 수 있으므로 사람이 과대적합이 발생하지 않도록 적절한 값을 지정해줘야함, max_depth의 default는 None)
R에서는 trials 파라미터로 의사결정트리 나무의 갯수를 늘려서 성능을 높였는데 파이썬에서 model = DecisionTreeClassifier(criterion= 'gini', max_depth = 5)에는 trials가 없고 RandomForest를 사용해야 R에서와 같은 trials기능을 사용할 수 있음. 랜덤포레스트는 뒤에서 다룰 예정
ㅇ독일은행 데이터를 파이썬으로 이용해서 의사결정 모델 만들기
R에서 훈련 데이터의 정확도를 91.88889%까지 올렸고, 테스트 데이터의 정확도는 73%까지 올렸음. FN은 21개까지 줄임.
# 1. 데이터 로드
import pandas as pd
credit = pd.read_csv("c:\\data\\credit.csv")
credit.shape #(1000, 17)
credit.head()
# 2. 결측치 확인
credit.isnull().sum() #결측치 없음 확인
# 3. 문자 데이터를 숫자로 변경
# credit.info() # 데이터가 문자, 숫자 섞여있음
credit2 = pd.get_dummies(credit.iloc[:,:-1]) # default컬럼이 label, 숫자데이터는 그대로 문자데이터만 숫자로 변경
credit2.shape #(1000, 44)로 늘어남
x = credit2 # 훈련시킬 데이터
y = credit['default'] # 정답 데이터
# 4. 훈련 데이터와 테스트 데이터 분리
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test = train_test_split(x,y, test_size=0.1, random_state = 1)
print(x_train.shape) #(900, 44)
print(x_test.shape) #(100, 44)
print(y_train.shape) #(900,)
print(y_test.shape) #(100,)
# 5. 훈련 데이터 정규화
# 숫자형 데이터는 단위가 다르므로 모두 정규화작업을 진행해야함
from sklearn.preprocessing import MinMaxScaler # 0~1 사이의 데이터로 정규화
scaler = MinMaxScaler()
scaler.fit(x_train) # 훈련데이터로 Min/Max 정규화 계산
x_train2 = scaler.transform(x_train) # 계산된 내용으로 훈련 데이터를 변경
x_test2 = scaler.transform(x_test) # 계산된 내용으로 테스트 데이터 변경
print(x_train2.max(), x_train2.min()) #1.0 0.0
print(x_test2.max(), x_test2.min()) #1.2142857142857142 0.0
> 테스트 데이터는 최대값이 1이 아님. scaler를 따로 x_test데이터로 훈련시켜서 적용시키면 최대값 1은 맞출 수 있지만 굳이 그럴 필요도 없을 뿐더러 나중에 정확도가 더 떨어짐. 어차피 모델들이 훈련데이터로 학습하기 때문에 훈련데이터에 맞추면 될 듯.
# 6. 의사결정트리 모델 생성
from sklearn.tree import DecisionTreeClassifier
model = DecisionTreeClassifier(criterion = 'entropy', max_depth = 5)
# 7. 모델 훈련
model.fit(x_train2, y_train)
#훈련데이터로 모델 연습 해봄
train_result = model.predict(x_train2)
print(sum(train_result == y_train) / len(y_train) * 100) # 77.0% 정확도
# 8. 훈련된 모델로 테스트 데이터 예측
result = model.predict(x_test2)
result
# 9. 모델 평가
print(sum(result == y_test) / len(y_test) * 100) # 76.0% 정확도
> 훈련데이터의 정확도 R에서는 91.8%였는데 파이썬은 77%, 테스트 데이터의 정확도가 R에서는 73%였는데 파이썬은 76%까지 출력됨.
from sklearn.metrics import confusion_matrix
a = confusion_matrix(y_test, result)
print(a)
[[58 12]
[12 18]] > FN값이 12개로 출력되고 있음.
문제275. (점심시간 문제) 위의 머신러닝 의사결정트리 모델의 성능이 조금 더 올라갈 수 있는지 max_depth를 조정해서 실험하시오.
max_depth = 5
훈련 데이터의 정확도 : 77%
테스트 데이터의 정확도 : 76%
FN값 : 12개
# 10. 모델 성능 개선
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import confusion_matrix
import pandas as pd
df_model = []
for i in range(5,31):
model_test = []
model = DecisionTreeClassifier(criterion = 'entropy', max_depth = i,random_state = 1)
model.fit(x_train2, y_train)
train_result = model.predict(x_train2)
train_pct = sum(train_result == y_train) / len(y_train) * 100 # 77.0% 정확도
result = model.predict(x_test2)
test_pct = sum(result == y_test) / len(y_test) * 100 # 76.0% 정확도
a = confusion_matrix(y_test, result)
FN = a[1,0]
model_test.append(i)
model_test.append(round(train_pct,2))
model_test.append(round(test_pct,2))
model_test.append(FN)
df_model.append(model_test)
df = pd.DataFrame(df_model)
df.columns = ['max_depth','train_pct','test_pct','FN']
df
>훈련과 테스트 데이터의 정확도 차이가 크면 오버피팅(과적합). 훈련과 테스트 데이터의 정확도가 적정한 것을 찾아야함.
> 오버피팅이 적으면서 FN값이 작은 max_depth를 정하면 됨.
> 어느 자리에서든지 동일한 결과로 출력되게끔 하려면,
훈련데이터와 테스트 데이터 나눌때, 모델 생성할 때 random_state를 설정해줘야함.
ㅇ iris데이터를 파이썬으로 이용해서 의사결정 모델 만들기
# 1. 데이터 로드
import pandas as pd
iris = pd.read_csv("c:\\data\\iris2.csv")
iris.head() # Sepal.Length,Sepal.Width,Petal.Length,Petal.Width,Species
iris.shape #(150, 5)
# 2. 결측치 확인
iris.isnull().sum() # 결측치 없음
# 3. 문자 데이터를 숫자로 변경
iris.info() # 문자데이터 없음
x = iris.iloc[:,:-1] # 학습데이터
y = iris.iloc[:,-1] # 정답데이터 Sepcies 컬럼
# 4. 훈련 데이터와 테스트 데이터 분리
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x,y,test_size = 0.1, random_state = 1)
print(x_train.shape) #(135, 4)
print(x_test.shape) #(15, 4)
print(y_train.shape) #(135,)
print(y_test.shape) #(15,)
# 5. 훈련 데이터 정규화
# 숫자데이터의 단위들이 모두 다르기때문에 정규화과정 필요
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler() # 정규화 모델 생성
scaler.fit(x_train) # 훈련 데이터로 계산
x_train2 = scaler.transform(x_train) # 계산된 값으로 훈련 데이터 변경해서 변수에 담음
x_test2 = scaler.transform(x_test)
print(x_train2.max(), x_train2.min()) #1.0 0.0
print(x_test2.max(),x_test2.min()) #1.0588235294117647 0.033898305084745756
# 6. 의사결정트리 모델 생성
from sklearn.tree import DecisionTreeClassifier
model = DecisionTreeClassifier(criterion = 'entropy', max_depth = 5, random_state = 1)
# 7. 모델 훈련
model.fit(x_train2, y_train)
# 8. 훈련된 모델로 테스트 데이터 예측
train_result = model.predict(x_train2)
test_result = model.predict(x_test2)
# 9. 모델 평가
print(sum(train_result == y_train) / len(y_train) * 100) # 100% 정확도
print(sum(test_result == y_test ) / len(y_test) * 100) # 100% 정확도
# 10. 모델 성능 개선
# 11. 모델 시각화
from sklearn.tree import plot_tree #의사결정트리를 그리는 모듈
from sklearn import tree #의사결정트리 모듈
import matplotlib.pyplot as plt
plt.figure(figsize = (12,12))
tree.plot_tree(model, filled = True, rounded = True) #filled = True하면 색깔이 표시됨
#rounded = True는 반올림
#plt.savefig('c:\\data\\tree_visualization.jpg') #저장
plt.show()
문제276. (빅데이터 실기시험 3유형) 아래의 wine데이터를 분류하는 분류모델을 생성하고 테스트 데이터의 정확도를 확인하시오. (훈련데이터와 테스트 데이터는 9:1)
데이터 : wine.csv
# 1. 데이터 로드
import pandas as pd
wine = pd.read_csv("c:\\data\\wine.csv")
wine.shape #(178, 14)
wine.head() #Type컬럼이 label
# 2. 결측치 확인
wine.isnull().sum() #결측치 없음
# 3. 문자 데이터를 숫자로 변경
# 문자 데이터 없음
x = wine.iloc[:,1:]
y = wine.iloc[:,0]
# 4. 훈련 데이터와 테스트 데이터 분리
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x,y,test_size = 0.1, random_state = 1)
# 5. 훈련 데이터 정규화
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
scaler.fit(x_train)
x_train2 = scaler.transform(x_train)
x_test2 = scaler.transform(x_test)
print(x_train2.min(), x_train2.max()) #0.0 1.0000000000000002
print(x_test2.min(), x_test2.max()) #-0.0326530612244898 0.9051355206847361
# 6. 의사결정트리 모델 생성
from sklearn.tree import DecisionTreeClassifier
model_wine = DecisionTreeClassifier(criterion = 'entropy', max_depth = 5, random_state = 1)
model_wine
# 7. 모델 훈련
model_wine.fit(x_train2, y_train)
# 8. 훈련된 모델로 테스트 데이터 예측
result_train = model_wine.predict(x_train2)
result_test = model_wine.predict(x_test2)
# 9. 모델 평가
print(sum(result_train == y_train)/len(y_train) * 100) #100.0
print(sum(result_test == y_test)/len(y_test) * 100) #88.88888888888889
from sklearn.metrics import confusion_matrix
cross = confusion_matrix(y_test, result_test)
cross
# 10. 모델 성능 개선
for i in range(1,30):
model_wine = DecisionTreeClassifier(criterion = 'entropy', max_depth = i, random_state = 1)
model_wine.fit(x_train2, y_train)
result_train = model_wine.predict(x_train2)
result_test = model_wine.predict(x_test2)
train_pct = sum(result_train == y_train)/len(y_train) * 100
test_pct = sum(result_test == y_test)/len(y_test) * 100
print('i = %d ---> train_pct : %s%%, test_pct : %s%%'%(i,train_pct, test_pct))
> max_depth가 2일때 테스트 데이터의 정확도 94.44% 모델이 가장 적합해 보임.
> 파이썬의 의사결정트리는 R의 의사결정트리처럼 여러개의 의사결정트리를 만들 수 있는 trials가 없음. 그래서 R에서처럼 의사결정트리를 여러개로 만들어서 샘플 데이터로 훈련하여 정답을 voting(다수결)로 구현하려면 RandomForest를 쓰면 됨.
문제277. 위의 wine데이터를 분류하는 모델을 RandomForest(의사결정트리 + 앙상블)로 구현
> 의사결정트리 모델
from sklearn.tree import DecisionTreeClassifier
model_wine = DecisionTreeClassifier(criterion = 'entropy', max_depth = 5, random_state = 1)
> 랜덤포레스트 모델
# 랜덤포레스트
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier(n_estimators = 5, random_state = 1)
model.fit(x_train2, y_train)
result_train = model.predict(x_train2)
result_test = model.predict(x_test2)
print(sum(result_train == y_train)/len(y_train) * 100) #100.0
print(sum(result_test == y_test)/len(y_test) * 100) #100.0
+) 전체 코드
# 1. 데이터 로드
import pandas as pd
wine = pd.read_csv("c:\\data\\wine.csv")
wine.shape #(178, 14)
wine.head() #Type컬럼이 label
# 2. 결측치 확인
wine.isnull().sum() #결측치 없음
# 3. 문자 데이터를 숫자로 변경
# 문자 데이터 없음
x = wine.iloc[:,1:]
y = wine.iloc[:,0]
# 4. 훈련 데이터와 테스트 데이터 분리
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x,y,test_size = 0.1, random_state = 1)
# 5. 훈련 데이터 정규화
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
scaler.fit(x_train)
x_train2 = scaler.transform(x_train)
x_test2 = scaler.transform(x_test)
# print(x_train2.min(), x_train2.max()) #0.0 1.0000000000000002
# print(x_test2.min(), x_test2.max()) #-0.0326530612244898 0.9051355206847361
# 6. 의사결정트리 모델 생성
from sklearn.tree import DecisionTreeClassifier
model_wine = DecisionTreeClassifier(criterion = 'entropy', max_depth = 5, random_state = 1)
model_wine
# 7. 모델 훈련
model_wine.fit(x_train2, y_train)
# 8. 훈련된 모델로 테스트 데이터 예측
result_train = model_wine.predict(x_train2)
result_test = model_wine.predict(x_test2)
# 9. 모델 평가
train_pct = sum(result_train == y_train)/len(y_train) * 100
test_pct = sum(result_test == y_test)/len(y_test) * 100
print(train_pct, test_pct)
# from sklearn.metrics import confusion_matrix
# cross = confusion_matrix(y_test, result_test)
# cross
# # 10. 모델 성능 개선
# 랜덤포레스트
from sklearn.ensemble import RandomForestClassifier
model_rd = RandomForestClassifier(n_estimators = 5, random_state = 1)
model_rd.fit(x_train2, y_train)
result_train = model_rd.predict(x_train2)
result_test = model_rd.predict(x_test2)
train_pct_rd = sum(result_train == y_train)/len(y_train) * 100
test_pct_rd = sum(result_test == y_test)/len(y_test) * 100
print(train_pct_rd, test_pct_rd)
'Study > class note' 카테고리의 다른 글
머신러닝 / 규칙기반 알고리즘(oneR, Riper) 파이썬 구현 (0) | 2022.02.10 |
---|---|
머신러닝 / 규칙기반 알고리즘(one R,Riper) 이론 및 R로 구현 (0) | 2022.02.09 |
머신러닝 / R로 의사결정트리 모델 구현하기 (0) | 2022.02.08 |
머신러닝 / 의사결정트리 알고리즘 (0) | 2022.02.07 |
머신러닝 / 나이브베이즈 복습 (0) | 2022.02.07 |