반응형

시작하기 전에 R, RStudio, KoNLP(한글 형태소 분석 패키지)가 설치되어 있어야한다.

특히 KoNLP는 다운받는 과정이 조금 복잡하므로 아래 링크를 참고하시길!

1. [R 프로그래밍] R, R Studio 다운로드

https://blog.naver.com/song_sec/221799018628

2. [R 프로그래밍] install.packages("KoNLP") - Konlpy 설치불가 이슈 해결

https://blog.naver.com/song_sec/221800340719

이번 포스팅에서는 R을 이용하여 카카오톡 채팅방을 아래 카테고리에 따라 분석할 것이다.

1) 카카오톡 채팅방에서 각 인원의 대화 지분

2) 시간대별 메세지 수 (몇시가 가장 활발하고, 몇시가 채팅이 없는지)

3) 가장 많이 등장하는 메세지(단어, 형태소) - 워드클라우드

4) 상관성 분석

나는 11명이 있는 친구들 단톡방을 대상으로 해당 분석들을 진행하였다.

1) 카카오톡 채팅방 각 인원의 대화 지분

(1) 결과물

 

 

 

(2) 코드 설명

나는 카카오톡 대화내용을 받아온 후, 메모장에서 전체바꾸기로 각 사람들의 이름을 '[이름]'으로 변경했다. 이는 나중에 있을 텍스트분석에서 친구들이 말한 내이름, 내가 발언하여 생긴 내 이름과 분리 하기 위함이다.

하지만 이것은 R에서 str_replace_all을 통해 바꿀 수도 있으므로 참고만 하시길!

 

 

library(KoNLP) #한글형태소 분석 라이브러리

library(stringr) #Regexp를 하기 위해. 한글을 문자, 단어별로 잘라내고 바꾸는 일 담당

library(wordcloud) #워드클라우드

library(RColorBrewer) #워드클라우드 색상

library(rvest) #html, xml 자료를 쉽게 가져와서 처리

library(NIADic) #KoNLP의 한글 사전 최신판

library(tm) #연관성 검사용

library(qgraph) #연관성 검사 결과값 시각화용

library(extrafont) #폰트 설정

suppressPackageStartupMessages(library(googleVis)) #차트그리기용

textdata<-file("KakaoTalkChats_GRP.txt", encoding='UTF-8') #파일

import data<-readLines(textdata, encoding='UTF-8')

 

head(data) # 불러온 파일 확인 data<-data[-1:-4] #파일의 1~4번째 줄은 필요 없어서 삭제

head(data) #삭제된 것을 확인

 

# 각 문단 별로 [이름]으로 시작되는 (rows)을 찾아 갯수를 pn에 입력

p1<-length(data[grep("\\[JONGSUN", data)])

p2<-length(data[grep("\\[BAEK", data)])

p3<-length(data[grep("\\[YEONGGYU", data)])

p4<-length(data[grep("\\[SUJIN", data)])

p5<-length(data[grep("\\[SEOKMIN", data)])

p6<-length(data[grep("\\[JINGU", data)])

p7<-length(data[grep("\\[SANGHYEOK", data)])

p8<-length(data[grep("\\[INVEST", data)])

p9<-length(data[grep("\\[MM", data)])

p10<-length(data[grep("\\[JONG", data)])

p11<-length(data[grep("\\[HEEDO", data)])

 

#talk_volumes에 모든 대화 갯수를 넣는다. ex. p1 p2 p3...p11 = 5245 5652 ... 1208 talk_volumes<-c(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11) #name에 각 구성원의 이름을 넣는다.

name<-c('JONGSUN','BAEK','YEONGGYU','SUJIN', 'SEOKMIN', 'JINGU','SANGHYEOK','INVEST','MM','JONG','HEEDO')

 

#그러면 mapping이 된다. name1-p1, name2-p2 ...

talk_stake<-data.frame(name, talk_volumes) #대화 지분 # pie chart를 그린다.

pie1<-gvisPieChart(talk_stake,options=list(width=400,height=300))

pie_bar<-gvisBarChart(talk_stake,options=list(width=600,height=300))

 

# 한글은 깨지는 경우가 있으므로 아래 코드를 추가한다.

header <-pie1$html$header header <- gsub("charset=utf-8", "charset=euc-kr", header)

pie1$html$header <- header #pieplot를 소환한다. plot(pie1) plot(pie_bar)

 

2) 시간대별 메세지 수 (몇시가 가장 활발, 몇시가 채팅이 없나)

(1) 결과물

gvisColumnChart. 오후 1시 메세지가 가장 많았다.

 

 

(2) 코드 설명

#시간대별 카톡량 분석

bfnoon<-data[grep("\\오전",data)] #오전으로 시작하는 줄의 data들을 bfnoon에 삽입

afnoon<-data[grep("\\오후",data)] #오후로 시작하는 줄의 data를 afnoon에 삽입

 

# 오전/오후 data를 삽입하면 각 시간대별로 분류해주는 함수

timefunc<-function(x){

time1<-x[grep("1:",x)]

time2<-x[grep("2:",x)]

time3<-x[grep("3:",x)]

time4<-x[grep("4:",x)]

time5<-x[grep("5:",x)]

time6<-x[grep("6:",x)]

time7<-x[grep("7:",x)]

time8<-x[grep("8:",x)]

time9<-x[grep("9:",x)]

time10<-x[grep("10:",x)]

time11<-x[grep("11:",x)]

time12<-x[grep("12:",x)]

return(c(length(time1), length(time2), length(time3), length(time4), length(time5), length(time6), length(time7), length(time8), length(time9),length(time10), length(time11), length(time12))) }

 

Beforenoon<-timefunc(bfnoon) #오전data를 시간대별로 분류하여 Beforenoon에 삽입

Afternoon<-timefunc(afnoon) #오후data를 시간대별로 분류하여 Afternoon에 삽입

time<-c('1H', '2H', '3H', '4H','5H', '6H','7H', '8H', '9H', '10H', '11H', '12H') #각 시간 삽입

 

total_time<-data.frame(time,Beforenoon,Afternoon) #시간, 오전, 오후를 하나의 frame으로 만들기

chart_by_time<-gvisColumnChart(total_time,options=list(height=500,weight=1000)) #만든 것을 chart로 만들기 plot(chart_by_time) #차트 그리기

 

 

3) 가장 많이 등장하는 메세지(단어, 형태소) 워드클라우드

(1) 결과물

wordcloud. 놀랍게도 메세지 삭제를 애들이 많이해서 "삭제"가 제일 많다. ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

piechart

20대 11명 대화방에서 가장 많이 나오는 단어들 ㅋㅋㅋ

 

 

(2) 코드 설명

가. 데이터 전처리: 텍스트분석을 위해서는 필요없는 정보(시간, 특수문자 등)를 지우는 과정이 꼭 필요하다.

#텍스트분석을 위한 데이터 전처리 #전처리된 것들만 모을 data_mod 생성

data_mod<-str_replace_all(data,"이모티콘","") %>% #텍스트분석을 진행할 것으로, 순수 "대화"가 아닌 텍스트 모두 제거

str_replace_all("\\오후 ","")%>%

str_replace_all("\\오전 ", "")%>%

str_replace_all("[ㄱ-ㅎ]+","")%>%

str_replace_all("[가-힣] :","")%>%

str_replace_all("[[A-Z]]","")%>%

str_replace_all("[[a-z]]","")%>%

str_replace_all("사진","") %>%

str_replace_all("[0-9]+.","")%>%

str_replace_all("년.월.일","")%>%

str_replace_all(".요일","")%>%

str_replace_all("[[:punct:]]","")%>% #맞춤법 안지킨 것들 보정

str_replace_all("겟","겠")%>%

str_replace_all("햇","했")%>%

str_replace_all("됬","됐")%>%

str_replace_all("됫","됐")%>%

str_replace_all("갓","갔")%>%

str_replace_all("댓","댔")%>%

str_replace_all("뎃","댔")%>%

str_replace_all("왓","왔")%>%

str_replace_all("랏","랐")%>%

str_replace_all("잇","있")%>%

str_replace_all("되겠","")%>%

 

#character()로 변경

as.character() #문자형(character)으로 변경

head(data_mod) #테스트 출력

useNIADic() #분석을 위한 사전

 

#전처리한 데이터에서 etractNoun함수로 명사만 추출

noun<-sapply(data_mod, extractNoun, USE.NAMES = F) %>%

unlist() #2단어 이상의 명사만 추출

noun2 <-Filter(function(x){nchar(x)>=2}, noun)

 

#가장 많이 등장한 단어 순으로 50개 정렬

head(noun2) wordFreq <-table(noun2)

noundta<-sort(wordFreq, decreasing=TRUE,50) #noundta<-noundta[-1]

print(noundta)

 

 

나. 워드클라우드 및 piechart

#워드클라우드 생성

set <- brewer.pal(7, "Set2") #워드클라우드를 위한 폰트색상 계열 설정

loadfonts(device="win") #폰트 불러오기

windowsFonts(headline=windowsFont("HY헤드라인M")) wordcloud(names(noundta), freq=noundta, min.freq = 100, random.order=T, rot.per = .1, colors=set, family="headline")

 

#상위20개 piechart 생성

top_20=(sort(noundta, decreasing=T), 20) pie(top_20)

4) 상관성분석

(1) 결과물

(2) 코드설명

#상관성분석

#SimplePos22: 명사/형용사/부사/독립언 분리

tt<-paste(unlist(SimplePos22(data_mod)))

head(tt,200)

 

#명사만 가져오기

alldta<-str_match_all(tt,"[가-힣]+/[N][C]|[가-힣]+/[N][Q]+")%>%

unlist() #형용사만 가져오기

alldta2<-str_match_all(tt,"[가-힣]+/[P][V]|[가-힣]+/[P][X]+[가-힣]+/[P][A]+[가-힣]+/[M][A]+")%>%

unlist() #명사로 추출된 단어들의 분류표인 /NC, /NQ 등을 제거

N<-str_replace_all(alldta, "/[N][C]","")%>%

str_replace_all("/[N][Q]","") %>%unlist()

 

#감정어로 분류한 단어들의 분류표들을 제거

PNM<-str_replace_all(alldta2, "/[P][V]","") %>%

str_replace_all("/[P][A]","") %>%

str_replace_all("/[M][A]","") %>%

str_replace_all("/[P][X]","") %>% unlist()

 

#명사들 상관성분석 #tm 패키지에서 제공하는 Corpus를 통해 분류된 단어들의 행렬을 만든다.

DtaCorpusNC<-Corpus(VectorSource(N))

myTdmNC<-TermDocumentMatrix(DtaCorpusNC, control=list(wordLengths=c(4,10), removePunctuation=T, removeNumbers=T, weighting=weightBin)) Encoding(myTdmNC$dimnames$Terms)="UTF-8"

#제대로 됐는지 확인

findFreqTerms(myTdmNC, lowfreq=10)

 

#행렬(matrix)로 변환하는게 상관성 분석의 핵심

mtNC<-as.matrix(myTdmNC)

mtrowNC<-rowSums(mtNC)

mtNC.order<-mtrowNC[order(mtrowNC, decreasing=T)]

freq.wordsNC<-sample(mtNC.order[mtNC.order>30], 25)

freq.wordsNC<-as.matrix(freq.wordsNC)

freq.wordsNC co.matrix<-freq.wordsNC %*% t(freq.wordsNC) #graph 생성

qgraph(co.matrix, labels=rownames(co.matrix), diag=FALSE, layout='spring', vsize=log(diag(co.matrix)*2))

 

 

5) 형용사(감정어) 상관성분석

(1) 결과물

(2) 코드설명: 위의 4) 명사 상관성분석과 코드는 모두 동일하며 NC부분만 PNM으로 변경했다.

# 형용사(감정어) 상관성분석

DtaCorpusPNM<-Corpus(VectorSource(PNM))

myTdmPNM<-TermDocumentMatrix(DtaCorpusPNM, control=list(wordLengths=c(4,10), removePunctuation=T, removeNumbers=T, weighting=weightBin)) Encoding(myTdmPNM$dimnames$Terms)="UTF-8" findFreqTerms(myTdmPNM, lowfreq=10)

mtPNM<-as.matrix(myTdmPNM)

mtrowPNM<-rowSums(mtPNM)

mtPNM.order<-mtrowNC[order(mtrowPNM, decreasing=T)]

freq.wordsPNM<-sample(mtNC.order[mtPNM.order>30], 25)

freq.wordsPNM<-as.matrix(freq.wordsPNM)

freq.wordsPNM co.matrix<-freq.wordsPNM %*% t(freq.wordsPNM)

qgraph(co.matrix, labels=rownames(co.matrix), diag=FALSE, layout='spring', vsize=log(diag(co.matrix)*2))

 

4), 5)의 상관성분석은 아직 잘 이해가 안되어서 조금 더 공부해보아야할 것 같다.

그래도 R 1일차 치고 이정도면 만족스러운 결과물이다!!!

내가 R을 다운받게된 계기는 이 분석을 진행하기 위해서였는데, 코드의 출처는 아래 링크와 같다.

다만 2017년 게시글이다보니 저때와 지금의 카톡 내려받기 txt 포맷이 조금 달라서(어느 os에서 다운받느냐에 따라 또 다르다!!!) 나는 조금씩 수정 하며 진행한 점을 참고하면 되겠다.

내 코드는 안드로이드에서 다운받은 카카오톡 대화내용 기준이다!

(그래봤자 data검색 / replace format쪽만 수정하면 된다)

https://m.post.naver.com/viewer/postView.nhn?volumeNo=9334713&memberNo=33264526&searchKeyword=%EC%B9%B4%EC%B9%B4%EC%98%A4%ED%86%A1&searchRank=1

반응형
반응형

.하고싶은 분석이 있어서 R에서 Konlpy 를 다운받으려고 시도했다: 2020-02-07

> install.packages("KoNLP")

WARNING: Rtools is required to build R packages but is not currently installed. Please download and install the appropriate version of Rtools before proceeding:

https://cran.rstudio.com/bin/windows/Rtools/

 

Using Rtools40 on Windows

Starting with R 4.0.0 (released April 2020), R for Windows uses a toolchain bundle called rtools40. This version of Rtools includes gcc 8.3.0, and introduces a new build system based on msys2, which makes easier to build and maintain R itself as well as th

cran.rstudio.com

 

설치가 안되어 여러 방법을 시도해봤다.

1. CRAN 미러를 자동으로, 한국으로도 바꿔봐도 KoNLP가 사라졌는지 설치가 되지 않더라.

2. R 버전문제인줄 알고 R을 5번은 삭제했다가 새버전 받았다가 반복했지만 똑같다.

3. R 사이트에서 Package를 찾아봐도 KoNLP PKG가 없다.

4. 구글링도 해봤으나 최근에 설치하신 분이 없다. . .

수많은 R을 삭제했다가 다시 깔았던 기록들...

그러다가 찾은

R Korea - KRSG(Korean R Study Group)

페이스북 링크 !!!

출처: https://www.facebook.com/groups/krstudy/265600956947517/

안되는 것 정상이라고 한다.

# java, rJava 설치

install.packages("multilinguer")

# 이때 mac 사용자는 데스크탑 비밀번호를 물어봅니다. 입력해줘야 설치가 진행됩니다.

library(multilinguer)

install_jdk()

# 위 함수에서 에러가 발생하면 알려주세요

# https://github.com/mrchypark/multilinguer/issues

# 의존성 패키지 설치

install.packages(c('stringr', 'hash', 'tau', 'Sejong', 'RSQLite', 'devtools'), type = "binary")

# 아카이브된 버전의 패키지 설치

install.packages("https://cran.r-project.org/src/contrib/Archive/KoNLP/KoNLP_0.80.2.tar.gz", repos=NULL, type="source")

설치 완료!!!

하지만 library("KoNLP")시 또 다른 이슈가 발생하는데... 이건 다음 포스팅에서!

 

반응형
반응형

> library("KoNLP")

Fail to install scala-library-2.11.8.jar. Recommand to install library manually in C:/Users/BAEK/Documents/R/win-library/3.6/KoNLP/java

Checking user defined dictionary!

KoNLP를 설치 후 library 실행 시 아래와 같은 에러가 발생하는 경우가 있다.

* KoNLP 설치방법

https://blog.naver.com/song_sec/221800340719

 

[R 프로그래밍] install.packages("KoNLP") - Konlpy 설치불가 이슈 해결

1 .하고싶은 분석이 있어서 R에서 Konlpy 를 다운받으려고 시도했다: 2020-02-07> install.packages(&...

blog.naver.com

해결방법

1. 아래 링크에서 java 파일을 다운받는다. (광고 / 이상한거 절대 아님)

https://drive.gumu.kr/sharing/IK7Bkj1lw

2. Error 상의 출력된 경로에 들어가서 다운받은 java 파일을(압축 풀고) 덮어쓰기 해주면 된다.

- 깔끔하게 끝 -

이슈 미발생 확인!

출처

https://gumu.kr/blog/1010/r-konlp%ED%8C%A8%ED%82%A4%EC%A7%80-%EC%84%A4%EC%B9%98-%EC%98%A4%EB%A5%98fail-to-install-scala-library-2-11-8-jar/

 

[R] KoNLP패키지 설치 오류(Fail to install scala-library-2.11.8.jar) - Gumu's treasure box

업데이트내용 본 내용은 R 4.0 이전 버전에서만 적용됩니다. 패치를 통해 설치오류가 해결되었다는 공지가 올라왔으나 아직도 지속적으로 설치가 안 되는 분들이 계시는 것으로 보아 완전히 문

gumu.kr

 

반응형
반응형

RStudio를 설치했는데 R을 안깔아서.. R Download 포스팅!

1. R 설치 링크 접속하여 R 다운로드

https://cloud.r-project.org/

 

The Comprehensive R Archive Network

 

cloud.r-project.org

 

캡처들은 3.5.3 버전으로 되어있는데, 3.5.3에서 나는 에러가 발생하여

3.5.3을 삭제하고 3.6.2로 다시 다운받았다. 링크는 3.6.2로 바꾸어뒀으니.. 캡처 내 버전은 신경쓰지 말길!

2. 다운로드 받기

왠지 재부팅하면 빨라질 것 같기도 하고... 근데 저 다운해주는 파일 server 자체가 느린 것 같기도 함.

3. 설치가 다 된후 다운된 exe파일을 실행한다.

4. 그리고 아까 설치한 RStudio를 다시 열어보자

RStudio 설치 링크

https://blog.naver.com/song_sec/221798927338

[R 프로그래밍] R Studio 설치/다운로드

R은 배워본 적 없지만 워낙 유명하기도 하고, 이번에 ADsP 공부하면서 재밌어보여 다운받게 됐다.이 또...

blog.naver.com

열렸다!!!

끝!

반응형
반응형

R은 배워본 적 없지만 워낙 유명하기도 하고, 이번에 ADsP 공부하면서 재밌어보여 다운받게 됐다.

이 또한 하나의 포스팅으로 보여 포스팅!! ㅋㅋ

* RStudio를 다운받기 전에 R을 먼저 다운받아야한다!

R 다운로드 받는 링크는 아래 포스팅 참고 : )

https://blog.naver.com/song_sec/221799018628

[R 프로그래밍] R, R Studio 다운로드

RStudio를 설치했는데 R을 안깔아서.. R Download 포스팅!​​1. R 설치 링크 접속하여 R 다운로드 ...

blog.naver.com

1. 설치 홈페이지 접속

https://rstudio.com/products/rstudio/download/

 

Download the RStudio IDE

RStudio is a set of integrated tools designed to help you be more productive with R. It includes a console, syntax-highlighting editor that supports direct code execution, and a variety of robust tools for plotting, viewing history, debugging and managing

www.rstudio.com

 

2. FREE 버전 다운로드

3. 각자 OS에 맞게 스크롤바 이동하여 적합한 OS버전 다운

4. 약 150MB가 다운되면 설치 팝업이 뜬다.

5. 전부 다음>만 누르면 완료된다.

 

6. 설치된 후 Rstudio를 검색하여 실행

7. 본인 PC의 bit에 맞게 선택 후 OK

끝!

* 사실 난 R을 안깔고 Rstudio부터 깔아서.. R을 설치하러 간다 :)

반응형
반응형

이전에 올리다 말았던 텍스트마이닝 프로젝트를 포스팅 하려다가, 최근에 노트북을 포맷해서 Jupyter notebook가 사라진 것을 확인하고, 내꺼 설치하면서 쓰게 된 주피터 노트북 설치 포스팅.

주피터 노트북은 웹 기반으로 코드를 짤 수 있는 플랫폼? 쉘 이라고 보면 된다.

Python으로 시각화 자료 만들 때 파이참(PyCharm)보다는 주피터 노트북으로 짜는게 한줄한줄 결과도 보이고 가볍게 잘 돌아가서 나는 항상 주피터노트북을 사용한다!

설치 방법

PowerShell에서 pip install notebook 치면 끝!

* 단, 1) python이 설치되어 있어야하고, 2)자바 환경변수가 미리 셋팅되어 있어야한다.

1) python 설치: 아래 python 홈페이지에서 각 os에 맞는 버전 설치

https://www.python.org/downloads/

 

Download Python

The official home of the Python Programming Language

www.python.org

 

 

2) java 환경변수 설정: 아래 링크에서 확인

https://blog.naver.com/song_sec/221793561305

[Java] jdk 설치 및 java 환경변수 설정

Python, Android를 쓰려면 java가 필수적인데 얼마 전 PC를 포맷하다보니 Java가 없어 재설치하게 되...

blog.naver.com

1), 2)가 완료되어 있다면, Windows PowerShell에서

pip install notebook 타이핑 후 약 20초간 파일들이 다운로드 된다.

설치가 완료되면 다시 jupyer notebook을 타이핑해본다.

> jupyter notebook

그러면 아래 빨간색 박스 안에 notebook에 access 가능한 링크들이 나온다.

이 링크 중 하나를 복사하여(나는 .html을 복붙한다) chrome이나 익스플로러 주소창에 복사하면

나만의 jupyter notebook이 생성된다.

폴더 하나를 New로 만들어서 사용하는 것을 추천.

나는 V_Jane으로 만들었고, 이 디렉토리는 로컬디스크(C:) > Users > 본인이름 경로에서 확인 가능하다.

따라서, 저 디렉토리에 파일을 넣고 싶으면 웹을 통해 Upload하는 방법도 있지만

아래와 같이 해당 V_Jane 디렉토리에 파일을 옮겨도 Jupyter notebook에서 자동 연동되어 사용할 수 있기 때문에 파일 업로드 / 불러오기에 정말 편하다.

끝!!

반응형
반응형

이번 포스팅은 3-1학기 데이터마이닝 수업 기말 개인프로젝트로 제출했던 전세계 1985-2016 자살률 분석 건이다.

자유주제여서 주제를 고민하다가 캐글에서 흥미로운 데이터를 찾아 가져왔다.

1. 분석할 데이터 및 목표

- 분석할 데이터: Suicide Rates Overview 1985 to 2016 from Kaggle

- 목표: 전세계 자살률을 알아보고, 각 속성이 자살률에 영향을 미치는지 그리고 어느 속성이 가장 영향을 미치는지 분석

https://www.kaggle.com/russellyates88/suicide-rates-overview-1985-to-2016

 

Suicide Rates Overview 1985 to 2016

Compares socio-economic info with suicide rates by year and country

www.kaggle.com

 

- DataSet

. Columns: 12개

country, year, sex, age, suicides_no, population, suicides/100k pop, country-year, HDI for year,

gdp_for_year ($), gdp_per_capita ($), generation

. Rows count: 27820개

2. 전처리 과정​

1) 패키지 선언

#데이터분석용 pkg

import pandas as pd

import numpy as np

import random as rnd #시각화용 pkg

import seaborn as sns

import matplotlib.pyplot as plt

%matplotlib inline #기계학습

from sklearn.linear_model

import LogisticRegression from sklearn.svm

import SVC, LinearSVC from sklearn.ensemble

import RandomForestClassifier from sklearn.neighbors

import KNeighborsClassifier from sklearn.naive_bayes

import GaussianNB from sklearn.linear_model

import Perceptron from sklearn.linear_model

import SGDClassifier from sklearn.tree

import DecisionTreeClassifier from sklearn.neural_network

import MLPClassifier

2) 데이터 로딩 및 확인

#데이터로딩

data = pd.read_csv('master.csv') # 데이터 시각화용. 원본

data_train = pd.read_csv('master_train.csv') #원본 데이터를 7:3으로 train:test로 편집함

data_test = pd.read_csv('master_test.csv') #train:70%, test:30%

print ("Data_train shape:", data_train.shape, "\n")

print ("Data_test shape:", data_test.shape, "\n")

print (data_train.info())

print('_'*40)

print (data_tnfo())

 

* 핵심 속성인 자살률에 대해 mean 값을 확인해봄

#suicides/100k pop의 mean 값 확인=12.16

data_train.describe()

#suicides/100k pop의 mean 값 확인=14.35

data_test.describe()

3) Missing Data 확인

: Missing Data가 많은 속성값은 해당 속성에 따라 결과값이 나온다고 가정하기 어려우므로 삭제 위함

#check missing values in test dataset

print(data_train.isnull().sum())

print('_'*40)

print(data_test.isnull().sum())

 

# 몇프로가 누락되었는지 퍼센트로 확인 = 0.6869 =>70% 누락

sum(pd.isnull(data_train['HDI for year']))/len(data_train["HDI for year"])

4) 누락 및 중복값 삭제

# 누락 및 중복값 Data 삭제. 70%가 누락된 HDI for year

data_train.drop('HDI for year', axis=1, inplace=True)

data_test.drop('HDI for year', axis=1, inplace=True)

 

#suicides_no와 population을 나눈 값이 'suicides/100k pop' * 10^-5 이므로 중복 속성 제거.

data_train.drop('suicides_no', axis=1, inplace=True)

data_train.drop('population', axis=1, inplace=True)

data_train.drop('country-year', axis=1, inplace=True)

 

# country 및 year 속성 별도 존재하여 삭제

data_train.drop(' gdp_for_year ($) ', axis=1, inplace=True)

 

#gdp_per_capita($)와 비례하므로 중복 속성. 삭제

data_train['age']=data['age'].str.strip(" years") # years 텍스트 제거

data_test.drop('suicides_no', axis=1, inplace=True)

data_test.drop('population', axis=1, inplace=True)

data_test.drop('country-year', axis=1, inplace=True)

# country 및 year 속성 별도 존재하여 삭제

data_test.drop(' gdp_for_year ($) ', axis=1, inplace=True)

 

#gdp_per_capita($)와 비례하므로 중복 속성. 삭제

data_test['age']=data['age'].str.strip(" years") # years 텍스트 제거 data_train.head()

5) 새로운 속성값 생성

- Over_mean_suicides: 평균보다 자살률이 클 경우 1, 작을 경우 0으로 열 추가

# 신규 속성인 Over_mean_suicides 만들어줌. 자살률이 전체 mean 자살률대비 크면 1, 작으면 0

# 해당 속성이 0보다 크면 1, 아니면 0

data_train['Over_mean_suicides'] = np.where(data_train['suicides/100k pop']>12.16, 1, 0) data_test['Over_mean_suicides'] = np.where(data_test['suicides/100k pop']>14.35, 1, 0)

data_train.head()

2. 데이터 시각화 및 간단 분석

1) 국가(Country)별 자살률 확인 및 시각화

2) 년도(year)별 자살률 확인 및 시각화

3) 성별(Sex)별 자살률 확인 및 시각화

4) 연령(age)별 자살률 확인 및 시각화

5) 1인당 GDP(gdp_per_capita($)) 별 자살률 확인 및 시각화

6) 세대(Generation)별 자살률 확인 및 시각화

1) 국가별 자살률 확인 및 상위 5개 국가 출력

#1) 국가별 자살률 확인

fig = plt.figure(figsize=(20,5))

plt.title('Suicide Rates by Country')

sns.barplot(x='country', y='suicides/100k pop', data=data[['country', 'suicides/100k pop']].groupby('country', as_index=False).mean().sort_values(by='suicides/100k pop', ascending=False)); plt.xticks(rotation=90);

 

#x축(country) 회전 ​ # 상위 5개 국가 출력 ==> 상위5국가: 리투아니아, 스리랑카, 러시아, 헝가리, 벨라루스 // 한국: 11위 data[['country','suicides/100k pop']].groupby('country', as_index=False).mean().sort_values(by='suicides/100k pop', ascending=False).head()

 

2) 년도별 자살률 시각화 및 상위 5개 년도 출력

: 1995년대 자살률이 높다. 이유는? 뒤에서...

#2)년도(year)별 자살률 확인 및 시각화 #시각화

fig, ax = plt.subplots(figsize=(20, 5))

plt.title('Suicide rates by year')

sns.lineplot(x='year', y='suicides/100k pop', data=data[['year','suicides/100k pop']].groupby('year',as_index=False).mean().sort_values(by='year',ascending=True),marker='o',color='RED');

ax.set(xticks=data['year'].unique());

 

# 상위 5개 년도 출력 ==> 상위5국가: 리투아니아, 스리랑카, 러시아, 헝가리, 벨라루스 // 한국: 11위

data[['year', 'suicides/100k pop']].groupby('year', as_index=False).mean().sort_values(by='suicides/100k pop', ascending=False).head()

3) 성별에 따른 자살률 확인 및 순위 출력

: 남성이 여성대비 4배이상 자살률이 높다.

#3) 성별(Sex)별 자살률 확인 및 시각화 => 남성이 여성 대비 4배 높음

fig = plt.figure(figsize=(2,3))

plt.title('Suicide rates by sex') sns.barplot(x='sex', y='suicides/100k pop', data=data[['sex', 'suicides/100k pop']].groupby('sex', as_index=False).mean().sort_values(by='suicides/100k pop', ascending=False)); data[['sex','suicides/100k pop']].groupby('sex', as_index=False).mean().sort_values(by='suicides/100k pop', ascending=False)

 

4) 연령대에 따른 자살률 확인 및 순위출력

: 고령일수록 자살률이 높다.

#4) 연령(age)별 자살률 확인 및 시각화 ==> 고령일수록, 남성일수록 자살률이 높다. fig=plt.figure(figsize=(5,4)); plt.title('Suicide rates by Age')

sns.barplot(x='age', y='suicides/100k pop',hue='sex', data=data[['age','suicides/100k pop','sex']].groupby(['age','sex'],as_index=False).mean().sort_values(by='suicides/100k pop',ascending=False));

data[['age','suicides/100k pop']].groupby('age', as_index=False).mean().sort_values(by='suicides/100k pop', ascending=False)

 

 

5) 1인당 GDP(gdp_per_capita($))별 자살률 확인 및 시각화

: GDP는 자살률과 관련이 없는 것으로 추측된다.

#5) 1인당 GDP(gdp_per_capita($)) 별 자살률 확인 및 시각화 ==> GDP와 자살률은 관련이 없다. 높든 낮든 자살률의 분포는 유사하다.

fig = plt.figure(figsize=(30,10))

plt.title('Suicide rates by gdp_per_capita ($)') sns.barplot(x='gdp_per_capita ($)', y='suicides/100k pop', data=data[['gdp_per_capita ($)', 'suicides/100k pop']].groupby('gdp_per_capita ($)', as_index=False).mean().sort_values(by='suicides/100k pop', ascending=False));

#data[['gdp_per_capita ($)','suicides/100k pop']].groupby('gdp_per_capita ($)', as_index=False).mean().sort_values(by='suicides/100k pop', ascending=False) data['gdp_per_capita ($)'].describe()

 

6) Generation에 따른 자살률 확인

: Generation X(세계 2차대전 이후, 대략 1970년대생), Silent 세대 (1920-40년대생. 유년기를 전쟁통으로 겪은, 조용히 지낼 수 밖에 없었던 세대) 자살률이 가장 높다.

6)generation별 자살률 및 시각화 => Genearation X세대 자살률이 가장 높음

f,ax=plt.subplots(1,2,figsize=(15,5)) data['generation'].value_counts().plot.pie(explode=[0.1,0.1,0.1,0.1,0.1,0.1],autopct='%1.1f%%',ax=ax[0],shadow=True)

ax[0].set_title('Suicide Rates by Generation') ax[0].set_ylabel('Suicides/100k pop') sns.countplot('generation',data=data,ax=ax[1]) ax[1].set_title('Suicide Rates by Generation')

plt.show() data[['generation','suicides/100k pop']].groupby('generation', as_index=False).mean().sort_values(by='suicides/100k pop', ascending=False)

* 데이터마이닝 과제에서는 속성별 분석은 여기까지만 진행했으나

데이터시각화 과목 프로젝트에서도 해당 주제를 선택하여

엑셀을 통해 추가적 분석을 진행하였다. 이또한 나름 시각화이므로 중간에 끼워넣어본다!!

다시 데이터마이닝으로 돌아와서...

3. Machine Learning 기법을 활용한 자살률 예측

- 사용 알고리즘

1) Logistic Regression

2) Support Vector Machines

3) Decision Tree

4) KNN

5) Naive Bayes

6) Linear SVC

7) Perceptron

8) Random Forest

9) Stochastic Gradient Decent

3-1) 데이터 추가 전처리: string값을 정수형으로 변환

#1) age 의 string을 정수로 바꾸기

def func(dataset): if dataset['age'] == '75+': # 75+ ==> 80 치환

return '80'

elif dataset['age'] =='55-74': # 55-74 ==> 65 치환

return '65'

elif dataset['age'] =='35-54': # 35-54 ==> 45 치환

return '45'

elif dataset['age'] =='25-34': # 25-34 ==> 30 치환

return '30'

elif dataset['age'] =='15-24': # 15-24 ==> 20 치환

return '20'

else: return '10' # 5-14 = 10 치환

 

#TrainData 적용

data_train['age'] = data_train.apply(func, axis=1)

data_train[['age','suicides/100k pop']].groupby('age', as_index=False).mean().sort_values(by='suicides/100k pop', ascending=False)

 

#TestData도 같이 적용

data_test['age'] = data_test.apply(func, axis=1)

data_test[['age','suicides/100k pop']].groupby('age', as_index=False).mean().sort_values(by='suicides/100k pop', ascending=False)

2) sex의 string을 정수로 바꾸기

def func(dataset): if dataset['sex'] == 'female': # 여자 = 0 으로 치환

return '0' else: return '1' # 남자 = 1 로 치환. spelling이 겹치므로 여자부터 치환해야함.

 

data_train['sex'] = data_train.apply(func, axis=1)

data_train[['sex','suicides/100k pop']].groupby('sex', as_index=False).mean().sort_values(by='suicides/100k pop', ascending=False) data_test['sex'] = data_test.apply(func, axis=1)

data_test[['sex','suicides/100k pop']].groupby('sex', as_index=False).mean().sort_values(by='suicides/100k pop', ascending=False)

 

3) Generation 의 string을 정수로 바꾸기

def func(dataset):

if dataset['generation'] == 'G.I. Generation': # G.I generation = 1

return '1'

elif dataset['generation'] =='Silent': # Silent = 2

return '2'

elif dataset['generation'] =='Boomers': # Boomers = 3

return '3'

elif dataset['generation'] =='Generation X': # Generation X = 4

return '4'

elif dataset['generation'] =='Millenials': # Millenials = 5

return '5'

else:

return '6' # Generation Z = 6

 

data_train['generation'] = data_train.apply(func, axis=1)

data_train[['generation','suicides/100k pop']].groupby('generation', as_index=False).mean().sort_values(by='suicides/100k pop', ascending=False)

data_test['generation'] = data_test.apply(func, axis=1)

data_test[['generation','suicides/100k pop']].groupby('generation', as_index=False).mean().sort_values(by='suicides/100k pop', ascending=False)

 

3-2) 학습집합 및 테스트 집합 준비

: 만들어 준 속성(Over_mean_suicides)을 예측값으로 사용.

이에 영향을 미치는 요소인 suicides/100k pop 은 제거하고, Country의 경우 나라가 100개이상이므로

String제거 복잡하여 속성 제거

- 비율: Training data(19474, 70%), Test Data(8346, 30%)

X_train = data_train.drop("Over_mean_suicides", axis=1)

X_train = X_train.drop("suicides/100k pop" , axis =1)

X_train = X_train.drop("country", axis=1) Y_train = data_train["Over_mean_suicides"]

 

X_test = data_test.drop("Over_mean_suicides" , axis=1).copy()

X_test = X_test.drop("suicides/100k pop" , axis =1)

X_test = X_test.drop("country" , axis =1)

X_train.shape, Y_train.shape, X_test.shape

 

3-3) 알고리즘 시작

#1. Logistic Regression

logreg = LogisticRegression(solver='lbfgs')

logreg.fit(X_train, Y_train)

Y_pred = logreg.predict(X_test)

acc_log= round(logreg.score(X_train, Y_train) * 100, 2)

acc_log

 

#2. Support Vector Machines

svc = SVC() solver='liblinear' svc.fit(X_train, Y_train)

Y_pred = svc.predict(X_test)

acc_svc = round(svc.score(X_train, Y_train) * 100, 2)

print(acc_svc)

 

#3. Decision Tree

decision_tree = DecisionTreeClassifier()

decision_tree.fit(X_train, Y_train)

Y_pred = decision_tree.predict(X_test)

acc_decision_tree = round(decision_tree.score(X_train, Y_train) * 100, 2)

acc_decision_tree

 

# 4. KNN

knn = KNeighborsClassifier(n_neighbors = 3)

knn.fit(X_train, Y_train)

Y_pred = knn.predict(X_test)

acc_knn = round(knn.score(X_train, Y_train) * 100, 2)

acc_knn ​

 

# 5. Gaussian Naive Bayes

gaussian = GaussianNB() gaussian.fit(X_train, Y_train)

Y_pred = gaussian.predict(X_test)

acc_gaussian = round(gaussian.score(X_train, Y_train) * 100, 2)

acc_gaussian

 

# 6. Linear SVC

linear_svc = LinearSVC()

linear_svc.fit(X_train, Y_train)

Y_pred = linear_svc.predict(X_test)

acc_linear_svc = round(linear_svc.score(X_train, Y_train) * 100, 2)

acc_linear_svc

# 7. Perceptron perceptron = Perceptron()

perceptron.fit(X_train, Y_train)

Y_pred = perceptron.predict(X_test)

acc_perceptron = round(perceptron.score(X_train, Y_train) * 100, 2)

acc_perceptron

 

#8. Random Forest

random_forest = RandomForestClassifier(n_estimators=100)

random_forest.fit(X_train, Y_train)

Y_pred = random_forest.predict(X_test)

random_forest.score(X_train, Y_train)

acc_random_forest = round(random_forest.score(X_train, Y_train) * 100, 2)

acc_random_forest

 

#9. Stochastic Gradient Descent

sgd = SGDClassifier() sgd.fit(X_train, Y_train)

Y_pred = sgd.predict(X_test)

acc_sgd = round(sgd.score(X_train, Y_train) * 100, 2)

acc_sgd

 

3-4. 알고리즘별 Score 정렬

models = pd.DataFrame({ 'Model': ['Support Vector Machines', 'KNN', 'Logistic Regression', 'Random Forest', 'Naive Bayes', 'Perceptron', 'Stochastic Gradient Decent', 'Linear SVC', 'Decision Tree'], 'Score': [acc_svc, acc_knn, acc_log, acc_random_forest, acc_gaussian, acc_perceptron, acc_sgd, acc_linear_svc, acc_decision_tree]}) models.sort_values(by='Score', ascending=False)

3-5) 최종 파일 생성

submission = pd.DataFrame({ "Country": data_test["country"], "If_over_mean_of_suicide": Y_pred }) submission.to_csv('final_pjt_20.csv', index=False) data_final = pd.read_csv('final_pjt_20.csv') data_final.info() data_final.describe()

 

결론적으로 전세계 자살률은 남성일수록, 고령일수록, gdp와는 관계가 없고, 전쟁과 가까운 세대일수록 높았다.

개인적인 생각으로는 못사는 나라일수록 자살률이 높다기보다는, 본인이 처한 경험과 환경에 따라 다른 것이 아닐까 생각이 든다. 후진국의 사람들은 다른 나라를 경험해보았을까? TV조차 없을텐데 그들에게 비교대상은 그 주위사람들뿐이지 않을까. 특히 나이가 먹을수록 몸도 마음도 약해지고, 주도적으로 할 수 있는 것 조차 한계가 생기기 때문에 안좋은 생각을 하기 상대적으로 쉬울 것 같다. 여기까진 내 생각일 뿐이고 또 다른 재미있는 주제가 있으면 들고오겠다 : )

 

3-1학기는 시험보랴 프로젝트하랴 정말 바빴었고 힘들었는데 지금보니 느낌이 또 색다르다! 역시 지나고보면 다 추억인가보다 !!(???)ㅋㅋㅋㅋㅋ

반응형
반응형

0-0. Tensorflow란?

TensorFlow는 머신러닝을 위한 엔드 투 엔드 오픈소스 플랫폼이다. 도구, 라이브러리, 커뮤니티 리소스로 구성된 포괄적이고 유연한 생태계를 통해 연구원들은 ML에서 첨단 기술을 구현할 수 있고 개발자들은 ML이 접목된 애플리케이션을 손쉽게 빌드 및 배포할 수 있다. (출처: tensorflow 홈페이지)

한마디로 파이썬 같은 건데, 머신러닝 돌릴 때 굉장히 간단한 코드로 모든 것을 할 수 있다.

Tensorflow 자체는 코드가 조금 어려웠으나, 그 위에 Keras라는 API를 얹어 코드가 매우 간단해졌다.

이번 포스팅에서는 Tensorflow 홈페이지 튜토리얼에서 제공하는 Keras가 적용된 Basic classification을 작성해보았다.

0-1. Tensorflow with Keras

이 튜토리얼에서는 운동화나 셔츠 같은 옷 이미지를 분류하는 신경망 모델을 train한다.

완전한 텐서플로(TensorFlow) 프로그램을 빠르게 살펴 보고, 자세한 내용은 앞으로 배우면서 더 설명한다. 텐서플로 모델을 만들고 훈련(train)할 수 있는 고수준 API인 tf.keras를 사용한다.

from __future__ import absolute_import, division, print_function, unicode_literals, unicode_literals

# tensorflow와 tf.keras를 임포트합니다

import tensorflow as tf from tensorflow import keras

# 헬퍼(helper) 라이브러리를 임포트합니다

import numpy as np import matplotlib.pyplot as plt # tensorflow version print(tf.__version__)

 

 

1. 패션 MNIST 데이터셋 임포트하기

10개의 범주(category)와 70,000개의 흑백 이미지로 구성된 패션 MNIST 데이터셋을 사용한다. 이미지는 해상도(28x28 픽셀)가 낮은 개별 옷 품목을 나타낸다:

- 패션 MNIST

컴퓨터 비전 분야의 "Hello, World" 프로그램격인 고전 MNIST 데이터셋을 대신해서 자주 사용된다. MNIST 데이터셋은 손글씨 숫자(0, 1, 2 등)의 이미지로 이루어져 있으며, 여기서 사용하려는 옷 이미지와 동일한 포맷이다.

패션 MNIST는 일반적인 MNIST 보다 조금 더 어려운 문제이고 다양한 예제를 만들기 위해 선택했다. 두 데이터셋은 비교적 작기 때문에 알고리즘의 작동 여부를 확인하기 위해 사용되곤 한다. 코드를 테스트하고 디버깅하는 용도로 좋다.

네트워크를 훈련하는데 60,000개의 이미지를 사용한다. 그다음 네트워크가 얼마나 정확하게 이미지를 분류하는지 10,000개의 이미지로 평가하겠다. 패션 MNIST 데이터셋은 텐서플로에서 바로 임포트하여 적재할 수 있다:

패션 MNIST 샘플 (Zalando, MIT License)

fashion_mnist = keras.datasets.fashion_mnist (train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()

load_data() 함수를 호출하면 네 개의 넘파이(NumPy) 배열이 반환된다:

- train_images, train_labels 배열: 모델 학습에 사용되는 train set.

- test_images, test_labels 배열: 모델 테스트에 사용되는 test set.

 

이미지는 28x28 크기의 넘파이 배열이고 픽셀 값은 0과 255 사이.

레이블(label)은 0에서 9까지의 정수 배열이며, 이 값은 이미지에 있는 옷의 클래스(class)를 나타낸다:

 

Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-labels-idx1-ubyte.gz 32768/29515 [=================================] - 0s 0us/step Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-images-idx3-ubyte.gz 26427392/26421880 [==============================] - 1s 0us/step Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-labels-idx1-ubyte.gz 8192/5148 [===============================================] - 0s 0us/step Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-images-idx3-ubyte.gz 4423680/4422102 [==============================] - 0s 0us/step

 

Label Class

0 T-shirt/top

1 Trouser

2 Pullover

3 Dress

4 Coat

5 Sandal

6 Shirt

7 Sneaker

8 Bag

9 Ankle boot

각 이미지는 하나의 레이블에 매핑되어 있다. dataset에 클래스 이름이 들어있지 않기 때문에 나중에 이미지를 출력할 때 사용하기 위해 별도의 변수를 만들어 저장한다:

class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

2. 데이터 탐색 (Explore the data)

모델을 훈련하기 전에 데이터셋 구조를 살펴본다. 다음 코드는 훈련 세트에 60,000개의 이미지가 있다는 것을 보여준다. 각 이미지는 28x28 픽셀로 표현된다:

train_images.shape len(train_labels) train_labels test_images.shape len(test_labels)

(60000, 28, 28) # train_images엔 60,000개의 이미지가 있음. 28x28 픽셀 60000 array([9, 0, 0, ..., 3, 0, 5], dtype=uint8) # 각 레이블은 0~9사이의 정수 (10000, 28, 28) # test_images엔 10,000개의 이미지가 있음. 28x28 픽셀 10000

3. 데이터 전처리 (Preprocess the data)

네트워크를 훈련하기 전에 데이터를 전처리해야 한다. train set에 있는 첫 번째 이미지를 보면 픽셀 값의 범위가 0~255 사이라는 것을 알 수 있다.

plt.figure() plt.imshow(train_images[0]) plt.colorbar() plt.grid(False) plt.show()

신경망 모델에 주입하기 전에 이 값의 범위를 0~1 사이로 조정한다. 이렇게 하려면 255로 나누어야 하는데, train set과 test set을 동일한 방식으로 전처리하는 것이 중요하다.

train_images = train_images / 255.0 test_images = test_images / 255.0

train set에서 처음 25개 이미지와 그 아래 클래스 이름을 출력해본다. 데이터 포맷이 올바른지 확인하고 네트워크 구성과 train할 준비를 마친다.

plt.figure(figsize=(10,10)) for i in range(25): plt.subplot(5,5,i+1) plt.xticks([]) plt.yticks([]) plt.grid(False) plt.imshow(train_images[i], cmap=plt.cm.binary) plt.xlabel(class_names[train_labels[i]]) plt.show()

4. 모델 구성 (Build the model)

신경망 모델을 만들려면 모델의 layer를 구성한 다음 모델을 컴파일한다.

- layer 설정(Set up the layers)

신경망의 기본 구성 요소는 (layer)으로, 층은 주입된 데이터에서 표현을 추출한다. 아마도 문제를 해결하는데 더 의미있는 표현이 추출될 것이다. 대부분 딥러닝은 간단한 층을 연결하여 구성된다.

tf.keras.layers.Dense와 같은 층들의 가중치(parameter)는 훈련하는 동안 학습된다.

model = keras.Sequential([ keras.layers.Flatten(input_shape=(28, 28)), keras.layers.Dense(128, activation='relu'), keras.layers.Dense(10, activation='softmax') ])

tf.keras.layers.Flatten: 네트워크의 1st layer로 2차원 배열(28 x 28 픽셀)의 이미지 포맷을 28 * 28 = 784 픽셀의 1차원 배열로 변환한다. 이 층은 이미지에 있는 픽셀의 행을 펼쳐서 일렬로 늘린다. 이 층에는 학습되는 가중치가 없고 데이터를 변환하기만 한다.

tf.keras.layers.Dense: 픽셀을 펼친 후에는 두 개의 층이 연속되어 연결된다. 이 층을 밀집 연결(densely-connected) 또는 완전 연결(fully-connected) 층이라고 부른다.

- 첫 번째 Dense layer: 128개의 노드(또는 뉴런)를 가지며, 두 번째 (마지막) layer는 10개 노드의 소프트맥스(softmax) 층이다. 이 layer은 10개의 확률을 반환하고 반환된 값의 전체 합은 1이다. 각 노드는 현재 이미지가 10개 클래스 중 하나에 속할 확률을 출력한다.

5. 모델 컴파일(Compile the model)

모델을 훈련하기 전에 필요한 몇 가지 설정이 모델 컴파일 단계에서 추가된다:

- 손실 함수(Loss function): 훈련 하는 동안 모델의 오차 측정. 모델의 학습이 올바른 방향으로 향하도록 이 함수를 최소화해야 한다.

- 옵티마이저(Optimizer): 데이터와 손실 함수를 바탕으로 모델의 업데이트 방법을 결정.

- 지표(Metrics): 훈련 단계와 테스트 단계를 모니터링하기 위해 사용한다. 다음 예에서는 올바르게 분류된 이미지의 비율인 정확도를 사용합니다.

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

6. 모델 훈련 (Train the model)

신경망 모델을 훈련하는 단계는 다음과 같다:

훈련 데이터를 모델에 주입-이 예에서는 train_imagestrain_labels 배열.

모델이 이미지와 레이블을 매핑하는 방법을 배운다.

테스트 세트에 대한 모델의 예측을 만듦-이 예에서는 test_images 배열. 이 예측이 test_labels 배열의 레이블과 맞는지 확인.

훈련을 시작하기 위해 model.fit 메서드를 호출하면 모델이 훈련 데이터를 학습:

model.fit(train_images, train_labels, epochs=5)

Train on 60000 samples Epoch 1/5 60000/60000 [==============================] - 4s 74us/sample - loss: 0.4948 - accuracy: 0.8255 Epoch 2/5 60000/60000 [==============================] - 4s 62us/sample - loss: 0.3725 - accuracy: 0.8664 Epoch 3/5 60000/60000 [==============================] - 4s 61us/sample - loss: 0.3349 - accuracy: 0.8774 Epoch 4/5 60000/60000 [==============================] - 4s 62us/sample - loss: 0.3115 - accuracy: 0.8860 Epoch 5/5 60000/60000 [==============================] - 4s 61us/sample - loss: 0.2946 - accuracy: 0.8930 <tensorflow.python.keras.callbacks.History at 0x7f1d480e31d0>

모델이 훈련되면서 손실과 정확도 지표가 출력된다. 이 모델은 훈련 세트에서 약 0.88(88%) 정도의 정확도를 달성한다.

7. 정확도 평가(Evaluate accuracy)

그다음 test set에서 모델의 성능을 비교한다:

test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2) print('\n테스트 정확도:', test_acc)

10000/1 - 1s - loss: 0.2867 - accuracy: 0.8601 테스트 정확도: 0.8601

test set의 정확도가 train set의 정확도보다 조금 낮다. train set의 정확도와 테스트 세트의 정확도 사이의 차이는 과대적합(overfitting) 때문이다

* 과대적합(overfitting)은 머신러닝 모델이 훈련 데이터보다 새로운 데이터에서 성능이 낮아지는 현상을 말한다.

8. 예측 만들기 (Evaluate accuracy)

훈련된 모델을 사용하여 이미지에 대한 예측을 만들 수 있다.

predictions = model.predict(test_images) # 여기서는 테스트 세트에 있는 각 이미지의 레이블을 예측. 첫 번째 예측을 확인: predictions[0]

array([1.6537431e-05, 8.6610027e-07, 1.9992506e-06, 9.1384734e-08, 1.2081074e-06, 1.7686512e-02, 9.6968342e-06, 1.6786481e-01, 2.6662360e-04, 8.1415164e-01], dtype=float32)

이 예측은 10개의 숫자 배열로 나타난다. 이 값은 10개의 옷 품목에 상응하는 모델의 신뢰도(confidence)를 나타낸다. 가장 높은 신뢰도를 가진 레이블을 찾아본다:

np.argmax(predictions[0]) test_labels[0]

9 # 모델은 이 이미지가 앵클 부츠(class_name[9])라고 가장 확신. # 이 값이 맞는지 테스트 레이블을 확인: 9

10개 클래스에 대한 예측을 모두 그래프로 표현:

def plot_image(i, predictions_array, true_label, img): predictions_array, true_label, img = predictions_array[i], true_label[i], img[i] plt.grid(False) plt.xticks([]) plt.yticks([]) plt.imshow(img, cmap=plt.cm.binary) predicted_label = np.argmax(predictions_array) if predicted_label == true_label: color = 'blue' else: color = 'red' plt.xlabel("{} {:2.0f}% ({})".format(class_names[predicted_label], 100*np.max(predictions_array), class_names[true_label]), color=color) def plot_value_array(i, predictions_array, true_label): predictions_array, true_label = predictions_array[i], true_label[i] plt.grid(False) plt.xticks([]) plt.yticks([]) thisplot = plt.bar(range(10), predictions_array, color="#777777") plt.ylim([0, 1]) predicted_label = np.argmax(predictions_array) thisplot[predicted_label].set_color('red') thisplot[true_label].set_color('blue')

0번째 원소의 이미지, 예측, 신뢰도 점수 배열을 확인.

i = 0 plt.figure(figsize=(6,3)) plt.subplot(1,2,1) plot_image(i, predictions, test_labels, test_images) plt.subplot(1,2,2) plot_value_array(i, predictions, test_labels) plt.show()

i = 12 plt.figure(figsize=(6,3)) plt.subplot(1,2,1) plot_image(i, predictions, test_labels, test_images) plt.subplot(1,2,2) plot_value_array(i, predictions, test_labels) plt.show()

몇 개의 이미지의 예측을 출력. 올바르게 예측된 레이블은 파란색이고 잘못 예측된 레이블은 빨강색. 숫자는 예측 레이블의 신뢰도 퍼센트(100점 만점)이다. 신뢰도 점수가 높을 때도 잘못 예측할 수 있다.

# 처음 X 개의 테스트 이미지와 예측 레이블, 진짜 레이블을 출력. 

# 올바른 예측은 파랑색으로 잘못된 예측은 빨강색으로 나타낸다. num_rows = 5 num_cols = 3 num_images = num_rows*num_cols plt.figure(figsize=(2*2*num_cols, 2*num_rows)) for i in range(num_images): plt.subplot(num_rows, 2*num_cols, 2*i+1) plot_image(i, predictions, test_labels, test_images) plt.subplot(num_rows, 2*num_cols, 2*i+2) plot_value_array(i, predictions, test_labels) plt.show()

마지막으로 훈련된 모델을 사용하여 한 이미지에 대한 예측을 만든다.

# 테스트 세트에서 이미지 하나를 선택 img = test_images[0] print(img.shape)

(28, 28)

# 이미지 하나만 사용할 때도 배치에 추가 img = (np.expand_dims(img,0)) print(img.shape)

(1, 28, 28)

이제 이 이미지의 예측을 만든다:

predictions_single = model.predict(img) print(predictions_single)

[[1.6537435e-05 8.6609879e-07 1.9992472e-06 9.1384756e-08 1.2081076e-06 1.7686490e-02 9.6968179e-06 1.6786472e-01 2.6662284e-04 8.1415176e-01]]

plot_value_array(0, predictions_single, test_labels) _ = plt.xticks(range(10), class_names, rotation=45)

model.predict는 2차원 넘파이 배열을 반환하므로 첫 번째 이미지의 예측을 선택합니다: np.argmax(predictions_single[0])

9

이전과 마찬가지로 모델의 예측은 레이블 9이다.

출처: 텐서플로우 공식홈페이지

- 영문판

https://www.tensorflow.org/tutorials/keras/classification?hl=en

 

첫 번째 신경망 훈련하기: 기초적인 분류 문제  |  TensorFlow Core

Note: 이 문서는 텐서플로 커뮤니티에서 번역했습니다. 커뮤니티 번역 활동의 특성상 정확한 번역과 최신 내용을 반영하기 위해 노력함에도 불구하고 공식 영문 문서의 내용과 일치하지 않을 수

www.tensorflow.org

- 국문판

https://www.tensorflow.org/tutorials/keras/classification?hl=ko

반응형
반응형

Dataset 가져온 출처: https://www.kaggle.com/c/titanic

 

Titanic - Machine Learning from Disaster | Kaggle

 

www.kaggle.com

 

Machine Learning 분석을 적용하여 어떤 사람들이 타이타닉호에서 생존할 수 있었는가에 대해 분석해봄.

ㅇ 활용 모델

- Logistic Regression

- k-Nearest Neighbors

- Support Vector Machines

- Naive Bayes classifier

- Decision Tree

- Artificial neural network

1. 데이터 전처리

kaggle에서 다운받은 excel의 데이터가 공백, 데이터형식 등 다른 부분이 많다.

그것들을 정제하기 위한 절차를 수행

 

1-1. 함수 선언 및 데이터 확인

1) 함수 선언

# 데이터 분석

import pandas as pd

import numpy as np

import random as rnd

# 시각화

import seaborn as sns

import matplotlib.pyplot as plt

%matplotlib inline #주피터 노트북 상 그래프 표현위한 라인

# 기계 학습

from sklearn.linear_model import LogisticRegression

from sklearn.svm import SVC, LinearSVC

from sklearn.ensemble import RandomForestClassifier

from sklearn.neighbors import KNeighborsClassifier

from sklearn.naive_bayes import GaussianNB

from sklearn.linear_model import Perceptron

from sklearn.linear_model import SGDClassifier

from sklearn.tree import DecisionTreeClassifier

from sklearn.neural_network import MLPClassifier

2) 데이터 로딩 및 확인

# 데이터 로딩 // df: dataframe 데이터 읽음

train_df = pd.read_csv('./train.csv')

test_df = pd.read_csv('./test.csv')

combine = [train_df, test_df] // 데이터 합침

print(train_df.columns.values) // values 열 출력

# preview the data

train_df.head() // method를 불러서 예쁘게 보여줌. head(): 5lines까지만 보여줌.

train_df.tail() // tail(): 뒤에서 5lines 보여줌.

# train data와 test data info 출력

train_df.info()

print('_'*40)

test_df.info()

train_df.describe()

1-2. Missing Value 처리 - Data 삽입을 위해 기존 Data의 중간값 / 평균값 구하기

# check missing values in train, test dataset

train_df.isnull().sum()

test_df.isnull().sum()

missing된 value는 age, cabin, 그리고 test dataset의 Fare.

# training data의 age, cabin의 경우 누락 값들은 전체 값 중 몇프로일까?

sum(pd.isnull(train_df['Age']))/len(train_df["PassengerId"]) // 전체 length에서 null값의 갯수를 나눈다.

sum(pd.isnull(train_df['Cabin']))/len(train_df["PassengerId"])

# Train의 Age분포를 히스토그램으로 확인해보자

ax = train_df["Age"].hist(bins=15, color='teal', alpha=0.8) // bins=bar 갯수, alpha=투명도

ax.set(xlabel='Age', ylabel='Count') // x, y축 레이블

plt.show()

# 중간값은 약 20-30대로 보인다. 정확한 중간값을 알아보자

train_df["Age"].median(skipna=True)

글쿤.

# 이번엔 train data의 Embarked 중간값을 알아보자

countplot 하나 써보장. 딱봐도 S가 제일 많다

# 마지막으로 Fare의 평균값은?

train_df["Fare"].mean(skipna=True)

정수써야하므로 32로 생각하자.

1-3. Missing Value 처리 - Data입력

- Embarked는 S가 가장 많으니 누락값에 S를 채워넣고,

- Fare는 평균값인 32를 취해서 누락값에 넣는다. (항구/티켓에 따라 다르지만 편의상)

- Cabin은 누락값 많았지만, 값들이 char형으로 평균/중간값 구하기 애매함.

그래서 Cabin 속성 제거.

# 누락된 값을 적절한 값으로 채워넣기

train_df["Age"].fillna(28, inplace=True)

test_df["Age"].fillna(28, inplace=True)

train_df["Embarked"].fillna("S", inplace=True)

test_df["Fare"].fillna(32, inplace=True)

# 누락된 값이 너무 많은 속성 제거

train_df.drop('Cabin', axis=1, inplace=True)

test_df.drop('Cabin', axis=1, inplace=True)

1-4. 데이터 속성별 값에 따라 생존자 확인

# 각 속성(열)에 따른 생존자 확률

train_df[['Pclass', 'Survived']].groupby(['Pclass'], as_index=False).mean().sort_values(by='Survived', ascending=False)

train_df[["Sex", "Survived"]].groupby(['Sex'], as_index=False).mean().sort_values(by='Survived', ascending=False)

train_df[["SibSp", "Survived"]].groupby(['SibSp'], as_index=False).mean().sort_values(by='Survived', ascending=False)

train_df[["Parch", "Survived"]].groupby(['Parch'], as_index=False).mean().sort_values(by='Survived', ascending=False)

Parch와 SibSp는 딱히 패턴이 안보인다. 버리자.

1-5. 데이터 시각화

# 나이별 비생존자와 생존자

g = sns.FacetGrid(train_df, col='Survived')

g.map(plt.hist, 'Age', bins=20)

# 나이 및 객실 등급별 생존여부

grid = sns.FacetGrid(train_df, col='Survived', row='Pclass', size=2.2, aspect=1.6) # 행: 객실 등급, 열: 생존여부

grid.map(plt.hist, 'Age', alpha=.5, bins=20) // plt.hist, alpha = 투명도, bins = 갯수

grid.add_legend();

# 꺾은선 그래프

Embarked, PClass, Sex에 따른 생존 여부

grid = sns.FacetGrid(train_df, col='Embarked', size=2.2, aspect=1.6)

grid.map(sns.pointplot, 'Pclass', 'Survived', 'Sex', palette='deep', order=[1, 2, 3], hue_order=None)

grid.add_legend()

1-6. 데이터 전처리: 속성 조정

# 우선 현재 보유하고 있는 속성을 다시 한 번 확인해보자

train_df.head()

# 속성 조정

PassengerId는 샘플별로 다르기 때문에 제거

Survived: 예측해야할 output

Age, Fare: 그대로 채택

Sex, Pclass, Embarked: 카테고리 값이므로 처리.

SibSp, Parch: Binary 값으로 수정

Ticket: 표 번호이므로 상관성이 없는 값이라 제거

Name: 한 번 살펴볼 것.

1-6-1. SibSp, Parch를 Binary 값으로 수정

# 신규 속성인 TravelSibSp, TravelParch 만들어줌

# 해당 속성이 0보다 크면 1, 아니면 0

train_df['TravelSibSp'] = np.where(train_df['SibSp']>0, 1, 0)

train_df['TravelParch'] = np.where(train_df['Parch']>0, 1, 0)

# 이후 SibSp, SibSp 제거

train_df.drop('SibSp', axis=1, inplace=True)

train_df.drop('Parch', axis=1, inplace=True)

# test 데이터도 마찬가지로 적용

test_df['TravelSibSp'] = np.where(test_df['SibSp']>0, 1, 0)

test_df['TravelParch'] = np.where(test_df['Parch']>0, 1, 0)

test_df.drop('SibSp', axis=1, inplace=True)

test_df.drop('Parch', axis=1, inplace=True)

1-6-2. Pclass, Embarked, Sex 처리

Pclass에 세 가지가 있으니 Pclass 라는 속성을 세 개로 쪼갠다. Pclass_1, Pclass_2, Pclass_3

Embarked도 마찬가지. S, C, Q 가 있으니 Embarked_S, Embarked_C, Embarked_Q

Sex도 마찬가지, female, male 이 있으니 Sex_female, Sex_femal

1-6-3. 쓸모없는 속성 제거

train_df4.drop('PassengerId', axis=1, inplace=True)

train_df4.drop('Name', axis=1, inplace=True)

train_df4.drop('Ticket', axis=1, inplace=True)

train_df4.drop('Sex_male', axis=1, inplace=True) // 어차피 성별은 0 아님 1이므로 하나 제거

train_df4.head() //

1-6-4. test_df에도 똑같이 해주자

test_df2 = pd.get_dummies(test_df, columns=["Pclass"])

test_df3 = pd.get_dummies(test_df2, columns=["Embarked"])

test_df4 = pd.get_dummies(test_df3, columns=["Sex"])

#test_df4.drop('PassengerId', axis=1, inplace=True) <--- 이건 나중에 평가를 위해 일단 지금은 지우지 말자

test_df4.drop('Name', axis=1, inplace=True)

test_df4.drop('Ticket', axis=1, inplace=True)

test_df4.drop('Sex_male', axis=1, inplace=True)

test_df4.head()

드디어 데이터 전처리 끝.

이제 ML(Machine Learning)을 이용하여 생존자를 예측해보자.

2. Machine Learning 활용한 생존자 예측

ㅇ 활용 모델

2.1 Logistic Regression

2.2 k-Nearest Neighbors

2.3 Support Vector Machines

2.4 Naive Bayes classifier

2.5 Decision Tree

2.6 Artificial neural network

2-0. 일단 학습집합과 테스트 집합 준비

나머지는 졸려서 to be continued...

반응형
반응형

이번 포스팅은 Linear Regression 구현으로 예제는 집 크기에 따른 집 값 예측을 하는 Housing prices(Example of ndrew Ng)이다.

1. Import, data loading

import num as np

import matplotlib.pyplot as plt

data = np.loadtxt("house_prices.txt", delimiter=",")

data #데이터 확인.

* 출력이 안예쁘다. numpy 패키지의 숫자 프린팅 옵션으로 숫자 포맷을 변경한다.

np.set_printoptions(suppress=True)

data

printoptions 함수는 아래 링크 참고.

https://docs.scipy.org/doc/numpy/reference/generated/numpy.set_printoptions.html

numpy.set_printoptions — NumPy v1.16 Manual

Scipy.org Docs NumPy v1.16 Manual NumPy Reference Routines Input and output index next previous numpy.set_printoptions numpy. set_printoptions ( precision=None , threshold=None , edgeitems=None , linewidth=None , suppress=None , nanstr=None , infstr=None , formatter=None , sign=None , floatmode=None...

docs.scipy.org

2. 데이터 셋을 X와 Y로 분리

x = data[:, :2] #모든 행 : 0, 1열

y= data[:, -1] #모든 행: 마지막 열. 이 문제에선 data[:,2]와 동일

3. 학습 데이터 및 테스트 데이터 분할

* 일부는 학습데이터에 활용하고, 일부는 학습 후 테스트 데이터로 활용함

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=4)

/*

- test_size: 테스트 데이터 비중. 여기선 값 중 20%만 테스트 값으로 하고 80%는 training data로 씀

- random_state: 랜덤으로 선택되는 데이터

random_state

:랜덤으로 선택하는 이유는 데이터가 이미 내림차순 등으로 정렬되어있을 경우 순서대로 50개를 뽑으면,

그건 랜덤학습이 아니라 이미 사람 손을 한번 탄 데이터임. 사람이 원하는 값이 나올 가능성이 높아짐.

중구난방으로 데이터를 학습시켜야 실제 예측값과 실제값이비슷하게 나올 수 있음.

*/

4. 학습 데이터와 테스트 데이터 plotting

plt.scatter(x_train[:,0], y_train, color='black') #학습데이터

plt.scatter(x_test[:,0], y_test, color='red') #테스트데이터

5. 선형회귀 모델 학습

model = linear_model.LinearRegression()

model.fit(x_train, y_train) #linearregression 모델에 x_train, y_train 학습

6. 테스트 데이터 넣어서 예측

result = model.predict(x_test)

7. 실제 가격과 예측 가격 비교

print(np.column_stack((x_test, y_test, result)))

#result가 6.에서 x_test로 돌린 예측 값인데 실제 값(y_test)과 거의 비슷하게 나옴.

첫 행의 집값은 314900이나, 예측값은 334034.---- 가 나왔음.

8. 그래프 제대로 그려보기

real = plt.scatter(x_test[:,0], y_test, color='red')

predict=plt.scatter(x_test[:,0], result, color='blue')

plt.legend((real, predict), ('real', 'prediction'))

plt.title('Real price vs. Predicted price')

plt.ylabel('Price')

plt.xlabel('House size')

plt.show()

9. 학습된 선형 모델과 예측 결과 plotting

plt.plot( [min(x_train[:,0]), max(x_train[:,0]) ],

[min(model.predict(x_train)), max(model.predict(x_train))])

#선을 그려보자. min <-> max간 선을 그려줌.

plt.scatter(x_test[:,0], y_test, color='red') #실제 결과

plt.scatter(x_test[:,0], result, color='blue') #예측한 결과

반응형

+ Recent posts