Я собрал список тезисов с новостных сайтов в Интернете и вручную пометил их по темам, используя их оригинальные ярлыки (например, политика, развлечения, спорт, финансы и т. Д.). Теперь я хочу сравнить сходство в использовании слов в аннотациях между любыми двумя темами (скажем, рефераты, помеченные как «политика», и те, которые помечены как «финансы»);однако из-за того, что число новостных выпусков подпадает под каждую тему, различается и длина слова между любыми двумя рефератами также различается, что затрудняет вычисление косинусного сходства документа за документом.
Поэтому я сделал ссылку наtext2vec
виньетка путем деления данных моего примера на тему, их синтаксического анализа и обработки, векторизации токенов в каждом реферате (то есть записи строки) и построения dtm для создания векторного пространства для сравнения.
Хотя методы, перечисленные в виньетке text2vec
, просты, выходные данные генерируются в матричном формате. Мне интересно, есть ли способ получить одну меру сходства (скажем, что-то между 0 и 1 или (-1, 1)) между любыми двумя наборами документов, помеченных по двум разным темам?
Я предоставляю свой текущий код ниже, также предоставляются небольшие 9-строчные данные тезисов новостей, которые подпадают под 3 различные темы (обратите внимание, что количество документов, относящихся к каждой теме, и длина их слов различны: в новостях, относящихся к теме «спорт», есть две записи, в теме «политика» - четыре записи, а в теме «финансы» - три записи). Не ожидайте получить значимый результат сходства из таких маленьких данных, это только пример.
Будет очень полезно, если кто-то сможет указать способы изменить мой существующий код и получить одну паруМера разумного сходства между любыми двумя темами.
# 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)?