언어/R

[R] 인공신경망(이차방정식 해 예측하기)

더날고싶은sm 2023. 7. 31. 14:35

1. 전체코드

a<-1
b<- sample(-10:10, 1000 ,replace = T)
c<- sample(-10:10, 1000 ,replace = T)
x<- sample(-10:10, 1000 ,replace = T)

# 근을 저장할 변수 초기화
x1 <- numeric(length(b))
x2 <- numeric(length(b))

# 근의 공식 계산 및 저장
for (i in 1:length(b)) {
  discriminant <- b[i]^2 - 4*a*c[i]
  if (discriminant >= 0) {
    x1[i] <- (-b[i] + sqrt(discriminant)) / (2*a)
    x2[i] <- (-b[i] - sqrt(discriminant)) / (2*a)
  }
}
equation <- function(x,b,c) x^2 +b*x +c

eq <- equation(x,x1+x2, x1*x2)

dataset <- data.frame(x1, x2, b,c)
View(dataset)

samp <- sample(1:nrow(dataset), round(nrow(dataset)*0.7))
dataset.train <- dataset[samp, ] ## 700개 훈련 데이터
dataset.test <- dataset[-samp, ] ## 300개 검정 데이터
nn1 <- nnet(dataset.train[,-(1:2)], dataset.train[,(1:2)], size=50, maxit=10000, linout=T)
z.prediction <- predict(nn1, dataset.test[,-(1:2)])

#결과 출력
predict(nn1, newdata = data.frame(b = 3, c = 2))
predict(nn1, newdata = data.frame(b = -5, c = 6))

data.frame(dataset.test, z.prediction)

 

2. 설명

1)

a<-1
b<- sample(-10:10, 1000 ,replace = T)
c<- sample(-10:10, 1000 ,replace = T)
x<- sample(-10:10, 1000 ,replace = T)

# 근을 저장할 변수 초기화
x1 <- numeric(length(b))
x2 <- numeric(length(b))

a*x^2 + b*x + c 의 해를 구하기 위해서 a,b,c는 상수로 고정, x1, x2 변수로 지정해 값을 예측

 

sample(-10:10, 1000 ,replace = T)

- -10에서 10까지 범위에서 1000개의 수를 중복하여 변수에 저장
- 10부터 10까지의 숫자 생성

- 숫자를 중복해서 1000개의 난수를 생성

- replace =TRUE는 중복을 허용

 

numeric(length(b))​

- b변수의 길이만큼 0으로 초기화된 숫자를 생성

-  length(b)는 b변수의 길이를 나타냄

 

2)

# 근의 공식 계산 및 저장
for (i in 1:length(b)) {
  discriminant <- b[i]^2 - 4*a*c[i]
  if (discriminant >= 0) {
    x1[i] <- (-b[i] + sqrt(discriminant)) / (2*a)
    x2[i] <- (-b[i] - sqrt(discriminant)) / (2*a)
  }
}
equation <- function(x,b,c) x^2 +b*x +c

eq <- equation(x,x1+x2, x1*x2)

- 근의 공식 이용 x1, x2가 변수이기 때문에 아직은 값이 정해지지 않은 상태이므로 근의 공식(a, b, c)을 이용해 x1, x2값을 구함(실근)

- sqrt는 루트를 표현

- equation이라는 함수를 만들고 위에서 구한 실근(x1, x2)을 이용하여 이차 방정식의 값을 계산

- b <- x1+x2

- c <- x1*x2

 

3)

dataset <- data.frame(x1, x2, b,c)
View(dataset)

samp <- sample(1:nrow(dataset), round(nrow(dataset)*0.7))
dataset.train <- dataset[samp, ] ## 700개 훈련 데이터
dataset.test <- dataset[-samp, ] ## 300개 검정 데이터
nn1 <- nnet(dataset.train[,-(1:2)], dataset.train[,(1:2)], size=50, maxit=10000, linout=T)
z.prediction <- predict(nn1, dataset.test[,-(1:2)])

#결과 출력
predict(nn1, newdata = data.frame(b = 3, c = 2))
predict(nn1, newdata = data.frame(b = -5, c = 6))

data.frame(dataset.test, z.prediction)

- 실근(x1, x2)을 구했으니 예측할 차례

- dataset이라는 데이터프레임을 만듦 ( data.frame으로 묶어서 값을 예측했다. 다른 방법으로는 아직 시도하지는 않았다.)

 

samp <- sample(1:nrow(dataset), round(nrow(dataset)*0.7))
dataset.train <- dataset[samp, ] ## 700개 훈련 데이터
dataset.test <- dataset[-samp, ] ## 300개 검정 데이터

- 이 부분이 예측할 때 중요( 앞에서 구한 1000개 값(x1, x2, b, c)들을 훈련 데이터, 검정 데이터 분류)

   (보통 7:3 비율로 훈련 데이터와 검정 데이터를 랜덤(round)선택한다. 하지만 상황에 따라서 비율을 다르게 할 수 있다.)

 

dataset.train <- dataset[samp, ] ## 700개 훈련 데이터
dataset.test <- dataset[-samp, ] ## 300개 검정 데이터

- dataset[samp, ]의 의미 -> samp에 저장된 행 인덱스를 사용해 데이터셋을 만든다. samp에서 0.7로 랜덤한 행들을 저장했으므로 700개 데이터가 들어가 있다. 또한, samp에 저장된 행 인덱스에 해당하는 행들을 선택하고, 열 인덱스는 생략했으므로 모든 열을 선택함

-dataset[-samp, ]의 의미 -> samp는 0.7만큼의 랜덤된 데이터를 저장했으므로 -samp는 0.3만큼의 랜덤된 데이터를 뜻한다.

 

nn1 <- nnet(dataset.train[,-(1:2)], dataset.train[,(1:2)], size=50, maxit=10000, linout=T)

- nnet함수를 사용해 인공신경망 모델을 학습한다. 

- dataset.train[ ,-(1:2)] : 학습 데이터셋에서 첫 번째와 두 번째 열을 제외한 나머지 열들을 입력 데이터로 사용(종속)

- dataset.train[ , (1:2)] : 학습 데이터셋에서 첫 번째와 두 번째 열을 출력 데이터로 사용(독립)

- size =50 : 은닉층 노드 수를 50개로 설정

- maxit=10000 : 최대 학습 반복 횟수를 10000번으로 설정 (한 번 학습할 때, 처음부터 끝까지 한 번 학습을 한뒤 다시 처음으로 돌아가서 두 번째 학습 시작)

- linout= T : 출력층의 활성화 함수로 선형 함수를 사용

 

final  value 0.558180 

- 실행하면 학습을 시작하는데 value값이 작아질수록 좋다.

- 학습한 뒤 value값

 

z.prediction <- predict(nn1, dataset.test[,-(1:2)])

#결과 출력
predict(nn1, newdata = data.frame(b = 3, c = 2))
predict(nn1, newdata = data.frame(b = -5, c = 6))

data.frame(dataset.test, z.prediction)

- 값을 예측할 차례

- z.prediction <- predict(nn1, dataset.test[,-(1:2)]) : 학습된 인공신경망 모델 nn1을 사용해 검증 데이터셋의 입력 데이터 셋에 대한 예측값을 계산하여 저장

- dataset.test[ , -(1:2)] : 검정 데이터셋(300개)에서 -(1:2) 는 열(x1, x2)값 제외, 모든 행 포함 

 

- 결과 출력 : nn1을 이용해서 b=3, c=2일 때의 예측된 x1,x2의 값 출력

> predict(nn1, newdata = data.frame(b = 3, c = 2))
             x1        x2
[1,] -0.9602916 -1.882697
> predict(nn1, newdata = data.frame(b = -5, c = 6))
           x1       x2
[1,] 3.005568 2.005807

 

- data.frame(dataset.test, z.prediction) : 검증 데이터셋(dataset.test)과 해당 데이터셋에 대한 이공신경망의 예측값(z.prediction)을 하나의 데이터프레임으로 합친다. 검증 데이터셋의 실제값과 예측값을 비교