Рассчитать суммарный косинус и расстояние Жакара между двумя наборами документов - PullRequest
1 голос
/ 30 сентября 2019

Я собрал список тезисов с новостных сайтов в Интернете и вручную пометил их по темам, используя их оригинальные ярлыки (например, политика, развлечения, спорт, финансы и т. Д.). Теперь я хочу сравнить сходство в использовании слов в аннотациях между любыми двумя темами (скажем, рефераты, помеченные как «политика», и те, которые помечены как «финансы»);однако из-за того, что число новостных выпусков подпадает под каждую тему, различается и длина слова между любыми двумя рефератами также различается, что затрудняет вычисление косинусного сходства документа за документом.

Поэтому я сделал ссылку на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)?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...