반응형

바이너리 분류 문제를 풀어보자.

logistic regression을 하면 된다.

linear regression은 출력이 실수범위로 주어진 샘플들을 거의 만족하는 수식을 찾아내는 거고, 그 수식을 기반으로 새로운 임의의 입력에 대해서 출력을 하여 그 값이  추측값이다.

logistic regression은 분류의 문제로 출력은 0 또는 1이다. 따라서 출력 범위가 실수 전체가 아니라 0/1 바이너리이다. 

이를 위해서 모델의 방식이 logistic function을 사용하게 된다. 0~1범위의 출력값을 갖는 함수를 이용하여 0에 가까운지 1에 가까운지로 0/1을 분류한다. sigmoid 함수를 사용할 경우 보통 0.5를 기준으로 분류.

여기서는 sigmoid 함수를 사용.


(x1,x2) -> O 또는 X로 구분하는 학습

아래의 검은 색은 학습 데이터로 이미 O, X가 지정되어 있는 데이터이다.

이를 학습하여, 빨간색의 점들을 O, X로 분류해 봤다.

왼쪽, 아래 부분들이 X, 오른쪽 상단 부분들이 O로 분류되는 모습이다. 테스트 데이터(빨간색)도 잘 분류하였다.

# deep learning test

# logistic regression( Binary classfication) multi vars.

#         ADD learning.... y=x2+x3 and

#         Decide big or low than 10


PLOTSHOW=TRUE


# training , X1=1 (bias)

X=matrix( c(1,1,1, 1,2,3, 1,4,2, 1,2,2, 1,5,4,

            1,7,4, 1,2,9, 1,7,7, 1,10,3, 1,9,4), byrow = T, ncol=3 ) 


# training result Y

Y=matrix( c(0, 0, 0, 0, 0, 

            1, 1, 1, 1, 1) ) 


# searching parameter, w1=bias 

W=c(0, 0, 0)



# drawing 

if ( PLOTSHOW ) {

  plot(1:10,1:10,type="n")

  pchs = vector(length = nrow(X))

  pchs[which(Y==0)]="X"

  pchs[which(Y==1)]="O"

  points(X[,2], X[,3], pch=pchs)

}





# G(X,W)=1/(1+e^-z)   , z=WX

G = function (X, W) {

  Z=X %*% W

  G = 1/(1+exp(-Z))

  return (G)

}



Cost =function (X, W, Y) {

  m = nrow(X)

  # Cost(W) = -1/m Sigma( y log(H(x))+(1-y)log(1-H(x)) )

  return ( (-1)/m * sum(Y*log(G(X,W)) + (1-Y)*log(1-G(X,W))) )

}



Gradient = function (X, W, Y, alpha) {

  m = nrow(X)

  W = W - alpha/m * ( t(X) %*% (G(X,W)-Y) )

  

  # w=w-alpha*cost'

  # cost' = -1/m Sigma ( X( (y-1)e^wx + Y) /(e^wx+1) )

  

  #W = W + alpha/m * ( t(X) %*% (((Y-1)*exp(X%*%W)+Y) / (exp(X%*%W)+1)) ) 

  return (W)

}


print( Cost(X, W, Y) )


#learning

alpha=0.05

for ( i in 1 : 6000 ) {

  W = Gradient(X,W,Y,alpha)

  if ( i %% 100==0 ) {

    print(paste("cnt=", i, " Cost=", Cost(X,W,Y), " W1(b)=", W[1,1], " W2=", W[2,1], " W3=", W[3,1] ))

  }

}


# predict

xmat = matrix(runif(10*3, 0, 11), nrow=10, ncol=3)

xmat[,1]=1

#xmat = matrix( c(1,1,1, 1,2,4, 1,4,1, 1,9,2, 1,6,8, 1,3,4,

#                 1,6,6, 1,4,6, 1,6,2), byrow = T, ncol=3 ) 

qy = G( xmat, W )

print (xmat)

print (qy)

threshold=0.5

qy2=ifelse(qy>threshold, 1, 0)

print(qy2)



# drawing 

if ( PLOTSHOW ) {

  pchs = vector(length = nrow(xmat))

  pchs[which(qy2==0)]="X"

  pchs[which(qy2==1)]="O"

  points(xmat[,2], xmat[,3], pch=pchs, col="red")

  

  # abline

  m=- ( W[2]/W[3])

  x1y0= (threshold-W[1])/W[2]

  abline(x1y0, m)

}


출력결과

1] 0.6931472

[1] "cnt= 100  Cost= 0.506130153063577  W1(b)= -0.742347709743049  W2= 0.166960447480382  W3= 0.13719656124762"

[1] "cnt= 200  Cost= 0.426904719548934  W1(b)= -1.36454376946518  W2= 0.21941982410039  W3= 0.211042797611876"

[1] "cnt= 300  Cost= 0.371538453508252  W1(b)= -1.88474084142892  W2= 0.263640326808228  W3= 0.27307497177045"

... 학습

[1] "cnt= 5900  Cost= 0.0989403091216031  W1(b)= -9.1090676929688  W2= 0.894710399352723  W3= 1.08049771083572"

[1] "cnt= 6000  Cost= 0.0982119304342858  W1(b)= -9.16885104353332  W2= 0.900021687190386  W3= 1.08680663800592"

      [,1]      [,2]      [,3]

 [1,]    1 6.5452887  8.024256

 [2,]    1 9.5209285  9.637048

 [3,]    1 6.8177543  1.780934

 [4,]    1 3.6139041  2.678026

 [5,]    1 0.6012657  7.200270

 [6,]    1 9.5897683  6.282960

 [7,]    1 7.7645759  4.530263

 [8,]    1 7.2534271  7.010700

 [9,]    1 9.8989604  2.489668

[10,]    1 1.0309055 10.951213

           [,1]

 [1,] 0.9956916

 [2,] 0.9999485

 [3,] 0.2502662

 [4,] 0.0471662

 [5,] 0.3095129

 [6,] 0.9981496

 [7,] 0.9395143

 [8,] 0.9931638

 [9,] 0.9202843

[10,] 0.9749335

      [,1]

 [1,]    1

 [2,]    1

 [3,]    0

 [4,]    0

 [5,]    0

 [6,]    1

 [7,]    1

 [8,]    1

 [9,]    1

[10,]    1

+ Recent posts