Part 3 Macroanalysis

Chapter 11 Clustering

Abstract : ์ด๋ฒˆ์žฅ์—์„œ๋Š” Machine clustering์— ๋Œ€ํ•ด์„œ ์†Œ๊ฐœํ•œ๋‹ค

11.1. ์†Œ๊ฐœ

์ด๋ฒˆ์žฅ์—์„œ๋Š” ์ž‘์€ corpus๋ฅผ ์‚ฌ์šฉํ•ด ๋ฌธ์„œ๋ฅผ ๋ฌด๋ฆฌ ์ง“๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์„ค๋ช…ํ•œ๋‹ค

11.2. ๋‹ค์‹œ๋ณด๊ธฐ

์ž‘์—…๊ณต๊ฐ„์„ TextAnalysisWithR ํด๋”๋กœ ์„ค์ •ํ•œ๋‹ค

setwd("E:/TextAnalysisWithR")
getwd()
## [1] "E:/TextAnalysisWithR"

11.3 R์—์„œ์˜ ์–ด๋–ค ์ด์ƒ

R์—์„œ ๋ฒกํ„ฐ๊ฐ’์„ ๋‚˜ํƒ€๋‚ผ๋•Œ [1]์ด๋ž€ ๊ฐ’์ด ์ฝ˜์†”์ฐฝ ๊ฐ€์žฅ ์•ž์— ๋‚˜์˜ค๋Š”๋ฐ ์ด ๊ฐ’์€ ๊ทธ ๋ฒกํ„ฐ์—์„œ์˜ ์ฒซ๋ฒˆ์งธ ๊ฐ’์ด๋ž€ ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค. R๊ณผ ๋‹ค๋ฅธ ์–ธ์–ด์˜ ์ฐจ์ด๋Š” R์˜ ์ธ๋ฑ์Šค๋Š” 1๋กœ ์‹œ์ž‘ํ•˜๋Š”๋ฐ ๋ฐ˜ํ•ด ๋‹ค๋ฅธ ์–ธ์–ด๋Š” 0์œผ๋กœ ์‹œ์ž‘ํ•œ๋‹ค. ์ด์— ๋Œ€ํ•ด ์ข€๋” ์•Œ์•„๋ณด์ž

nations=c(Joyce="Irish", Twain="American", Dickens="English")
nations=c(nations, Smith=NA)
is.na(nations) # is.na๋Š” na๊ฐ’์„ ํ™•์ธํ•˜๋Š” ํ•จ์ˆ˜
##   Joyce   Twain Dickens   Smith 
##   FALSE   FALSE   FALSE    TRUE

NA๋กœ ์ž…๋ ฅ๋˜์–ด์žˆ๋Š” Smith์— ๋Œ€ํ•ด์„œ๋งŒ TRUE์˜ ๊ฐ’์ด ๋‚˜ํƒ€๋‚œ๋‹ค. nchar(nations) Smith๊ฐ€ ๊ฐ€์ง„ ๊ฐ’์€ NA๋กœ 0์ด ๋‚˜์™€์•ผ ํ•˜๋Š”๋ฐ 2๊ฐ€ ๋‚˜์˜จ๋‹ค. ์—ฌ๊ธฐ์„œ ncharํ•จ์ˆ˜๋Š” NA์— ๋Œ€ํ•ด์„œ 2๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์„ ์•Œ์•„์•ผ ํ•œ๋‹ค.

11.4 Corpus ์ˆ˜์ง‘

input.dir="E:/TextAnalysisWithR/TextAnalysisWithR/data/XMLAuthorCorpus"

์ด๋ฒˆ์žฅ์—์„œ ์‚ฌ์šฉํ•  ๋ฐ์ดํ„ฐ๋“ค์€ ์œ„์˜ ์œ„์น˜์— ์œ„์น˜ํ•ด์žˆ๋‹ค. dirํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ์ €์žฅ๋˜์–ด์žˆ๋Š” ํŒŒ์ผ๋“ค์„ ๋ถˆ๋Ÿฌ์˜จ๋‹ค

files.v=dir(path=input.dir, pattern=".*xml")

์œ„์˜ ๊ฒฐ๊ณผ๊ฐ’์˜ ์ฒซ๋ฒˆ์งธ ํŒŒ์ผ์„ ๋ณด๋ฉด ์ž‘๊ฐ€๋ฏธ์ƒ์ธ๋ฐ ์ด๋ฒˆ์žฅ์—์„œ ๋‹จ์–ด์˜ ๋ฌด๋ฆฌ๋ฅผ ์ง€์€ํ›„ ๋‹จ์–ด๋ฅผ ๋น„๊ตํ•˜์—ฌ ์ต๋ช…์˜ ์ž‘๊ฐ€๋ฅผ ์ถ”์ธกํ•  ์ˆ˜ ์žˆ๋‹ค. 10์žฅ์—์„œ ๋ดค๋“ฏ์ด XMLํŒŒ์ผ์„ ๋‹ค๋ฃฐ๋•Œ๋Š” xmlTreeParseํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š”๋ฐ ์ด๋Š” ๋ช‡๊ฐ€์ง€ ์˜ต์…˜์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ์ฒซ๋ฒˆ์งธ๋Š” ํŒŒ์ผ์˜ ์œ„์น˜์— ๋Œ€ํ•œ ์˜ต์…˜์ด๋‹ค. ๋”ฐ๋ผ์„œ ํŒŒ์ผ์˜ ์ €์žฅ๋œ ์œ„์น˜๋ฅผ ์•Œ์•„๋ณด๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด์ž

library(XML) file.path(input.dir, files.v) # input.dir๊ณผ ํ•ฉ์ณ์ ธ ์ €์žฅ๋œ ์œ„์น˜๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. xmlTreeParse(file.path(input.dir, files.v[1], useInternalNodes=TRUE))

์ž‘์—…๊ณต๊ฐ„๋‚ด์˜ ๋ชจ๋“  XMlํŒŒ์ผ์„ ํ•˜๋‚˜์˜ ๊ฐ์ฒด์— ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด ๋จผ์ € listํ˜•ํƒœ์˜ ๋นˆ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ  for๋ฐ˜๋ณต๋ฌธ์„ ์‹œ์ž‘ํ•œ๋‹ค.

library(XML)
book.freqs.l=list()
for(i in 1:length(files.v)){
  doc.object=xmlTreeParse(file.path(input.dir, files.v[i]),
                          useInternalNodes=TRUE)
}

11.5 ๋‹ค๋ฅธ ํ•จ์ˆ˜

XMLํŒŒ์ผ์„ ๋ถˆ๋Ÿฌ์™”์œผ๋‹ˆ ํŒŒ์ผ๋“ค์—์„œ ๋‹จ์–ด์˜ ๋นˆ๋„์ˆ˜๋ฅผ ์ถ”์ถœํ•ด๋‚ด์•ผ ํ•œ๋‹ค. ์ด๊ฒƒ์€ ์ฒซ ์žฅ์—์„œ ํ–ˆ๋˜๊ฒƒ๊ณผ ์œ ์‚ฌํ•˜๋‚˜ XML์„ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ์ฐจ์ด๊ฐ€ ์žˆ์–ด ์•ฝ๊ฐ„์˜ ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” getTEIWordTableListํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์ด ํ•จ์ˆ˜๋Š” XML๊ฐ์ฒด๋งŒ ํ•„์š”๋กœ ํ•œ๋‹ค. getTEIWordTableList=function(doc.object){ ํ•„์š”ํ•œ ์ฝ”๋“œ } ํ˜•์‹์œผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค. 1.์ž‘์—…์„ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ๋ชจ๋“  XMLํŒŒ์ผ์„ ํ•ฉ์ณ์•ผ ํ•œ๋‹ค. ์ด๋Š” getNodesetํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค

paras=getNodeSet(doc.object, "/tei:TEI/tei:text/tei:body//tei:p",
                 c(tei="http://www.tei-c.org/ns/1.0"))

2.์ด๋ ‡๊ฒŒ ๋ถˆ๋Ÿฌ์˜จ ๋ฌธ๋‹จ์— ๋Œ€ํ•ด ํ•ฉ์น˜๋Š” ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. ๋ฐ˜ํ™˜๊ฐ’์ด listํ˜•ํƒœ์™€ ๋น„์Šทํ•˜๋ฏ€๋กœ sapply์™€ xmlValue ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•œ๋‹ค.

words=paste(sapply(paras, xmlValue), collapse=" ")

3.tolowerํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด ๋ชจ๋“  ๋ฌธ์ž๋ฅผ ์†Œ๋ฌธ์ž๋กœ ๋ฐ”๊พธ๊ณ  \W๋ฅผ ์ด์šฉํ•ด ์ •๊ทœํ‘œํ˜„์‹์„ ์‚ญ์ œํ•œ๋‹ค.

words.lower=tolower(words)
words.l=strsplit(words.lower, "\\W")
  1. ๊ฒฐ๊ณผ๊ฐ’์ด listํ˜•ํƒœ์ด๋ฏ€๋กœ ๋ฒกํ„ฐํ˜•ํƒœ๋กœ ๋ฐ”๊ฟ”์ค€๋‹ค
word.v=unlist(words.l)
  1. ๊ณต๋ฐฑ๊ฐ’์ด ์žˆ์œผ๋ฏ€๋กœ ๊ณต๋ฐฑ๊ฐ’์„ ์ œ์™ธํ•œ ๊ฐ’๋งŒ์„ tableํ•จ์ˆ˜๋กœ ๋ถˆ๋Ÿฌ์˜จ๋‹ค
book.freqs.t=table(word.v[which(word.v!="")])
  1. ์ „์ฒด์—์„œ ๊ทธ ํŠน์ • ๋‹จ์–ด๊ฐ€ ์ฐจ์ง€ํ•˜๋Š” ๋น„์œจ์„ ๊ณ„์‚ฐํ•œ๋‹ค
book.freqs.rel.t=100*(book.freqs.t/sum(book.freqs.t))

์œ„์˜ ๊ณผ์ •์„ ์‚ฌ์šฉ์ž ํ•จ์ˆ˜๋กœ ๋งŒ๋“  ํ•จ์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

getTEIWordTableList=function(doc.object){
  paras=getNodeSet(doc.object,
                   "/tei:TEI/tei:text/tei:body//tei:p",
                   c(tei="http://www.tei-c.org/ns/1.0"))
  words=paste(sapply(paras, xmlValue), collapse=" ")
  words.lower=tolower(words)
  words.l=strsplit(words.lower, "\\W")
  word.v=unlist(words.l)
  book.freqs.t=table(word.v[which(word.v!="")])
  book.freqs.rel.t=100*(book.freqs.t/sum(book.freqs.t))
  return(book.freqs.rel.t)
}

๋งŒ๋“  ์‚ฌ์šฉ์žํ•จ์ˆ˜๋ฅผ corpusFunctions.r ํŒŒ์ผ์— ์ €์žฅํ•œ๋‹ค. ์‚ฌ์šฉ์ž ์ •์˜ํ•จ์ˆ˜๋ฅผ ๋ถˆ๋Ÿฌ์™€ for๋ฌธ์„ ์ด์šฉํ•ด ์ด์ „ ์ ˆ์—์„œ ํ• ๋ ค๊ณ  ํ–ˆ๋˜ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

source("E:/TextAnalysisWithR/TextAnalysisWithR/code/corpusFunctions.r")
library(XML)
book.freqs.l=list()
for(i in 1:length(files.v)){
  doc.object=xmlTreeParse(file.path(input.dir, files.v[i]),
                          useInternalNodes=TRUE)
  worddata=getTEIWordTableList(doc.object)
  book.freqs.l[[files.v[i]]]=worddata
}

๋‚˜์˜จ ๊ฒฐ๊ณผ๊ฐ’์— ๋Œ€ํ•ด ํ™•์ธํ•œ๋‹ค.

class(book.freqs.l)
## [1] "list"
names(book.freqs.l)
##  [1] "anonymous.xml"  "Carleton1.xml"  "Carleton10.xml" "Carleton11.xml"
##  [5] "Carleton12.xml" "Carleton13.xml" "Carleton14.xml" "Carleton2.xml" 
##  [9] "Carleton3.xml"  "Carleton4.xml"  "Carleton5.xml"  "Carleton6.xml" 
## [13] "Carleton7.xml"  "Carleton8.xml"  "Carleton9.xml"  "Donovan1.xml"  
## [17] "Donovan2.xml"   "Driscoll1.xml"  "Driscoll2.xml"  "Driscoll3.xml" 
## [21] "Edgeworth1.xml" "Jessop1.xml"    "Jessop2.xml"    "Jessop3.xml"   
## [25] "Kyne1.xml"      "Kyne2.xml"      "LeFanu1.xml"    "LeFanu2.xml"   
## [29] "LeFanu3.xml"    "LeFanu4.xml"    "LeFanu5.xml"    "LeFanu6.xml"   
## [33] "LeFanu7.xml"    "Lewis.xml"      "McHenry1.xml"   "McHenry2.xml"  
## [37] "Norris1.xml"    "Norris2.xml"    "Norris3.xml"    "Norris4.xml"   
## [41] "Polidori1.xml"  "Quigley1.xml"   "Quigley2.xml"
str(book.freqs.l)
## List of 43
##  $ anonymous.xml : table [1:8536(1d)] 0.000979 0.000979 0.000979 0.000979 0.003918 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:8536] "_i_" "02" "03" "05" ...
##  $ Carleton1.xml : table [1:6148(1d)] 0.03282 0.00193 0.00193 0.00193 0.00193 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:6148] "_" "_abouchal_" "_acushla" "_acushla_" ...
##  $ Carleton10.xml: table [1:8807(1d)] 0.00897 0.00069 0.00345 0.00138 0.00207 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:8807] "_" "_abouchal" "_amin" "_aqua" ...
##  $ Carleton11.xml: table [1:6068(1d)] 0.03581 0.00565 0.00188 0.00188 0.00188 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:6068] "_" "_a" "_aegroto_" "_ahir" ...
##  $ Carleton12.xml: table [1:8463(1d)] 0.007506 0.000834 0.000834 0.000834 0.000834 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:8463] "_" "_a" "_as" "_at" ...
##  $ Carleton13.xml: table [1:11695(1d)] 0.001905 0.001429 0.000476 0.000476 0.000476 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:11695] "_" "_a" "_ad" "_all_" ...
##  $ Carleton14.xml: table [1:9706(1d)] 0.00362 0.000603 0.000603 0.000603 0.000603 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:9706] "_" "_a" "_alanna_" "_always_" ...
##  $ Carleton2.xml : table [1:2456(1d)] 0.01856 0.00928 0.01856 0.00928 0.00928 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:2456] "_" "_acushla_" "_black" "_cardin_" ...
##  $ Carleton3.xml : table [1:8241(1d)] 0.004975 0.000829 0.000829 0.000829 0.000829 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:8241] "_" "__banaght" "_a" "_achora" ...
##  $ Carleton4.xml : table [1:4942(1d)] 0.00171 0.00171 0.00171 0.00171 0.00171 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:4942] "_belles" "_cast" "_castaway_" "_dramatis" ...
##  $ Carleton5.xml : table [1:2702(1d)] 0.00797 0.00797 0.00797 0.00797 0.00797 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:2702] "_ballydhas_" "_bouchaleens_" "_chevalier" "_coortin_" ...
##  $ Carleton6.xml : table [1:2014(1d)] 2.9506 0.0115 0.0344 0.0115 0.0344 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:2014] "a" "abandon" "abandoned" "abbey" ...
##  $ Carleton7.xml : table [1:8443(1d)] 0.006834 0.00205 0.00205 0.001367 0.000683 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:8443] "_" "_a" "_achora" "_achora_" ...
##  $ Carleton8.xml : table [1:3773(1d)] 0.017 0.0034 0.0034 0.0034 0.0034 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:3773] "_" "_arraghid_" "_avich" "_avillish_" ...
##  $ Carleton9.xml : table [1:8778(1d)] 0.003773 0.001509 0.000755 0.000755 0.000755 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:8778] "_" "_a" "_ab" "_adequate_" ...
##  $ Donovan1.xml  : table [1:5991(1d)] 0.00223 0.0067 0.00223 0.00223 2.24343 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:5991] "0" "1" "16" "47the" ...
##  $ Donovan2.xml  : table [1:5147(1d)] 0.00262 0.00262 0.00262 0.00262 0.00262 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:5147] "000" "1" "18" "216" ...
##  $ Driscoll1.xml : table [1:12373(1d)] 0.003968 0.000661 0.001984 0.001323 0.000661 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:12373] "__________" "________________________charles" "__________a" "__________as" ...
##  $ Driscoll2.xml : table [1:9409(1d)] 0.00819 0.00234 0.00234 0.00117 0.00117 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:9409] "0" "000" "10" "136" ...
##  $ Driscoll3.xml : table [1:10629(1d)] 0.003997 0.001599 0.000799 0.000799 0.001599 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:10629] "000" "1" "10" "100" ...
##  $ Edgeworth1.xml: table [1:1912(1d)] 0.0263 0.00877 0.00877 0.00877 0.00877 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:1912] "_can_" "_child_" "_edinburgh" "_extract" ...
##  $ Jessop1.xml   : table [1:4040(1d)] 0.00491 0.00983 0.00491 0.00491 0.00491 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:4040] "1188" "17" "1874" "1876" ...
##  $ Jessop2.xml   : table [1:4292(1d)] 0.00732 0.00366 0.00366 0.00366 0.00366 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:4292] "000" "1813" "1876" "1877" ...
##  $ Jessop3.xml   : table [1:2207(1d)] 0.0104 0.0104 2.2314 0.0415 0.0623 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:2207] "1897" "23d" "a" "abandoned" ...
##  $ Kyne1.xml     : table [1:9179(1d)] 0.00103 0.00103 0.00103 0.00103 0.00103 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:9179] "08" "102the" "118" "12th" ...
##  $ Kyne2.xml     : table [1:9996(1d)] 0.00171 0.000855 0.000855 0.00171 0.000855 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:9996] "1" "10" "12" "13" ...
##  $ LeFanu1.xml   : table [1:4045(1d)] 0.00354 0.01415 0.00354 0.00354 0.00354 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:4045] "_" "_a" "_all_" "_an" ...
##  $ LeFanu2.xml   : table [1:4085(1d)] 0.02313 0.00771 0.00386 0.00386 0.00386 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:4085] "_" "_a" "_alias_" "_all_" ...
##  $ LeFanu3.xml   : table [1:2588(1d)] 0.00701 0.00701 0.00701 0.00701 0.00701 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:2588] "_are_" "_can" "_dried" "_here_" ...
##  $ LeFanu4.xml   : table [1:5495(1d)] 0.00214 0.00214 0.00214 0.00214 0.00214 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:5495] "_" "_de" "_ma" "_vous" ...
##  $ LeFanu5.xml   : table [1:14656(1d)] 0.011292 0.000452 0.000452 0.000452 0.000452 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:14656] "_" "_a" "_a_" "_ad" ...
##  $ LeFanu6.xml   : table [1:11489(1d)] 0.010677 0.000593 0.007118 0.001186 0.000593 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:11489] "_" "_30th" "_a" "_a_lon" ...
##  $ LeFanu7.xml   : table [1:11909(1d)] 0.02825 0.00113 0.000565 0.000565 0.000565 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:11909] "_" "_a" "_abhor_" "_ably_" ...
##  $ Lewis.xml     : table [1:4668(1d)] 0.00279 0.02786 0.00279 0.00836 0.00279 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:4668] "_" "_i_" "04" "1" ...
##  $ McHenry1.xml  : table [1:7347(1d)] 0.00246 0.00123 0.00123 0.00123 0.00246 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:7347] "1" "1723" "1730" "1750" ...
##  $ McHenry2.xml  : table [1:6864(1d)] 0.00121 0.00242 0.00242 0.00121 0.00121 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:6864] "1734" "1754" "1755" "1776" ...
##  $ Norris1.xml   : table [1:9055(1d)] 0.000756 0.000756 2.276713 0.003024 0.000756 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:9055] "_" "1" "a" "abandoned" ...
##  $ Norris2.xml   : table [1:4388(1d)] 2.21192 0.00322 0.00322 0.00966 0.00322 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:4388] "a" "abandon" "abandonment" "able" ...
##  $ Norris3.xml   : table [1:8989(1d)] 0.000819 0.000819 0.000819 0.000819 0.000819 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:8989] "100" "15c" "1858" "1878" ...
##  $ Norris4.xml   : table [1:10783(1d)] 0.000584 2.366981 0.000584 0.000584 0.001169 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:10783] "2" "a" "aback" "abandon" ...
##  $ Polidori1.xml : table [1:2926(1d)] 0.01555 0.01555 0.00778 0.0311 0.01555 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:2926] "__________" "______________" "____________________" "________________________________________________________________" ...
##  $ Quigley1.xml  : table [1:7155(1d)] 0.12579 0.00217 0.00217 0.00217 0.00217 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:7155] "000" "00970" "01082" "019" ...
##  $ Quigley2.xml  : table [1:8058(1d)] 0.00165 0.07423 0.01155 0.0033 0.00165 ...
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:8058] "00" "000" "1" "10" ...

11.6 ์œ ํด๋ฆฌ๋“œ๊ฑฐ๋ฆฌ์™€ ๊ด€๋ฆฌ๋˜์ง€์•Š์€ clustering

์„œ๋กœ ๋‹ค๋ฅธ ๋‘๊ฐœ์˜ ํ…์ŠคํŠธ๋ฅผ ๊ตฌ๋ถ„ํ•˜๋Š” ๊ฐ€์žฅ ํšจ๊ณผ์ ์ธ ๋ฐฉ๋ฒ•์€ ์ž์ฃผ ๋“ฑ์žฅํ•˜๋Š” ํŠน์ • ๋นˆ๋„์˜ ์„ ๋น„๊ตํ•˜๋Š” ๊ฒƒ์ด๋‹ค.(์˜ˆ๋ฅผ๋“ค๋ฉด, the, of, and, to ๋“ฑ์ด ์žˆ๋‹ค) ์ด๋ฅผ ์ธก์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์œ ํด๋ฆฌ๋“œ ๊ฑฐ๋ฆฌ์™€ ๊ด€๋ จ์ด ์žˆ๋‹ค. ์œ ํด๋ฆฌ๋“œ๊ฑฐ๋ฆฌ์™€ ํ”ผํƒ€๊ณ ๋ผ์Šค๊ฑฐ๋ฆฌ๋ฅผ ์ด์šฉํ•ด ๊ฐ๊ฐ์˜ ๋ถ๊ณผ ๋‹ค๋ฅธ ๋ถ๋“ค๊ฐ„์˜ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ฑฐ๋ฆฌ๊ฐ€ ๊ฐ€๊นŒ์šธ์ˆ˜๋ก ๋น„์Šทํ•œ ํŠน์ง•์ด ์žˆ๋‹ค๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์„ ์•Œ๊ธฐ์œ„ํ•ด ์˜ˆ๋ฅผ ๋“ค์–ด๋ณด์ž a,b,c ๋ผ๋Š” 3๊ฐœ์˜ ๋ถ์ด ์žˆ๊ณ  f1,f2์˜ ํŠน์ง•์ด ์žˆ์œผ๋ฉฐ ์ธก์ •๊ฐ’์€ ๊ฐ๊ฐ์˜ ๋ถ์—์„œ์˜ ๋ฐฑ๋ถ„์œจ์ด๋‹ค

a=c(10,5)
b=c(11,6)
c=c(4,13)
my.m=rbind(a,b,c)
colnames(my.m)=c("f1","f2")

์ ๋“ค๊ฐ„์˜ ๊ฑฐ๋ฆฌ ๊ณ„์‚ฐ์„ ์œ„ํ•ด distํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•œ๋‹ค.

dist(my.m)
##           a         b
## b  1.414214          
## c 10.000000  9.899495

๋‹จ์ˆœ ๊ฑฐ๋ฆฌ๋งŒ ๊ฐ€์ง€๊ณ  a,b๋Š” ๊ฐ€๊นŒ์šด ๊ด€๊ณ„์ด๊ณ  c๋Š” ๋‹ค๋ฅด๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ํŠน์ง•์˜ ์ˆ˜๊ฐ€ ๋งŽ์•„์ง„๋‹ค๊ณ ํ•ด๋„ ๊ณ„์‚ฐ์€ ๋ณต์žกํ•ด์ง€์ง€๋งŒ ๊ธฐ๋ณธ ๋ฐฉ๋ฒ•์€ ๋ณ€ํ•˜์ง€ ์•Š๋Š”๋‹ค.(์œ ํด๋ฆฌ๋“œ ๊ฑฐ๋ฆฌ๋ฅผ ์ด์šฉ) book.freqs.l ๊ฐ์ฒด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฏ€๋กœ ์ด๋ฅผ data matrixํ˜•ํƒœ๋กœ ๋ณ€ํ™˜์‹œ์ผœ ๋ถ„์„์„ ํ•œ๋‹ค.

11.7 Listํ˜•ํƒœ๋ฅผ Data matrix๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ

๋ณ€ํ™˜ํ•˜๊ธฐ ์œ„ํ•ด mapply๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ๊ฒฐ๊ณผ๊ฐ’์œผ๋กœ listํ˜•ํƒœ๋กœ๋œ freqs.l๊ฐ์ฒด๋ฅผ ์–ป๋Š”๋ฐ ์ด๋Š” book.freqs.l๊ณผ ๋น„์Šทํ•˜๋‚˜ freqs.l์€ ๊ฐ ๋ฆฌ์ŠคํŠธ๋‚ด์—์„œ๋Š” data.frameํ˜•์‹์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

freqs.l=mapply(data.frame,
               ID=seq_along(book.freqs.l),
               book.freqs.l,
               SIMPLIFY=FALSE,
               MoreArgs=list(stringsAsFactors=FALSE))

๋‘ ๊ฐ์ฒด์˜ ์ฐจ์ด๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

class(freqs.l[[1]])
## [1] "data.frame"
class(book.freqs.l[[1]])
## [1] "table"

์ฃผ์˜ํ•ด์•ผ ํ• ๊ฒƒ์€ ์œ ํด๋ฆฌ๋“œ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ„์‚ฐํ•˜๊ธฐ์œ„ํ•ด์„œ๋Š” ๊ฐ์ฒด๋ฅผ matrixํ˜•ํƒœ๋กœ ๋ฐ”๊ฟ”์•ผ ํ•œ๋‹ค.

freqs.df=do.call(rbind, freqs.l)
dim(freqs.df)
## [1] 300447      3
result=xtabs(Freq~ID+Var1, data=freqs.df)
dim(result)
## [1]    43 53233
colnames(result)[500:600]
##   [1] "attempt"         "attempted"       "attend"         
##   [4] "attendant"       "attended"        "attention"      
##   [7] "attentions"      "attentive"       "attested"       
##  [10] "attire"          "attitude"        "attorney"       
##  [13] "attorneys"       "attrition"       "au"             
##  [16] "auburn"          "auction"         "audible"        
##  [19] "audibly"         "auditor"         "auditory"       
##  [22] "aught"           "august"          "auld"           
##  [25] "aunt"            "authentic"       "authoritatively"
##  [28] "authority"       "authorize"       "automatically"  
##  [31] "automobile"      "automobiles"     "autumn"         
##  [34] "avail"           "available"       "avenue"         
##  [37] "average"         "averred"         "avoid"          
##  [40] "avoided"         "avoiding"        "avowal"         
##  [43] "avuncular"       "await"           "awaited"        
##  [46] "awaiting"        "awake"           "awakening"      
##  [49] "aware"           "away"            "awe"            
##  [52] "awesome"         "awful"           "awfully"        
##  [55] "awkward"         "axe"             "axes"           
##  [58] "aye"             "azaleas"         "b"              
##  [61] "baby"            "back"            "backbone"       
##  [64] "backed"          "background"      "backs"          
##  [67] "backward"        "bad"             "bade"           
##  [70] "badge"           "badly"           "baffled"        
##  [73] "baffling"        "bag"             "baggage"        
##  [76] "bah"             "bait"            "balance"        
##  [79] "balanced"        "bale"            "baleful"        
##  [82] "ball"            "ballad"          "ballads"        
##  [85] "bally"           "band"            "bandaged"       
##  [88] "bandmaster"      "bandsaw"         "bandsaws"       
##  [91] "bang"            "banged"          "banishment"     
##  [94] "banisters"       "bank"            "banker"         
##  [97] "bankers"         "bankrupt"        "bankruptcy"     
## [100] "banks"           "banter"
class(result)
## [1] "xtabs" "table"

clusting์„ ํ•˜๊ธฐ์œ„ํ•ด result๊ฐ’์„ matrix๊ฐ์ฒด๋กœ ๋ณ€ํ™˜์‹œ์ผœ์ค˜์•ผ ํ•œ๋‹ค.(applyํ•จ์ˆ˜ ์ด์šฉ)

final.m=apply(result, 2, as.numeric)

11.8 Clustring์„ ์œ„ํ•œ ๋ฐ์ดํ„ฐ ์ค€๋น„

clustering์„ ํ•˜๊ธฐ์ „์— ๋นˆ๋„์— ๋”ฐ๋ผ ๋ฐ์ดํ„ฐ๋ฅผ ์„ ๋ณ„ํ•ด๋†“๋Š”๊ฒŒ ์œ ์šฉํ•˜๋‹ค ์„ ๋ณ„ํ•˜๋Š” ๋ฐฉ๋ฒ•์—๋Š” ์—ฌ๋Ÿฌ๊ฐ€์ง€๊ฐ€ ์žˆ๋Š”๋ฐ ๊ทธ์ค‘ ํ•œ๊ฐ€์ง€๋Š” ๋นˆ๋„์ˆ˜๊ฐ€ ๋†’์€ 100๊ฐ€์ง€๋งŒ์„ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์ด๋‹ค ๋˜ํ•œ ๋„์ˆ˜์— ๋Œ€ํ•œ ๊ฒฝ๊ณ„๋ฅผ ๊ตฌํ•˜๋Š”๊ฒƒ๋„ ์ข‹์€ ๋ฐฉ๋ฒ•์ธ๋ฐ ์ „์ฒด์—์„œ ๊ทธ ๋‹จ์–ด๊ฐ€ ๋ช‡ํ”„๋กœ ์ฐจ์ง€ํ•˜๋Š”์ง€๋ฅผ ๋”ฐ์ง€๊ณ  .25๊ฐ’์„ ๋„˜๋Š” ๊ฐ’๋งŒ์„ ๊ฐ€์ง€๊ณ  ์˜ค๋Š”๊ฒƒ์„ ์„ ํ˜ธํ•œ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด applyํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•œ๋‹ค

smaller.m=final.m[,apply(final.m, 2, mean)>=.25]

๋‘ ๊ฐ์ฒด๋ฅผ ๋น„๊ตํ•ด๋ณธ๋‹ค

dim(final.m)
## [1]    43 53233
dim(smaller.m)
## [1] 43 53

11.9 Clustering

distํ•จ์ˆ˜(์œ ํด๋ฆฌ๋“œ ๊ฑฐ๋ฆฌ ๊ตฌํ•˜๊ธฐ)์™€ hclust(๋ฐ์ดํ„ฐ๊ฐ„ ๊ฑฐ๋ฆฌ๋ฅผ ์ด์šฉํ•ด ๋ฌด๋ฆฌ์ง“๊ธฐ)๋ฅผ ์ด์šฉํ•œ๋‹ค 1.๊ฑฐ๋ฆฌ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ ๋‹ค

dm=dist(smaller.m)
  1. dm์„ ํ†ตํ•ด cluster๋ถ„์„์„ ์‹ค์‹œํ•œ๋‹ค
cluster=hclust(dm)
  1. labels๋ฅผ ์ด์šฉํ•ด ์ฑ…์˜ ์ด๋ฆ„์„ ๊ฐ€์ ธ์˜จ๋‹ค
cluster$labels=names(book.freqs.l)
  1. ๊ฒฐ๊ณผ๊ฐ’์„ ํ”Œ๋กœํŒ…ํ•œ๋‹ค
plot(cluster)

anonymous.xml์€ kyne1.xml๊ณผ kyne2.xml์‚ฌ์ด์— ์žˆ๋Š”๊ฑธ๋กœ ๋ด์„œ ์ด ์ €์ž๋ฅผ Peter B.Kyne์ผ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๋‹ค.