수업에서 배운 오로지 수업에 의한
기본적으로 성능을 고려하지는 않음
우선, 다시 스케일링을 했다. 이유는 통일성을 위해서와 여러 전처리를 겪다보니 상당히 더러워진 데이터를 처음부터 정제하기 위해서.
아무튼 다시 전처리를 진행했고 그 내용은 (2) 와 별반 다르지 않다.
이를 바탕으로 Regression이나 Classification 모두를 사용해보았다.
물론 Regression이 연속형 데이터 셋에서 사용해야겠지만 처음에 의도했던 가중치를 구하고 점수화하기 위해서는 Regression도 꽤 괜찮은 시도이지 않나 생각한다. (반박시 니말 맞음)

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
# 독립변수와 종속변수 분리
X = scaled_df.drop('체형(5단계)', axis=1)
y = scaled_df['체형(5단계)']
# 학습용 데이터와 테스트용 데이터로 분할
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 선형회귀 모델 생성
model = LinearRegression()
# 모델 학습
model.fit(X_train, y_train)
# 테스트 데이터로 예측
y_pred = model.predict(X_test)
# 모델 평가
print('Mean Squared Error:', mean_squared_error(y_test, y_pred))
print('R-squared:', r2_score(y_test, y_pred))
# 회귀 계수 및 절편 확인
print('회귀 계수:', model.coef_)
print('절편:', model.intercept_)
이렇게 했고,
Mean Squared Error: 0.40243497053114224
R-squared: 0.39775192031961526
회귀 계수: [-9.37354968e-01 -4.02410453e-02 1.91497713e-02 3.08648919e-02
-1.55393524e-01 -6.55652814e-02 2.08768800e+01]
절편: 1.7824412288754636
이런 결과를 얻었다. 물론 데이터가 전부 0~1로 minmax scaling되어있어서 값자체가 매우 작게 나온 부분도 존재한다.
그리고 성능이 떨어진다면 어쩔수 없다. 데이터가 너무 구림(설문조사데이터라서)
시각화하면

다음은 classification이다.
우선 기존의 음주량, 흡연량 같은 데이터를 범주형으로 바꿔주고
의사결정나무->랜덤포레스트->랜덤포레스트 Grid Serach로 확대했다.
data['일반담배 하루 흡연량'] = np.select(
[data['일반담배 하루 흡연량'] <= 0, (data['일반담배 하루 흡연량'] > 0) & (data['일반담배 하루 흡연량'] <= 10),
(data['일반담배 하루 흡연량'] > 10) & (data['일반담배 하루 흡연량'] <= 19),
(data['일반담배 하루 흡연량'] > 19) & (data['일반담배 하루 흡연량'] <= 80)],
[0, 1, 2, 3]
)
data['주간 음주 총량'] = np.select(
[data['주간 음주 총량'] <= 0, (data['주간 음주 총량'] > 0) & (data['주간 음주 총량'] <= 1),
(data['주간 음주 총량'] > 1) & (data['주간 음주 총량'] <= 10),
(data['주간 음주 총량'] > 10) & (data['주간 음주 총량'] <= 44)],
[0, 1, 2, 3]
)
범주형으로 바꿔주고
1. 의사결정나무
X = data[['격렬한 신체활동 일수', '중증도 신체활동 일수', '걷기 실천 일수', '주간 아침식사 일수', '일반담배 하루 흡연량', '주간 음주 총량']]
y = data['체형']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
model2 = DecisionTreeClassifier(random_state=42)
model2.fit(X_train, y_train)
accuracy = model2.score(X_test, y_test)
print(f"의사결정나무 모델의 정확도: {accuracy}")
의사결정나무 모델의 정확도: 0.44363034743559443
2. 랜덤포레스트
from sklearn.ensemble import RandomForestClassifier
X = data[['격렬한 신체활동 일수', '중증도 신체활동 일수', '걷기 실천 일수', '주간 아침식사 일수', '일반담배 하루 흡연량', '주간 음주 총량']]
y = data['체형']
# 데이터를 훈련 세트와 테스트 세트로 나눔
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 랜덤 포레스트 모델 생성 및 훈련
rf_model = RandomForestClassifier(n_estimators=100, random_state=42)
rf_model.fit(X_train, y_train)
# 모델 평가
accuracy = rf_model.score(X_test, y_test)
print(f"랜덤 포레스트 모델의 정확도: {accuracy}")
랜덤 포레스트 모델의 정확도: 0.45402978019380763
3. 그리드 서치
from sklearn.model_selection import train_test_split, GridSearchCV
X = data[['격렬한 신체활동 일수', '중증도 신체활동 일수', '걷기 실천 일수', '주간 아침식사 일수', '일반담배 하루 흡연량', '주간 음주 총량']]
y = data['체형']
# 데이터를 훈련 세트와 테스트 세트로 나눔
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 탐색할 하이퍼파라미터 그리드 설정
param_grid = {
'n_estimators': [100, 150, 200, 300], # 트리의 개수
'max_depth': [10, 20, 30, 40], # 트리의 최대 깊이
# 추가적인 하이퍼파라미터 설정 가능
}
# 랜덤 포레스트 모델 생성 및 훈련
rf_model = RandomForestClassifier(random_state=42)
rf_model.fit(X_train, y_train)
grid_search = GridSearchCV(estimator=rf_model, param_grid=param_grid, cv=3, n_jobs=-1, verbose=2)
grid_search.fit(X_train, y_train)
# 최적의 하이퍼파라미터와 최고 성능 출력
print("최적의 하이퍼파라미터:", grid_search.best_params_)
print("최고 성능:", grid_search.best_score_)
# 최적의 모델로 테스트 세트 평가
best_model = grid_search.best_estimator_
test_accuracy = best_model.score(X_test, y_test)
print("테스트 세트 정확도:", test_accuracy)
Fitting 3 folds for each of 16 candidates, totalling 48 fits
최적의 하이퍼파라미터: {'max_depth': 10, 'n_estimators': 200}
최고 성능: 0.4730839685634935
테스트 세트 정확도: 0.47624675017726303
어떻게 해도 성능이 0.5를 못넘는다. 이게 분류를 제대로 하는게 맞나 싶은데 워낙 row가 많고 피쳐의 응답이 부정확하며 어쩌면 애초에 비만과 우리가 정한 요인간의 가설이 부정확한것은 아니었나 생각해본다.
2023.11.30 내용 수정
-BMI 를 feature에 추가
-target attribute를 1,2로 binary한 상태로 바꿈
첨부파일 참고
'IE & SWCON > Data Science' 카테고리의 다른 글
새로운 비만 평가 지표를 만들기 위해서 (2) (1) | 2023.11.14 |
---|---|
새로운 비만 평가 지표를 만들기 위해서 (1) (0) | 2023.11.10 |
[금융공공데이터취합] 재정패널조사 (0) | 2023.09.16 |
[캐글] 랜덤포레스트 회귀기법으로 자전거 사용량 예측하기 (0) | 2023.05.01 |
[부스트코스] 건강정보데이터 분석하기 (0) | 2023.03.22 |