- POSTECH에서 제공하는 MOOC 중, 머신러닝기법과 R프로그래밍 Ⅱ 과정입니다.
ⅩⅥ. 딥러닝과 텍스트 마이닝
1. Neural Networks
Concepts
- 인공신경망은 기계학습(Machine Learning)의 통계적 학습 알고리즘 중 하나
- 컴퓨터 비전, 자연어 처리, 음석 인식 등 영역에서 사용
- AI ⊂ Machine Learning ⊂ Neural Network
- 신경망 모델(Neural Network)
- Perceptron을 한 단위로 하는 네트워크를 구축하여, 인간의 신경세포(Neuron)와 유사한 기능을 하도록 제안
Perceptron - Single Layer
- 하나의 Perceptron은 단순히 다수의 입력과 가중치의 선형 결합을 계산하는 역할을 수행
- Activation 함수에 따라 선형결합으로 생성되는 출력값이 결정
- Binary Threshold
- Sigmoid
- ReLU(Rectified Linear Unit)
- tanh
Multi-layer perceptron
Perceptron으로 구성된 Single Layer들이 Multi-layer를 만듦
- Input layer와 Output layer 사이에는 Hidden layer가 존재하여 Non-linear transformation 수행
Output layer에서 Softmax 함수를 통해 가장 큰 값을 손쉽게 알 수 있음
- Exponential 함수로 항상 양수 결과치가 도출되고 이를 통해 확률값을 도출
Neural Network 수행
- mxnet 패키지는 R4.0 버전 이후부터 실행 불가
- R 3.6.2버전 설치해서 실행 필요
1
2
3
4
5
6
7
8
9
10
11
12
13
14# require mxnet
install.packages("https://github.com/jeremiedb/mxnet_winbin/raw/master/mxnet.zip",repos = NULL)
library(mxnet)
# If you have Error message "no package called XML or DiagrmmeR", then install
install.packages("XML")
install.packages("DiagrammeR")
#library(XML)
#library(DiagrammeR)
#devtools::install_github("rich-iannone/DiagrammeR")
#install.packages('devtools')
#library(devtools) - 데이터 불러오기
1
2
3
4
5
6
7
8
9# read csv file
iris<-read.csv("data/week16_1/iris.csv")
attach(iris)
# change to numeric from character variable : Species
iris[,5] = as.numeric(iris[,5])-1
table(Species)
# check the data
head(iris, n=10) - 학습데이터와 검증데이터
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17# split train & test dataset
# training (n=100)/ test data(n=50)
set.seed(1000,sample.kind="Rounding")
N<-nrow(iris)
tr.idx<-sample(1:N, size=N*2/3, replace=FALSE)
# split train data and test data
train<-data.matrix(iris[tr.idx,])
test<-data.matrix(iris[-tr.idx,])
# feature & Labels
# 객체별 Feature와 Label로 분리
# Label은 5번째 열에 위치
train_feature<-train[,-5]
trainLabels<-train[,5]
test_feature<-test[,-5]
testLabels <-test[,5] - Hidden Layer 구성
1
2
3
4
5
6# Build nn model
# first layers
require(mxnet)
my_input = mx.symbol.Variable('data')
fc1 = mx.symbol.FullyConnected(data=my_input, num.hidden = 200, name='fc1') # 200개의 뉴런 형성
relu1 = mx.symbol.Activation(data=fc1, act.type='relu', name='relu1')1
2
3# second layers
fc2 = mx.symbol.FullyConnected(data=relu1, num.hidden = 100, name='fc2') # 100개의 뉴런 형성
relu2 = mx.symbol.Activation(data=fc2, act.type='relu', name='relu2') - Output Layer 구성
1
2
3
4
5
6# third layers
fc3 = mx.symbol.FullyConnected(data=relu2, num.hidden = 3, name='fc3') # 3개로 분류(0,1,2)해야 하므로 3개의 Output 뉴런 생성
# softmax
softmax = mx.symbol.SoftmaxOutput(data=fc3, name='sm')
# sofrmax 결과를 통해 가장 큰 값 선택 - 모델 학습
1
2
3
4
5
6
7
8
9
10
11
12# training
mx.set.seed(123, sample.kind="Rounding")
device <- mx.cpu()
model <- mx.model.FeedForward.create(softmax,
optimizer = "sgd", # Stochastic Gradient Descent
array.batch.size=10, # 총 10개 그룹
num.round = 500, learning.rate=0.1,
X=train_feature, y=trainLabels, ctx=device,
eval.metric = mx.metric.accuracy,
array.layout = "rowmajor",
epoch.end.callback=mx.callback.log.train.metric(100))
graph.viz(model$symbol) - 모델 테스트
1
2
3
4
5# testing
predict_probs <- predict(model, test_feature, array.layout = "rowmajor")
predicted_labels <- max.col(t(predict_probs)) - 1
table(testLabels, predicted_labels)
sum(diag(table(testLabels, predicted_labels)))/length(predicted_labels)
2. Convolutional Neural Networks
Features
- 신경망 모델(Neural Net)
- 입력값으로 객체의 특성(feature)을 받고, 출력된 값과 실제 값을 비교하는 과정을 거침(지도학습; Supervised Learning)
- 하나의 이미지는 수많은 픽셀들이 모여 형성하며, 특정 색에 해당하는 특정 값을 가짐
- 이미지의 모든 픽셀값을 입력값으로 갖는 신경망 모델을 만들 수 있음
Intuitions
고해상도 이미지의 경우 특성 feature 수가 너무 많아짐
- 모든 뉴런이 모든 픽셀과 연결(fully connected)되어 있을 경우, 모델 학습에 큰 어려움이 있음
- 각 뉴런들이 이미지의 일부 특성 feature에만 연결될 수 있는 구조가 더 더 적합함
- Convolution operation을 통해 구현 가능
Convolutional Neural Network
- Feed forward Network: x
i^n^을 구함- Convilution
- Max Pooling
- Activation function
- Backpropagation: Error 최소화
- Feed forward Network: x
Concolution Operation
- 임의의 값으로 설정된 filter가 전체 이미지 중 일부의 선형 결합을 계산
- 각각 결괏값은 하나의 Neuron이 되며, filter는 해당 Neuron의 가중치과 됨
- 결괏값의 사이즈를 정하기 위해서는 Stride, Padding, Depth 고려 필요
- Stride: filter를 몇 칸 이동할지 결정
- Padding: input 주변에 0으로 padding을 삽입
- Depth number of filter: 3차원상의 neuron의 깊이를 결정
Pooling
- Convolutional Layer 사이에 Pooling Layer를 넣는 방법이 많이 사용됨
- 추출한 이미지에서 지역적인 부분 특징만 뽑아 다음 layer로 넘겨줌
- 이를 통해 ① 가중치의 수를 줄일 수 있으며, ② 과적합(overfitting)을 방지할 수 있음
- 대표적으로 가장 큰 값(Local Maxima)만을 뽑아내는 Max Pooling이 많이 사용됨
MNIST
- Modified National Institute of Standards and Technology
- 손으로 쓴 숫자를 인식하기 위해 사용되는 데이터
- 28x28 pixel(784)의 흑백 이미지(0-255)들이 있음
- 0부터 9까지 총 70,000개의 손글씨 이미지가 있음
CNN in R
- 신경망 모델 생성을 위한 패키지: mxnet
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26# Load MNIST mn1
# 28*28, 1 channel images
mn1 <- read.csv("mini_mnist.csv")
set.seed(123,sample.kind="Rounding")
N<-nrow(mn1)
tr.idx<-sample(1:N, size=N*2/3, replace=FALSE)
# split train data and test data
train_data<-data.matrix(mn1[tr.idx,])
test_data<-data.matrix(mn1[-tr.idx,])
# 0과 1 사이에 분포하도록 Nomalized(0: 검정색 / 255: 흰색)
test<-t(test_data[,-1]/255)
features<-t(train_data[,-1]/255)
labels<-train_data[,1]
# data preprocession
features_array <- features
# 입력 데이터의 차원을 설정(픽셀*객체 개수)
# ncol(features): 학습 데이터 수(866)
dim(features_array) <- c(28,28,1,ncol(features))
test_array <- test
dim(test_array) <- c(28,28,1,ncol(test))
ncol(features)
table(labels) - Convolutional Layer 구성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37# Build cnn model
# first conv layers
my_input = mx.symbol.Variable('data')
conv1 = mx.symbol.Convolution(data=my_input, kernel=c(4,4), stride=c(2,2), pad=c(1,1), num.filter = 20, name='conv1')
relu1 = mx.symbol.Activation(data=conv1, act.type='relu', name='relu1')
mp1 = mx.symbol.Pooling(data=relu1, kernel=c(2,2), stride=c(2,2), pool.type='max', name='pool1')
# second conv layers
conv2 = mx.symbol.Convolution(data=mp1, kernel=c(3,3), stride=c(2,2), pad=c(1,1), num.filter = 40, name='conv2')
relu2 = mx.symbol.Activation(data=conv2, act.type='relu', name='relu2')
mp2 = mx.symbol.Pooling(data=relu2, kernel=c(2,2), stride=c(2,2), pool.type='max', name='pool2')
# fully connected
fc1 = mx.symbol.FullyConnected(data=mp2, num.hidden = 1000, name='fc1')
relu3 = mx.symbol.Activation(data=fc1, act.type='relu', name='relu3')
fc2 = mx.symbol.FullyConnected(data=relu3, num.hidden = 3, name='fc2')
# softmax
sm = mx.symbol.SoftmaxOutput(data=fc2, name='sm')
# training
mx.set.seed(100,sample.kind="Rounding")
device <- mx.cpu()
model <- mx.model.FeedForward.create(symbol=sm,
optimizer = "sgd",
array.batch.size=30,
num.round = 70, learning.rate=0.1,
X=features_array, y=labels, ctx=device,
eval.metric = mx.metric.accuracy,
epoch.end.callback=mx.callback.log.train.metric(100))
graph.viz(model$symbol)
# test
predict_probs <- predict(model, test_array)
predicted_labels <- max.col(t(predict_probs)) - 1
table(test_data[, 1], predicted_labels)
sum(diag(table(test_data[, 1], predicted_labels)))/length(predicted_labels) - 네트워크 시각화 함수: graph.viz(model$symbol)
1
graph.viz(model$symbol)
3. 텍스트 마이닝
텍스트 마이닝이란?
- 텍스트마이닝(Text mining)
- 웹페이지, 이메일, 소셜네트워크 기록 등 전자문서 파일로부터 특정 연관성(동시적으로 빈도 높은 단어 추출)을 분석하는 방법
- 다양한 방식의 알고리즘을 이용해 대용량의 텍스트로부터 트렌드와 관심어를 찾아내는 기법으로 사용
텍스트 마이닝 필요 패키지
- Natural language processing
- install.packages(‘NLP’)
- text mining package
- install.packages(‘tm’)
- visualizing
- install.packages(‘wordcloud’)
- color displaying
- install.packages(‘RColorBrewer’)
- Korean processing
- install.packages(‘KoNLP’)
- import twitter data
- install.packages(‘twitteR’)
1 | # set library (set in order) |
- 사용 데이터: tm에 포함된 crude
1
2
3
4# 20 new articles from Reuter- 21578 data set
data(crude)
# To know abour crude data
help(crude)텍스트 마이닝- 함수
함수|설명 및 예제코드
|—|—|
str(x[[1]])|데이터 구조 정보(첫 번째 파일 구조) / str(crude[[1]])
content(x[[1]])|문서 내용(첫 번째 분서 내용)
meta(X)|메타정보(x에 기록된 저자, 날짜, id 등 정보) / meta(ctude[[1]])
inspect(X)|코퍼스, 텍스트, 문서행렬 등 정보 제공 / data(crude), inspect(crude[1:3]), inspect(crude[[1]]), tdm <- TermDocumentMatrix(crude), inspect(tdm)
lapply(x, content)|파일 내용을 보여줌 / lapply(crude, content)
1 | # information about the first file in crude data |
1 | # inspect function |
텍스트 마이닝- 전처리 함수
함수|설명
|—|—|
tm_map(x, removePunctuation)|문장부호 제거(. , “” ‘’)
tm_map(x, stripWhitespace)|공백문자 제거
tm_map(x, removeNumbers)|숫자 제거
텍스트 마이닝 실습
문장부호 없애기: tm_map(x, removePunctuation)
1
2
3# 1. remove punctuation in documnet
crude<-tm_map(crude, removePunctuation)
content(crude[[1]])숫자 제거: tm_map(x, removeNumbers)
1
2
3# 2. remove numbers
crude<-tm_map(crude, removeNumbers)
content(crude[[1]])스톱워즈 제거: 언어별로 다르며 별도 지정 가능
1
2
3# 3. remove stopwords
crude<-tm_map(crude, function(x) removeWords(x,stopwords()))
content(crude[[1]])참고: 스톱워즈 리스트
1
stopwords() #stopwords("en") 174개, stopwords("SMART")" 517개
문서 행렬 구성: TermDocumentMatrix(문서이름)
1
2
3# 4. contruct term-doucument matrix
tdm<-TermDocumentMatrix(crude)
inspect(tdm)결과 해석
- DOCS 144: crude 문서 번호 144에 나오는 단어들의 빈도
문서 행렬을 행렬로 변환
1
2
3# 5. read tdm as a matrix
m<-as.matrix(tdm)
head(m)단어의 빈도 순서로 정렬
1
2
3# 6. sorting in high frequency to low frequency
v<-sort(rowSums(m), decreasing=TRUE)
v[1:10] # 가장 높은 것부터 [1:10]번까지텍스트마이닝 수행
- 단어 이름과 빈도를 결합한 행렬을 데이터 프레임으로 저장
- crude 관련 기사 파일로부터 962개 단어를 분류해 빈도 계산
1
2
3
4# 7. match with freq and word names
d<-data.frame(word=names(v), freq=v)
head(d) #가장 빈도 높은 단어 6개
d[957:962, ] #가장 빈도 낮은 단어 6개
텍스트마이닝 결과 그리기
1
2
3# 7. plot a word cloud
wordcloud(d$word, d$freq)
# help(wordcloud)1
2
3
4
5
6
7
8# 7-1. Now lets try it with frequent words plotted first
# par(mfrow = c(1, 1),mar=c(1,2,3,1))
wordcloud(d$word,d$freq,c(8,.3),2,,FALSE,.1)
# 7-2. color plot with frequent words plotted first
pal <- brewer.pal(9,"BuGn")
pal <- pal[-(1:4)]
wordcloud(d$word,d$freq,c(8,.3),2,,FALSE,,.15,pal)