この質問には直接回答が得られていないため、2016 年に JHU Capstone、Capstone n-grams のコミュニティ メンターとして書いた記事から関連コンテンツを再投稿します。どのくらいの処理能力が必要ですか?
概要
ジョンズ ホプキンス大学のデータ サイエンス専門コースの学生は、通常、テキストの分析に必要なオブジェクトによって消費されるメモリ量が原因で、コース プロジェクトに苦労しています。この質問は、生データ ファイルにある 400 万以上のドキュメントを処理するための最善の方法について尋ねます。この質問に対する簡単な答えは、マシンの RAM の量に依存するということです。R オブジェクトは RAM に存在する必要があるため、処理中のオブジェクトによって消費される RAM の量を理解する必要があります。
16Gb の RAM を搭載したマシンは、3 つのファイルのすべてのデータを小さなチャンクで処理したり、データのランダム サンプルを処理したりせずに処理する必要があります。私のテストでは、ファイルを処理するために必要な作業メモリは、バージョン 0.99.22quanteda::tokens_ngrams()
から関数によって出力されたオブジェクトのサイズの約 1.5 から 3 倍であることを示しています。したがって、1 Gb のトークン化されたコーパスであり、4 を生成するために 9 Gb の RAM を消費します。 quanteda
Gb n-gram オブジェクト。quanteda
コンピューターに複数のコア/スレッドがある場合、自動的に複数のスレッドが使用されることに注意してください。
メモリ使用量の推測を減らすために、Swift Key が後援するキャップストーンのファイルを分析するために必要なオブジェクトによって消費される RAM の量の概要を以下に示します: テキストの予測。
生データ
Capstone プロジェクトで使用される生データ ファイルは 3 つあります。readLines()
またはなどのテキスト処理関数を使用してメモリにロードされるreadr::read_lines()
と、結果のオブジェクト サイズは次のようになります。
- en_US.blogs.txt: 249 Mb
- en_US.news.txt: 250 Mb
- en_US.twitter.txt: 301 Mb
これらのファイルを 1 つのオブジェクトに結合し、コーパスに変換する必要があります。合わせて約 800 Mb の RAM を消費します。
コーパスに変換するとquanteda::corpus()
、結果のファイル サイズは 1.1 GB になります。
N-gram オブジェクトのサイズ
n-gram 処理に使用できる RAM の量を最大化するには、コーパスが生成されたら、への入力として使用されるトークン化されたコーパス以外のすべてのオブジェクトをメモリから削除する必要がありますtokens_ngrams()
。さまざまな n-gram のオブジェクト サイズは次のとおりです。
- 2 グラム: 6.3 Gb
- 3 グラム: 6.5 Gb
- 4 グラム: 6.5 Gb
- 5 グラム: 6.3 Gb
- 6 グラム: 6.1 Gb
少ないメモリで作業する
8 Gb の RAM を搭載した MacBook Pro で capstone データの 25% のサンプルを処理でき、4 Gb の RAM で Ubuntu Linux を実行している HP Chromebook で 5% のサンプルを処理できました。
オブジェクト サイズ: 25% サンプル
- 2 グラム: 2.0 Gb
- 3 グラム: 2.9 Gb
- 4 グラム: 3.6 Gb
- 5 グラム: 3.9 Gb
- 6 グラム: 4.0 Gb
オブジェクトのサイズ: 5% サンプル
- 2 グラム: 492 Mb
- 3 グラム: 649 Mb
- 4 グラム: 740 Mb
- 5 グラム: 747 Gb
- 6 グラム: 733 Gb
小さなグループでデータを処理する
元の質問に対する Ken Benoit のコメントに追加すると、数値グループを割り当て (たとえば、1 ~ 20 の ID を繰り返して 20 グループに分割)、corpus_segment()
関数を使用してグループ ID でコーパスをセグメント化できます。ただし、このアプローチでは、物理的に分割されたコーパスではなく、タグ付けされたコーパスが作成されます。必要なすべての n-gram を生成する一般的なプロセスは、次の擬似コードで表されます。
split the raw data into a list of <n> groups for processing
create a list of corpuses
for each corpus
for each size n-gram
1. generate n-grams
2. write to file
3. rm() n-gram object
コーパスをリストに分割し、1 セットの n-gram を処理するコードは、データがダウンロードされてswiftkey.zip
ファイルから抽出されると、次のようになります。
library(readr)
library(data.table)
blogFile <- "./capstone/data/en_us.blogs.txt"
newsFile <- "./capstone/data/en_us.news.txt"
twitterFile <- "./capstone/data/en_us.twitter.txt"
blogData <- read_lines(blogFile)
newsData <- read_lines(newsFile)
twitterData <- read_lines(twitterFile)
allData <- c(blogData,newsData,twitterData) # about 800mb file
rm(blogData,newsData,twitterData,blogFile,newsFile,twitterFile)
# create 20 groups, and use to split original data into a list
groupId <- paste0("GROUP",sprintf("%02.0f",(1:length(allData) %% 20)+1))
split_data <- split(allData,groupId)
library(quanteda)
theTexts <- lapply(split_data,corpus)
system.time(ngram2 <- lapply(theTexts,function(x) tokens_ngrams(tokens(x),n=2)))
head(ngram2[[1]])
i7 Intel プロセッサを搭載した MacBook Pro では、n-ngram を生成するのに約 10 分かかり、結果の出力ngram2
は 20 セットの 2-gram のリストであることに注意してください。
...そして、最初のグループの最初の 3 つのテキストの出力は次のとおりです。
> head(ngram2[[1]])
Tokens consisting of 6 documents.
text1 :
[1] "Fallout_by" "by_Ellen" "Ellen_Hopkins" "Hopkins_(" "(_p"
[6] "p_." "._1-140" "1-140_)"
text2 :
[1] "Ed_Switenky" "Switenky_," ",_manager"
[4] "manager_of" "of_traffic" "traffic_engineering"
[7] "engineering_and" "and_operations" "operations_,"
[10] ",_couldn't" "couldn't_comment" "comment_on"
[ ... and 21 more ]
text3 :
[1] "the_autumn" "autumn_rains" "rains_in" "in_righteousness"
[5] "righteousness_."
メモリを節約するためにファイルをディスクに書き込む追加のコードと、処理前にデータを消去して n グラムを頻度表に統合するコードは、学生の作業として残されます。