1

オンライン ニュース Web サイトから要約のリストを収集し、元のラベル (政治、エンターテイメント、スポーツ、金融など) を使用して、トピックごとに手動でラベルを付けました。ここで、任意の 2 つのトピック (たとえば、「政治」というラベルの付いたアブストラクトと「金融」というラベルの付いたアブストラクト) の間で、アブストラクトの単語の使用方法の類似性を比較したいと思います。ただし、各トピックに該当するニュースのアブストラクトの数が異なり、2 つのアブストラクト間の単語の長さも異なるため、ドキュメントごとのコサイン類似度を計算することは困難です。

そこで私が行ったのは、サンプル データをトピックごとに分割し、それらを解析してステミングし、各要約 (行エントリ) のトークンをベクトル化し、dtm を構築して比較用のベクトル空間を作成することで、ビネットをtext2vec 参照することでした。

text2vecビネットにリストされているメソッドは簡単ですが、出力はマトリックス形式で生成されます。2 つの異なるトピックの下でラベル付けされた 2 つのドキュメント セット間で単一の類似度 (たとえば、0 と 1 または (-1, 1) の間の何か) を取得する方法があるかどうか疑問に思っています。

現在のコードを以下に示します。3 つの異なるトピックに分類されるニュース要約の小さな 9 行のデータも提供されます (各トピックに属するドキュメントの数と単語の長さがすべて異なることに注意してください: トピックに関連するニュース「スポーツ」には 2 つのエントリ、トピック「政治」には 4 つのエントリ、トピック「金融」には 3 つのエントリがあります)。このような小さなデータから意味のある類似性の結果が得られるとは期待しないでください。これは単なる例としての役割を果たします。

誰かが私の既存のコードを変更して、任意の 2 つのトピック間の単一のペアワイズ類似度を取得する方法を指摘できれば、非常にありがたいです。

# load required packages
library(foreign)
library(stringr)
library(text2vec)

news <- read.csv("https://www.dropbox.com/s/rikduji15mr5o89/news.csv?dl=1")
names(news)[1] <- "text"
as.character(news$text)
names(news)[2] <- "topic"
as.character(news$topic)
news$topic <- c(1, 1, 2, 2, 2, 2, 3, 3, 3)

prep_fun = function(x) {
  x %>% 
    # make text lower case
    str_to_lower %>% 
    # remove non-alphanumeric symbols
    str_replace_all("[^[:alnum:]]", " ") %>% 
    # collapse multiple spaces
    str_replace_all("\\s+", " ")
}

news$text_clean = prep_fun(news$text)
df <- news[c("topic", "text_clean")]
doc_set_1 <- df[which(df$topic==1), ]
doc_set_2 <- df[which(df$topic==2), ]
doc_set_3 <- df[which(df$topic==3), ]

it1 = itoken(doc_set_1$text_clean, progressbar = FALSE)
it2 = itoken(doc_set_2$text_clean, progressbar = FALSE)
it3 = itoken(doc_set_3$text_clean, progressbar = FALSE)

it = itoken(df$text_clean, progressbar = FALSE)
v = create_vocabulary(it) 
# %>% prune_vocabulary(doc_proportion_max = 0.1, term_count_min = 5)
vectorizer = vocab_vectorizer(v)

dtm1 = create_dtm(it1, vectorizer)
dtm2 = create_dtm(it2, vectorizer)
dtm3 = create_dtm(it3, vectorizer)

# calculate jaccard distance
d1_d2_jac_sim = sim2(dtm1, dtm2, method = "jaccard", norm = "none")
d2_d3_jac_sim = sim2(dtm2, dtm3, method = "jaccard", norm = "none")
d1_d3_jac_sim = sim2(dtm1, dtm3, method = "jaccard", norm = "none")

# calculate cosine distance
d1_d2_cos_sim = sim2(dtm1, dtm2, method = "cosine", norm = "l2")
d2_d3_cos_sim = sim2(dtm2, dtm3, method = "cosine", norm = "l2")
d1_d3_cos_sim = sim2(dtm1, dtm3, method = "cosine", norm = "l2")

# calculate cosine distance adjusted for tf-idf
dtm = create_dtm(it, vectorizer)
tfidf = TfIdf$new()
dtm_tfidf = fit_transform(dtm, tfidf)
d1_d2_tfidf_cos_sim = sim2(x = dtm_tfidf, method = "cosine", norm = "l2")

# any way to get tfidf_cos_sim for (d1, d3), (d2, d3)?

4

0 に答える 0