학교 머신러닝 수업에서 회귀 프로젝트로 독버섯 분류한 내용입니다. 로지스틱 회귀와 트리 회귀를 통해 독버섯을 분류해봤습니다.
독버섯 데이터
독 버섯 데이터는 UCI와 캐글에 있는 mushroom-classification를 이용하였습니다.
https://www.kaggle.com/datasets/uciml/mushroom-classification
Mushroom Classification
Safe to eat or deadly poison?
www.kaggle.com
프로젝트 설명
현재 독버섯 데이터는 22개의 컬럼과 독성과 식용에 해당하는 1개의 컬럼 데이터가 8124 개가 존재합니다. 이중에서 모든 컬럼을 이용하는 것이 아니라 실제 버섯을 발견했을 때 흔히 알수 있는 컬럼을 이용해 독버섯을 분류할 수 있는지에 대한 프로젝트입니다.
제가 생각한 컬럼은 버섯 모자 색깔, 모자 모양, 모자 표면 느낌, 아가미 색깔,아가미 부착 여부, 냄새, 서식지, 밀도로 생각했습니다. 여기서 밀도는 버섯을 발견했을 때 혼자 자랐는지 뭉쳐서 자랐는지에 대한 데이터입니다.
사용하는 컬럼
•cap-shape: bell=b,conical=c,convex=x,flat=f, knobbed=k,sunken=s
•habitat: grasses=g,leaves=l,meadows=m,paths=p,urban=u,waste=w,woods=d
프로젝트 소스코드
로지스틱 회귀
X = df.drop(["veil-type","bruises","gill-spacing","gill-size","stalk-shape","stalk-root","stalk-surface-above-ring","stalk-surface-below-ring","stalk-color-above-ring","stalk-color-below-ring","ring-number","ring-type","spore-print-color","veil-color"], axis=1)
print(X.shape)
X = pd.get_dummies(X,drop_first=True)
Y = X["class_p"]
X = X.drop(["class_p"],axis=1)
print(X.shape)
버섯 데이터를 먼저 불러옵니다.
X = df.drop(["veil-type","bruises","gill-spacing","gill-size","stalk-shape","stalk-root","stalk-surface-above-ring","stalk-surface-below-ring","stalk-color-above-ring","stalk-color-below-ring","ring-number","ring-type","spore-print-color"], axis=1)
print(X.shape)
X = pd.get_dummies(X,drop_first=True)
Y = X["class_p"]
X = X.drop(["class_p"],axis=1)
print(X.shape)
(8124, 9)
(8124, 48)
앞에서 설명한 컬럼만 남기고 모든 컬럼을 삭제합니다. 그리고 데이터가 범주형 데이터여서 원핫 인코딩을 적용하였습니다.
원핫 인코딩은 해당하는 컬럼의 데이터를 1 나머지를 0으로 변환하는 방법입니다. 48개의 컬럼으로 늘어난 것을 확인할 수 있습니다.
X_train, X_test, y_train, y_test = train_test_split(X, Y, random_state=42, test_size=0.4)
from sklearn.linear_model import LogisticRegression
lr = LogisticRegression()
lr.fit(X_train, y_train)
print("train_score = ",lr.score(X_train,y_train))
print("test_score = ", lr.score(X_test,y_test))
train_score = 0.9917931883463275
test_score = 0.9910769230769231
8124 개의 데이터 중 0.4 비율로 테스트 데이터를 나눈 후 학습한 데이터 예측과 테스트 데이터 예측 결과입니다.
모두 0.99 로 독버섯과 식용버섯을 잘 구분하는 것을 확인 할 수 있습니다.
트리 회귀
from sklearn.tree import DecisionTreeRegressor
from sklearn.preprocessing import LabelEncoder
df = pd.read_csv("mushrooms.csv")
df = df.astype("category")
le=LabelEncoder()
for column in df.columns:
df[column] = le.fit_transform(df[column])
X = df.drop(["veil-type","bruises","gill-spacing","gill-size","stalk-shape","stalk-root","stalk-surface-above-ring","stalk-surface-below-ring","stalk-color-above-ring","stalk-color-below-ring","ring-number","ring-type","spore-print-color","veil-color"], axis=1)
Y = X["class"]
X = X.drop(["class"],axis=1)
X_train, X_test, y_train, y_test = train_test_split(X, Y, random_state=42, test_size=0.4)
Rtree = DecisionTreeRegressor(random_state=1,min_samples_leaf=30,max_depth=10)
Rtree.fit(X_train,y_train)
print("Train Tree ", Rtree.score(X_train,y_train))
print("test Tree ", Rtree.score(X_test,y_test))
Train Tree 0.9533798421647444
test Tree 0.9487696851000633
트리 회귀인 경우 데이터가 예측이 로지스틱 회귀보다 현저히 낮은 것을 확인할 수 있습니다. 따라서 트리 회귀보다는 로지스틱 회귀를 통해 구현하는 것이 모델의 성능을 더 높일 수 있습니다. 하지만 여기서 트리회귀의 성능을 높이기 위해 파라미터 튜닝을 진행해 봤습니다.
from sklearn.model_selection import GridSearchCV
parms = {'min_impurity_decrease':[0.0001,0.0002,0.0003,0.0004,0.0005],
'max_depth' : range(5,50,1),
'min_samples_split' : range(2,100,10)}
gs = GridSearchCV(DecisionTreeRegressor(random_state=42), parms,n_jobs=-1)
gs = gs.fit(X_train, y_train)
bst = gs.best_params_
print(gs.best_score_)
print(bst)
DTR = DecisionTreeRegressor(random_state=42,min_impurity_decrease=0.0001,min_samples_split=2,max_depth=13)
DTR.fit(X_train,y_train)
print("DTR : ", DTR.score(X_train,y_train))
print("DTR : ", DTR.score(X_test,y_test))
0.9772508960286842
{'max_depth': 13, 'min_impurity_decrease': 0.0001, 'min_samples_split': 2}
DTR : 0.9847212193694225
DTR : 0.9720927330269121
파라미터 튜닝 해당하는 결과 해당하는 트리를 만들어 테스트 데이터와 트레인 데이터를 예측해본 결과 정확도가 0.03 정도 오른 것을 확인할 수 있었습니다.
import seaborn as sns
feature_importance_values = DTR.feature_importances_
feature_importances = pd.Series(feature_importance_values, index=X_train.columns)
feature_top5 = feature_importances.sort_values(ascending=False)[:10]
plt.figure(figsize=[8, 6])
plt.title('Feature Importances 5')
sns.barplot(x=feature_top5, y=feature_top5.index)
plt.show()
트리 회귀 결과 중요한 데이터를 seaborn 을 통해 그래프로 표시해봤습니다. 냄새와 아가미 색깔이 독버섯 판별에 중요한 영향을 끼친다는 사실을 알 수 있었습니다.
내용 정리
독버섯 분류에 대한 회귀를 구현하는 방법은 다양하지만 이번 프로젝트에서는 로지스틱 회귀와 트리 회귀를 통해 구현했습니다.
로지스틱 회귀는 데이터가 숫자로 변환됐을 때 끼치는 영향을 방지하기 위해 라벨인코딩이 아닌 원핫인코딩을 이용해 전처리 하였습니다.
트리 회귀 경우 데이터를 단순히 숫자로 변환해도 문제가 생기지 않기 때문에 라벨인코딩을 이용해 전처리하였습니다. 또한 정확도가 낮아 하이퍼 파라미터 튜닝을 진행해 정확도를 올렸습니다.
데이터에 해당하는 모델의 정확도를 올리는 것은 중요합니다. 그것보다도 다양한 방법을 적용해 보는 것도 중요한 것을 이번 프로젝트를 통해 깨달았습니다.
'머신러닝 > 프로젝트' 카테고리의 다른 글
AI를 활용해 무료로 음악 생성해보기 (4) | 2024.11.29 |
---|---|
사칙연산 계산기 MLP 로 구현하기 (0) | 2022.12.21 |