본문 바로가기
R 과 데이터분석/기초 문법 ~ 머신러닝

[R 데이터분석] 9장. 정형(DB데이터)과 비정형 데이터 처리

by JoyfulS 2019. 9. 13.

chap09_한글 감성분석.zip
0.07MB

# Chap09_1_Formal

# 정형 데이터(DB Data) 처리


# Oracle or MySQL(MariaDB)
# Maria DB 정형 데이터 처리

# 패키지 설치
# - RJDBC 패키지를 사용하기 위해서는 우선 java를 설치해야 한다.
#install.packages("rJava") # R + JAVA
install.packages("DBI")
install.packages("RJDBC") # JDBC()함수 제공 

# 패키지 로딩
library(DBI)
Sys.setenv(JAVA_HOME='C:\\Program Files\\Java\\jre1.8.0_144')
library(rJava)
library(RJDBC) # rJava에 의존적이다.

################ MariaDB or MySql ##################
drv <- JDBC(driverClass="com.mysql.jdbc.Driver", 
            classPath="C:\\1_Spring_boot\\tools\\mysql-connector-java-5.1.46\\mysql-connector-java-5.1.46\\mysql-connector-java-5.1.46-bin.jar")

### 주의 : classPath는 저장위치 잘 확인해서 적용할 것


# driver가 완전히 로드된 후 db를 연결한다.
conn <- dbConnect(drv, "jdbc:mysql://127.0.0.1:3306/bigdata", "root", "1234")
#################################################           

query <- "show tables"
dbGetQuery(conn, query)

# table 생성 
query <- "create table goods(code int, name varchar(50), su int, dan int)"
dbSendUpdate(conn, query)

# table 조회 
dbGetQuery(conn, "select * from goods")
# code name su   dan 

# insert
query <- "insert into goods values(1, '전화기', 4, 250000)"
dbSendUpdate(conn, query)

# select 
dbGetQuery(conn, "select * from goods")

# update
query <- "update goods set name='phone' where code=1"
dbSendUpdate(conn, query)

dbGetQuery(conn, "select * from goods")

# delete
dbSendUpdate(conn, "delete from goods where code=1")

dbGetQuery(conn, "select * from goods")

# table 제거 
dbSendUpdate(conn, "drop table goods")

dbGetQuery(conn, "show tables")

# db 연결 종료 
dbDisconnect(conn) # TRUE


 

--------------------------------------------------------------------------------------------------------------

 

 

# Chap09_2_Informal 

 

# 비정형 데이터 처리

# 1. 토픽분석(텍스트 마이닝)  

# 2. 연관어 분석(단어와 단어 사이 연관성 분석)  

 

 

 

##################################################
# 1. 토픽분석(텍스트 마이닝) 
# - 시각화 : 단어 빈도수에 따른 워드 클라우드
###################################################

# 1. 패키지 설치 
# 1) rJava 설치 : R에서 java 사용을 위한 패키지
Sys.setenv(JAVA_HOME='C:\\Program Files\\Java\\jre1.8.0_151')
install.packages("rJava")
library(rJava) # 로딩
# 2) install.packages
install.packages(c("KoNLP", "wordcloud", "tm")) 
# 3) 패키지 로딩
library(KoNLP) # 한글 사전 
# Building dictionary structures.
library(tm) # 전처리 용도 
# 필요한 패키지를 로딩중입니다: NLP
library(wordcloud) # 단어 구름 시각화 - #필요한 패키지를 로딩중입니다: RColorBrewer

 

### 사용된 파일은 https://joyfuls.tistory.com/4 에서 다운 받으실 수 있습니다.


# 2. facebook_bigdata.txt 가져오기
facebook <- file("C:\\2_Rwork\\Part-II/facebook_bigdata.txt", encoding="UTF-8")
facebook_data <- readLines(facebook) # 줄 단위 데이터 생성
head(facebook_data) # 앞부분 6줄 보기 - 줄 단위 문장 확인 
str(facebook_data) # chr [1:76]

# 3. 세종 사전 사용 및 단어 추가
# term='추가단어', tag=ncn(명사지시코드)
user_dic <- data.frame(term=c("R 프로그래밍","페이스북","김조이","소셜네트워크"), tag='ncn')
buildDictionary(ext_dic='sejong', user_dic = user_dic)

# 4. 단어추출 사용자 함수 정의
# (1) 사용자 정의 함수 실행 순서 : 문자변환 -> 명사 단어추출 -> 공백으로 합침
exNouns <- function(x) { 
  paste(extractNoun(as.character(x)), collapse=" ")
}
# (2) exNouns 함수 이용 단어 추출 
# 형식) sapply(vector, 함수) -> 76개 vector 문장(원소)에서 단어 추출 
facebook_nouns <- sapply(facebook_data, exNouns) 
# (3) 단어 추출 결과
str(facebook_nouns) # [1:76] attr(*, 'names')=ch [1:76] 

# 5. 데이터 전처리   
# (1) 말뭉치(코퍼스:Corpus) 생성 : 텍스트를 처리할 수 있는 자료의 집합 
myCorpus <- Corpus(VectorSource(facebook_nouns)) 
myCorpus # Content:  documents: 76
inspect(myCorpus[1]) # corpus 내용 보기 
inspect(myCorpus[2])
# (2) 데이터 전처리 : 말뭉치 대상 전처리 
myCorpusPrepro <- tm_map(myCorpus, removePunctuation) # 문장부호 제거
myCorpusPrepro <- tm_map(myCorpusPrepro, removeNumbers) # 수치 제거
myCorpusPrepro <- tm_map(myCorpusPrepro, tolower) # 소문자 변경
myCorpusPrepro <-tm_map(myCorpusPrepro, removeWords, stopwords('english')) # 불용어제거
stopwords('english')
# (3) 전처리 결과 확인 
myCorpusPrepro # Content:  documents: 76
inspect(myCorpusPrepro[1:5]) # 데이터 전처리 결과 확인(숫자, 영문 확인)


# 6. 단어 선별(단어 길이 2개 ~ 8개)
# 단어길이 2개 이상(한글 1개 2byte) 단어 선별 -> matrix 변경
myCorpusPrepro_term <- TermDocumentMatrix(myCorpusPrepro, 
                                    control=list(wordLengths=c(4,16))) 
myCorpusPrepro_term


# 7. 단어 빈도수 구하기

# (1) Corpus -> 평서문 변환 : matrix -> data.frame 변경
myTerm_df <- as.data.frame(as.matrix(myCorpusPrepro_term)) 
# (2) 단어 빈도수 내림차순 정렬 
wordResult <- sort(rowSums(myTerm_df), decreasing=TRUE) 


# 8. wordcloud 생성 (디자인 적용전)
myName <- names(wordResult) # 단어 이름 생성 -> 빈도수의 이름 
wordcloud(myName, wordResult) # 단어구름 적성

# 9. 단어구름에 디자인 적용(빈도수, 색상, 랜덤, 회전 등)
# (1) 단어이름과 빈도수로 data.frame 생성
word.df <- data.frame(word=myName, freq=wordResult) 
str(word.df) # word, freq 변수
# (2) 단어 색상과 글꼴 지정
pal <- brewer.pal(12,"Paired") # 12가지 색상 pal <- brewer.pal(9,"Set1") # Set1~ Set3
# 폰트 설정세팅 : "맑은 고딕", "서울남산체 B"
windowsFonts(malgun=windowsFont("맑은 고딕"))  #windows
# (3) 단어 구름 시각화 - 별도의 창에 색상, 빈도수, 글꼴, 회전 등의 속성을 적용하여 
x11( ) # 별도의 창을 띄우는 함수
wordcloud(word.df$word, word.df$freq, 
          scale=c(5,1), min.freq=2, random.order=F, 
          rot.per=.1, colors=pal, family="malgun")

# 10. 차트 시각화  
#(1) 상위 10개 토픽추출
topWord <- head(sort(wordResult, decreasing=T), 10) # 상위 10개 토픽추출 
# (2) 파일 차트 생성 
pie(topWord, col=rainbow(10), radius=1) # 파이 차트-무지개색, 원크기
# (3) 빈도수 백분율 적용 
pct <- round(topWord/sum(topWord)*100, 1) # 백분율
names(topWord)
# (4) 단어와 백분율 하나로 합친다.
lab <- paste(names(topWord), "\n", pct, "%")
# (5) 파이차트에 단어와 백분율을 레이블로 적용 
pie(topWord, main="SNS 빅데이터 관련 토픽분석", col=rainbow(10), cex=0.8, labels=lab)

 

 

###########################################
# 2. 연관어 분석(단어와 단어 사이 연관성 분석) 
#   - 시각화 : 연관어 네트워크 시각화,
###########################################

# 한글 처리를 위한 패키지 설치
Sys.setenv(JAVA_HOME='C:\\Program Files\\Java\\jre1.8.0_151')
library(rJava) # 아래와 같은 Error 발생 시 Sys.setenv()함수로 java 경로 지정
library(KoNLP) # rJava 라이브러리가 필요함

# 1.텍스트 파일 가져오기
#----------------------------------------------------
marketing <- file("C:\\2_Rwork\\Part-II/marketing.txt", encoding="UTF-8")
marketing2 <- readLines(marketing) # 줄 단위 데이터 생성
close(marketing) 
head(marketing2) # 앞부분 6줄 보기 - 줄 단위 문장 확인 
str(marketing2)

# 2. 줄 단위 단어 추출
#----------------------------------------------------
# Map()함수 이용 줄 단위 단어 추출 
lword <- Map(extractNoun, marketing2) 
length(lword) # [1] 472
lword <- unique(lword) # 중복제거1(전체 대상)
length(lword) # [1] 353(119개 제거)
lword <- sapply(lword, unique) # 중복제거2(줄 단위 대상) 
length(lword) 
class(lword) # list
lword # 추출 단어 확인

# 3. 전처리
#----------------------------------------------------
# 1) 길이가 2~4 사이의 단어 필터링 함수 정의
filter1 <- function(x){
  nchar(x) <= 4 && nchar(x) >= 2 && is.hangul(x)
}
# 2) Filter(f,x) -> filter1() 함수를 적용하여 x 벡터 단위 필터링 
filter2 <- function(x){
  Filter(filter1, x)
}
# is.hangul() : KoNLP 패키지 제공
# Filter(f, x) : base
# nchar() : base -> 문자 수 반환

# 3) 줄 단어 대상 필터링
lword_final <- sapply(lword, filter2)
lword_final # 추출 단어 확인(길이 1개 단어 삭제됨)


# 4. 트랜잭션 생성 : 연관분석을 위해서 단어를 트랜잭션으로 변환
#----------------------------------------------------
# arules 패키지 설치
install.packages("arules")
library(arules) 
#--------------------
# arules 패키지 제공 기능
# - Adult,Groceries 데이터 셋
# - as(),apriori(),inspect(),labels(),crossTable()=table()
#-------------------
wordtran <- as(lword_final, "transactions") # 중복 word 있으면 error발생
wordtran 

# 트랜잭션 내용 보기 -> 각 트랜잭션의 단어 보기
inspect(wordtran)  


# 5.단어 간 연관규칙 산출
#----------------------------------------------------
# 트랜잭션 데이터를 대상으로 지지도와 신뢰도를 적용하여 연관규칙 생성
# 형식) apriori(data, parameter = NULL, appearance = NULL, control = NULL)
tranrules <- apriori(wordtran, parameter=list(supp=0.25, conf=0.05)) 
inspect(tranrules) # 연관규칙 생성 결과


# 6.연관어 시각화 
#----------------------------------------------------
# (1) 데이터 구조 변경 : 연관규칙 -> label 추출  
rules <- labels(tranrules, ruleSep=" ")  
rules

# 문자열로 묶인 연관단어를 행렬구조 변경 
rules <- sapply(rules, strsplit, " ",  USE.NAMES=F) 
rules

# list -> matrix 반환
rulemat <- do.call("rbind", rules)
rulemat

# (2) 연관어 시각화를 위한 igraph 패키지 설치
install.packages("igraph") # graph.edgelist(), plot.igraph(), closeness() 함수 제공
library(igraph)   

# (3) edgelist보기 - 연관단어를 정점 형태의 목록 제공 
ruleg <- graph.edgelist(rulemat[c(12:59),], directed=F) # [1,]~[11,] "{}" 제외
ruleg

# (4) edgelist 시각화
X11()
plot.igraph(ruleg, vertex.label=V(ruleg)$name,
            vertex.label.cex=1.2, vertex.label.color='black', 
            vertex.size=20, vertex.color='green', vertex.frame.color='blue')

 

 

댓글