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
watsonx.ai Dojo #5 ファインチューニングとInstructLAB
oniak3ibm
PRO
0
160
マルチプロダクト開発の現場でAWS Security Hubを1年以上運用して得た教訓
muziyoshiz
2
2.2k
TSKaigi 2024 の登壇から広がったコミュニティ活動について
tsukuha
0
160
Amazon VPC Lattice 最新アップデート紹介 - PrivateLink も似たようなアップデートあったけど違いとは
bigmuramura
0
190
非機能品質を作り込むための実践アーキテクチャ
knih
3
950
権威ドキュメントで振り返る2024 #年忘れセキュリティ2024
hirotomotaguchi
2
730
サーバレスアプリ開発者向けアップデートをキャッチアップしてきた #AWSreInvent #regrowth_fuk
drumnistnakano
0
190
LINEスキマニにおけるフロントエンド開発
lycorptech_jp
PRO
0
330
小学3年生夏休みの自由研究「夏休みに Copilot で遊んでみた」
taichinakamura
0
150
KnowledgeBaseDocuments APIでベクトルインデックス管理を自動化する
iidaxs
1
260
アップデート紹介:AWS Data Transfer Terminal
stknohg
PRO
0
180
フロントエンド設計にモブ設計を導入してみた / 20241212_cloudsign_TechFrontMeetup
bengo4com
0
1.9k
Featured
See All Featured
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
38
1.9k
Done Done
chrislema
181
16k
Designing Experiences People Love
moore
138
23k
Raft: Consensus for Rubyists
vanstee
137
6.7k
Navigating Team Friction
lara
183
15k
Rails Girls Zürich Keynote
gr2m
94
13k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
28
9.1k
Thoughts on Productivity
jonyablonski
67
4.4k
Visualization
eitanlees
146
15k
Put a Button on it: Removing Barriers to Going Fast.
kastner
59
3.6k
Building Flexible Design Systems
yeseniaperezcruz
327
38k
4 Signs Your Business is Dying
shpigford
181
21k
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!!