👩‍💼

3.1 보스턴 주택가격 예측분석 SAS - 1

여기서는 SAS UNIVERSITY 에서 사용할 수 있는 다양한 회귀분석 모델을 가지고 분석을 진행해보는 예제를 다뤄볼 예정입니다.
대부분의 SAS 유저들이 SAS를 이용한 회귀분석은 학교 수업이나 다른 교재들을 통해 한번쯤을 다뤄봤을거라 생각하여 보스턴 주택 가격 분석 데이터를 선정했습니다.
 
 

1. 개요

캐글의 고전적인 문제이고 머신러닝을 공부하는 사람이라면 누구나 한번쯤 다뤄봤을 Boston house price dataset을 통해 회귀분석을 하는 과정을 연습할 수 있습니다.
정식 대회 명칭은 House Price Advanced Regression Techniques입니다.
여러가지 집에 관련된 데이터를 활용하여 주택 가격을 예측하는 것이 목표이고, 다양한 변수들을 다뤄봄으로써 데이터 분석역량을 더 높일 수 있습니다. 옛날이나 지금이나 집값에 관심이 높은건 여전한가 봅니다.
이번 분석에서의 목표는 연속형 변수를 타겟으로 한 모델을 만들어보고 캐글에 제출해보는 것 입니다.

2. 데이터 분석 - 베이스 라인 만들기

회귀분석과 Lasso 회귀분석을 이용한 캐글에 제출할 베이스라인 모델을 만들어 보도록 하겠습니다.

1) 데이터 읽어오기

1-1 데이터 옮기기

House라는 폴더를 하나 생성한 뒤 다운 받은 데이터셋을 드래그하여 house 폴더에 옮겨놓습니다. 관련 데이터셋은 파일은 하단에 첨부해두었습니다.

1-2 라이브러리 설정

PATH를 house 폴더 주소로 지정하고, Libname 구문을 사용하여 house라는 라이브러리 이름을 설정하고, "&PATH"를 입력한 뒤 실행합시다.
%LET PATH=house/; LIBNAME house "&PATH";

1-3 데이터 가져오기

다음과 같이 Train 데이터와 Test 데이터를 가져옵시다.
PROC IMPORT DATAFILE = "house/train_SU.csv" OUT = house.TRAIN DBMS = CSV; RUN;
PROC IMPORT DATAFILE = "house/test_SU.csv" OUT = house.test DBMS = CSV; RUN;

2) 데이터 전처리

이번 베이스라인 모델에서는 사용하지 않는 변수에 대한 처리만 진행하겠습니다. Drop 문을 사용하여 분석에 사용하지 않는 변수들을 제외시킬수 있습니다.
보통 데이터 중 대다수가 Missing인 경우, 관측치 대부분이 한가지 값으로만 있는 경우, 타겟변수와의 상관성이 적은 경우, 변수간의 연관성이 높은 경우, 실제 분석에 사용하기 적절하지 않는 경우 등 여러 사유로 인해 변수를 제외합니다.
DATA House.TRAIN_1; SET House.TRAIN; DROP Street Alley Utilities Condition2 RoofMatl BsmtFinType2 BsmtFinSF2 Heating LowQualFinSF WoodDeckSF OpenPorchSF PoolArea PoolQC MiscFeature MiscVal MoSold YrSold; RUN;

3) 모델 구축 - 회귀모델 구축

3-1 회귀모델 구축

Proc Glmselect를 사용하여 회귀모델을 구축해봅시다. 먼저 사용할 구문에 대해 설명을 드리자면 연속형 변수만 사용할 수 있는 Proc GLM과는 다르게 Proc Glmselect에서는 변수 중 범주형 변수가 있을 경우에도 모델 구축이 가능합니다. 그리고 간단한 옵션으로 인해 여러 회귀모델을 변경할 수 있는 것이 장점입니다. (Stepwise / Forward / Backward / Lasso 등)
proc glmselect data=House.Train_1 plots=asePlot; class BldgType BsmtCond BsmtExposure BsmtFinType1 BsmtQual CentralAir Condition1 Electrical ExterCond ExterQual Exterior1st Exterior2nd Fence FireplaceQu Foundation Functional GarageCond GarageFinish GarageQual GarageType HeatingQC HouseStyle KitchenQual LandContour LandSlope LotConfig LotFrontage LotShape MSZoning MasVnrType Neighborhood PavedDrive RoofStyle SaleCondition SaleType; model SalePrice = BedroomAbvGr BldgType BsmtCond BsmtExposure BsmtFinSF1 BsmtFinType1 BsmtFullBath BsmtHalfBath BsmtQual BsmtUnfSF CentralAir Condition1 Electrical EnclosedPorch ExterCond ExterQual Exterior1st Exterior2nd Fence FireplaceQu Fireplaces Foundation FullBath Functional GarageArea GarageCars GarageCond GarageFinish GarageQual GarageType GarageYrBlt GrLivArea HalfBath HeatingQC HouseStyle KitchenAbvGr KitchenQual LandContour LandSlope LotArea LotConfig LotFrontage LotShape MSSubClass MSZoning MasVnrArea MasVnrType Neighborhood OverallCond OverallQual PavedDrive RoofStyle SaleCondition SaleType ScreenPorch TotRmsAbvGrd TotalBsmtSF YearBuilt YearRemodAdd FlrSF_1st FlrSF_2nd Porch_3Ssn / selection=stepwise; store out=house_model; run;
코드가 길어보이지만 나눠서 보면 간단합니다.
1. Data 부분에는 위에서 생성한 Train_1을 입력합니다. 2. Plot부분은 변수별 영향도를 확인하기 위한 옵션입니다. 여기서는 asePlot을 그려봅니다. 3. Class에는 범주형 변수만 입력하면 됩니다. 4. Model에서는 타겟변수 = 독립변수 1 독립변수 2 ... 독립변수 n 이런식으로 입력하면 되는데, 이 모델에서의 타겟은 SalePrice이고 = 그외 ID를 제외한 나머지 변수들을 입력하면 됩니다. 5. 변수 입력 후 '/' 다음에 사용하고 싶은 모델을 넣습니다. 여기서는 Stepwise(단계적 방법)을 사용합니다. 6. store out은 스코어링을 위한 모델을 저장하는 용도로 사용됩니다. 입력 후 실행시키면 결과는 다음과 같습니다.
Stepwise 방법을 적용한 결과 총 16개의 변수가 선택된것을 확인할 수 있습니다.
notion imagenotion image
각 변수별 영향도 그래프 입니다. 시각화 되어 위의 표보다 더 보기가 쉽습니다.
notion imagenotion image
 
모델은 Step 16까지 진행되었으며, 결과는 다음과 같습니다.
 
notion imagenotion image
 

3-2 회귀모델 - 스코어링

앞서 사용했던 Proc plm을 사용하여 Test데이터에 대한 예측결과를 출력합시다.
proc plm restore=house_Model; score data=House.TEST out=House.score pred=Predicted lcl=Lower ucl=Upper; run;
생성된 House.score 중 Kaggle에 제출하기 위한 변수 ID, SalePrice만 추출합니다. 전처리가 되지 않아 모델 적합이 잘 안되어 예측값 중 Null값(.)으로 되어있는 부분이 있습니다. Null값이 있으면 제출이 되지 않기 때문에 그 부분을 처리하기 위해 If 문을 활용하여 0으로 변경합니다. Predict는 SalePrice로 이름을 변경합니다.
DATA RESULT_1; SET HOUSE.SCORE; if predicted = . then predicted = 0; KEEP ID Predicted; RENAME PREDICTED = SalePrice; RUN;
이제 회귀분석의 마지막 코드입니다. 제출파일을 생성하기 위해 Proc Export를 사용하여 Result_REG.csv를 생성합니다.
PROC EXPORT DATA = Result_1 Outfile = 'house/Result_REG.csv' DBMS=CSV REPLACE; RUN;
왼쪽 라이브러리에 Result_REG.csv가 생성된 것을 확인할 수 있다. 파일을 마우스 오른쪽 버튼을 눌러 Download를 합니다.
 
notion imagenotion image
 

3-3 Kaggle 제출 - Stepwise 회귀 Baseline 모델

 
결과는 0.64162로 총 4,551명(2020년 11월 28일 기준) 중에서 4,350위 권의 순위 입니다.지만 아무런 전처리를 하지 않은 상황과 기본 회귀모델을 적용하여 괜찮은 결과를 낸 것을 볼 수 있습니다.
 
notion imagenotion image

4) 모델 구축 - Lasso 회귀모델

4-1 Lasso 회귀모델 구축

코드는 위의 회귀모델과 거의 비슷합니다. 다만 selection 부분을 LASSO로 변경하고, store out은 회귀모델과 구분하기 위해 이름을 변경합니다. 여기서는 house_model_LASSO로 입력합니다.
selection=LASSO; store out=house_model_LASSO;
 
LASSO 모델에서는 총 12개의 변수가 사용되었습니다. 16개의 변수를 사용한 Stepwise회귀 모델과 성능차이가 얼마나 나는지 궁금하네요.
notion imagenotion image
변수 영향도 그래프입니다. 회귀모델 그래프보다 변수간 영향도 차이가 덜 나는 것처럼 보입니다.
notion imagenotion image
 
Lasso 회귀모델은 Step12까지 진행되었으며, 통계량 결과는 다음과 같습니다.
notion imagenotion image
 

4-2 Lasso 회귀모델 - 스코어링

위와 동일하게 Proc plm을 사용하여 예측결과를 산춣합니다.
proc plm restore=house_Model_LASSO; score data=House.TEST out=House.score_LASSO pred=Predicted lcl=Lower ucl=Upper; run;
이제 LASSO모델도 마지막을 향해 가고 있습니다. 생성된 House.score_LASSO에서 Kaggle 제출에 필요한 변수들만 추출합니다. 항목 이름을 제외한 나머지 사항은 위의 회귀모델과 같습니다.
DATA RESULT_2; SET HOUSE.SCORE_LASSO; if predicted = . then predicted= 0; KEEP ID Predicted; RENAME PREDICTED = SalePrice; RUN;
마지막으로 Proc Export를 사용하여 Result_LASSO.csv를 생성해봅시다.
PROC EXPORT DATA = Result_2 Outfile = 'house/Result_LASSO.csv' DBMS=CSV REPLACE; RUN;
 

4-3 Kaggle 제출 - LASSO 회귀 모델

제출한 결과 같은 데이터에 모델만 Lasso로 변경만 해도 0.55707로 스코어가 약 0.09가 좋아졌고, 약 4,300위 초반대로 올라간 것을 확인할 수 있습니다. 이처럼 동일한 데이터라도 모델을 변경했을때 좋은 결과를 얻을 수 있는 것을 확인했습니다.
 
notion imagenotion image
 

3. 결론

본격적인 데이터 분석에 앞서 가장 기본적인 작업만으로도 Kaggle에 결과를 제출해보았습니다. 어떠신가요? 왜 전처리가 필요하고 더 좋은 모델들을 사용하고 비교해봐야하는지 느껴지지 않으신가요? 심화분석에서는 데이터를 좀더 면밀히 들여다보고 여러가지 모델을 활용하여 좋은 결과를 도출해보도록 하겠습니다.
 
분석 참조