Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
TokyoR#98_TextAnalysis
kilometer
April 16, 2022
Technology
0
270
TokyoR#98_TextAnalysis
第98回Tokyo.Rで発表したテキスト分析に関する内容です。
kilometer
April 16, 2022
Tweet
Share
More Decks by kilometer
See All by kilometer
TokyoR#99_Divergence
kilometer
1
100
Tokyo.R #97 Data Visualization
kilometer
1
140
Tokyo.R #96 theory of probability
kilometer
4
2.1k
Bayesian statistics Tokyo.R#94
kilometer
5
2k
統計関連学会連合大会チュートリアル資料
kilometer
5
2.5k
Tokyo.R#93 Data processing
kilometer
2
390
Tokyo.R#91 Regression Analysis
kilometer
3
550
90thTokyo.R
kilometer
4
960
Tokyo.R#89 Data visualization
kilometer
1
410
Other Decks in Technology
See All in Technology
データエンジニアと作るデータ文化
yuki_saito
4
1.1k
Build 2022で発表されたWindowsアプリ開発のあれこれ振り返ろう
hatsunea
1
360
ひとりでも安定して 組織を変える活動を続けていくための ストレスマネジメント
pastelinc
0
760
Camp Digital 2022: tailored advice
kyliehavelock
0
130
Building smarter apps with machine learning, from magic to reality
picardparis
4
3.2k
出張スクラムマスターとしての FEARLESS CHANGE な生き方
naitosatoshi
1
1.2k
1人目SETとして入社して2ヶ月の間におこなったこと
tarappo
3
400
2022年度新卒技術研修「エンジニアマインド」講義
excitejp
PRO
0
330
Implementing Kubernetes operators in Java with Micronaut - TechWeek Java Summit 2022
alvarosanchez
0
110
Scrum Fest Osaka 2022 段階的スクラムマスターのススメ
orimomo
0
680
組織の崩壊と再生、その中で何を考え、感じたのか。 そして本当に必要だったもの
kosako
0
960
FoodTechにおける商流・金流・物流の進化/Evolution of Commercial, Financial, and Logistics in FoodTech
dskst
0
370
Featured
See All Featured
Building Applications with DynamoDB
mza
83
4.7k
Practical Orchestrator
shlominoach
178
8.6k
Docker and Python
trallard
27
1.6k
Navigating Team Friction
lara
175
11k
The Invisible Side of Design
smashingmag
290
48k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
212
20k
Agile that works and the tools we love
rasmusluckow
319
19k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
237
19k
Thoughts on Productivity
jonyablonski
43
2.3k
Mobile First: as difficult as doing things right
swwweet
213
7.5k
Imperfection Machines: The Place of Print at Facebook
scottboms
253
12k
Testing 201, or: Great Expectations
jmmastey
21
5.4k
Transcript
#98 @kilometer00 2022.04.16 Text Analysis
Who!? 誰だ?
Who!? 名前: 三村 @kilometer 職業: ポスドク (こうがくはくし) 専⾨: ⾏動神経科学(霊⻑類) 脳イメージング
医療システム⼯学 R歴: ~ 10年ぐらい 流⾏: だんごむし
None
宣伝!! (書籍の翻訳に参加しました。)
* Tokyo.R 運営チーム 情報の科学と技術 70巻4号, pp.181-186, 2020 1. はじめに 2.
Rの基礎知識 2.1. Rとは 2.2. RとRStudioのインストール 2.3. 基本的操作 2.4. パッケージについて 2.5. tidyverseについて 2.6. ⽇本語エンコード 3. テキスト・マイニング 3.1. 形態素解析 3.2. RMeCabのセットアップ 3.3. サンプルデータの準備 4. 単語の出現頻度 4.1. バッグ・オブ・ワーズ 4.2. ワードクラウド 5. 2-グラム・モデル 5.1. 共起ネットワークグラフ 6. 確率的⾔語モデル 6.1. トピックモデル 6.2. LDA実⾏例 7. おわりに
RMeCab package installation on Mac brew install mecab brew install
mecab-ipadic brew upgrade brew update brew doctor install.packages("RMeCab", repos = "http://rmecab.jp/R") 1. Homebrew – maintenance 2. Homebrew – install Mecab & its dictionary (IPA) 3. R – install RMeCab package
RMeCab package installation on Mac RMeCab::RMeCabC("すもももももももものうち") 4. Demonstration – RMeCab
package [[1]] 名詞 "すもも" [[2]] 助詞 "も" [[3]] 名詞 "もも" ...
RMeCab package installation on Mac RMeCab::RMeCabC("すもももももももものうち") %>% unlist() 名詞 助詞
名詞 助詞 "すもも" "も" "もも" "も" 名詞 助詞 名詞 "もも" "の" "うち" 4. Demonstration – RMeCab package
⾛れメロス 太宰治 メロスは激怒した。必ず、かの邪智暴虐の王を除かなければならぬと決意した。メロスには政治がわからぬ。メロスは、村の牧⼈である。 笛を吹き、⽺と遊んで暮して来た。けれども邪悪に対しては、⼈⼀倍に敏感であった。きょう未明メロスは村を出発し、野を越え⼭越え、 ⼗⾥はなれた此のシラクスの市にやって来た。メロスには⽗も、⺟も無い。⼥房も無い。⼗六の、内気な妹と⼆⼈暮しだ。この妹は、村の 或る律気な⼀牧⼈を、近々、花婿として迎える事になっていた。結婚式も間近かなのである。メロスは、それゆえ、花嫁の⾐裳やら祝宴の 御馳⾛やらを買いに、はるばる市にやって来たのだ。先ず、その品々を買い集め、それから都の⼤路をぶらぶら歩いた。メロスには⽵⾺の 友があった。セリヌンティウスである。今は此のシラクスの市で、⽯⼯をしている。その友を、これから訪ねてみるつもりなのだ。久しく 逢わなかったのだから、訪ねて⾏くのが楽しみである。歩いているうちにメロスは、まちの様⼦を怪しく思った。ひっそりしている。もう 既に⽇も落ちて、まちの暗いのは当りまえだが、けれども、なんだか、夜のせいばかりでは無く、市全体が、やけに寂しい。のんきなメロ
スも、だんだん不安になって来た。路で逢った若い衆をつかまえて、何かあったのか、⼆年まえに此の市に来たときは、夜でも皆が歌をう たって、まちは賑やかであった筈だが、と質問した。若い衆は、⾸を振って答えなかった。しばらく歩いて⽼爺に逢い、こんどはもっと、 語勢を強くして質問した。⽼爺は答えなかった。メロスは両⼿で⽼爺のからだをゆすぶって質問を重ねた。⽼爺は、あたりをはばかる低声 で、わずか答えた。 「王様は、⼈を殺します。」 「なぜ殺すのだ。」 「悪⼼を抱いている、というのですが、誰もそんな、悪⼼を持っては居りませぬ。」 「たくさんの⼈を殺したのか。」 「はい、はじめは王様の妹婿さまを。それから、御⾃⾝のお世嗣を。それから、妹さまを。それから、妹さまの御⼦さまを。それから、皇 后さまを。それから、賢⾂のアレキス様を。」 「おどろいた。国王は乱⼼か。」 「いいえ、乱⼼ではございませぬ。⼈を、信ずる事が出来ぬ、というのです。このごろは、⾂下の⼼をも、お疑いになり、少しく派⼿な暮 しをしている者には、⼈質ひとりずつ差し出すことを命じて居ります。御命令を拒めば⼗字架にかけられて、殺されます。きょうは、六⼈ 殺されました。」 聞いて、メロスは激怒した。「呆れた王だ。⽣かして置けぬ。」 メロスは、単純な男であった。買い物を、背負ったままで、のそのそ王城にはいって⾏った。たちまち彼は、巡邏の警吏に捕縛された。 調べられて、メロスの懐中からは短剣が出て来たので、騒ぎが⼤きくなってしまった。メロスは、王の前に引き出された。 「この短⼑で何をするつもりであったか。⾔え!」暴君ディオニスは静かに、けれども威厳を以て問いつめた。その王の顔は蒼⽩で、眉間 の皺は、刻み込まれたように深かった。 「市を暴君の⼿から救うのだ。」とメロスは悪びれずに答えた。 「おまえがか?」王は、憫笑した。「仕⽅の無いやつじゃ。おまえには、わしの孤独がわからぬ。」 「⾔うな!」とメロスは、いきり⽴って反駁した。「⼈の⼼を疑うのは、最も恥ずべき悪徳だ。王は、⺠の忠誠をさえ疑って居られる。」 「疑うのが、正当の⼼構えなのだと、わしに教えてくれたのは、おまえたちだ。⼈の⼼は、あてにならない。⼈間は、もともと私慾のかた まりさ。信じては、ならぬ。」暴君は落着いて呟き、ほっと溜息をついた。「わしだって、平和を望んでいるのだが。」 「なんの為の平和だ。⾃分の地位を守る為か。」こんどはメロスが嘲笑した。「罪の無い⼈を殺して、何が平和だ。」 電⼦付録 (1) 太宰治作『⾛れメロス』テキストデータサンプル
dat <- read.table(file = "data/melos.txt", fileEncoding = "shift-jis", header =
FALSE, stringsAsFactors = FALSE)) ⽇本語データの読み込み
dat <- read.table(file = "data/melos.txt", fileEncoding = "shift-jis", header =
FALSE, stringsAsFactors = FALSE)) ⽇本語データの読み込み エンコーディング UTF-8 Shift-JIS JIS X 0208 Unicode Character Windows Mac, Linux ⽂字 ⽂字コード
dat <- read.table(file = "data/melos.txt", fileEncoding = "shift-jis", header =
FALSE, stringsAsFactors = FALSE)) ⽇本語データの読み込み > dat %>% as_tibble() # A tibble: 77 x 1 V1 <chr> 1 ⾛れメロス 2 太宰治 3 メロスは激怒した。必ず、かの邪智暴虐の王を除かな… 4 「王様は、⼈を殺します。」 5 「なぜ殺すのだ。」
Text Data Intention Event decode encode feedback
データ 情報のうち意思伝達・解釈・処理に 適した再利⽤可能なもの 国際電気標準会議(International Electrotechnical Commission, IEC)による定義
データ 情報のうち意思伝達・解釈・処理に 適した再利⽤可能なもの 情報 実存を符号化した表象
データ 情報のうち意思伝達・解釈・処理に 適した再利⽤可能なもの 情報 実存を符号化した表象 実存 観察の有無によらず存在している ものそのもの 写像(符号化)
写像 (mapping) !: # → % # % ある情報の集合の要素を、別の情報の集合の ただ1つの要素に対応づけるプロセス
写像 リンゴ (実存) リンゴ (情報) mapping
情報量 実存 情報 データ リンゴ = 1 符号化
情報量 実存 情報 データ リンゴ = 1 符号化 情報量の損失
Text = Data Statistical modeling Intention Event decode encode feedback
Computational estimation =
形態素解析 すもももももももものうち すもも/も/もも/も/もも/の/うち 名詞 助詞 名詞 助詞 名詞 助詞 名詞
MeCab 意味を担う最⼩の単位
雑談:どちらかというと「すもものうち」 スモモ モモ スモモ属 スモモ亜属 スモモ亜属 Shi et al., Journal
of Integrative Plant Biology, 55(11), 2013
mecab_result <- dat %>% # tibbleには変換せずdata.frameのまま使う RMeCab::RMeCabDF() > dat[9,1] [1]
"「おどろいた。国王は乱⼼か。」" > mecab_result[[9]] 記号 動詞 助動詞 記号 "「" "おどろい" "た" "。" 名詞 助詞 名詞 助詞 "国王" "は" "乱⼼" "か" 記号 記号 "。" "」" 形態素解析
mecab_result[[9]] %>% data.frame(term = ., class = names(.)) term class
1 「 記号 2 おどろい 動詞 3 た 助動詞 4 。 記号 5 国王 名詞 6 は 助詞 7 乱⼼ 名詞 8 か 助詞 9 。 記号 10 」 記号 データの整形
dat <- mecab_result %>% purrr::map_dfr( ~ data.frame( term = .,
class = names(.)) ) %>% tidyr::as_tibble() データの整形 # A tibble: 6,432 x 2 term class <chr> <chr> 1 ⾛れ 動詞 2 メロス 名詞 3 太宰 名詞
dat %>% write.csv( file = "data/melos_words.csv", row.names = FALSE )
データの出⼒ ! !data melos_words.csv melos.txt tokyor98.Rproj ! tokyor98
確率的⾔語モデル ! 語彙 「/おどろい/た/。/国王/は/乱⼼/か/。/」 ... 確率 単語i 単語j 単語k ...
... 確率分布 サンプリング
Text = Data Intention Event decode encode feedback ! "#
Estimation
! " 芥川⿓之介 太宰治
お伽草紙(作品ID:307) ⼈間失格(作品ID:301) 斜陽(作品ID:1565) 津軽(作品ID:2282) ⾛れメロス(作品ID:1567) 芥川⿓之介 太宰治 ! " 単語
155,333単語 233,063単語 ⻘空⽂庫:https://www.aozora.gr.jp/index.html 蜘蛛の⽷(作品ID:92) 猿(作品ID:139) ⻭⾞(作品ID:42377) 地獄変(作品ID:60) ⿐(作品ID:42) 侏儒の⾔葉(作品ID:43751) 着物(作品ID:1137) 煙草と悪魔(作品ID:163) 神神の微笑(作品ID:68) ⻄⽅の⼈(作品ID:141) 邪宗⾨(作品ID:59) 酒⾍(作品ID:161) ⽑利先⽣(作品ID:101) 戯作三昧(作品ID:37) 仙⼈(作品ID:143) 杜⼦春(作品ID:170) Mensura Zoili(作品ID:97)
お伽草紙(作品ID:307) ⼈間失格(作品ID:301) 斜陽(作品ID:1565) 津軽(作品ID:2282) ⾛れメロス(作品ID:1567) 芥川⿓之介 太宰治 ! " 形容詞
2,219単語 4,704単語 ⻘空⽂庫:https://www.aozora.gr.jp/index.html 蜘蛛の⽷(作品ID:92) 猿(作品ID:139) ⻭⾞(作品ID:42377) 地獄変(作品ID:60) ⿐(作品ID:42) 侏儒の⾔葉(作品ID:43751) 着物(作品ID:1137) 煙草と悪魔(作品ID:163) 神神の微笑(作品ID:68) ⻄⽅の⼈(作品ID:141) 邪宗⾨(作品ID:59) 酒⾍(作品ID:161) ⽑利先⽣(作品ID:101) 戯作三昧(作品ID:37) 仙⼈(作品ID:143) 杜⼦春(作品ID:170) Mensura Zoili(作品ID:97)
dat_AD %>% dplyr::filter(class == "形容詞") %>% dplyr::select(term) %>% table() %>%
wordcloud::wordcloud( words = names(.), freq = ., min.freq = 5, family = "Hiragino Mincho Pro W6” ) ワードクラウドの描画
! " 芥川⿓之介 太宰治
確率的⾔語モデル ! 語彙 「/おどろい/た/。/国王/は/乱⼼/か/。/」 ... 確率 単語i 単語j 単語k ...
... 確率分布 互いに独⽴にサンプリング “Bag-of-words” モデル
形態素解析 うらにわにはにわとりがいる うらにわ/には/にわとり/が/いる うらにわ/には/に/わ/とり/が/いる うら/に/わに/は/にわとり/が/いる ?
形態素解析 うらにわにはにわとりがいる うらにわ/には/にわとり/が/いる うらにわ/には/に/わ/とり/が/いる うら/に/わに/は/にわとり/が/いる ? > RMeCabC("うらにわにはにわとりがいる") %>% +
unlist() 動詞 助詞 名詞 助詞 名詞 助詞 動詞 "うら" "に" "わに" "は" "にわとり” "が" "いる"
形態素解析 うらにわにはにわとりがいる うらにわ/には/にわとり/が/いる うらにわ/には/に/わ/とり/が/いる うら/に/わに/は/にわとり/が/いる ? Bi-gram モデル = 単語の出現確率は直前の単語に依存する
.class <- c("名詞", "形容詞", "動詞") dat_bigram <- dat %>% dplyr::filter(class
%in% .class) %>% dplyr::rename(pre = term) %>% dplyr::mutate(post = lead(pre)) %>% dplyr::select(pre, post) %>% dplyr::filter(!is.na(post)) > dat_bigram # A tibble: 2,676 x 2 pre post <chr> <chr> 1 ⾛れ メロス 2 メロス 太宰 3 太宰 治 4 治 メロス Bi-gram モデル
.word <- c("メロス", "王", "妹", "セリヌンティウス") .font <- "Hiragino Mincho
Pro W6" dat_bigram %>% dplyr::filter(pre %in% .word) %>% igraph::graph.data.frame() %>% plot(vertex.color = "white", vertex.label.family = .font) Bi-gram モデル
Bi-gram モデル ! ! ! ! 共起ネットワークグラフ
Text = Data Intention Event decode encode feedback ! "#
Estimation
! " # 確率 単 語 i 単 語 j
単 語 k 確率分布 確率 単 語 i 単 語 j 単 語 k 確率分布 確率 単 語 i 単 語 j 単 語 k 確率分布 確率的⾔語モデル:トピック推定 Estimation
潜在ディリクレ配分法 Latent Dirichlet Allocation (LDA) ! " # $ %
& ⽂ごと 単語ごと トピックごと Farhadloo & Rolland, Sentiment Analysis and Ontology Engineering, pp.1-24, Springer, 2013 確率 i j k Topicごとの単語頻度分布 (Dirichlet分布) Word ! 1 2 3 ⽂章dのTopicに対する 帰属確率分布(Dirichlet分布) Topic " Dirichlet分布 パラメータ Dirichlet分布 パラメータ どのTopicに分類されそう? 観察された単語 Topicごとの特徴は? Topicの分布 潜在Topic (多項分布) 単語の頻度分布
お伽草紙(作品ID:307) ⼈間失格(作品ID:301) 斜陽(作品ID:1565) 津軽(作品ID:2282) ⾛れメロス(作品ID:1567) 芥川⿓之介 太宰治 ! " 単語
155,333単語 233,063単語 ⻘空⽂庫:https://www.aozora.gr.jp/index.html データ 蜘蛛の⽷(作品ID:92) 猿(作品ID:139) ⻭⾞(作品ID:42377) 地獄変(作品ID:60) ⿐(作品ID:42) 侏儒の⾔葉(作品ID:43751) 着物(作品ID:1137) 煙草と悪魔(作品ID:163) 神神の微笑(作品ID:68) ⻄⽅の⼈(作品ID:141) 邪宗⾨(作品ID:59) 酒⾍(作品ID:161) ⽑利先⽣(作品ID:101) 戯作三昧(作品ID:37) 仙⼈(作品ID:143) 杜⼦春(作品ID:170) Mensura Zoili(作品ID:97)
蜘蛛の⽷(作品ID:92) 猿(作品ID:139) ⻭⾞(作品ID:42377) 地獄変(作品ID:60) ⿐(作品ID:42) 侏儒の⾔葉(作品ID:43751) 着物(作品ID:1137) 煙草と悪魔(作品ID:163) 神神の微笑(作品ID:68) ⻄⽅の⼈(作品ID:141)
邪宗⾨(作品ID:59) 酒⾍(作品ID:161) ⽑利先⽣(作品ID:101) 戯作三昧(作品ID:37) 仙⼈(作品ID:143) 杜⼦春(作品ID:170) Mensura Zoili(作品ID:97) お伽草紙(作品ID:307) ⼈間失格(作品ID:301) 斜陽(作品ID:1565) 津軽(作品ID:2282) ⾛れメロス(作品ID:1567) 芥川⿓之介 太宰治 ! " 動詞, 形容詞, 名詞 66,065単語 97,664単語 ⻘空⽂庫:https://www.aozora.gr.jp/index.html データ
> dat_AD %>% + filter(class %in% c("名詞", "形容詞", "動詞")) #
A tibble: 163,729 x 5 title author term class paragraph <chr> <chr> <chr> <chr> <int> 1 MENSURAZOILI 芥川⿓之介 僕 名詞 1 2 MENSURAZOILI 芥川⿓之介 船 名詞 1 3 MENSURAZOILI 芥川⿓之介 サルーン 名詞 1 4 MENSURAZOILI 芥川⿓之介 まん中 名詞 1 5 MENSURAZOILI 芥川⿓之介 テーブル 名詞 1 6 MENSURAZOILI 芥川⿓之介 へだて 動詞 1 7 MENSURAZOILI 芥川⿓之介 妙 名詞 1 8 MENSURAZOILI 芥川⿓之介 男 名詞 1 9 MENSURAZOILI 芥川⿓之介 向い 動詞 1 10 MENSURAZOILI 芥川⿓之介 あっ 動詞 1 # … with 163,719 more rows データ
dat_for_LDA <- dat_AD %>% dplyr::select(-paragraph) %>% dplyr::filter(class %in% .class) %>%
dplyr::unite(col = term, c(term, class)) %>% dplyr::group_by(author, title, term) %>% dplyr::mutate(wordCount = n()) %>% dplyr::distinct() %>% tidyr::pivot_wider( values_from = wordCount, values_fill = 0, names_from = term ) 前処理
> dat_for_LDA # A tibble: 22 x 19,578 # Groups:
author, title [22] title author 僕_名詞 船_名詞 サルーン_名詞 まん <chr> <chr> <int> <int> <int> 1 MENS… 芥川⿓之介… 17 8 5 2 煙草と悪… 芥川⿓之介… 0 1 0 3 猿 芥川⿓之介… 1 0 0 4 戯作三昧… 芥川⿓之介… 0 0 0 5 ⻭⾞ 芥川⿓之介… 493 3 0 6 邪宗⾨… 芥川⿓之介… 0 0 0 7 酒⾍ 芥川⿓之介… 0 0 0 8 神神の微… 芥川⿓之介… 0 2 0 9 ⻄⽅の⼈… 芥川⿓之介… 0 0 0 10 仙⼈ 芥川⿓之介… 0 0 0 # … with 12 more rows, and 19,572 more variables: 前処理
result <- dat_for_LDA %>% dplyr::ungroup() %>% dplyr::select(!c(title, author)) %>% topicmodels::LDA(k
= 5, control = list(seed = 0)) LDAの実⾏ dat_topics <- result %>% topicmodels::topics() %>% dplyr::bind_cols( dat_for_LDA %>% dplyr::select(title, author), topic = .) %>% dplyr::arrange(topic, author) 22作品(芥川17, 太宰5)を5つのトピックに分類 作品ごとに割り当てられたトピックを整形
LDAの実⾏結果 ⾛れメロス 斜陽 ⼈間失格 お伽草紙 津軽 Mensura Zoili, 煙草と悪魔 戯作三昧,
⻭⾞, 神神の微笑 ⻄⽅の⼈, 仙⼈, 蜘蛛の⽷ ⽑利先⽣, 侏儒の⾔葉 猿, 酒⾍, 地獄変, ⿐ 着物, 杜⼦春 邪宗⾨ 芥川⿓之介 太宰治 Topic 1 2 3 4 5
Text = Data Intention Event decode encode feedback ! "#
Estimation
Enjoy!!