[프로젝트로 배우는 데이터사이언스] 탐색한 데이터로 모델성능 개선

문유주·2021년 10월 3일
0

💎 탐색한 데이터로 모델성능 개선

🔼 성능 개선

# 임신 횟수가 7회 이상이면 당뇨병 발병 확률이 높다는 것을 알았으므로
# 전체 임신 횟수 데이터를 제외하고 임신 횟수가 7회 이상일 때의 데이터만 이용
train = df[:614].copy()
test = df[614:].copy()
feature_names2 = train.columns.tolist()
feature_names2.remove("Pregnancies")
feature_names2.remove("Outcome")
label_name = 'Outcome'

X_train = train[feature_names2]
y_train = train[label_name]
X_test = test[feature_names2]
y_test = test[label_name]

# 머신러닝 알고리즘 가져오기
from sklearn.tree import DecisionTreeClassifier
model = DecisionTreeClassifier()

# 학습
model.fit(X_train, y_train)

# 예측
y_predict = model.predict(X_test)

# 실제값 - 예측값에 절대값을 씌운 값이 1이면 틀린 예측 >> output 42에서 36으로 바뀜
diff_count = abs(y_test - y_predict).sum()

# 예측의 정확도 >> output 72%에서 76%로 올라감
(len(y_test) - diff_count) / len(y_test) * 100
# 범주형 카테코리를 수치형 카테코리로 변환시켜 적용
# 나이 데이터를 25세미만, 25세이상 60세미만, 60세이상으로 나눔
df["Age_low"] = df["Age"] < 25
df["Age_middle"] = (df["Age"] >= 25) & (df["Age"] <= 60)
df["Age_high"] = df["Age"] > 60
df[["Age", "Age_low", "Age_middle", "Age_high"]].head()

train = df[:614].copy()
test = df[614:].copy()
feature_names3 = train.columns.tolist()
feature_names3.remove("Pregnancies")
feature_names3.remove("Outcome")
label_name = 'Outcome'

X_train = train[feature_names3]
y_train = train[label_name]
X_test = test[feature_names3]
y_test = test[label_name]

# 머신러닝 알고리즘 가져오기
model = DecisionTreeClassifier()

# 학습
model.fit(X_train, y_train)

# 예측
y_predict = model.predict(X_test)

# 실제값 - 예측값에 절대값을 씌운 값이 1이면 틀린 예측 >> output 36에서 40으로 바뀜
diff_count = abs(y_test - y_predict).sum()

# 예측의 정확도 >> output 76%에서 74%로 내려감
(len(y_test) - diff_count) / len(y_test) * 100

# 이전보다 성능이 나빠졌으므로 사용하지 않음
df = df.drop(["Age_low","Age_middle","Age_high"], axis=1)
# 인슐린의 0 값을 null로 채우는 컬럼 생성
df["Insulin_nan"] = df["Insulin"].replace(0, np.nan)
df[["Insulin", "Insulin_nan"]].head()

# 당뇨병이 발병했을 때와 하지 않았을 때의 인슐린 수치 평균/중앙값 확인
df.groupby(["Outcome"])["Insulin", "Insulin_nan"].agg(["mean", "median"])

#결측치를 인슐린 수치 중앙값으로 대체
df.loc[(df["Outcome"] == 0) & (df["Insulin_nan"].isnull()), "Insulin_nan"] = 102.5
df.loc[(df["Outcome"] == 1) & (df["Insulin_nan"].isnull()), "Insulin_nan"] = 169.5

train = df[:614].copy()
test = df[614:].copy()
feature_names4 = train.columns.tolist()
feature_names4.remove("Pregnancies")
feature_names4.remove("Insulin")
feature_names4.remove("Outcome")
label_name = 'Outcome'

X_train = train[feature_names4]
y_train = train[label_name]
X_test = test[feature_names4]
y_test = test[label_name]

# 머신러닝 알고리즘 가져오기
model = DecisionTreeClassifier()

# 학습
model.fit(X_train, y_train)

# 예측
y_predict = model.predict(X_test)

# 실제값 - 예측값에 절대값을 씌운 값이 1이면 틀린 예측 >> output 36에서 17로 바뀜
diff_count = abs(y_test - y_predict).sum()

# 예측의 정확도 >> output 76%에서 89%로 올라감
(len(y_test) - diff_count) / len(y_test) * 100
# Insulin_nan 컬럼 이상치 제거
# 사분위수 범위 계산 >> output 67
IQR3 = df["Insulin_nan"].quantile(0.75)
IQR1 = df["Insulin_nan"].quantile(0.25)
IQR = IQR3 - IQR1

# IQR3보다 1.5IQR 초과하는 값을 이상치로 간주 >> 270이상 제거
OUT = IQR3 + (IQR * 1.5)

train = df[:614].copy()
test = df[614:].copy()
train = train[train["Insulin_nan"] < 270]
feature_names5 = train.columns.tolist()
feature_names5.remove("Pregnancies")
feature_names5.remove("Insulin")
feature_names5.remove("Outcome")
label_name = 'Outcome'

X_train = train[feature_names5]
y_train = train[label_name]
X_test = test[feature_names5]
y_test = test[label_name]

# 머신러닝 알고리즘 가져오기
model = DecisionTreeClassifier()

# 학습
model.fit(X_train, y_train)

# 예측
y_predict = model.predict(X_test)

# 실제값 - 예측값에 절대값을 씌운 값이 1이면 틀린 예측 >> output 17에서 19로 바뀜
diff_count = abs(y_test - y_predict).sum()

# 예측의 정확도 >> output 89%에서 87%로 내려감
(len(y_test) - diff_count) / len(y_test) * 100
# 이 데이터에서 인슐린 이상치를 제거하는 것은 의미가 없는 것으로 결론
# 피처 스케일링
# 숫자의 범위가 다르면 feature 별로 비중이 다르게 계산될 수 있으므로 스케일링 기법을 사용
# Glucose, DiabetesPedigreeFunction 컬럼에 대해 스케일링 진행
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(df[["Glucose", "DiabetesPedigreeFunction"]])
scale = scaler.transform(df[["Glucose", "DiabetesPedigreeFunction"]])
df[["Glucose", "DiabetesPedigreeFunction"]] = scale

train = df[:614].copy()
test = df[614:].copy()
feature_names6 = train.columns.tolist()
feature_names6.remove("Pregnancies")
feature_names6.remove("Insulin")
feature_names6.remove("Outcome")
label_name = 'Outcome'

X_train = train[feature_names6]
y_train = train[label_name]
X_test = test[feature_names6]
y_test = test[label_name]

# 머신러닝 알고리즘 가져오기
model = DecisionTreeClassifier()

# 학습
model.fit(X_train, y_train)

# 예측
y_predict = model.predict(X_test)

# 실제값 - 예측값에 절대값을 씌운 값이 1이면 틀린 예측 >> output 17에서 18로 바뀜
diff_count = abs(y_test - y_predict).sum()

# 예측의 정확도 >> output 89%에서 88%로 내려감
(len(y_test) - diff_count) / len(y_test) * 100
# 이 데이터에서 피처 스케일링을 진행하는 것은 의미가 없는 것으로 결론

0개의 댓글