Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
TokyoR#98_TextAnalysis
Search
kilometer
April 16, 2022
Technology
0
570
TokyoR#98_TextAnalysis
第98回Tokyo.Rで発表したテキスト分析に関する内容です。
kilometer
April 16, 2022
Tweet
Share
More Decks by kilometer
See All by kilometer
TokyoR#111_ANOVA
kilometer
2
850
TokyoR109.pdf
kilometer
1
450
TokyoR#108_NestedDataHandling
kilometer
0
760
TokyoR#107_R_GeoData
kilometer
0
400
SappoRo.R_roundrobin
kilometer
0
130
TokyoR#104_DataProcessing
kilometer
1
670
TokyoR#103_DataProcessing
kilometer
0
860
TokyoR#102_RMarkdown
kilometer
1
620
TokyoR#101_RegressionAnalysis
kilometer
0
360
Other Decks in Technology
See All in Technology
オプトインカメラ:UWB測位を応用したオプトイン型のカメラ計測
matthewlujp
0
180
WACATE2024冬セッション資料(ユーザビリティ)
scarletplover
0
210
マイクロサービスにおける容易なトランザクション管理に向けて
scalar
0
130
Storage Browser for Amazon S3
miu_crescent
1
190
コンテナセキュリティのためのLandlock入門
nullpo_head
2
320
サーバレスアプリ開発者向けアップデートをキャッチアップしてきた #AWSreInvent #regrowth_fuk
drumnistnakano
0
200
Amazon Kendra GenAI Index 登場でどう変わる? 評価から学ぶ最適なRAG構成
naoki_0531
0
110
組織に自動テストを書く文化を根付かせる戦略(2024冬版) / Building Automated Test Culture 2024 Winter Edition
twada
PRO
16
4.3k
Amazon SageMaker Unified Studio(Preview)、Lakehouse と Amazon S3 Tables
ishikawa_satoru
0
160
.NET 9 のパフォーマンス改善
nenonaninu
0
970
kargoの魅力について伝える
magisystem0408
0
210
UI State設計とテスト方針
rmakiyama
2
600
Featured
See All Featured
For a Future-Friendly Web
brad_frost
175
9.4k
A better future with KSS
kneath
238
17k
Raft: Consensus for Rubyists
vanstee
137
6.7k
What's in a price? How to price your products and services
michaelherold
243
12k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
26
1.5k
Fireside Chat
paigeccino
34
3.1k
The Cult of Friendly URLs
andyhume
78
6.1k
The Pragmatic Product Professional
lauravandoore
32
6.3k
Large-scale JavaScript Application Architecture
addyosmani
510
110k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
127
18k
How STYLIGHT went responsive
nonsquared
95
5.2k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
28
4.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!!