Вычислить TCM на основе невзвешенного набора слов, используя text2vec в R?

Я пытаюсь вычислить матрицу совпадения терминов (или TCM) из корпуса, используя пакет text2vec в R (поскольку у него есть хороший параллельный бэкенд). Я следил за этим руководством, но при изучении некоторых игрушечных примеров я заметил, что функция create_tcm выполняет какое-то масштабирование или взвешивание по термин-термин значений совпадения встречаемости. Я знаю, что он использует скип-граммы внутри, но в документации не упоминается, как он их масштабирует - ясно, что более отдаленные термины/униграммы имеют более низкий вес.

Вот пример:

tcmtest = function(sentences){
  tokens <- space_tokenizer(sentences)
  it = itoken(tokens, progressbar = FALSE)
  vocab <- create_vocabulary(it, ngram = c(ngram_min = 1L, ngram_max = 1L))
  vectorizer <- vocab_vectorizer(vocab,  grow_dtm = FALSE, skip_grams_window = 5L)
  return(create_tcm(it, vectorizer))
}

> tcmtest(c("a b", "a b c"))
3 x 3 sparse Matrix of class "dgTMatrix"
  b c   a
b . 1 2.0
c . . 0.5
a . . .  
> tcmtest(c("a b", "c a b"))
3 x 3 sparse Matrix of class "dgTMatrix"
  b   c a
b . 0.5 2
c . .   1
a . .   .
> tcmtest(c("a b", "c a a a b"))
3 x 3 sparse Matrix of class "dgTMatrix"
  b    c        a
b . 0.25 2.833333
c . .    1.833333
a . .    .  

Вопрос: есть ли способ отключить это поведение, чтобы все термины/униграммы в окне скип-грамм обрабатывались одинаково? То есть, если термин дважды встречается внутри контекстного окна другого термина в корпусе, в матрице ТКМ он должен иметь цифру «2».

Бонусный вопрос: как вообще работает масштабирование по умолчанию? Если вы добавите больше «а» к последнему примеру, то значение b-c будет линейно уменьшаться, в то время как значение b-a на самом деле увеличивается, хотя больше вхождений или «a» появляется дальше от «b».


person user3554004    schedule 30.10.2016    source источник
comment
Бонусный вопрос: в последнем примере b — 4-я буква от c. Это 1/4. Для a и c у вас есть a в 1, 2 и 3 буквах от c. Это 1 + 1/2 + 1/3 = 1,833333. Для b и a у вас есть 2 случая, когда a находится рядом с b, а затем еще два случая, когда он находится на расстоянии 2 и 3 от b соответственно. Это 2 + 1/2 + 1/3. Поскольку у вас есть skip_grams_window = 5, c("a b", "c a a a a a a b") и c("a b", "c a a a a a b") дадут тот же результат, что и tcmtest.   -  person Jota    schedule 30.10.2016
comment
@Jota круто, это имеет смысл. Теперь, как мне обойти это масштабирование?   -  person user3554004    schedule 30.10.2016
comment
@user3554004 user3554004 на самом деле вы не используете параллельный бэкэнд в своем примере. Посмотрите, как мы создаем jobs в этой винье. Также хочу добавить, что использование параллельного бэкенда на tcm имеет смысл только для очень больших корпусов.   -  person Dmitriy Selivanov    schedule 31.10.2016
comment
@DmitriySelivanov спасибо за комментарий; Я только начинаю, и это очень полезно. Если вы не возражаете, я спрошу, каков диапазон, в котором корпус (в токенах) будет считаться достаточно большим, чтобы оправдать распараллеливание задания tcm? (насколько я понимаю, при подгонке перчаток по умолчанию используется низкоуровневый параллелизм?)   -  person user3554004    schedule 01.11.2016
comment
@user3554004 user3554004 Подгонка GloVe выполнена с помощью RcppParallel, поэтому нет накладных расходов (как на оперативную память, так и на процессор). tcmcreation отличается — мы вычисляем его для каждого фрагмента, а затем суммируем их, см. здесь. Однако в этом случае мы сталкиваемся с накладными расходами в потреблении памяти... Пока у нас достаточно оперативной памяти, мы можем попытаться увеличить ее параллельно. Но по моему опыту tcm сборка обычно не является узким местом - мы строим один раз, а повторно используем много раз. Создание tcm в 1 теме на английской википедии занимает ~ 2 часа.   -  person Dmitriy Selivanov    schedule 01.11.2016
comment
@ user3554004 теперь (text2vec ›= 0,5) вы можете указать вектор взвешивания непосредственно в функции create_tcm.   -  person Dmitriy Selivanov    schedule 01.02.2017


Ответы (1)


ОБНОВЛЕНИЕ 01 февраля 2017 г. Обновление отправлено на github - теперь вы можете указать вектор взвешивания непосредственно в create_tcm.

Функция взвешивания определяется здесь. Если вам нужен одинаковый вес для каждого термина в окне, вам нужно настроить функцию взвешивания, чтобы она всегда возвращала 1 (просто клонируйте репозиторий, измените определение функции и соберите пакет из исходного кода с помощью devtools или R CMD build):

inline float weighting_fun(uint32_t offset) {
  return 1.0;
}

Однако несколько человек уже просили об этой функции, и я, вероятно, включу ее в следующую версию.

person Dmitriy Selivanov    schedule 30.10.2016