멋사 AI스쿨 main lecture by 박조은 강사님
회고
사실 Fact: 주택 데이터 실습 캐글 제출, 벤츠 데이터셋 실습 시작
느낌 Feeling: 피처엔지니어링의 다양한 방법을 학습하고 반복을 통해 꾹꾹 다지고 있는 것 같다
교훈 Finding: TIL 정리를 좀 더 성실하게 해서 지나간 내용은 찾기 쉽게 하자
수치데이터의 결측치를 0으로 채우면 안되는 값
-> 현실 세계를 바탕으로 고려하기
나이, 키, 몸무게, 혈당 수치, 인슐린 수치 등
주택 데이터에서 화장실 수, 2층면적, 지하면적, 주차장면적은 해당 시설이 없다면 0이 될 수 있음
로그 변환
수치형 데이터라도, 피처의 .nunique()를 확인해서 특정 숫자 이하의 빈도수를 가지고 있는 데이터는 범주형으로 간주
범주형 변수 보기
df.select\_dtypes(include="object")
KFold Cross Validation
from sklearn.model_selection import KFold kf = KFold(n_splits=5, shuffle=True, random_state=42)
회귀 실제값과 예측값 비교하기
(시각화 - regplot, kdeplot, r2 score)
# regplot 으로 예측값에 대한 회귀선 그리기
sns.regplot(x=y_train, y=y_valid_pred)
# kdeplot으로 실제값과 예측값 비교하기
sns.kdeplot(y_train)
sns.kdeplot(y_valid_pred)
r2 스코어 확인하기
# r^2 score
from sklearn.metrics import r2_score
r2_score(y_train, y_valid_pred)
피처 중요도 확인하기 (상위 20개만)
.nlargest() 상위 숫자 n개 가져오기
fi =pd.Series(model.feature_importances_)
fi.index = model.feature_names_in_
fi.nlargest(20)
# 피처 중요도 시각화 하기
# sns.barplot(x=model.feature_importances_, y=model.feature_names_in_)
fi.nlargest(20).plot.barh()
피처 선택 예시
# 정답인 SalePrice는 꼭 제외
feature_names = []
feature_names.extend(num_log_feature)
feature_names.append("TotalSF")
feature_names.remove("SalePrice")
.append(list) : 통째로 넣는다
.extend(list) : 리스트의 각 요소를 따로따로 넣는다
제출 결과
https://www.kaggle.com/competitions/house-prices-advanced-regression-techniques/leaderboard
예측한 점수: rmse
점수 제출할때 지수 변환 submit\["SalePrice"\] = np.expm1(y\_predict)
## 수치형
* 결측치 대체(Imputation)
* 수치형 변수를 대체할 때는 원래의 값이 너무 왜곡되지 않는지도 주의
* 중앙값(중간값), 평균값 등의 대표값으로 대체할 수도 있지만,
* 당뇨병 실습에서 했던 회귀로 예측해서 채우는 방법도 있다.
* 당뇨병 실습에서 했던 인슐린을 채울 때 당뇨병 여부에 따라 대표값을 구한 것처럼
* 여기에서도 다른 변수를 참고해서 채워볼 수도 있다.
* 스케일링 - Standard, Min-Max, Robust
* 변환 - log
* 이상치(너무 크거나 작은 범위를 벗어나는 값) 제거 혹은 대체
* 오류값(잘못된 값) 제거 혹은 대체
* 이산화 - cut, qcut
## 범주형
* 결측치 대체(Imputation)
* 인코딩 - label, ordinal, one-hot-encoding
* 범주 중에 빈도가 적은 값은 대체하기
벤츠 데이터 Mercedes-Benz Greener Manufacturing
- 메르세데스 벤츠 사의 제조 과정에서 테스트 단계에 드는 시간을 예측하세요.
In this competition, Daimler is challenging Kagglers to tackle the curse of dimensionality and reduce the time that cars spend on the test bench. Competitors will work with a dataset representing different permutations of Mercedes-Benz car features to predict the time it takes to pass testing. Winning algorithms will contribute to speedier testing, resulting in lower carbon dioxide emissions without reducing Daimler’s standards.
제조업에서 빅데이터의 활용
- 제조 공정 스케줄 최적화 가능
- 다양한 옵션 선택에 대한 소비자에게 출고까지 걸리는 시간 예측 가능
- 산업체간 데이터 거래, 협업
벤츠 데이터셋의 특징
익명화된 데이터: 회사 보안 등으로 가려진 데이터셋으로 캐글에 상당수 존재
y : 제조 과정에서 테스트 단계에 드는 시간을 예측하세요.
숫자 범위 히트맵 확인하기
plt.figure(figsize=(12,7))
sns.heatmap(train.select_dtypes(include='number'), cmap="Blues_r")
하나의 값만 가지는 피처는 변별력이 없기 때문에 제거
nunique로 값 1개인지 확인 -> 결측치 있는지 확인 -> 단일한 값만 가지고 있는 변수 삭제
train_one_idx = train_nunique[train_nunique==1].index
print(train.shape, test.shape) # 제거 전
train.drop(columns=train_one_idx, inplace=True)
test.drop(columns=train_one_idx, inplace=True)
print(train.shape, test.shape) # 제거 후
원핫인코딩
sklearn OneHotEncoder활용
from sklearn.preprocessing import OneHotEncoder
ohe = OneHotEncoder(handle_unknown="ignore")
train_ohe = ohe.fit_transform(train.select_dtypes(exclude="number"))
test_ohe = ohe.transform(test.select_dtypes(exclude="number"))
print(train_ohe.shape, test_ohe.shape)
OneHotEncoder 는 전체 데이터를 변환하기 때문에 범주가 아닌 수치 데이터도 모두 인코딩한다.
그래서 범주값 데이터만 따로 넣어 인코딩해주고 다시 합쳐야 한다.
handle_unknown="ignore" test 에는 등장하지만 train에는 없다면 무시
pd.get_dummies() 의 장점은 이런 전처리 없이 범주 데이터만 OneHotEncoding 한다는 점이다
범주형 데이터 원핫인코딩 후, 수치형 데이터와 concat해서 사용
df_train_ohe = pd.DataFrame(train_ohe.toarray(), columns=ohe.get_feature_names_out())
df_train_ohe.index = train.index # 인덱스 맞추기
df_test_ohe = pd.DataFrame(test_ohe.toarray(), columns=ohe.get_feature_names_out())
df_test_ohe.index = test.index
train_num = train.select_dtypes(include="number")
pd.concat([df_train_ohe, train_num], axis=1)