728x90

본 실습 내용은 패스트캠퍼스 강의임을 먼저 알립니다 ~!

 

실습 내용은 대학원 입시 합격률 예측입니다. 아래는 학생들 성적과 관련된 것 데이터이며 target은 Chan of admit입니다. 연속형 데이터를 임의로 정한 기준으로 통해 0,1로 구분하여 분류하는 분류 문제로도 실습이 진행되었습니다. 

데이터 전처리 과정보다는 머신러닝에 초점을 맞추어 졌습니다. 

필기은 코드 내에 주석으로 처리되어있습니다.

#파일 로드
rawdata1 <- read.csv('university.csv', head=TRUE)
rawdata1

#데이터 형태 확인
str(rawdata1)

#결측치 확인
sum(is.na(rawdata1$GRE.Score))
sum(is.na(rawdata1$TOEFL.Score))
sum(is.na(rawdata1$University.Rating))
sum(is.na(rawdata1$SOP))
sum(is.na(rawdata1$LOR))
sum(is.na(rawdata1$Research))
sum(is.na(rawdata1$Chance.of.Admit))

#유니크값 확인: 이상치 확인, 데이터 분포 확인 
unique(rawdata1$GRE.Score)
unique(rawdata1$TOEFL.Score)
unique(rawdata1$University.Rating)
u_rating_table <- table(rawdata1$University.Rating)
u_rating_table #각 레이팅 별로 해당하는 데이터가 몇갠지 알수 있다. 3등급 학교출신들이 가장 많다.

unique(rawdata1$SOP) #0.5점 단위 점수를 계산
unique(rawdata1$LOR)
unique(rawdata1$Research) #factor로 볼것이냐 number로 볼것인가(둘다 가능하다)

#타켓값이 가장 중요 
unique(rawdata1$Chance.of.Admit)
#0과1사이에 있는지 확인
max(rawdata1$Chance.of.Admit)
min(rawdata1$Chance.of.Admit)

#보통 연속형 타켓은 값에 제한이 없지만 이 데이터에는 0~1사이라는 제한이 있다. 고로, 로지스틱 회귀를 사용해야한다. (선형회귀를 사용x)

#히스토그램
#par : 한 화면에 그래프 여러 개 그릴때 사용
#mar: 여백설정-> 아래,왼쪽,위,오른쪽 순으로
par(mfrow=c(3,2), mar=c(5.1,4.1,4.1,2.1))

hist(rawdata1$GRE.Score, main='GRE 점수 히스토그램',xlab='GER점수', col='Orange')

hist(rawdata1$TOEFL.Score, main='토플 점수 히스토그램',xlab='토플점수', col='green')

hist(rawdata1$SOP, main='자기소개서 점수 히스토그램',xlab='자기소개서점수', col='blue')

hist(rawdata1$CGPA, main='학부 점수 히스토그램',xlab='학부점수', col='darkmagenta')

hist(rawdata1$LOR, main='추천서 점수 히스토그램',xlab='추천서점수', col='yellow')

boxplot(rawdata1$Chance.of.Admit, main='대학원 합격 확률 점수 히스토그램',xlab='대학원 합격 확률', col='red')

#파이차트
par(mfrow=c(1,2), mar=c(1,1,1,1))
pie(u_rating_table, main='학부 대학 레이팅',radius=2)

#변수 산점도
plot(rawdata1)


##데이터 분리
set.seed(2021)
newdata <- rawdata1
train_ratio <- 0.7
datatotal <- sort(sample(nrow(newdata),nrow(newdata)*train_ratio))
train <- newdata[datatotal,]
test <- newdata[-datatotal,]

library(caret)
#로지스틱회귀
ctrl <- trainControl(method='repeatedcv', repeats = 5)
logistic_fit <- train(Chance.of.Admit~.,
                      data=train,
                      method='glm', #generalized linear model 
                      trControl=ctrl,
                      preProcess=c('center','scale'),
                      metric='RMSE')
logistic_fit

#예측
logistic_pred <- predict(logistic_fit,test)
logistic_pred

#테스트의 RMSE 구하는 세가지 방법
#1. postResample
postResample(pred=logistic_pred, obs= test$Chance.of.Admit)

#2. RMSE
RMSE(logistic_pred, test$Chance.of.Admit)

#3.직접계산
sqrt(mean((logistic_pred-test$Chance.of.Admit)^2))

#Rsquared 직접계산 1- 설명불가능한 변동(오차)
y_bar = mean(test$Chance.of.Admit)
1-(sum((logistic_pred-test$Chance.of.Admit)^2)/sum((test$Chance.of.Admit-y_bar)^2))

#MAE 계산하는 3가지 방법
#1. PostResample
#2. MAE
MAE(logistic_pred, test$Chance.of.Admit)

#3. 직접계산
mean(abs(logistic_pred-test$Chance.of.Admit))


#엘라스틱넷(L1패널티+L2패널티)
#대표적인 목적함수(최적화 시키고자 하는 함수)는 오차제곱 합
#목적함수를 최적화 한다는 것은 목적함수를 최소화(or 최대화) 시키는 모수를 추정
#머신러닝의 목적은 이 모수를 추정하는 것

#제약식=패널티=정규화 : 목적함수의 최적화를 돕는 역할
#최적화된 모수=목적함수+패널티

#L1마름모(라쏘): 최소화 시킬려는 베타값은 마름모 안에 있다.
#L2타원(릿지): 위와 같다
logit_panal_fit <- train(Chance.of.Admit~.,
                      data=train,
                      method='glmnet',
                      trControl=ctrl,
                      preProcess=c('center','scale'),
                      metric='RMSE')
logit_panal_fit
plot(logit_panal_fit)
#알파= 1이 된다면 Lasso 회귀
#알파가=0이면 릿지 회귀
#알파는 두 패널티의 비율을 나타낸다.
#람다: 전체 제약식의 크기를 결정
# 람다[릿지 패널티 + 릿지 패널티]

#예측
logit_penal_pred <- predict(logit_panal_fit,test)

#postResample
postResample(pred=logit_penal_pred, obs= test$Chance.of.Admit)


#랜덤포레스트
rf_fit <- train(Chance.of.Admit~.,
                         data=train,
                         method='rf',
                         trControl=ctrl,
                         preProcess=c('center','scale'),
                         metric='RMSE')
rf_fit
#mtry: 각 트리에서 랜덤하게 선택되는 분할 피쳐 후보 갯수 즉, mtry가 클수록 각 트리의 가지가 많아진다.

rf_pred <- predict(rf_fit, test)
postResample(pred=rf_pred, obs= test$Chance.of.Admit)




#선형서포트벡터머신
svm_fit <- train(Chance.of.Admit~.,
                data=train,
                method='svmLinear',
                trControl=ctrl,
                preProcess=c('center','scale'),
                metric='RMSE')
svm_fit
svm_pred_fit <- predict(svm_fit, test)
postResample(pred=svm_pred_fit, obs= test$Chance.of.Admit) 





#비선형서포트벡터머신
svm_poly_fit <- train(Chance.of.Admit~.,
                 data=train,
                 method='svmPoly',
                 trControl=ctrl,
                 preProcess=c('center','scale'),
                 metric='RMSE')
svm_poly_fit
svm_pred_fit <- predict(svm_poly_fit, test)
postResample(pred=svm_pred_fit, obs= test$Chance.of.Admit)
#scale: 내적을 스케일하는 역할

#-----------분류--------------
#파일 로드
rawdata2 <- read.csv('university.csv', head=TRUE)

#타켓변수 살펴보기
par(mfrow=c(1,2), mar=c(5.1 ,4.1 ,4.1 ,2.1))
hist(rawdata2$Chance.of.Admit, main='대학원 합격 확률 히스토그램', xlab='대학원 합격 확률',col='red')
boxplot(rawdata2$Chance.of.Admit, main='대학원 합격 확률 box-plot', col ='red')
#데이터 중심인 0.7을 기준으로 삼았다.

summary(rawdata2$Chance.of.Admit)
target_median=median(rawdata2$Chance.of.Admit)
target_median

#타켓 연속혀 -> 범주형
#rawdata2[행,열]
rawdata2[(rawdata2$Chance.of.Admit<target_median),'Chance.of.Admit']="0"
rawdata2[(rawdata2$Chance.of.Admit>=target_median),'Chance.of.Admit']="1"
rawdata2$Chance.of.Admit <- as.factor(rawdata2$Chance.of.Admit)
str(rawdata2)

unique(rawdata2$Chance.of.Admit)

#데이터분리
set.seed(2021)
newdata <- rawdata2
train_ratio <- 0.7
datatotal <- sort(sample(nrow(newdata),nrow(newdata)*train_ratio))
train <- newdata[datatotal,]
test <- newdata[-datatotal,]

customGrid <- expand.grid(k=1:20)
knn_fit2 <- train(Chance.of.Admit~.,
                  data=train,
                  method='knn',
                  trControl=ctrl,
                  preProcess=c('center','scale'),
                  tuneGrid=customGrid,
                  metric='Accuracy')
knn_fit2

#예측
knn_pred <- predict(knn_fit2, test)
confusionMatrix(knn_pred,test$Chance.of.Admit)

#=================================

#logit Boost: 간단한 모형 만들어가면서 성능개선
logit_boost_fit <- train(Chance.of.Admit~.,
                  data=train,
                  method='LogitBoost',
                  trControl=ctrl,
                  preProcess=c('center','scale'),
                  metric='Accuracy')
logit_boost_fit

#예측
logit_boost_pred <- predict(logit_boost_fit, test)
confusionMatrix(logit_boost_pred,test$Chance.of.Admit)

#=================================
#penalized 로지스틱:L2정규화
library(caret)
ctrl <- trainControl(method='repeatedcv',repeats = 5)
logit_plr_fit <- train(Chance.of.Admit~.,
                         data=train,
                         method='plr',
                         trControl=ctrl,
                         preProcess=c('center','scale'),
                         metric='Accuracy')
logit_plr_fit
#람다: 제약시의 크기를 조절하는 값
#cp(complexity parameter): 복잡성을 일컫는말, aic or bic(default)
plot(logit_plr_fit)

#예측
logit_plr_pred <- predict(logit_plr_fit, test)
confusionMatrix(logit_plr_pred,test$Chance.of.Admit)

#=================================
#나이브베이즈: 각 피처를 독립으로 가정, 조건부 확률
ctrl <- trainControl(method='repeatedcv',repeats = 5)
nb_fit <- train(Chance.of.Admit~.,
                       data=train,
                       method='naive_bayes',
                       trControl=ctrl,
                       preProcess=c('center','scale'),
                       metric='Accuracy')
nb_fit
#usekernel: 히스토그램을 이용하여 실제 분포를 추정
#adjist: 커널함수값의 bandwidth 값 조절
#laplace: 라플라스 스무딩 파라미터 값 조절. 자세한건 강의 자료참고, 데이터가 적을 경우 추정된 값의 비율이 0또는 1과 같이 극단적인 값으로 추정하는 것 즉 한쪽으로 쏠리는걸 방지
plot(nb_fit)

#예측
nb_pred <- predict(nb_fit, test)
confusionMatrix(nb_pred,test$Chance.of.Admit)


#=================================
#랜덤포레스트
ctrl <- trainControl(method='repeatedcv',repeats = 5)
rf_fit <- train(Chance.of.Admit~.,
                data=train,
                method='rf',
                trControl=ctrl,
                preProcess=c('center','scale'),
                metric='Accuracy')
rf_fit
#예측
rf_pred <- predict(rf_fit, test)
confusionMatrix(rf_pred,test$Chance.of.Admit)


#=================================
#서포트벡터
ctrl <- trainControl(method='repeatedcv',repeats = 5)
svm_fit <- train(Chance.of.Admit~.,
                data=train,
                method='svmLinear',
                trControl=ctrl,
                preProcess=c('center','scale'),
                metric='Accuracy')
svm_fit

#예측
svm_pred <- predict(svm_fit, test)
confusionMatrix(svm_pred,test$Chance.of.Admit)


#=================================
#커널 소프트벡터
ctrl <- trainControl(method='repeatedcv',repeats = 5)
svm_poly_fit <- train(Chance.of.Admit~.,
                data=train,
                method='svmPoly',
                trControl=ctrl,
                preProcess=c('center','scale'),
                metric='Accuracy')
svm_poly_fit
#예측
svm_poly_pred <- predict(svm_poly_fit, test)
confusionMatrix(svm_poly_pred,test$Chance.of.Admit)
728x90

+ Recent posts