knitr::opts_chunk$set(collapse = FALSE, comment = "##")

本ページはQuick Start Guideの日本語訳であり,英語のテキスト分析を通じてquantedaの基本的な使い方を説明する.日本語の分析法に関しては,以下のページを参照.

パッケージのインストール {#installing-the-package}

quantedaCRANからインストールできる.GUIのRパッケージインストーラを使用してインストールするか,次のコマンドを実行する.

install.packages("quanteda")

GitHubから最新の開発バージョンをインストールする方法については,https://github.com/quanteda/quanteda を参照.

インストールが推奨されるパッケージ {#additional-recommended-packages}

quantedaには連携して機能を拡張する一連のパッケージがあり,それらをインストールすることが推奨される.

コーパスの作成 {#creating-a-corpus}

まず,quantedaを読み込んで,パッケージの関数とデータにアクセスできるようにする.

library(quanteda)

利用可能なコーパス {#currently-available-corpus-sources}

quantedaにはテキストを読み込むためのシンプルで強力なパッケージ,readtextがあります.このパッケージのreadtext()は,ローカス・ストレージやインターネットからファイル読み込み,corpus()にデータ・フレームを返す.

readtext()で利用可能なファイルやデータの形式:

quantedaのコーパスを生成する関数である corpus()は,以下の種類のデータを読み込むことができる.

文字列からコーパスを作成 {#building-a-corpus-from-a-character-vector}

コーパスを作成する最も簡単な方法は,corpus()を用いて,すでにRに読み込まれた文字列ベクトル作成することである.文字列ベクトルをRに取り込む方法はさまざまなので,高度なRユーザーは,コーパスをいろいろな方法で作り出せる.

次の例では,quantedaパッケージに含まれているイギリスの政党が2010年の総選挙のために発行したマニフェストのテキストデータ(data_char_ukimmig2010)からコーパスを作成している.

corp_uk <- corpus(data_char_ukimmig2010)  # テキストからコーパスを作成
summary(corp_uk)

コーパスを作成したあとでも,docvarsを用いると,必要に応じて文書に対応した変数をこのコーパスに追加することができる.

たとえば,Rのnames()関数を使って文字ベクトル(data_char_ukimmig2010)の名前を取得し,これを文書変数(docvar())に追加することができる.

docvars(corp_uk, "Party") <- names(data_char_ukimmig2010)
docvars(corp_uk, "Year") <- 2010
summary(corp_uk)

readtextパッケージを用いたファイルの読み込み {#loading-in-files-using-the-readtext-package}

require(readtext)

# Twitter json
dat_json <- readtext("~/Dropbox/QUANTESS/social media/zombies/tweets.json")
corp_twitter <- corpus(dat_json)
summary(corp_twitter, 5)
# generic json - needs a textfield specifier
dat_sotu <- readtext("~/Dropbox/QUANTESS/Manuscripts/collocations/Corpora/sotu/sotu.json",
                  textfield = "text")
summary(corpus(dat_sotu), 5)
# text file
dat_txtone <- readtext("~/Dropbox/QUANTESS/corpora/project_gutenberg/pg2701.txt", cache = FALSE)
summary(corpus(dat_txtone), 5)
# multiple text files
dat_txtmultiple1 <- readtext("~/Dropbox/QUANTESS/corpora/inaugural/*.txt", cache = FALSE)
summary(corpus(dat_txtmultiple1), 5)
# multiple text files with docvars from filenames
dat_txtmultiple2 <- readtext("~/Dropbox/QUANTESS/corpora/inaugural/*.txt",
                             docvarsfrom = "filenames", sep = "-",
                             docvarnames = c("Year", "President"))
summary(corpus(dat_txtmultiple2), 5)
# XML data
dat_xml <- readtext("~/Dropbox/QUANTESS/quanteda_working_files/xmlData/plant_catalog.xml",
                  textfield = "COMMON")
summary(corpus(dat_xml), 5)
# csv file
write.csv(data.frame(inaug_speech = texts(data_corpus_inaugural),
                     docvars(data_corpus_inaugural)),
          file = "/tmp/inaug_texts.csv", row.names = FALSE)
dat_csv <- readtext("/tmp/inaug_texts.csv", textfield = "inaug_speech")
summary(corpus(dat_csv), 5)

コーパスオブジェクトの使い方 {#how-a-quanteda-corpus-works}

コーパスの原理 {#corpus-principles}

quantedaのコーパスは,元の文書をユニコード(UTF-8)に変換し,文書に対するメタデータと一緒に格納しすることで、ステミングや句読点の削除などの処理よって変更されないテキストデータの静的な保管庫になるように設計されている.これによって,コーパスから文書を抽出して新しいオブジェクトを作成した後でも,コーパスには元のデータが残り,別の分析を,同じコーパスを用いて行うことができる.

コーパスから文書を取り出すためには,as.character()と呼ばれる関数を使用する.

as.character(data_corpus_inaugural)[2]

summary()により,コーパス内のテキストの要約を行うことができる.

data(data_corpus_irishbudget2010, package = "quanteda.textmodels")
summary(data_corpus_irishbudget2010)

summary()の出力をデータ・フレームとして保存し,基本的な記述統計を描画することができる.

tokeninfo <- summary(data_corpus_inaugural)
if (require(ggplot2))
    ggplot(data = tokeninfo, aes(x = Year, y = Tokens, group = 1)) +
    geom_line() +
    geom_point() +
    scale_x_continuous(labels = c(seq(1789, 2017, 12)), breaks = seq(1789, 2017, 12)) +
    theme_bw()

# Longest inaugural address: William Henry Harrison
tokeninfo[which.max(tokeninfo$Tokens), ]

コーパスに対する操作 {#tools-for-handling-corpus-objects}

コーパスの結合 {#adding-two-corpus-objects-together}

+演算子を用いると,簡単に二個のコーパスを連結できます.コーパスが異なる構造を持つ場合でも,文書変数が失われることはなく,コーパスのメタデータも引き継がれる.

library(quanteda)
corp1 <- corpus(data_corpus_inaugural[1:5])
corp2 <- corpus(data_corpus_inaugural[53:58])
corp3 <- corp1 + corp2
summary(corp3)

コーパスから文書を抽出 {#subsetting-corpus-objects}

corpus_subset()により,文書変数に適用される論理条件に基づいて文書を抽出することができる.

summary(corpus_subset(data_corpus_inaugural, Year > 1990))
summary(corpus_subset(data_corpus_inaugural, President == "Adams"))

コーパス内の文書の探索 {#exploring-corpus-texts}

kwic()(keywords-in-context)は単語の検索を行い,その単語が現れる文脈を表示する.

toks <- tokens(data_corpus_inaugural)
kwic(toks, pattern = "terror")
kwic(toks, pattern = "terror", valuetype = "regex")
kwic(toks, pattern = "communist*")

上記の要約では,"Year"と"President"は各文書に結び付けられた変数であり,docvars()によってそれらにアクセスできる.

head(docvars(data_corpus_inaugural))

quanteda.corporaをインストールすることで,より多くのコーパスを試すことができる.

コーパスから特長を抽出 {#extracting-features-from-a-corpus}

文書のスケーリングなどの統計分析を行うためには,それぞれの文書の特長をまとめた行列を作成する必要があり,quantedaでは,このような行列を生成するために dfm()を使いる. dfmはdocument-feature matrixの略で,行が文書(document),列が特長(feature)となる行列である.行と列をこのように定義する理由は,データ分析では行が分析単位になり,各列が分析対象になる変数となるのが一般的だからである.多くのソフトウェアでは,この行列をdocument-term matrixと呼ぶが,quantedaが語(term)でなはく特長(feature)という用語を使うのは,特長のほうが一般性を持つからで,テキスト分析では,単語,語幹,単語の集合,Nグラム,品詞など様々なものが文書の特長となる.

文書のトークン化 {#tokenizing-texts}

テキストを簡単にトークン化するために,quantedatokens()と呼ばれる強力なコマンドを提供する.この関数は,文字ベクトルのトークンのリストからなるオブジェクトを生成する.このオブジェクトでは,リストの一つ一つの要素は入力された文書に対応している.

tokens()は保守的に設計されており、ユーザーが明示的に指示を与えないかぎりは,要素を削除しない.

txt <- c(text1 = "This is $10 in 999 different ways,\n up and down; left and right!",
         text2 = "@kenbenoit working: on #quanteda 2day\t4ever, http://textasdata.com?page=123.")
tokens(txt)
tokens(txt, remove_numbers = TRUE,  remove_punct = TRUE)
tokens(txt, remove_numbers = FALSE, remove_punct = TRUE)
tokens(txt, remove_numbers = TRUE,  remove_punct = FALSE)
tokens(txt, remove_numbers = FALSE, remove_punct = FALSE)
tokens(txt, remove_numbers = FALSE, remove_punct = FALSE, remove_separators = FALSE)

また,tokens()には個々の文字をトークン化するオプションもある.

tokens("Great website: http://textasdata.com?page=123.", what = "character")
tokens("Great website: http://textasdata.com?page=123.", what = "character",
         remove_separators = FALSE)

もしくは,一文ごとにトークン化するオプションもある.

# sentence level         
tokens(c("Kurt Vongeut said; only assholes use semi-colons.",
         "Today is Thursday in Canberra:  It is yesterday in London.",
         "En el caso de que no puedas ir con ellos, ¿quieres ir con nosotros?"),
         what = "sentence")

文書行列の作成 {#constructing-a-document-feature-matrix}

データからすぐに文書行列を作成したい場合は、dfm()に直接文字列ベクトルもしくはコーパスを渡すと、自動的にトークン化が行われ。dfm()は、デフォルトで大文字から小文字への置換や,句読点を除去などの操作を適用する.また,dfm()からtokens()の全てのオプションを利用できる.

corp_inaug_post1990 <- corpus_subset(data_corpus_inaugural, Year > 1990)

# make a dfm
dfmat_inaug_post1990 <- dfm(tokens(corp_inaug_post1990))
dfmat_inaug_post1990[, 1:5]

以下の例ではdfm()の追加のオプションを用いて、ストップワードの削除(remove)と語のステミング(stem)を行っている.

# make a dfm, removing stopwords and applying stemming
dfmat_inaug_post1990 <- tokens(corp_inaug_post1990, remove_punct = TRUE) |>
    tokens_remove(stopwords("english")) |>
    tokens_wordstem() |>
    dfm()
dfmat_inaug_post1990[, 1:5]

removeによって,文書行列から除外するトークンを指定する.stopwords()は,幾つかの言語で定義されたストップワードのリストを返す.

head(stopwords("en"), 20)
head(stopwords("ru"), 10)
head(stopwords("ar", source = "misc"), 10)

文書行列の表示 {#viewing-the-document-feature-matrix}

RStudioの"Environment"パネル,またはRのView()を用いることで,dfmに格納された値を見ることができる.

dfmat_uk <- data_char_ukimmig2010 |>
    tokens(remove_punct = TRUE) |>
    tokens_remove(stopwords("english")) |>
    dfm()
dfmat_uk

頻度が最も高い特長を見るには,topfeatures()を用いる.

topfeatures(dfmat_uk, 20)  # 20 most frequent words

dfmをtextplot_wordcloud()に渡すことで,ワードクラウドを描画できる.この関数は,オブジェクトや引数をwordcloudパッケージのwordcloud()に渡すので,ワードクラウドの表示を変更できる.

set.seed(100)
library("quanteda.textplots")
textplot_wordcloud(dfmat_uk, min_count = 6, random_order = FALSE,
                   rotation = .25,
                   color = RColorBrewer::brewer.pal(8, "Dark2"))

変数による文書のグループ化 {#grouping-documents-by-document-variable}

quantedaでは,dfmを作成する際に,文書変数の値によって文書をグループ化するすることができる.

dfmat_ire <- tokens(data_corpus_irishbudget2010, remove_punct = TRUE) |>
    tokens_remove(stopwords("en")) |>
    tokens_group(groups = party) |>
    dfm()

また、以下のように,dfmを語の頻度順に並べ替えて,中身を確かめられる.

dfm_sort(dfmat_ire)[, 1:10]

辞書による語のグループ化 {#grouping-words-by-dictionary-or-equivalence-class}

キーワードがあらかじめ分かっている場合,dictionary()によって辞書を作成し、語の出現回数を測定できる。次の例では,テロリズムに関連する言葉や経済に関連する言葉が,クリントン以降の大統領演説でどのように異なるかを示している.

corp_inaug_post1991 <- corpus_subset(data_corpus_inaugural, Year > 1991)

テロリズムと経済という2つのリストからなる辞書を作成する.

dict <- dictionary(list(terror = c("terrorism", "terrorists", "threat"),
                        economy = c("jobs", "business", "grow", "work")))

文書行列を作成するときに,この辞書をdfm()dictionaryに渡す.

dfmat_inaug_post1991_dict <- tokens(corp_inaug_post1991) |>
    tokens_lookup(dict) |>
    dfm()
dfmat_inaug_post1991_dict

dictionary()は,LIWCやWordstatなどの一般的な辞書ファイルを読み込むことができる.以下では,LIWCの辞書を大統領就任演説に適用している.

dictliwc <- dictionary(file = "~/Dropbox/QUANTESS/dictionaries/LIWC/LIWC2001_English.dic",
                       format = "LIWC")
dfmat_inaug_subset <- dfm(data_corpus_inaugural[52:58], dictionary = dictliwc)
dfmat_inaug_subset[, 1:10]

追加の事例 {#further-examples}

文書の類似性 {#similarities-between-texts}

dfmat_inaug_post1980 <- data_corpus_inaugural |>
    corpus_subset(Year > 1980) |>
    tokens(remove_punct = TRUE) |>
    tokens_remove(stopwords("english")) |>
    tokens_wordstem() |>
    dfm()

library("quanteda.textstats")
tstat_obama <- textstat_simil(dfmat_inaug_post1980,
                              dfmat_inaug_post1980[c("2009-Obama", "2013-Obama"), ],
                              margin = "documents", method = "cosine")
tstat_obama
# dotchart(as.list(tstat_obama)$"2009-Obama", xlab = "Cosine similarity")

上記の文書間の類似性から樹形図を作成して,大統領を階層的に分類することができる.

data_corpus_sotu <- readRDS(url("https://quanteda.org/data/data_corpus_sotu.rds"))

dfmat_sotu <- data_corpus_sotu |>
    corpus_subset(Date > as.Date("1980-01-01")) |>
    tokens(remove_punct = TRUE) |>
    tokens_remove(stopwords("english")) |>
    tokens_wordstem() |>
    dfm()
dfmat_sotu <- dfm_trim(dfmat_sotu, min_termfreq = 5, min_docfreq = 3)

# hierarchical clustering - get distances on normalized dfm
library("quanteda.textstats")
tstat_dist <- textstat_dist(dfm_weight(dfmat_sotu, scheme = "prop"))
# hiarchical clustering the distance object
pres_cluster <- hclust(as.dist(tstat_dist))
# label with document names
pres_cluster$labels <- docnames(dfmat_sotu)
# plot as a dendrogram
plot(pres_cluster, xlab = "", sub = "",
     main = "Euclidean Distance on Normalized Token Frequency")

文書間と同様に用語間の類似性も測定できる.

tstat_sim <- textstat_simil(dfmat_sotu, dfmat_sotu[, c("fair", "health", "terror")],
                          method = "cosine", margin = "features")
lapply(as.list(tstat_sim), head, 10)

文書のスケーリング {#scaling-document-positions}

quantedaには多数のテキスト分析のためのモデルが含まれている.ここでは,ワードフィッシュ(textmodel_wordfish())による教師なしの文書のスケーリングを2010年のアイルランドの予算討論の分析に用いている.

library("quanteda.textmodels")
dfmat_ire <- dfm(tokens(data_corpus_irishbudget2010))
tmod_wf <- textmodel_wordfish(dfmat_ire, dir = c(2, 1))

# plot the Wordfish estimates by party
textplot_scale1d(tmod_wf, groups = docvars(dfmat_ire, "party"))

トピックモデル {#topic-models}

convert()を用いると,dfmをtopicmodelsLDA()形式のデータに転換し,簡単にトピックモデルを適用できる.

dfmat_ire2 <- data_corpus_irishbudget2010 |>
    tokens(remove_punct = TRUE, remove_numbers = TRUE) |>
    tokens_remove(stopwords("english")) |>
    tokens_wordstem() |>
    dfm()
dfmat_ire2 <- dfm_trim(dfmat_ire2, min_termfreq = 4, max_docfreq = 10)
dfmat_ire2

set.seed(100)
if (require(topicmodels)) {
    my_lda_fit20 <- LDA(convert(dfmat_ire2, to = "topicmodels"), k = 20)
    get_terms(my_lda_fit20, 5)
}


quanteda/quanteda documentation built on May 5, 2024, 8:33 p.m.