Redditの Web API をRから操作していろいろなデータを抽出して遊ぶ。
Redditで遊ぼうTokyo.R #1062023/06/10@bob3bob3
View Slide
RedditとはWikipediaによると……● Reddit(レディット)はアメリカ合衆国の掲示板型ソーシャルニュースサイト。● 主に英語圏のユーザーを対象とする。● ニュース記事、画像のリンクやテキストを投稿し、コメントをつけることが可能。● 2021年1月時点の月間利用者数は 4億3000万人。欧米ではTwitterユーザー数並び利用時間を超える。
ブッコ抜く!RedditExtractoRパッケージを使うとRedditの公式APIからいろいろなデータが取得できます。自然言語処理やネットワーク分析の勉強など、いろいろ遊べるリアルなデータが手に入る。Twitterのデータが取れなくなってガッカリしている方々もぜひ。主な関数は以下。● find_subreddits(): キーワードでsubreddit(板)を検索する。● find_thread_urls(): 特定のsubredditからthread(スレ)のURLを抽出する。● get_thread_content(): threadの詳細情報を抽出する。● get_user_content(): ユーザーの詳細情報を抽出する。
Rのスレを抽出する find_thread_urls()library(conflicted)library(tidyverse)library(RedditExtractoR)thread_URLs <- find_thread_urls(sort_by = "top",subreddit = "rstats",period = "month") |>drop_na() |>as_tibble()RのsubredditのURLはhttps://www.reddit.com/r/rstats/ 。● find_thread_urls()を使って指定した板(subreddit)から各スレのURLを抽出します。● URLの赤文字の部分でsubredditを指定する。● ソート方法はhot、new、top、rising。● periodは期間の指定でhour、day、week、month、year、all。● キーワードの設定もできます。● なぜか空行が1行入るので最後にdrop_na()する。● 最後は個人的な好みで tibbleにしてます。● 取得の上限は1,000件です。
Rのスレを抽出する find_thread_urls()
各スレの詳細情報を取得する get_thread_contets()先ほど取得したスレッドのリストの URLの情報を使って、各スレの詳細情報を取得する。1件あたり2秒ぐらいかかるので 100件ぐらいだと3分ちょっとかかる。取得した情報にはスレそのものの詳細情報と、スレについたコメントの情報が含まれるのでそれぞれを取り出しておく。thread_contents <- thread_URLs |>pull(url) |>get_thread_content()# 各スレの詳細情報threads_info <- thread_contents |>pluck("threads")# 各スレについたコメントの情報comments_info <- thread_contents |>pluck("comments")
スレッドの詳細情報
スレのコメント
スコアの高いスレ#scoreの高いスレthreads_top10 <- threads_info |>slice_max(score, n=10) |>select(author, title, score, url)"マイクロソフトはCRAN Time Machineの保守を終了しました"
スコアの高いコメント#scoreの高いコメントcomments_top10 <- comments_info |>slice_max(score, n=10) |>select(author, score, comment, url)"人々がつまづくのを見るので、これについての重要な注意:!!はtidyverseの関数呼び出しで*だけ*動作します。それは*全体的なR言語の機能ではありません *。"
ネットワークにしてみる「誰が立てたスレッドに誰がコメントしたか?」という視点でネットワークにしてみる。● URLをキーにスレの情報とコメントの情報をjoin。● 削除されたアカウントは取り除く● スレを立てた場合とコメントした場合でノードを分けたいので、スレを立てた場合はアカウント名の後に「_poster」を付ける。edges_raw <- threads_info |>select(url, author) |>left_join(comments_info |> select(url, author),by = "url",suffix = c(".thread", ".comment"),) |>select(!url) |>drop_na() |>dplyr::filter(author.thread != "[deleted]"| author.comment != "[deleted]") |>mutate(author.thread = paste0(author.thread, "_poster"))
ノードのリストを作るノードのリストを作る● せっかくなので各ノードの次数も igraphで計算しておく。# ノードごとの次数を計算library(igraph)dgr <- edges_raw |>graph_from_data_frame() |>degree()# ノードのリストを作るnodes <- edges_raw |>select(author.thread) |>distinct() |>mutate(type = "poster") |>rename(id = author.thread) |>bind_rows(bi_graph |>select(author.comment) |>distinct() |>mutate(type = "commenter") |>rename(id = author.comment)) |>left_join(tibble(id = dgr |> names(),dgr = dgr),by = "id")
エッジのリストを作るスレ主とコメント主でグループ化し件数をカウント。後でCytoscapeに読み込ませたいので、列名をスレ主はtarget、コメント主はsourceに変更。# あとでCytoscapeに読ませる関係で# 列名をsourceとtargetに変更edges <- edges_raw |>summarise(freq = n(),.by = c(author.thread, author.comment)) |>rename(source = author.comment,target = author.thread)
Cytoscapeで描画ネットワーク図の描画は Cytoscapeが圧倒的に優れている。● Rcy3パッケージでRからCytoscapeを操作できる。Rcy3はCRANではなくBioconductorからインストールする。● 事前にCytoscapeをインストールし、Cytoscape内でCyRESTをインストールしておく。● また、createNetworkFromDataFrames()を実行する前にCytoscapeを立ち上げておく。# install.packages("BiocManager")# BiocManager::install("RCy3")library(RCy3)createNetworkFromDataFrames(nodes,edges,title="rstats network",collection="Reddit Network")
Cytoscapeで描画見栄えはCytoscapeでいじってます。赤がスレ主。
Enjoy!