2013-05-19 7 views
5

テキストベースのトレーニングデータとテストデータがあるとします。具体的には、トレーニングとテストという2つのデータセットがあり、どちらもテキストを含む1つの列を持ち、手元にある仕事のために興味があります。新しい(テスト)データを使用して同じDocumentTermMatrixを再作成する方法

Rでtmパッケージを使用して、トレーニングデータセットのテキスト列を処理しました。空白、句読点、およびストップワードを削除した後、私はコーパスを抹消し、最終的に各文書の単語の頻度/カウントを含む1グラムの文書用語行列を作成しました。次に、例えば50という所定のカットオフをとり、50を超える数の用語を保持した。

これに続いて、DTMと依存関係を使用してGLMNETモデルを訓練する変数(これはトレーニングデータに含まれていました)。すべてが今まで滑らかで簡単に実行されます。

ただし、テストデータや将来新しくなる可能性のあるデータでモデルをスコアリング/予測するにはどうすればよいですか?

具体的には、私が見つけようとしているのは、新しいデータに正確なDTMを作成する方法です。

新しいデータセットに元のトレーニングデータと類似の単語が含まれていない場合は、すべての用語のカウントがゼロになる必要があります(これは問題ありません)。しかし、私は、新しいコーパス上で全く同じDTM(構造に関して)を複製できるようにしたいと考えています。

アイデアやアイデアはありますか?

+0

(と私は私が持ってわからないんだけど、何を実証する再現可能な例なし:ここtmについては

は、おそらく第二コーパスのためのDTM行列を再構築するためのもう一つの簡単な方法ですこれを行う最も簡単な方法は、すべてのデータを使用して用語 - 文書行列を作成し、その行列をテストとトレーニングのセットに分割することです。そうすれば、たとえ1つの行列に複数の項の零点しかない場合でも、両方の行列にすべての項を表すことができます。用語 - 文書行列を作成する前にデータを分割しているため、問題が発生しています。 – SchaunW

+1

私はSchaunに同意しますが、私が現在持っているテストデータでのみ行うことができます。私は明日新しいデータを取得するときに動作するソリューションを探しています。それ以外の場合は、常に新しいデータを既存のデータに追加することは苦痛であり、DTMを再作成し、毎回モデルを再学習します。 – Godel

+1

また、使用するサンプルデータを用意することで、質問に簡単に答えることができます。これについては、新しいデータをterm-document行列に変換し、 'plyr'パッケージの' rbind.fill'関数を使用して古いデータにバインドしてください。これにより元の両方の行列のすべての列を持つ新しい行列が作成されます。トレーニングデータに含まれていなかった新しいデータの用語については、トレーニングデータにはNAsの列が含まれます。それらの列を削除することができます。あなたの新しいデータはあなたのトレーニングデータに含まれていても新しいデータには含まれていませんが、それらのNAをゼロで置き換えることができます。 – SchaunW

答えて

7

私が正しく理解していれば、dtmを作成しました。最初のdtmと同じ列(つまり用語)を持つ新しい文書から新しいdtmを作成したいとします。そのような場合、それは、このようなサブ設定おそらく、最初の条項により、第2のDTMを何かの問題である必要があります。

は、まず、いくつかの再現性のあるデータを設定...

これはあなたですトレーニングデータ...

library(tm) 
# make corpus for text mining (data comes from package, for reproducibility) 
data("crude") 
corpus1 <- Corpus(VectorSource(crude[1:10]))  
# process text (your methods may differ) 
skipWords <- function(x) removeWords(x, stopwords("english")) 
funcs <- list(tolower, removePunctuation, removeNumbers, 
       stripWhitespace, skipWords) 
crude1 <- tm_map(corpus1, FUN = tm_reduce, tmFuns = funcs) 
crude1.dtm <- DocumentTermMatrix(crude1, control = list(wordLengths = c(3,10))) 

そして、これはあなたの試験データである...

corpus2 <- Corpus(VectorSource(crude[15:20])) 
# process text (your methods may differ) 
skipWords <- function(x) removeWords(x, stopwords("english")) 
funcs <- list(tolower, removePunctuation, removeNumbers, 
       stripWhitespace, skipWords) 
crude2 <- tm_map(corpus2, FUN = tm_reduce, tmFuns = funcs) 
crude2.dtm <- DocumentTermMatrix(crude2, control = list(wordLengths = c(3,10))) 

ここでは何をしたいんビットです:

今、私たちは学習データに存在している試験データの唯一の用語を保つ...

# convert to matrices for subsetting 
crude1.dtm.mat <- as.matrix(crude1.dtm) # training 
crude2.dtm.mat <- as.matrix(crude2.dtm) # testing 

# subset testing data by colnames (ie. terms) or training data 
xx <- data.frame(crude2.dtm.mat[,intersect(colnames(crude2.dtm.mat), 
              colnames(crude1.dtm.mat))]) 

は最後にある学習データ中の用語のための試験データへのすべての空の列を追加しますない試験データで...

# make an empty data frame with the colnames of the training data 
yy <- read.table(textConnection(""), col.names = colnames(crude1.dtm.mat), 
       colClasses = "integer") 

# add incols of NAs for terms absent in the 
# testing data but present # in the training data 
# following SchaunW's suggestion in the comments above 
library(plyr) 
zz <- rbind.fill(xx, yy) 

のでzzは、テストドキュメントのデータフレームですが、トレーニング文書(つまり、同じ構造を有しています。 SchaunWが指摘するように、それらの多くにはNAが含まれています)。

あなたが望む線に沿っているのですか?

+0

はいベン。これはかなり役に立ちます。どうもありがとう。 :) – Godel

+0

心配しないで!そして、サンプルデータを作成して関連する質問に含める方法を知っています。 – Ben

+0

これはしばらくの間、解決策を探していましたが、Dmitriyによって以下のものも試してみます。 – Tetlanesh

12

tmには非常に多くの落とし穴があります...さらに効率的なtext2vecvectorization vignetteを参照してください。私が正しくあなたの質問を理解している場合

crude2.dtm <- DocumentTermMatrix(crude2, control = list 
       (dictionary=Terms(crude1.dtm), wordLengths = c(3,10))) 
+3

それは素晴らしいですが、 'Dictionary()'はもはやサポートされておらず、代わりに 'Terms()'を使わなければなりません。 – Khozzy

+0

素晴らしい例では、間違いなくこれを試してみましょう、これを行うネイティブな方法を探していました。私は実際に私が使用するパッケージのvingietesを読むべきだと思います:) – Tetlanesh

+1

私はこのソリューションは、それが疎な行列から変換していないので、はるかに優れていると思います – elactic