1

我从在线新闻网站收集了一份摘要列表,并使用它们的原始标签(例如,政治、娱乐、体育、金融等)按主题手动标记它们。现在我想比较任何两个主题(例如,标记为“政治”的摘要与标记为“金融”的摘要)之间摘要中单词使用的相似性;但是,由于每个主题下的新闻摘要数量不同,并且任何两个摘要之间的字长也不同,这使得逐篇文档的余弦相似度计算变得困难。

所以我所做的就是通过按主题划分示例数据、解析和提取它们、向量化每个摘要(即行条目)中的标记并构建 dtm 以创建用于比较的向量空间来引用text2vec 小插图。

虽然小插图中列出的方法text2vec很简单,但输出是以矩阵格式生成的。我想知道是否有任何方法可以在标记为两个不同主题的任何两组文档之间获得单个相似性度量(例如,介于 0 和 1 或 (-1, 1) 之间的某个值)?

我在下面提供了我当前的代码,还提供了属于 3 个不同主题的新闻摘要的小 9 行数据(请注意,属于每个主题的文档数量和它们的字长都是不同的:与主题有关的新闻“体育”有两个条目,主题“政治”有四个条目,主题“金融”有三个条目)。不要期望从这么小的数据中得到有意义的相似性结果,它只是作为一个例子。

如果有人能指出修改我现有代码的方法并获得任何两个主题之间的单个成对相似性度量,那将不胜感激。

# 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