반응형



안녕하세요


오늘은 수치분석의 꽃 회귀분석에 대해 알아보도록 하겠습니다.(개인적인 생각임ㅎ)



회귀란?


유전학자 프린시스 골턴이 유전의 법칙을 연구하다가 나온 명칭으로


아버지의 키가 크다고 할지라도 아들의 키는 아들세대의 평균으로 접근하는 경향이 있다.


즉 평균으로의 회귀를 의미합니다.


회귀분석은 하나의 종속변수가 나머지 다른 독립변수들과의 어떠한 관계를 갖는가를 분석하는 방법입니다.



(기본적으로 ML에서 분류는 카테고리를 예측하는 것, 회귀는 수치 값을 예측하는 것입니다.)




회귀분석의 종류는 아래와 같이 다양합니다.






회귀 분석의 원리


회귀분석이란 회귀선을 도출하는 과정입니다.


y = ax + b (a, b: 회귀모수)


예를들어,

위의 그래프는

평수(독립변수)가 집값(종속변수)에 영향을 주는 정도를 나타낸 그래프입니다.



위의 직선의 경우


y = w1 * X + w2


여기서 잔차의 제곱의 합이 최소가 되도록 하는 최적의 선을 구하는 방법으로 최소 자승법을 이용합니다.





코드로 회귀분석에대해 더욱 자세히 알아보겠습니다.


이것은 제가 만든 미니 프로젝트 코드입니다.


주제: 첫 주의 누적관객 수가 그 영화의 흥망을 결정한다는 말이 있습니다.


이번에 그 첫 주 누적관객수에 영향을 미치는 요인을 영화 배급사가 결정할 수 있는 수치적인 요인으로 독립변수를 선택하였습니다.


종속변수: 첫 주 누적관객수

독립변수: 첫 주 누적 상영횟수, 첫 주 누적 스크린 수, 같은 날 개봉한 영화 수


data: 영화관입장권통합전산망 오픈API

################ 첫 주의 관객 수가 흥망을 결정한다. ################## ################ 첫 주 관객 수에 영향을 미치는 요인 ################## # db(mysql)에서 data 가져오기(2013-01-01 ~ 2018-06-15) library(RMySQL)


# dget() 함수는 이미 생성한 익명함수를 r로 로드하여 사용할 수 있습니다.

# 비밀번호와 주소를 감추기 위해 사용하였습니다. mysqldbConnect <- dget("mysqldbConnect.R") conn <- mysqldbConnect(dbname = "movieanalysis") c_sql <- "SELECT COUNT(*) FROM movie where openDt != ''" count <- dbGetQuery(conn, c_sql) count        # 19316

# r로 db에 있는 데이터 로드하기 r_sql <- c("SELECT * FROM movie where openDt != ''") document_r <- dbGetQuery(conn, r_sql) head(document_r)


######## 데이터 전처리 ############## # 한글이 깨지는 것을 복구하기위해 사용하였습니다. Encoding(document_r$movieNm) <-"UTF-8" head(document_r)

# 2013-01-01 이전 데이터 생략하기 document <- document_r[document_r$openDt > as.Date('2013-01-01'),] head(document) # 같은 날 개봉한 영화 수 (직접생성): sameDate document$sameDate <- '' for (i in 1:nrow(document)){ # print(j) document[i,"sameDate"] <- sum(document$openDt[i] == document$openDt) }


# normalization 등을 위해 data 전처리 str(document) document$salesAcc <- as.numeric(document$salesAcc) document$audiAcc <- as.numeric(document$audiAcc) document$audiChange <- as.numeric(document$audiChange) document$sameDate <- as.numeric(document$sameDate) document$showCnt <- as.numeric(document$showCnt) document$showRange <- substring(strptime(as.character(document$showRange), "%Y%m%d"), 1, 10) document$showRange <- as.Date(document$showRange) nrow(document) # table 정리 ncol = which(colnames(document) == "openDt") ncol1 = which(colnames(document) == "scrnCnt") ncol2 = which(colnames(document) == "sameDate") ncol3 = which(colnames(document) == "showRange")

# 개봉한지 7일 뒤의 날짜를 추가한다.

table <- cbind.data.frame(document[,-c(ncol,ncol1,ncol2,ncol3)],

"scrnCnt" = document[,ncol1],"openDate" = document[,ncol],

"sameDate" = document[,ncol2], "showRange" = document[,ncol3],

"after_7days" = (as.Date(document$openDt)+7))

# 누적 데이터 구하기 library(data.table) table <- as.data.table(table) table <- table[,Cum.showCnt := cumsum(showCnt), by = movieCd] table <- table[,Cum.rank := cumsum(rank), by = movieCd] table$scrnCnt <- as.numeric(table$scrnCnt) table <- table[,Cum.scrnCnt := cumsum(scrnCnt), by = movieCd] head(table) # 첫 주 누적관객수 및 누적데이터만 추출하기 movieWeek <- NULL for (z in 1:nrow(table)){ if (table$after_7days[z] == table$showRange[z]){ movieWeek <- rbind(table[z,],movieWeek) } } head(movieWeek)

movieWeek$openDate <- as.Date(movieWeek$openDate) movieWeek[(movieWeek$movieNm == movieWeek$movieNm) & (movieWeek$openDate <= movieWeek$showRange),]

############## 다중 회귀 분석 ############ normalize <- function(x) { return ( (x-min(x)) / (max(x) - min(x)) ) } # 정규화: 종속변수에 대한 독립변수의 영향을 파악하기위해 # 독립변수: 그 주 개봉하는 영화수, 누적 스크린 수, 누적 상영횟수 (only 수치데이터) movie_n <- as.data.frame(lapply(movieWeek[,c("Cum.scrnCnt","sameDate","Cum.showCnt")],

normalize)) head(movie_n) head(movieWeek) movieWeek_n <- cbind(movieWeek[ , -c("sameDate","Cum.showCnt","Cum.rank","Cum.scrnCnt")],

movie_n) head(movieWeek_n) # train data set과 test data set 나누기 set.seed(18)    # 여러값 중 좋은 set.seed()값 찾기 nrow <- round(dim(movieWeek_n)[1]*0.7)


# data shuffle하기 train_indx <- sample(1:dim(movieWeek_n)[1], nrow, replace = F)

movie_train <- movieWeek_n[1:train_indx,] movie_test <- movieWeek_n[(train_indx+1): nrow(movieWeek_n),] nrow(movie_train) nrow(movie_test)

# 다중회귀모델 생성하기

set.seed(1)

# 선형 모델 함수 lm()이용 library(stats)

model <-lm(audiAcc ~ (sameDate + Cum.showCnt + Cum.scrnCnt), data= movie_train) summary(model)    # r-squared(결정계수) 값 등을 확인한다.

# Adjusted R-squared: 0.79


# test data set result result <- predict(model,movie_test[,c("sameDate", "Cum.showCnt", "Cum.scrnCnt")]) str(result) result<- as.vector(result) str(movie_test$audiAcc) str(result) # 테스트 데이터의 라벨과 예측결과와 상관관계가 어떻게 되는지 확인한다. cor(result, movie_test$audiAcc) # 0.914286 : 양의 상관관계가 매우 높다.



# 어떤 독립변수가 어떤 종속변수에 영향을 많이 미치는 가?

# 시각화. pairs.panels library(psych) pairs.panels(movieWeek_n[,c("audiAcc", "Cum.showCnt", "Cum.scrnCnt", "sameDate")],

main = "첫 주 관객 수에 영향을 미치는 요인") # audiAcc와 Cum.showCnt의 상관관계는 0.88정도이다.





 




추가) 상관관계란


상관분석은 두 변수가 서로 어떠한 관계인지 파악하는 분석으로 기울기에 따라 양의 상관관계, 음의 상관관계로 나눌 수 있습니다.


점들의 흩어진 모습을 보고 두 변수의 관계를 파악하는데 밀도의 차이에 따라서 상관계수를 나타냅니다.


상관계수는 -1에서 1사이의 값을 가지며

상관계수의 수치가 0에 가까울수록 상관관계가 약하다는 뜻이고

+1에 가까우면 양의 상관관계가, -1에 가까우면 음의 상관관계가 강하다는 것을 의미합니다.



위의 코드에서 꼭 알아야하는 것!!


1. library(stats)를 이용하였다.


2. library(stats) 중 lm()함수를 이용하여 회귀분석을 하였다.


# 선형 모델 함수 lm()이용 model <-lm(audiAcc ~ (sameDate + Cum.showCnt + Cum.scrnCnt), data= movie_train) summary(model)    # r-squared(결정계수) 값 등을 확인한다.

# Adjusted R-squared: 0.79 # 독립변수가 많으면 저절로 높아질 수 있는 Multiple R-squared대신 사용

# test data set result result <- predict(model,movie_test[,c("sameDate", "Cum.showCnt", "Cum.scrnCnt")])


lm()함수를 이용하여 하나의 독립변수를 이용하면 단순회귀분석이 가능합니다!!





오늘은 여기까지!!


더 궁금하신 점은 댓글 남겨주세요~


다음은 연관규칙 알고리즘으로 돌아오겠습니다

반응형

+ Recent posts