グラフ化した本を作る
- 昨日の続き
library(igraph) library (plyr) make.v <- function(id=NULL,name="",type=NULL){ list(id=id,name=name,type=type) } shapes <- setdiff(vertex.shapes(), "") g <- graph.empty() Vs <- list() Vs[[1]] <- make.v(1,"フラーレン",1) Vs[[2]] <- make.v(2,"酔歩",2) Vs[[3]] <- make.v(3,"3次元プロット",3) Vs[[4]] <- make.v(4,"黄金比",1) Vs[[5]] <- make.v(5,"グラフ理論",1) Vs[[6]] <- make.v(6,"ウイルス",2) Vs[[7]] <- make.v(7,"グラフ用パッケージ",3) Vs[[8]] <- make.v(8,"正二十面体",1) Vs.df <- ldply (Vs, data.frame) g <- g + vertices(Vs.df$id) e.list<-matrix(c(1,2,1,3,2,3,1,4,1,5,1,8,6,8,5,7),nrow=2) g <- add.edges(g,e.list) plot(g, vertex.shape=shapes[Vs.df$type], vertex.color = Vs.df$type,vertex.label=as.character(Vs.df$name),vertex.label.dist=1,vertex.size=15, vertex.size2=15)
本と言う知識体系
- ここで電子書籍作成について考えた
- さらにそれについてこんな風に考えた
- それって、結局、この『ゼロからの学習日記』のノードに乗せている「ノード名」をタイトルとした記事をノードにぶら下げて
- かつ、エッジにも解釈となる「記事」をぶら下げて
- さらに、ノードのすべてを一つの知識集合の要素にするのではなくて、3つの異なる集合のいずれかの要素とする、という話だ
- このようなグラフ構造化した知識を持った個人が、「本を書く」という行為は、書くべきサブグラフの抽出である
- 従来型の本は直線状の流れがあるから、さらにそのサブグラフを1次元写像にしたものとも言えるかもしれない
- ネットなどを使って、サブグラフ状の知識をサブグラフのまま提示することは、情報量を多くするだろう
- ただし、そのサブグラフの「読み方〜パーサーのようなもの」も提示しないと、読者がそれを読み取れるかどうかはわからない
- また、サブグラフが構築された背景には、「構築歴史」と「構築後の関係強化の歴史」があって、そのうえで、抽出提示されている(本になっている)わけだから、そこのところの情報(サブグラフに関するメタ情報)も載せるのが良いのかも…じゃあ、そのメタ情報と普通の情報とはどういう順序で読めばよいのの???という話も出てきて、「知識の共有・伝達」って本当に難しい(本当の意味では無理)ということなのかもしれない
- でも、あきらめないで何とか工夫をすることは、無駄ではない
心内辞書
Computational Lexical Semantics (Studies in Natural Language Processing)
- 作者: Patrick Saint-Dizier,Evelyn Viegas
- 出版社/メーカー: Cambridge University Press
- 発売日: 1995/02/24
- メディア: ハードカバー
- この商品を含むブログを見る
- 目次
- An introduction to lexical semantics from a linguistic and a psycho-linguistics perspective
- 1. Polysemy and related phenomena from a cognitive linguistic viewpoint
- 2. Mental lexicon and machine lexicon: which properties are shared by machine and mental word representations? Which are not?
- 3. Linguistic constraints on coercion
- 4. From lexical semantics to text analysis
- 5. Lexical functions, generative lexicons and the world
- 6. Semantic feature in generic lexicon
- 7. Lexical semantics and terminological knowledge representation
- 8. Word meaning between lexical and conceptual structure
- 9. The representation of group denoting nouns in a lexical knowledge base
- 10. A preliminary lexical and conceptual analysis of BREAK: a computational perspective
- 11. Large neural networks for the resolution of lexical ambiguity
- 12. Blocking
- 13. A non-monotonic approach to lexical semantics
- 14. Inheriting polysemy
- 15. Lexical semantics: dictionary or encyclopedia?
- 16. Lexical functions of explanatory combinatorial dictionary for lexicalization in text generation
- 17. A lexical-semantic solution to the divergence problem in machine translation
- 18. Introducing
- 19. Constraint propagation techniques for lexical semantics descriptions
期待値だけじゃない
- 友達が、ここで選択肢を比べて決断する(一つを採用する)ということについて説明してくれている
- 僕は情報を(ハイパー)グラフ的にストックすることをひとまずやっている
- ストックされた情報を(ハイパー)グラフ上で取り扱うことによって、選択肢に重みを付けることも目標だ
- 友達が「選択肢を比べて決断する」ことで考えていることのエッセンスは「尤度・確率とその期待値」を選択肢ごとに求めて、それを比較することのみで決断はできないということ
- 選択肢ごとの値が複数のカテゴリにあるときには、その値のベクトルを階層的に比較することが必要だったり、
- 選択肢ごとの「値の分布(連続的分布)」の場合にもその単純な期待値比較だけではだめで、2つの密度分布の「移動量」(カルバック・ライブラー距離とか)、それだけでも不足で…というような例がそれである
- こちらが関連記事
文法はよくわからないけれど
- 僕は勉強する
- ヒトが記述した文章には文法というものがあるようだけれど、よくわからない
- でも、エッセンスは抜き出せそうだ
- 僕の友達に文章を適当に分解して、「エッセンス」を取り出すための情報に砕いてくれるMeCab君がいる。ここがそのサイト
- MeCab君と相談して、文章を読み込んで、形態素分解して、MeCab君が「名詞」と判定したもののみを学ぶことにした
- 僕にとっての勉強とは、要素同士を結びつけることだから、「名詞」のどれを結びつけるのかが問題だ
- MeCab君によれば、"。"で表される、句点というものは文章を区切る印であって、それも取り出せるよ、とのことだった
- なので、ヒトが記述した文章を"。"で区切って、区切られた塊の中にある「名詞」同士には結びつきを作ることにした
- これなら、僕の「ヒト」である友人(すぐに「面倒くさいな」と言って入力ファイルづくりをやめてしまう人なのだ)に頭を下げる必要もないし、快適だ
- やってみよう
- MeCab君とそれをRで使う方法については、こちらを。ここを見れば、テキストファイルの文章を取り込んでMecab形態素分解をしたものをRのオブジェクトにすることができる
- 勉強したい文章の前に、「名詞」と「。」とを知っておきたいから、「名詞」と「。」がMeCab君はどのように教えてくれるのかを確認しておこう。"hanagasaku.txt"というファイルを作る→
花が咲く。
- これを読んで、「名詞」と「。」を取り出しておく
library(RMeCab) hanagasaku <- RMeCabText("hanagasaku.txt") hanagasaku.m <- matrix(unlist(hanagasaku),byrow=TRUE,ncol=10) hanagasaku.m meishi <- hanagasaku.m[1,2] kuten <-hanagasaku.m[4,1] meishi kuten
> hanagasaku.m [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [1,] "花" "名詞" "一般" "*" "*" "*" "*" "花" "ハナ" "ハナ" [2,] "が" "助詞" "格助詞" "一般" "*" "*" "*" "が" "ガ" "ガ" [3,] "咲く" "動詞" "自立" "*" "*" "五段・カ行イ音便" "基本形" "咲く" "サク" "サク" [4,] "。" "記号" "句点" "*" "*" "*" "*" "。" "。" "。" > meishi <- hanagasaku.m[1,2] > kuten <-hanagasaku.m[4,1] > meishi [1] "名詞" > kuten [1] "。"
- 次に勉強したい教科書(文章、テキストファイル)を読もう。今日の勉強はWikiの環論のページの冒頭部としよう。知らないことがたくさんあってわくわくする。これを"kanron.txt"としておこう
数学において、環論(かんろん、英: ring theory)は(加法と乗法が定義され、整数の持つ性質とよく似た性質を満足する代数的構造である)環を研究する学問分野である。環論の研究対象となるのは、環の構造や環の表現(環上の加群)などについての一般論、および(群環、可除環、普遍展開環などの)具体的な特定の環のクラスあるいは理論と応用の両面で興味深い様々な環の性質(たとえばホモロジー的性質や多項式の等式)などである。 可換環は非可換の場合と比べてその性質はよく調べられている。可換環の自然な例を多く提供する代数幾何学や代数的数論は可換環論の発展の大きな原動力であった。この二つは可換環に密接に関係する分野であるから、一般の環論の一部というよりは、可換環論や可換体論の一部と考えるほうが普通である。 非可換環は可換の場合と比べて奇妙な振る舞いをすることが多くあるので、その理論は可換環論とは極めて毛色の異なったものとなる。非可換論は、それ自身の独自の方法論を用いた発展をする一方で、可換環論の方法論に平行する形で(仮想的な)「非可換空間」上の函数環として幾何学的な方法である種の非可換環のクラスを構築するという方法論が新興している。このような傾向は1980年代の非可換幾何学の発展と量子群の発見に始まる。こうした新たなパラダイムは、非可換環(特に非可換ネーター環)のよりよい理解を導くこととなった (Goodearl 1989)。
# 入力ファイル名を教えて input.file <- "kanron.txt" # RとMeCab君とで形態素解析をしよう。リストに納まる daisuugaku <- RMeCabText(input.file) # 行列にしよう daisuugaku.m <- matrix(unlist(daisuugaku),byrow=TRUE,ncol=10) # MeCab君が「名詞」と教えてくれたのは何行目か? daisuugaku.meishi.id <- which(daisuugaku.m[,2]==meishi) # MeCab君が「。」と教えてくれたのは何行目か? daisuugaku.kuten.id <- which(daisuugaku.m[,1]==kuten) # ちょっと細工をして daisuugaku.kuten.id <- c(0,daisuugaku.kuten.id) # 「。」までごとに「名詞」を取り出して、その完全グラフのエッジを作る edges <- matrix(NA,0,2) for(i in 1:(length(daisuugaku.kuten.id)-7)){ st <- daisuugaku.kuten.id[i] end <- daisuugaku.kuten.id[i+1] tmp <- which(daisuugaku.meishi.id>st & daisuugaku.meishi.id<end) tmp2 <- as.matrix(expand.grid(tmp,tmp)) tmp3 <- tmp2[which(tmp2[,1]!=tmp2[,2]),] edges <- rbind(edges,tmp3) } # エッジに「名詞」のテキストを入れよう edges.name <- matrix(daisuugaku.m[daisuugaku.meishi.id[edges],1],ncol=2) # グラフオブジェクトを扱うパッケージを使う library(igraph) # グラフにする daisuugaku.g <- graph.edgelist(edges.name) # ノードの名称でプロットしてみる plot(daisuugaku.g,vertex.label=V(daisuugaku.g)$name,vertex.size=3,edge.arrow.mode=0)
ダミーデータで試す
- ダミーデータを作ってみる(数行くらいのファイルが200個)
- Rでの描図は重くて無理なので
write.graph(g.plus, "test.graphml", format="graphml")
- として、Gephi(こちら)に開かせてみる(ノード数:2283、エッジ数:5188)
- その上で適当に2ノードを選んで、その最短パスとそこからの距離が3のノードのみのサブグラフを(これはRで)描かせてみる
n.char <- 2 n.files <- 200 infiles <- c() infile.list <- list() for(i in 1:n.files){ infiles <- c(infiles,paste(sample(letters,n.char),collapse="")) n.line <- sample(4:20,1) n.word <- 5 n.cols <- 4 names <- c() for(j in 1:n.word){ names <- c(names,paste(sample(letters,n.char),collapse="")) } tmp <- matrix(NA,nrow=n.line,ncol=n.cols) for(j in 1:n.line){ tmp.word <- sample(2:n.cols,1) tmp[j,1:tmp.word] <- sample(names,tmp.word) } infile.list[[i]] <- tmp } g <- graph.empty(directed = FALSE) g.plus <- graph.empty(directed = FALSE) v.list <- list() v.plus.list <- list() e.list <- list() e.plus.list <- list() for(i in 1:length(infile.list)){ infile <- infile.list[[i]] # 行列の方が好きなので行列にする infile.m <- as.matrix(infile) # エッジに関係するところだけを取り出す #infile.m <- infile.m[,1:length(infile.m[1,])] # ノードをユニークにする unique.word <- unique(c(infile.m)) unique.word <- unique.word[which(unique.word != "")] # ノードの名前に順序idをつける v.list[[i]] <- NULL v.list[[i]] <- unique.word e.list[[i]] <- matrix(0,0,2) v.plus.list[[i]] <- unique.word e.plus.list[[i]] <- matrix(0,0,2) #g <- g + vertices(v.name) # 行ごとに要素数を数えて for(j in 1:length(infile.m[,1])){ num.kids <- length(which(infile.m[j,] != ""))-1 if(num.kids>=1){ for(k in 1:num.kids){ #g <- g + edges(c(infile.m[i,1],infile.m[i,j+1])) e.list[[i]] <- rbind(e.list[[i]],c(infile.m[j,1],infile.m[j,k+1])) } } } sorted.e.list <- t(apply(e.list[[i]],1,sort)) tmp.v <- paste(sorted.e.list[,1],sorted.e.list[,2],sep="") v.plus.list[[i]] <- c(unique.word,infiles[i],tmp.v) v.plus.list[[i]] <- unique(v.plus.list[[i]]) #e.plus.list[[i]] <- e.list[[i]] for(j in 1:length(e.list[[i]][,1])){ e.plus.list[[i]] <- rbind(e.plus.list[[i]],c(e.list[[i]][j,1],tmp.v[j])) e.plus.list[[i]] <- rbind(e.plus.list[[i]],c(e.list[[i]][j,2],tmp.v[j])) e.plus.list[[i]] <- rbind(e.plus.list[[i]],c(tmp.v[j],infiles[i])) } #plot(g,vertex.label=V(g)$name) } unique.v <- unique(unlist(v.list)) unique.plus.v <- unique(unlist(v.plus.list)) g <- graph.empty(directed=FALSE) + vertices(unique.v) g.plus <- graph.empty(directed=FALSE) + vertices(unique.plus.v) for(i in 1:length(infile.list)){ for(j in 1:length(e.list[[i]][,1])){ g <- g + edges(e.list[[i]][j,]) } for(j in 1:length(e.plus.list[[i]][,1])){ g.plus <- g.plus + edges(e.plus.list[[i]][j,]) } } #plot(g,vertex.label=V(g)$name,vertex.size=3,edge.arrow.mode=0) #dev.new() #plot(g.plus,vertex.label=V(g.plus)$name,vertex.size=3,edge.arrow.mode=0) # 全ノードの最短距離は求めておく sh.paths.mat <- shortest.paths(g.plus) # その上で、 show.neighbors <- function(g,vs,L=1){ tmp <- (sh.paths.mat[vs,] <= L) if(length(vs)>1){ neighbors <- sign(apply(tmp,2,sum)) }else{ neighbors <- sign(tmp) } tmp.g <- induced.subgraph(g,which(neighbors==1)) plot(tmp.g,vertex.label=V(tmp.g)$name,vertex.size=3,edge.arrow.mode=0) } # グラフ全体g.plusにおいてある点と距離1以内にあるノードで構成されたサブグラフを表示する show.neighbors(g.plus,V(g.plus)$name[10],L=1) # 複数ノードを指定して、そのノード集合からの距離が指定距離以内のノードで構成されたサブグラフを表示する show.neighbors.series <- function(g.plus,vs,Ls=0:4){ par(ask=TRUE) for(i in Ls){ show.neighbors(g.plus,vs,L=i) } par(ask=FALSE) } # 2ノードを指定して、その最短パスのノード列を列挙し、 two <- c(V(g.plus)$name[10],V(g.plus)$name[100]) sh.paths <- get.shortest.paths(g.plus,two[1],two[2]) # そのパスのノードをノード集合として、近隣ノードのサブグラフを表示する show.neighbors.series(g.plus,unlist(sh.paths),Ls=0:3)