私はTM
パッケージで多くの分析を行っています。私の最大の問題の1つは、ステミングとステミングのような変換に関連しています。
私がいくつかの会計関連の用語を持っているとしましょう(私はスペルの問題を知っています)。
ステミング後、次のようになります。
accounts -> account
account -> account
accounting -> account
acounting -> acount
acount -> acount
acounts -> acount
accounnt -> accounnt
結果:3つの用語(アカウント、アカウント、アカウント)。これらはすべて同じ用語に関連しているため、1つ(アカウント)が好きでした。
1) スペルを修正することは可能ですが、私はRでそれを試みたことがありません。それも可能ですか?
2) もう1つのオプションは、参照リスト、つまりaccount =(accounts、account、accounting、acounting、acount、acounts、accounnt)を作成し、すべての出現箇所をマスター用語に置き換えることです。 Rでこれをどのように行うのですか?
繰り返しになりますが、どんな助け/提案も大歓迎です。
同義語のリストを設定し、それらの値を置き換えることができます。例えば
synonyms <- list(
list(Word="account", syns=c("acount", "accounnt"))
)
これは、「acount」と「accounnt」を「account」に置き換えたいことを示しています(ステミング後にこれを行っていると想定しています)。それでは、テストデータを作成しましょう。
raw<-c("accounts", "account", "accounting", "acounting",
"acount", "acounts", "accounnt")
次に、リスト内の単語を主要な同義語に置き換える変換関数を定義しましょう。
library(tm)
replaceSynonyms <- content_transformer(function(x, syn=NULL) {
Reduce(function(a,b) {
gsub(paste0("\\b(", paste(b$syns, collapse="|"),")\\b"), b$Word, a)}, syn, x)
})
ここでは、content_transformer
関数を使用してカスタム変換を定義します。そして基本的には、gsub
を実行して各単語を置き換えます。これをコーパスで使用できます
tm <- Corpus(VectorSource(raw))
tm <- tm_map(tm, stemDocument)
tm <- tm_map(tm, replaceSynonyms, synonyms)
inspect(tm)
そして、これらすべての値が必要に応じて「アカウント」に変換されていることがわかります。他の同義語を追加するには、メインのsynonyms
リストにリストを追加するだけです。各サブリストには、「Word」と「syns」という名前を付ける必要があります。
フリック氏は質問2に答えました。質問1に答えてアプローチしています。
これは、既知のWordデータベース(DICTIONARY
from qdapDictionaries
)のバイナリ検索を使用するアプローチです。バイナリルックアップは確かに遅いですが、置換についていくつかの仮定を行う場合(文字数の違いの範囲など)。したがって、基本的な考え方は次のとおりです。
Corpus
のbag_o_words
を使用して、qdap
をユニークな単語の袋に変えますqdapDictionaries
'DICTIONARY
データセット)で調べて、match
[.____を使用して認識できない単語を見つけます。]misses
は、ルックアップするものになりますnchar
を使用して大きな違いをなくすために、辞書内の単語の文字数を決定しますmisses
の各要素をループ(sapply
)で実行し、次の手順を実行します。tm::stemDocument
を使用してmisses
から各要素をステム処理しますnchar
を使用して、文字数を決定し、その範囲内にない文字を辞書から削除します。agrep
とmax.distance
を使用して、辞書からより多くの単語を削除しますagrep
)を使用して、欠落した要素に最も近い辞書から単語を決定します[これはqdap:::Ldist
と呼ばれるqdap
からエクスポートされない関数であることに注意してください]gsub
bingに使用できる名前付きベクトルです。tm_map
をカスタムのtm
フレーバーのgsub
関数とともに使用して、単語を置き換えますtm_map
とstemDocument
でステミングを行いますこれがコードです。私はあなたが提供した単語といくつかのランダムな単語を使用して偽のCorpus
を作成し、これを最初から最後まで行う方法を示しました。 range
に提供されているsapply
とmax.distance
で遊ぶことができます。これらを緩くすると検索が遅くなりますが、締めすぎると間違いを犯しやすくなります。これは実際には一般的な意味でのスペル修正の答えではありませんが、とにかくステミングしていたのでここで機能します。 Aspell
パッケージがありますが、これまで使用したことがありません。
terms <- c("accounts", "account", "accounting", "acounting", "acount", "acounts", "accounnt")
library(tm); library(qdap)
fake_text <- unlist(lapply(terms, function(x) {
paste(sample(c(x, sample(DICTIONARY[[1]], sample(1:5, 1)))), collapse=" ")
}))
fake_text
myCorp <- Corpus(VectorSource(fake_text))
terms2 <- unique(bag_o_words(as.data.frame(myCorp)[[2]]))
misses <- terms2[is.na(match(terms2, DICTIONARY[[1]]))]
chars <- nchar(DICTIONARY[[1]])
replacements <- sapply(misses, function(x, range = 3, max.distance = .2) {
x <- stemDocument(x)
wchar <- nchar(x)
dict <- DICTIONARY[[1]][chars >= (wchar - range) & chars <= (wchar + range)]
dict <- dict[agrep(x, dict, max.distance=max.distance)]
names(which.min(sapply(dict, qdap:::Ldist, x)))
})
replacer <- content_transformer(function(x) {
mgsub(names(replacements), replacements, x, ignore.case = FALSE, fixed = FALSE)
})
myCorp <- tm_map(myCorp, replacer)
inspect(myCorp <- tm_map(myCorp, stemDocument))
この質問から、qdap
パッケージのスペルチェックを書こうと思いました。ここで役立つかもしれないインタラクティブなバージョンがあります。 qdap >= version 2.1.1
で入手できます。つまり、現時点では開発バージョンが必要です。インストールする手順は次のとおりです。
library(devtools)
install_github("qdapDictionaries", "trinker")
install_github("qdap", "trinker")
library(tm); library(qdap)
##説明したようにCorpus
を再作成します。
terms <- c("accounts", "account", "accounting", "acounting", "acount", "acounts", "accounnt")
fake_text <- unlist(lapply(terms, function(x) {
paste(sample(c(x, sample(DICTIONARY[[1]], sample(1:5, 1)))), collapse=" ")
}))
fake_text
inspect(myCorp <- Corpus(VectorSource(fake_text)))
##インタラクティブなスペルチェッカー(check_spelling_interactive
)
m <- check_spelling_interactive(as.data.frame(myCorp)[[2]])
preprocessed(m)
inspect(myCorp <- tm_map(myCorp, correct(m)))
correct
関数は、check_spelling_interactive
の出力からクロージャ関数を取得するだけで、新しいテキスト文字列に「修正」を適用できます。