24.01.29
머신러닝 캐글 실습
캐글에서 House Prices 문제를 풀며 연습 진행
1. 패키지 리스트업 및 데이터 불러오기
# 패키지
import pandas as pd
import numpy as np
# 간단 EDA
import matplotlib.pyplot as plt
import seaborn as sns
# 파이썬 통계 (전통적인 회귀 모형들 때문에 활용)
import scipy.stats as stats
# 데이터 처리
from sklearn.model_selection import train_test_split
# 데이터 불러오기
train_path = '/content/drive/MyDrive/train.csv'
test_path = '/content/drive/MyDrive/test.csv'
train_df = pd.read_csv(train_path) # 81컬럼
test_df = pd.read_csv(test_path) # 80컬럼
2. EDA
# target 변수인 salesprice의 분포 파악
sns.histplot(train_df['SalePrice'])
# 왼쪽으로 쏠린 분포를 나타내어 로그 변환 적용
np.log1p(train_df['SalePrice'])
train_df["SalePrice"] = np.log1p( train_df["SalePrice"])
sns.histplot( train_df["SalePrice"])
# 일부 변수들의 상관성 확인
corr_train = train_df.corr()
corr_train
num = 10 # 제일 직선의 상관성이 큰 10개를 보겠다.
col = corr_train.nlargest(num, 'SalePrice')['SalePrice'].index
coeff = np.corrcoef(train_df[col].values.T)
coeff
# heatmap
h_map = sns.heatmap(coeff,
annot=True,
xticklabels=col.values,
yticklabels=col.values
)
# Id 컬럼은 따로 저장하고 train, test 데이터에서는 삭제
train_id = train_df.loc[:,"Id"]
test_id = test_df.loc[:,"Id"]
train_df.drop("Id", axis=1, inplace = True)
test_df.drop("Id", axis=1, inplace = True)
# train에만 있는 정답을 분리
y_df = train_df.loc[:,"SalePrice"]
train_df.drop("SalePrice", axis=1, inplace = True)
3. 데이터 전처리
# GrLivArea의 분포 확인
sns.lmplot(data=train_df, x= 'GrLivArea',y='SalePrice')
# 이상치를 확인하고 기준을 잡아 제거 : 4000 으로 설정
train_df.drop(train_df[train_df["GrLivArea"]>4000].index, inplace= True)
# 1) 문자형 컬럼 결측치 : None으로 처리
nones = ['PoolQC', 'MiscFeature', 'Alley','Fence', 'FireplaceQu', 'GarageType','GarageFinish',
'GarageQual','GarageCond','BsmtQual','BsmtCond','BsmtExposure','BsmtFinType1','BsmtFinType2',
'MasVnrType']
for col in nones:
train_df[col].fillna( "None", inplace=True)
test_df[col].fillna("None", inplace=True)
# 2) 수치형 컬럼 결측치 : 0으로 처리
zeros = ['GarageYrBlt','GarageArea','GarageCars','BsmtFinSF1','BsmtFinSF2','BsmtUnfSF','TotalBsmtSF',
'BsmtFullBath','BsmtHalfBath','MasVnrArea']
for col in zeros:
train_df[col].fillna(0, inplace=True)
test_df[col].fillna(0, inplace=True)
# 3) Utilites컬럼 확인
train_df["Utilities"].value_counts()
test_df["Utilities"].value_counts()
# test에서 누락되어 있는 컬럼 / 변화가 없는 컬럼이라 제거
train_df.drop("Utilities", axis = 1, inplace= True)
test_df.drop("Utilities", axis = 1, inplace= True)
# 4) # train의 값들을 기준으로 계산을 해서 채우려고 함
train_df["MSZoning"].value_counts()
test_df["MSZoning"].value_counts()
# None 처리가 애매한 것들에 대해 최빈값으로 처리
# 최빈값 확인
train_df["MSZoning"].value_counts().index[0] # 방법1
train_df["MSZoning"].mode()[0] # 방법2
freq = ['MSZoning','Exterior1st',
'Exterior2nd','SaleType','Electrical',
'KitchenQual','Functional']
for col in freq:
# test_df 누락값은 'train_df' 기준의 최빈값으로 채워야 한다.
train_df[col].fillna(train_df["MSZoning"].mode()[0], inplace=True )
test_df[col].fillna(train_df["MSZoning"].mode()[0], inplace=True)
# LotFrontage 컬럼 확인
train_df['old_LotFrontage'] = train_df["LotFrontage"]
# 결측치를 Neighborhood 컬럼의 group별 대표값으로 설정
train_df["LotFrontage"] = train_df.groupby(by="Neighborhood")["LotFrontage"].transform(
lambda x: x.fillna(x.median())
)
train_df.head()
# 중간 확인용 결측치 확인
train_df["LotFrontage"].isnull().sum()
train_df[train_df["old_LotFrontage"].isnull()].loc[:, ["Neighborhood","LotFrontage","old_LotFrontage"]]
# ---------------------------------------
# 이를 test에도 그대로 적용
test_df["old_LotFrontage"] = test_df["LotFrontage"]
test_df = pd.merge(test_df, ref_table, how='left', on = 'Neighborhood')
test_df.head()
# test_df에서 LotFrontage컬럼이 누락된 경우만 y값을 밀어 채우기가 필요하다.
test_df.loc[test_df['LotFrontage_x'].isnull(), "LotFrontage_x"] = test_df.loc[test_df['LotFrontage_x'].isnull(), "LotFrontage_y"]
test_df.drop("LotFrontage_y",axis=1, inplace=True)
test_df.rename(columns = {'LotFrontage_x': 'LotFrontage'}, inplace= True)
# ---------------------------------------
# 최종 전처리 결과 확인
train_df.drop("old_LotFrontage",axis=1, inplace=True)
test_df.drop("old_LotFrontage",axis=1, inplace=True)
train_df.isnull().sum().sum()
test_df.isnull().sum().sum()
4. 인코딩
# 라벨인코딩
from sklearn.preprocessing import LabelEncoder
ordinals = ['LotShape','LandSlope','OverallQual','OverallCond','ExterQual','ExterCond','BsmtQual',
'BsmtCond','BsmtExposure','BsmtFinType1','BsmtFinType2','HeatingQC','Electrical','KitchenQual',
'Functional','FireplaceQu','GarageFinish','GarageQual','GarageCond','PavedDrive','PoolQC','Fence']
for col in ordinals:
le = LabelEncoder()
le.fit( train_df[col])
train_df[col] = le.transform(train_df[col] )
prev_class = list(le.classes_)
for label in np.unique(test_df[col]):
if label not in prev_class: # unseen data
prev_class.append(label)
le.classes_ = np.array(prev_class)
test_df[col] = le.transform( test_df[col])
## 원핫 인코딩
nominals = ['MSSubClass','MSZoning','Street','Alley','LandContour','LotConfig','Neighborhood','Condition1','Condition2','BldgType','HouseStyle','RoofStyle','RoofMatl',
'Exterior1st','Exterior2nd','MasVnrType','Foundation','Heating','CentralAir','GarageType','MiscFeature','SaleType','SaleCondition','MoSold','YrSold']
train_df = pd.get_dummies( train_df, columns=nominals, prefix_sep = "_" )
test_df = pd.get_dummies( test_df, columns=nominals, prefix_sep = "_" )
cat_dummies = [col for col in train_df if "_" in col and col.split("_")[0] in nominals]
for col in cat_dummies:
if col not in test_df.columns:
print("컬럼추가:", col)
test_df[col] = 0
for col in test_df.columns:
if ('_'in col) and (col.split('_')[0] in nominals) and (col not in cat_dummies):
print("제거된 컬럼: ", col)
test_df.drop(col,axis=1, inplace=True)
print(train_df.shape)
print(test_df.shape)
5. Scaler
from sklearn.preprocessing import StandardScaler
from re import X
scaler = StandardScaler()
scaler.fit(train_df)
X_train = scaler.transform(train_df)
X_train = pd.DataFrame(X_train, columns=train_df.columns)
test_df = pd.DataFrame(test_df, columns = train_df.columns)
X_test = scaler.transform(test_df)
X_test = pd.DataFrame(X_test, columns = train_df.columns)
X_train
X_test
전처리 주의사항
- train을 기준으로 train/test에 대한 전처리를 하자.
- train과 test을 쌍으로 같이 전처리를 하는 습관이 필요하다.
- 전처리를 하는 과정에서 주의할 사항은 test는 전혀 모른다고 생각하고 오로지 기준으로 train만 가지고 해야한다.
'ASAC 빅데이터전문가과정 > ML' 카테고리의 다른 글
ASAC 43일차_머신러닝 10일차 (0) | 2024.08.30 |
---|---|
Linux 실습 환경 만들기 / VirtualBox, Ubuntu 설치 (0) | 2024.08.30 |
ASAC 40일차_머신러닝 8일차 (0) | 2024.08.30 |
ASAC 39일차_머신러닝 7일차 (0) | 2024.08.30 |
ASAC 36일차_머신러닝 6일차 (0) | 2024.08.24 |