2017-05-18 10 views
1

文書内の特定の用語に対する単語の近接度と、平均近接度(ワード単位)を計算する方法を理解しようとしています。私はそれに似た質問があることを知っていますが、私に必要な答えを与えたり、助けてくれと指摘するものはありません。にどちらかの側の言葉は、左へ15((私は交換可能で、この数をしたいと思います)私は15内に現れるものを言葉見ることができるようにしたい文書内の特定の用語に対する単語の近接度を計算する方法

song <- "Far over the misty mountains cold To dungeons deep and caverns old We 
must away ere break of day To seek the pale enchanted gold. The dwarves of 
yore made mighty spells, While hammers fell like ringing bells In places deep, 
where dark things sleep, In hollow halls beneath the fells. For ancient king 
and elvish lord There many a gleaming golden hoard They shaped and wrought, 
and light they caught To hide in gems on hilt of sword. On silver necklaces 
they strung The flowering stars, on crowns they hung The dragon-fire, in 
twisted wire They meshed the light of moon and sun. Far over the misty 
mountains cold To dungeons deep and caverns old We must away, ere break of 
day, To claim our long-forgotten gold. Goblets they carved there for 
themselves And harps of gold; where no man delves There lay they long, and 
many a song Was sung unheard by men or elves. The pines were roaring on the 
height, The winds were moaning in the night. The fire was red, it flaming 
spread; The trees like torches blazed with light. The bells were ringing in 
the dale And men they looked up with faces pale; The dragon’s ire more fierce 
than fire Laid low their towers and houses frail. The mountain smoked beneath 
the moon; The dwarves they heard the tramp of doom. They fled their hall to 
dying fall Beneath his feet, beneath the moon. Far over the misty mountains 
grim To dungeons deep and caverns dim We must away, ere break of day, 
To win our harps and gold from him!" 

と15:それでは、私は次のテキストを持っているとしましょうそれが現れるたびに、「火」という言葉(また交換可能)という言葉の意味(右)。私は各単語と、それがこの「火」の各インスタンスについてこの15語のスパンに現れる回数を見たいと思っています。たとえば、「火」は3回使用されます。それらの3回のうち、「光」という言葉は両側で15語以内に2回入る。私は単語を表示するテーブル、15の指定された近接度、最大距離(この場合は12)、最小距離(7)、および平均距離の表示回数を表示します。 9.5)。

私はこの作業を行うためにいくつかのステップとパッケージが必要だと考えました。私の最初の考えは、特定の用語の周りの "ウィンドウ"を選択できるようになるので、quantaから "kwic"関数を使うことでした。その後、kwicの結果に基づいた用語の頻度カウントはそれほど難しくありません(頻度のためのストップワードは削除されますが、単語の近接度は除外されます)。私の本当の問題は、焦点の期間から最大、最小、平均の距離を見つけて、その結果を素敵な素敵なテーブルに入れて、頻度と列数を降順に並べるというものです。距離、および平均距離。

library(quanteda) 
library(tm) 

mysong <- char_tolower(song) 

toks <- tokens(mysong, remove_hyphens = TRUE, remove_punct = TRUE, 
remove_numbers = TRUE, remove_symbols = TRUE) 

mykwic <- kwic(toks, "fire", window = 15, valuetype ="fixed") 
thekwic <- as.character(mykwic) 

thekwic <- removePunctuation(thekwic) 
thekwic <- removeNumbers(thekwic) 
thekwic <- removeWords(thekwic, stopwords("en")) 

kwicFreq <- termFreq(thekwic) 

すべてのヘルプははるかに高く評価されています。ここでは

は、私がこれまで持っているものです。

+0

あなたのドキュメントはどれくらいの大きさですか?私は何百万という言葉にうまく対応できないかもしれない解決策について考えることができます。 –

+0

@David Robinson - 今、私は、例としてハムレットの演劇を見ています。私は本当に一度に1つのドキュメントで作業する必要があると思います。私はシェイクスピアコーパス全体にそれを展開することさえできますが、これは100,000語以下の単語であると私は信じています。私はシェイクスピアからウィリアム・オブ・ティアまでの様々なテキストにこれを使用できるようにしたいと考えていますが、何百万語もの単語部門には何もありません。 – DHranger

+0

その場合、以下の私の解決策を見て、それがあなたの目的にとって十分に効率的かどうかを見てください。 'difference_inner_join'は、必要に応じてより効率的にすることができます。 –

答えて

2

私のtidytextfuzzyjoinパッケージの組み合わせでこれを解決することをお勧めします。

あなたは、1行あたりの単語データフレームにそれをトークン化position列を追加し、ストップワードを削除することで起動することができます。

library(tidytext) 
library(dplyr) 

all_words <- data_frame(text = song) %>% 
    unnest_tokens(word, text) %>% 
    mutate(position = row_number()) %>% 
    filter(!word %in% tm::stopwords("en")) 

あなたはその後、言葉だけfireを見つけ、そしてdifference_inner_join()を使用することができますfuzzyjoinから、それらの行の15語以内のすべての行を検索します。 とsummarize()を使用して、各単語の希望する統計情報を取得できます。この場合

library(fuzzyjoin) 

nearby_words <- all_words %>% 
    filter(word == "fire") %>% 
    select(focus_term = word, focus_position = position) %>% 
    difference_inner_join(all_words, by = c(focus_position = "position"), max_dist = 15) %>% 
    mutate(distance = abs(focus_position - position)) 

words_summarized <- nearby_words %>% 
    group_by(word) %>% 
    summarize(number = n(), 
      maximum_distance = max(distance), 
      minimum_distance = min(distance), 
      average_distance = mean(distance)) %>% 
    arrange(desc(number)) 

出力:このアプローチはまた、あなたが一度に複数のフォーカス単語に分析を行うことができますことを

# A tibble: 49 × 5 
     word number maximum_distance minimum_distance average_distance 
     <chr> <int>   <dbl>   <dbl>   <dbl> 
1  fire  3    0    0    0.0 
2 light  2    12    7    9.5 
3  moon  2    13    9    11.0 
4 bells  1    14    14    14.0 
5 beneath  1    11    11    11.0 
6 blazed  1    10    10    10.0 
7 crowns  1    5    5    5.0 
8  dale  1    15    15    15.0 
9 dragon  1    1    1    1.0 
10 dragon’s  1    5    5    5.0 
# ... with 39 more rows 

注意。 filter(word == "fire")filter(word %in% c("fire", "otherword"))に変更し、group_by(word)group_by(focus_word, word)に変更するだけです。

2

tidytext答えは良いものですが、これに適合させることができるquantedaでのツールがあります。ウィンドウ内でカウントする主な機能はkwic()ではなく、fcm()(機能共起マトリックス)です。

require(quanteda) 

# tokenize so that intra-word hyphens and punctuation are removed 
toks <- tokens(song, remove_punct = TRUE, remove_hyphens = TRUE) 

# all co-occurrences 
head(fcm(toks, window = 15, context = "window", count = "frequency")[, "fire"]) 
## Feature co-occurrence matrix of: 155 by 1 feature. 
## (showing first 6 documents and first feature) 
##   features 
## features fire 
## Far   1 
## over   1 
## the   5 
## misty  1 
## mountains 0 
## cold   0 

head(fcm(toks, window = 15, context = "window", count = "frequency")["light", "fire"]) 
## Feature co-occurrence matrix of: 1 by 1 feature. 
## 1 x 1 sparse Matrix of class "fcm" 
##   features 
## features fire 
## light 2 

ターゲットからの単語の平均距離を取得するには、距離に対する重み関数のハックを少し必要とします。以下では、重みを適用して位置に応じてカウントを考慮します。これは、これらが合計されてからウィンドウ内の合計周波数で除算されるときの加重平均を提供します。 「光」のご例えば、例えば:

# average distance 
fcm(toks, window = 15, context = "window", count = "weighted", weights = 1:15)["light", "fire"]/
    fcm(toks, window = 15, context = "window", count = "frequency")["light", "fire"] 
## 1 x 1 Matrix of class "dgeMatrix" 
##   features 
## light 9.5 
## features fire 

私は位置に重みの組み合わせを使用して、これを「ハック」する方法を見つけ出すことができますが、最小値と最大値の位置が少し複雑で取得し、各位置にバイナリマスクを作成し、それを距離に変換します。 (あまりにもうまくいきませんので、私はより洗練された方法を考えない限り、きちんとした解決策を推奨しています)