문제 3
2번의 데이터를 기준으로 최동원의 성적이라면 연봉이 어떨지 예측하시오.
답 : 저는 데이터 예측을 위해 선형 회귀(Linear Regression)를 사용 할 것입니다. 그리고 이상하다면 이상치가 있는 지 확인 하고 이상치가 많다면 해당 컬럼의 이상치를 제거하고 훈련을 시켜서 예측을 시켜볼 것입니다.
코드
1. 이상치 제거X, 모든 컬럼 사용 후 예측
# 데이터 쪼개기
from sklearn.model_selection import train_test_split
# 숫자형 데이터가 아닌 값은 빼놓기
X = baseball.drop(columns=['연봉','팀명', '선수명'], axis=1)
y = baseball['연봉']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=13)
# 데이터 학습
from sklearn.linear_model import LinearRegression
reg = LinearRegression()
reg.fit(X_train, y_train)
# 오차 검사
import numpy as np
from sklearn.metrics import mean_squared_error
pred_tr = reg.predict(X_train)
pred_test = reg.predict(X_test)
rmse_tr = np.sqrt(mean_squared_error(y_train, pred_tr))
rmse_test = np.sqrt(mean_squared_error(y_test, pred_test.astype('int64')))
rmse_tr, rmse_test
확인 해본 결과 오차가 train 데이터는 3억이 나왔고 test 데이터에서는 4억이 나온 것을 확인하였습니다.
매우 심각합니다...예측이 너무 오류가 많은 것으로 나왔습니다.
2. 해당 데이터 스케일링 후 예측해보기
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import RobustScaler
estimators = [('scaler', RobustScaler()), ('clf', LinearRegression())]
pipe = Pipeline(estimators)
pipe.fit(X_train, y_train)
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
import numpy as np
import pandas as pd
y_pred = pipe.predict(X_test)
y_pred = y_pred.astype('int64')
# 성능 메트릭 계산
mse = mean_squared_error(y_test, y_pred)
mae = mean_absolute_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
# 성능 출력
print("평균 제곱 오차 (MSE):", mse)
print("평균 절대 오차 (MAE):", mae)
print("결정 계수 (R²):", r2)
데이터마다 값의 범위가 너무 다르다 판단되어 우선 RobustScaler를 통해 데이터들을 모두 스케일링 해주고 예측을 해보았습니다.
그 결과 평균 절대오차가 3억으로 되면서 1억 정도의 값이 낮아진 것을 확인하였습니다.
그래서 스케일링을 꼭 해주면서 중요한 컬럼의 값만 학습시켜서 예측하면 성능이 더 올라갈 것이라 판단하였습니다.
3. 이상치 확인 후 제거
박스플롯을 이용해 각 컬럼들의 값들을 시각화 해본 결과 확실히 선수들마다의 값이 너무 다른 것이 확인 되었습니다.
그래서 이상치가 여럿 존재하므로 IQR을 이용하여 이상치를 제거하기로 판단 하였습니다.
고칠 점 : countplot사용하여 모든 컬럼들을 확인을 했어야 했는데 확인하지 않고 모두 이상치가 있다고 판단...
(해당 과정 또한 이상치를 확인 할 때 모든 컬럼을 확인을 했어야 했는데 제가 일부 컬럼들만 확인하고 모든 컬럼에 이상치가 있다 판단하여 모든 컬럼들의 이상치를 제거하였습니다.)
def remove_outliers(df, column):
Q1 = df[column].quantile(0.25)
Q3 = df[column].quantile(0.75)
IQR = Q3 - Q1
# 이상치 기준 설정
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
# 이상치가 아닌 데이터만 필터링
return df[(df[column] >= lower_bound) & (df[column] <= upper_bound)]
# 제거할 컬럼 목록
columns_to_check = ['생년월일', '순위', 'ERA', 'G', 'W', 'L', 'SV', 'HLD', 'WPCT', 'IP', 'H',
'HR', 'BB', 'HBP', 'SO', 'R', 'ER', '연봉', 'WHIP']
# 이상치 제거
for col in columns_to_check:
baseball = remove_outliers(baseball, col)
# 결과 확인
baseball
4. 이상치 제거 후 모든 컬럼 기준으로 예측 값 확인.
estimators = [('scaler', StandardScaler()), ('clf', LinearRegression())]
pipe = Pipeline(estimators)
pipe.fit(X_train, y_train)
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
import numpy as np
import pandas as pd
y_pred = pipe.predict(X_test)
y_pred = y_pred.astype('int64')
# 성능 메트릭 계산
mse = mean_squared_error(y_test, y_pred)
mae = mean_absolute_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
# 성능 출력
print("평균 제곱 오차 (MSE):", mse)
print("평균 절대 오차 (MAE):", mae)
print("결정 계수 (R²):", r2)
확인 결과 확실히 2억 7천으로 약 3천 만원이 작아진 것을 확인 할 수 있었습니다.
다음에는 상관계수에 따른 컬럼들만 사용하여 예측을 해보면 좀 더 좋아질 것 같습니다.
5. 상관 계수 0.2이상 컬럼들 사용(이상치 제거 전의 상관 계수)
columns = corr_baseball[corr_baseball['연봉'].abs() >= 0.2].index.tolist()
columns.remove('연봉')
from sklearn.model_selection import train_test_split
X = baseball[columns]
y = baseball['연봉']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=13)
pipe.fit(X_train, y_train)
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
import numpy as np
import pandas as pd
y_pred = pipe.predict(X_test)
# 성능 메트릭 계산
mse = mean_squared_error(y_test, y_pred)
mae = mean_absolute_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
# 성능 출력
print("평균 제곱 오차 (MSE):", mse)
print("평균 절대 오차 (MAE):", mae)
print("결정 계수 (R²):", r2)
확인 결과 평균 오차가 2억 6천으로 약 1천 만원 정도 떨어진 것을 확인 할 수 있었습니다.
이번에는 상관계수가 0.3이상인 값으로 측정을 해봐야할 것 같습니다
6. 상관 계수 0.3이상 컬럼들 사용(이상치 제거 전의 상관 계수)
columns = corr_baseball[corr_baseball['연봉'].abs() >= 0.3].index.tolist()
columns.remove('연봉')
from sklearn.model_selection import train_test_split
X = baseball[columns]
y = baseball['연봉']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=13)
pipe.fit(X_train, y_train)
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
import numpy as np
import pandas as pd
y_pred = pipe.predict(X_test)
# 성능 메트릭 계산
mse = mean_squared_error(y_test, y_pred)
mae = mean_absolute_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
# 성능 출력
print("평균 제곱 오차 (MSE):", mse)
print("평균 절대 오차 (MAE):", mae)
print("결정 계수 (R²):", r2)
0.3을 기준으로 하니 확실히 오차가 2억 2천으로 약 4천 만 원이 줄어든 것을 확인 할 수 있었습니다.
이번에는 이상치 제거 한 후의 상관계수를 통해 확인 해보겠습니다.
7. 상관 계수 0.3이상 컬럼들 사용(이상치 제거 후의 상관 계수) 후 연봉 예측하기
corr_baseball2 = baseball.corr(numeric_only=True)['연봉'].to_frame()
columns = corr_baseball2[corr_baseball2['연봉'].abs() >= 0.3].index.tolist()
columns.remove('연봉')
from sklearn.model_selection import train_test_split
X = baseball[columns]
y = baseball['연봉']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=13)
pipe.fit(X_train, y_train)
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
import numpy as np
import pandas as pd
y_pred = pipe.predict(X_test)
# 성능 메트릭 계산
mse = mean_squared_error(y_test, y_pred)
mae = mean_absolute_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
# 성능 출력
print("평균 제곱 오차 (MSE):", mse)
print("평균 절대 오차 (MAE):", mae)
print("결정 계수 (R²):", r2)
최종적으로 값을 확인 해본 결과 1억 9천 까지 떨어진 것을 확인 할 수 있었습니다. 하지만 더 이상 파라미터 값을 조정해도 떨어지지않고 오히려 안좋은 방향으로 가는 것을 확인 할 수 있었습니다.
그래서 최종적으로 각 연도 마다의 최동원 선수의 연봉을 확인 해보았습니다.
이렇게 각 연도의 최동원 선수 데이터를 이용하여 연봉을 계산 해낼 수 있었습니다.(매우 부정확하지만요....)
해당 프로젝트를 하면서 느낀 것이 많았습니다. 우선 데이터를 다룰 때는 절대 대충해서는 안되고 어떤 것을 뺄 때는 왜 빼는지에 대한 이유가 있어야하며 어느 하나의 데이터만 확인 하지 않는 것 모든 값들을 잘 분석해봐야 한다는 것을 깨달을 수 있었습니다.
아마도 제가 대충 EDA를 하다보니 해당 값또한 너무 부정확하게 나왔던 것 같습니다.
다음에는 해당 내용을 가지고 EDA를 다시 해봐야 할 것 같습니다!!
그래도 여기까지 봐주셔서 감사합니다.
이 글은 제로베이스 데이터 분석 취업 스쿨의 강의 자료 일부를 발췌하여 작성되었습니다.
이상입니다.
'Project > Machine Learning' 카테고리의 다른 글
Project - Instacart 데이터 물품 재구매 예측하기(RFM) (0) | 2024.11.19 |
---|---|
Project - Instacart 데이터 물품 재구매 예측하기 (0) | 2024.11.18 |
[Zero-base] 최동원 선수 연봉 예측하기 - 보충 (1) | 2024.10.29 |
[Zero-base] 최동원 선수 연봉 예측하기 - 2 (0) | 2024.10.21 |
[Zero-base] 최동원 선수 연봉 예측하기 - 1 (1) | 2024.10.18 |