Как стать автором
Обновить

Комментарии 15

Word2vec принимает данные для обучения в виде текстового файла с одной длинной строкой, содержащей слова, разделенные пробелами (выяснил это, анализируя примеры работы с word2vec из официальной документации). Склеил наборы данных в одну строку и сохранил её в текстовом файле.


Неверно. Перевод строки используется как разделитель документов. Соответственно — одна строка, один документ. Это очень полезно, если текст предварительно побит на фразы или составлен из большого количества независимых друг от друга текстов.
Извините, не нарочно ответил ниже.

Я попробовал сейчас на скорую руку просто ввести два абзаца в строку обучающей выборки, ничего заметно не изменилось. Пространство слов из word2vec — это матрица, первый столбец — слова из словаря, начиная со второго по последний — значения компонент вектора. Есть вероятность, что эти значения меняются для слов, которые находятся между переводом строки, но это сложно увидеть. Если получу подтверждение, напишу update.
Смотрите в код, и будет Вам счастье.
Да, счастья бы не помешало.

Вот так модель считывает слова из файла:
void ReadWord(char *word, FILE *fin) {
  int a = 0, ch;
  while (!feof(fin)) {
    ch = fgetc(fin);
    if (ch == 13) continue;
    if ((ch == ' ') || (ch == '\t') || (ch == '\n')) {
      if (a > 0) {
        if (ch == '\n') ungetc(ch, fin);
        break;
      }
      if (ch == '\n') {
        strcpy(word, (char *)"</s>");
        return;
      } else continue;
    }
    word[a] = ch;
    a++;
    if (a >= MAX_STRING - 1) a--;   // Truncate too long words
  }
  word[a] = 0;
}

Из кода видно, что EOL может и не быть в файле, а значит моя фраза абсолютно корректна.
Теперь, что будет, если EOL в файле есть.
Он заменяется на специальное слово:
</s>
Это слово не участвует в расчете частоты, поэтому не выбрасывается из словаря и всегда находится в его начале. Если EOL в тексте несколько, меняется распределение слов, находящихся рядом с EOL. Вот расчет дистанции, если EOL только один:
Word: </s>  Position in vocabulary: 0
          Word   CosDist
1       factor 0.3524520
2  frightening 0.3380254
3        admit 0.3336470
4        scary 0.3289483
5     scariest 0.3148671
6         prom 0.3142520
7         time 0.3083785
8   paranormal 0.3076151
9       cheesy 0.3073355
10   impressed 0.3042146

А вот, если три (текст тот же самый, просто я добавил три EOL):
Word: </s>  Position in vocabulary: 0
1       yelling 0.3524468
2       toddler 0.3464943
3       janitor 0.3398002
4       running 0.3376773
5         drunk 0.3368221
6         bunch 0.3361016
7            iq 0.3348956
8  pathetically 0.3328072
9  unbelievably 0.3261482
10     retarded 0.3218134

А теперь попробуйте из этого что-то понять про абзацы внутри текста.
Удачи!
Найдите место в коде, где идёт непосредственное обучение, и увидите, что по EOL движение по окну прекращается. Впрочем, если Вам важно показать свою правоту — спорить не буду.
Спасибо, Вы правы. Нашел, написал update.
На самом деле разница очень заметна. Всё зависит от корпуса, если у Вас любые тексты, то разбиение их на абзацы/предложения даёт слабый эффект, поскольку тематика текста не сильно изменяется, и соответсвенно, сохраняется при пересечении границы фраз.

Однако, если Вы используете специальные источники информации — в виде коротких, несвязанных друг с другом реплик, то тематика при пересечении границы реплики меняется кардинально, и, соответственно, эффект ощутим.

Такж эффект ощутим, если Вы учитесь с коротким окном — для предсказания грамматических аттрибутов слов и знаков препинания.
Да, спасибо. Пробовал и так, не нашел на что это влияет. В примере от разработчиков одна большая строка на 80 мегабайт: mattmahoney.net/dc/text8.zip
Влияет на качество. Совсем немного, но влияет. Влияние зависит от задачи, конечно, и его трудно измерить без эталона, а эталона у нас нет.
Разница в том, что без перевода строк слова из соседних предложений будут «соседними» и будут влиять друг на друга. Хорошо это или плохо, по-вашему?
Да, спасибо. Уже написал update.
Как и автор топика некоторое время назад заинтересовался той самой задачкой на Kaggle. Только на Python + Gensim. И вот тут меня заклинило и не могу понять один нюанс, т.ч. если кто-то знает — подскажите пожалуйста.
В чем разница между моделями Word2Vec (есть и в gensim и в Google-реализации), Phrase2Vec (есть в gensim, в Google-реализации есть что-то похожее: Word2Phrase), Doc2Vec (есть только в gensim)
С сайта gensim: The training algorithms were originally ported from the C package code.google.com/p/word2vec and extended with additional functionality.

Единственное, чего не понял, почему они не используют оригинальную кластеризацию из word2vec и предлагают взять K-Means из scikit-learn вот в этом примере.
В gensim своя реализация word2vec, там не используется код из оригинальной библиотеки. Поэтому, чтоб не плодить велосипеды и не реализовывать еще и k-means, кластеризации в gensim нет. Она там и не нужна, раз можно взять готовую проверенную реализацию из scikit-learn.
НЛО прилетело и опубликовало эту надпись здесь
Спасибо!
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Изменить настройки темы

Истории