Word2Vec в примерах

Волею судеб в мои руки попал обученный на поисковых запросах Word2Vec. Под катом даны примеры использования с пояснениями.

Что есть Word2Vec?

Word2Vec — это технология от гугл, которая заточена на статистическую обработку больших массивов текстовой информации. W2V собирает статистику по совместному появлению слов в фразах, после чего методами нейронных сетей решает задачу снижения размерности и выдает на выходе компактные векторные представления слов, в максимальной степени отражающие отношения этих слов в обрабатываемых текстах. Советую почитать первоисточник, дабы не полагаться на мой путанный пересказ технологии.

Какой Word2Vec исследовался?

Для обучения были взяты запросы к отечественному интернет-поисковику, соответственно — в массе своей русскоязычные. Длина вектора — 256 элементов, доступны как для алгоритма «skipgrams», так и «bag of words». Общее количество слов — более 2.6 миллиона, это все слова русского языка, многие слова из других языков, опечатки, названия и коды — в общем всё, что только люди могли искать.

Запросы к поисковику сильно отличаются по характеристикам от обычных текстов, и это даёт некоторое новое качество результатов.

Опечатки

./distance vectors.bin
Enter word or sentence (EXIT to break): преключение

Word: преключение Position in vocabulary: 124515

Word Cosine distance
— приключение 0.748698
преключения 0.726111
приключения 0.692828
приключеия 0.670168
прключение 0.666706
приключеня 0.663286
прключения 0.660438
приключени 0.659609


К нашим услугам не только разрешение опечаток в запросе, но и полный перечень всех опечаток, совершаемых людьми. Все опечатки собраны в единый кластер, что удобно. Отличие от систем проверки правописания — кардинальное. Ведь опечатка разрешается не методом вычисления расстояния Левенштейна (минимальное количество изменений, необходимых для получения из ошибочной формы правильной), а по статистике реальных ошибок реальных пользователей.

Транслитерация, не та раскладка

./distance vectors.bin
Enter word or sentence (EXIT to break): avito

Word: avito Position in vocabulary: 1999

Word Cosine distance
— awito 0.693721
авито 0.675299
fvito 0.661414
авита 0.659454
irr 0.642429
овито 0.606189
аviто 0.598056


./distance vectors.bin
Enter word or sentence (EXIT to break): пщщпду
— пщщщпду 0.723194
пщщпд 0.721070
пщпд 0.712373
пщппду 0.704579
пщщаду 0.695897
пщщпдк 0.694641
пщпду 0.692646
ппщду 0.681183
пщщп 0.660203
пгпд 0.653649
гугл 0.649897
поопду 0.647420
ппщпду 0.643923
пщщплу 0.641619
нфтвуч 0.640587
пщщпдуюкг 0.631423
пщщпу 0.620105
gogle 0.616396
иштп 0.612234
google 0.608240


Хотя задачи транслитерации и исправления неверной раскладки и решаются более простыми и быстрыми методами, всё равно приятно, что Word2Vec способен здесь не подкачать.

Названия сайтов, сайты-аналоги

./distance vectors.bin
Enter word or sentence (EXIT to break): гугл
— гугол 0.850174
гугле 0.809912
гогл 0.786360
гугль 0.760508
гоогл 0.734248
гуг 0.731465
гугла 0.726011
гуугл 0.725497
гкгл 0.724901
гугул 0.722874
гогле 0.719596
гугд 0.719277
гугел 0.715329
гугал 0.713950
яндекс 0.695366
google 0.690433
googl 0.669867


./distance vectors.bin
Enter word or sentence (EXIT to break): mail
— rambler 0.777771
meil 0.765292
inbox 0.745602
maill 0.741604
yandex 0.696301
maii 0.675455
myrambler 0.674704
zmail 0.657099
mefr 0.655842
jandex 0.655119
gmail 0.652458
вкmail 0.639919


Кластеризация слов — основная функция Word2Vec, и как видно, работает она хорошо.

Семантически близкие слова

./distance vectors.bin
Enter word or sentence (EXIT to break): кофе
— коффе 0.734483
чая 0.690234
чай 0.688656
капучино 0.666638
кофн 0.636362
какао 0.619801
эспрессо 0.599390
кофя 0.595211
цикорий 0.594247
кофэ 0.593993
копучино 0.587324
шоколад 0.585655
капучинно 0.580286
кардамоном 0.566781
латте 0.563224


./distance vectors2.bin
Enter word or sentence (EXIT to break): кофе
— зернах 0.757635
растворимый 0.709936
чая 0.709579
коффе 0.704036
mellanrost 0.694822
сублемированный 0.694553
молотый 0.690066
кофейные 0.680409
чай 0.679867
декофеинизированный 0.678563
капучино 0.677856
monoarabica 0.676757
свежесваренный 0.676544
декаф 0.674104
гевалия 0.673163
расстворимый 0.659948
etiopia 0.657329
электротурке 0.652837


Первая выдача — Word2Vec в режиме «skipgrams» — то есть в режиме выделения слов по их окружению, тогда как вторая выдача — Word2Vec в режиме «bag of words» — выделение слов вместе с их окружением. Первая — слова, взаимозаменяемые с кофе, во втором — слова, характеризующие кофе. Вторая выдача особенно полезна, когда мы начинаем задумываться, как оценить важность слов в запросе. Какое слово является главным, а какое конкретизирует запрос.

Кластеризация запроса

./distance vectors2.bin

Enter word or sentence (EXIT to break): мобильный телефон
— сотовый 0.811114
телефона 0.776416
смартфон 0.730191
телфон 0.719766
мобильного 0.717972
мобильник 0.706131
телефо 0.698894
тлефон 0.695520
тлф 0.693121
мобильнный 0.692854
телеон 0.688251
телефоны 0.685480
телефрн 0.674768
сотового 0.673612


Запрос, составленный из нескольких слов, может быть сведён к одному, наиболее характерному слову. Причём совершенно необязательно, что это слово присутствует в оригинальном запросе вообще. Можно сравнивать многословные запросы между собой и без промежуточной трансляции к одному слову. Здесь мы видим перефразировку и расширение запроса в действии.

Семантические отношения между словами

Самый интересный участок описания Word2Vec у гугла — это как они превращали короля в королеву нехитрыми арифметическими операциями над векторами. На поисковых запросах такой фокус провернуть не удалось, мало в последнее время ищут королей и королев, но кое-какие семантические отношения действительно выделяются.

Требуется найти такое слово, которое относится к Германии так-же, как Париж относится ко Франции.

./word-analogy vectors2.bin

Enter three words (EXIT to break): франция париж германия
— мюнхен 0.716158
берлин 0.671514
дюссельдорф 0.665014
гамбург 0.661027
кельн 0.646897
амстердам 0.641764
франкфурт 0.638686
прага 0.612585
ашаффенбург 0.609068
дрезден 0.607926
нюрнберг 0.604550
люденшайд 0.604543
гмунден 0.590301


./word-analogy vectors2.bin

Enter three words (EXIT to break): сша доллар украина

— гривне 0.622719
долар 0.607078
гривны 0.597969
рубля 0.596636
доллара 0.588882
гривна 0.584129
рублю 0.578501
рубль 0.574094
доллару 0.565995
тенге 0.561814
долара 0.561768
валют 0.556239
доллор 0.548859
гривня 0.544302


Впечатляет…

Оценка важности слов в запросе

Принцип оценки прост. Надо определить, к какому кластеру тяготеет запрос в целом, а потом выбрать слова, максимально удалённые от центра этого кластера. Такие слова и будут главными, а остальные — уточняющими.

./importance vectors.bin

Enter word or sentence (EXIT to break): купить пиццу в москве

Importance купить = 0.159387
Importance пиццу = 1
Importance в = 0.403579
Importance москве = 0.455351

Enter word or sentence (EXIT to break): скачать сумерки

Importance скачать = 0.311702
Importance сумерки = 1

Enter word or sentence (EXIT to break): владимир путин

Importance владимир = 0.28982
Importance путин = 1

Enter word or sentence (EXIT to break): никита путин

Importance никита = 0.793377
Importance путин = 0.529835


Владимир для Путина — слово почти неважное. Почти все Путины, встречающиеся в интернете — Владимиры. А вот Никита Путин — наоборот, Никита важнее. Потому что необходимо из всех Путиных в интернете выбрать именно Никит.

Выводы

Как таковых выводов здесь немного. Технология работает и работает хорошо. Надеюсь, что данный пост будет использован в качестве иллюстрации на русском языке к тем возможностям, которые скрыты в Word2Vec.
Поделиться публикацией

Похожие публикации

Комментарии 35
    0
    Спасибо огромное!
    Описано много очень полезных применений, до которых сходу не додуматься…
    (Где бы большую базу поисковых запросов получить, только для английского языка?)

    >к какому кластеру тяготеет запрос в целом, а потом выбрать слова, максимально удалённые от центра этого кластера
    Применяете суммирование для выбора «к какому кластеру тяготеет запрос», или что-то другое?
      0
      Простое суммирование. Я пока не встречал упоминаний о применении к векторам других операций кроме сложения и вычитания. Про базу — увы, помочь не смогу. Но подозреваю, что всё возможно.
        0
        Кстати, про английский язык. Несмотря на то, что поисковик отечественный, доля запросов на английском в логах — достаточная для:

        ./distance vectors.bin
        Enter word or sentence (EXIT to break): mobile phone

        Word: mobile Position in vocabulary: 4535

        Word: phone Position in vocabulary: 4638

        Word Cosine distance
        — phon 0.700428
        mobail 0.695479
        fhone 0.652987
        admod 0.649055
        android 0.646858
        phine 0.621545
        i9377 0.617742
        phohe 0.614031
        controlapp 0.613575
        sphone 0.611676
        smartphone 0.611611
        rewie 0.610843
        у171 0.608957
        modile 0.608724

        Enter word or sentence (EXIT to break): tea

        Word: tea Position in vocabulary: 21903

        Word Cosine distance
        — coffee 0.643698
        polyphenols 0.635377
        oolong 0.632906
        tieguanyin 0.619304
        manalishi 0.617811
        kusmi 0.613416
        bagging 0.600910
        gretna 0.600548
        lemon 0.597524
        herbs 0.595191
        knutsen 0.591500
        rooibos 0.587569
        lipton 0.585795
        tikuanyin 0.585217

        ./word-analogy vectors.bin
        Enter three words (EXIT to break): france paris germany

        Word: france Position in vocabulary: 26295

        Word: paris Position in vocabulary: 14409

        Word: germany Position in vocabulary: 30576

        Word Distance
        — zittau 0.543055
        köln 0.542991
        koln 0.531496
        bodensee 0.526570
        vienna 0.524553
        moskau 0.517277
        berlin 0.514151
        pulitzer 0.513104
        flemings 0.511986
          0
          Тут покопался, есть ещё любопытная штука — переводы:

          Enter three words (EXIT to break): france франция germany

          Word: france Position in vocabulary: 26651

          Word: франция Position in vocabulary: 4784

          Word: germany Position in vocabulary: 30582

          Word Distance
          — германия 0.748171
          англия 0.692712
          нидерланды 0.665715
          великобритания 0.651329
          польша 0.643118
          голландия 0.634778
          португалия 0.631533
          венгрия 0.631244
          дания 0.630158
          австрия 0.627997
          бельгия 0.624365
          румыния 0.623177
          италия 0.609178
          швейцария 0.601199
          япония 0.600262
          норвегия 0.590909
          испания 0.588349
          шотландия 0.572040
          чехия 0.571055
      0
      А где Вы взяли vectors.bin и vectors2.bin? На странице проекта только Wikipedia, Google news и подобное.
        0
        OK, дисклаймер для тех, кто хочет попробовать.
        Судя по всему, файлы ./demo-word.sh и ./demo-phrases.sh, а также всё остальное не работают на виртуальных машинах. обсуждение. Видимо, потому на digitalocean машине не получилось это запустить.
          0
          Судя по всему, файлы ./demo-word.sh и ./demo-phrases.sh, а также всё остальное не работают на виртуальных машинах.

          Ну убунте работают без проблем, «из коробки». Они сначала выкачивают сотню мегабайт текста, а потом по нему учатся. Текст, разумеется, на английском. Кстати, у меня есть непонимание/несогласие с гуглом. У них текст идёт сплошняком, без разбивки на фразы, а я всё-же считаю, что на фразы бить надо.

          А где Вы взяли vectors.bin и vectors2.bin?

          Они были получены обучением по логам поисковых запросов.
            0
            Хм… а где Вы взяли логи поисковых запросов?
              0
              «Волею судеб в мои руки попал...» и далее по тексту.
                0
                Не известная ли база П**ва?
        0
        В какой кодировке загружать в него текст?
        Пробовал UTF-8 и Windows-1251. В результате у него в базе все в иероглифах.
          0
          под линуксом — UTF8, под windows — cygwin и тоже UTF8
          +1
          На отдельный пост не тянет, но хочу поделиться результатами решения одной специфичной задачки. Хочется сделать чат робота на естественном языке, для чего нужно на каждую реплику, которую говорят роботу, генерировать наиболее подходящие варианты ответной реплики. При этом, в большей степени важно не содержание ответной реплики, а её грамматический строй. На вопрос надо говорить ответ, на приветствие — приветствие, и так далее.

          Есть нафармленный в интернете массив диалогов, в виде — реплика, ответная реплика. Диалоги на любую тему, из художественной литературы, общим объёмом порядка 70 миллионов реплик.

          Диалоги можно конвертировать в набор документов для обучения Word2Vec следующим образом:

          Q1_Добрый Q2_день A1_Здорова A3_коли A4_не A5_шутишь.

          Q — маркировка первой фразы (вопроса или стимула), A — маркировка второй фразы (ответа). Цифры — позиция слова в фразе. Обучившись в течении примерно месяца в режиме Bag of Words (слова, которые встречаются рядом с исследуемым словом) получаем следующие возможности:

          1. Поиск близких по структуре и смыслу фраз (переформулировка).

          Скажи-ка дядя, ведь недаром, Москва, спалённая пожаром, французу отдана?
          0.914966: Скажи-ка об этом самим ужам-охотникам:
          0.893654: Скажи-ка свое полное имя.
          0.891312: Ну-ка взгляни, Семен,
          0.873881: Поищи-ка таких, да и нам скажи.
          0.873735: Ну-ка объясни, это любопытно!
          0.873634: Ну-ка говори, Валя, что случилось?
          0.872774: Ну-ка посмотрите: полезная вещь или нет?
          0.872202: Ну-ка вставай, завтра обижаться будешь,
          DONE.

          Добрый день!
          1: Добрый день!
          1: Добрый день!
          0.954915: Добрый день! Узнали меня?
          0.952281: Добрый день! Можно?
          0.948676: Добрый день! Вы
          0.940227: Добрый день! Добрый вечер!
          0.937763: Добрый день! Машина испортилась?
          0.93659: Добрый день! спросила она после едва заметного кивка.
          DONE.

          Какого цвета трава?
          0.980484: Какого цвета машина?
          0.978484: Какого цвета волосы?
          0.977465: Какого цвета костюм?
          0.977016: Какого цвета глаза?
          0.975344: Какого цвета хоть?
          0.97237: Какого цвета пламя?
          0.955668: Какого цвета волосы? Длинные или короткие?
          0.955133: Какого цвета туфли подойдут?
          DONE.

          Скажи мне правду.
          1: Скажи мне правду.
          0.967608: Скажи мне правду. Скажи!
          0.89703: Скажи мне правду. Ты даешь мальчишке курить травку?
          0.896007: Скажи мне правду. Ты же хотел поговорить.
          0.895684: Говори мне правду.
          0.893773: Скажи мне правду. Это мой ребенок?
          0.8775: Расскажите мне правду.
          0.868331: Рассказать мне правду.
          DONE.

          Лошади едят овёс и сено.
          0.841129: Наши взяли Охабы и Зеленцы.
          0.833975: Китодоны едят планктон объяснил Акбар.
          0.821173: Внизу все плачут и молятся.
          0.820205: Люди пьют и лечатся.
          0.818104: Там французский, биология и математика.
          0.815571: Там мсье Хамит и Анри.
          0.814675: Их считают напыщенными и самодовольными.
          0.813978: Ты крикнула Рикса и отшатнулась.
          DONE.

          2. Поиск наиболее подходящих ответных реплик.

          Пошёл к чёрту.
          0.358482: Сам пошел.
          0.218869: Сам пошел, хер моржовый.
          0.211025: Ладно. К черту извинения.
          0.192231: Небось к молодым пьяный не пошел.
          0.182824: Сам сходи. Чего раскомандовался?
          0.180226: Сам пошел. В сопровождении товарищей.
          0.166116: Сам бросился.
          0.161054: Сам таким стать хочешь?
          DONE.

          Скажи-ка дядя, ведь недаром, Москва, спалённая пожаром, французу отдана?
          0.324889: Каков дядя Коля-то, а?!
          0.287213: А и ну ее вправду!
          0.271654: Нету, говорим, дядя.
          0.250956: Есть тетка, дядя — брат отца.
          0.238712: Однако хорош ты, мой батюшка!
          0.238036: Скоро ль у тебя эта-то?
          0.23739: Да подойди, бабушка, поближе.
          0.236985: Напрасно совершенно: Он генерал.
          DONE.

          Добрый день!
          0.413948: Здравствуйте! Добрый день!
          0.39247: Здравствуйте, добрый день!
          0.375028: Добрый день! Кто там? Да заходите же!
          0.368717: Добрый день! Как поживаете?
          0.368398: Уф! Добрый вечер!
          0.359914: Добрый день! Как спалось?
          0.358044: День добрый, Слушаю вас!
          0.357747: Добрый день! Как вы там поживаете?
          DONE.

          Какого цвета трава?
          0.330939: Порошок желтого цвета.
          0.311489: Цвет красный был.
          0.292815: Волосы какого цвета?
          0.292406: Белого.
          0.288948: Насыщенные цвета всем идут.
          0.2826: А глаза? Такого яркого синего цвета?
          0.282592: Они голубого цвета. Очень светлые.
          0.28217: Любой подойдет. Они одинакового цвета.
          DONE.

          Скажи мне правду.
          0.423083: Правду? Всегда.
          0.41969: Всю правду?
          0.398263: Да какую правду?
          0.381713: Но не всю правду.
          0.375799: Скажи ему всю правду.
          0.372596: Что? Какую правду?!..
          0.37069: Просто скажи мне правду.
          0.334264: Ему я скажу правду.
          DONE.

          Лошади едят овёс и сено.
          0.332526: Лошади едят каждый день.
          0.297902: И лошади едят?.. Такое?
          0.243042: Пусть их собаки едят! А пленные есть?
          0.241101: Но и овец убивают.
          0.233398: Едят, привычные они к соленому.
          0.231596: Так лошади тоже еще живут?!
          0.225183: Как много лошадей!
          0.219477: Да. Лошадей и коров достаточно.
          DONE.

          Особенно мне нравится «Порошок желтого цвета», именно потому, что превратить его в «Трава зеленого цвета» — довольно просто. С этим можно работать.
            0
            Я бы предложил тебе посмотреть на arxiv.org/pdf/1506.05869v2.pdf и подобные работы.
            word2vec неплохо обобщает, но дальше тебе нужно породить сильно нелинейную структуру, а ты её аппроксимируешь линейной — типа как в SVM.
            А пока что наиболее интересный обобщатель для нелинейных структур, типа «thought vector» — LSTM.
              0
              Спасибо за ссылку на статью, я её уже видел. Подход гугла понятный, но мне не нравится — я не люблю нейронные сети именно из-за эффекта «чёрного ящика». Вроде работает, но как — непонятно. Плюс к этому — стратегическая задача связаться с онтологиями, что для нейронной сети будет трудно сделать — там графовая структура представления информации, а сетки пока нормально умеют работать с векторами фиксированного размера (в крайнем случае — с их последовательностями).

              А word2vec хорош низким порогом вхождения — прикрепи к словам дополнительные идентификаторы — и можно учиться в стиле «стимул-реакция», причём на последовательностях. Узнавание последовательностей по их неполной части — «из коробки».
                0
                Да, но у вас тогда будет аналог линейной регрессии, применённой к каждому элементу последовательности. Нету обобщения между элементами, есть только поиск похожей синтаксической структуры.
                Особенно показателен этот пример (синтаксис полностью поработил семантику):
                >>Лошади едят овёс и сено.
                >Внизу все плачут и молятся.

                В отличие от этого, RNN/LSTM/Memory networks допускают перестановки элементов. Не обязательно автоматически строить фразу, можно считать Paragraph Vectors и потом искать ближайший, скажем, как в методах Paraphrase detection.
                Мне кажется, даже аналог SVD, применённый к векторам-как-элементам показал бы неплохие результаты в передаче смысла, но увы, наше векторное пространство в word2vec одноэлементно.

                Но главная причина же не в этом, а в том, что у всех методов невысокое качество работы, и непонятно, как его увеличивать.
                Причём, наиболее вероятно, что причина низкой точности — небольшая доступная вычислительная мощность (по сравнению с человеком).
                Поэтому, как и с экспертными системами в 70е, приходится смириться с невозможностью решения произвольных задач, и решать узкие задачи в конкретной предметной области.

                Но графы, которые используются для статистики наподобие наивного байеса — почти ничем не отличаются от графов, скормленных нейросети, и поэтому уже хранящихся в виде знаний внутри нейросети — того же word2vec. При иллюзии простоты редактирования, проблемы с массовыми ошибками ассоциативности в графовом представлении всё равно не решить — а значит, точность ассоциативных рассуждений даже до 95% всё равно не довести — и логические рассуждения так и останутся недоступными.

                Я видел много разных моделей, мне больше всего понравилась идея из работы по переводу, где похожие фразы, например, «какого цвета трава» и «цвета трава» подавались в нейросеть со знаком плюс, а непохожие — со знаком минус. Подобная сеть неплохо научалась выделять понятия, и кластеризовать уже понятия, а не слова, что использовалось в дальнейшем для построения базы переводов.

                Да и вообще, не зря во всех выдающихся работах анализируют структуру получившихся векторов, например, лежат ли «three days ago» и «a couple of days ago» рядом? как далеко от них «three days grace» (название муз.группы) и «3 days ago»?

                Мне кажется, будущее всё же за «фразовым мышлением» — thought vectors или как нибудь ещё его можно назвать. Можно прикинуть и основные операции, которые компьютер должен научиться производить с такими объектами. Основная проблема, мне кажется — в критериях оптимизации. У нас нет огромных dataset-ов для подобных задач, а unsupervised обучение компьютеру доверить тоже мы не можем. Поэтому нужно найти такие критерии оптимизации, которые позволят научить данные thought vectors, а потом ещё и увеличить их точность до высокого уровня. Вот тогда можно уже и на ИИ замахнуться.
                Как пример, можно представить, что модели мы скармливаем данные вида «собака — животное» (и другие графовые связи), и получаем более точное внутреннее представление. И проблема word2vec будет тогда в том, что она на данных знаниях мало чему научится. А значит, нужно искать другие мат. модели для обучения, дополняющие word2vec.
                  0
                  Собственно, я ставил перед собой узкую задачу — угадать синтаксическую структуру ответа, и я её, в целом, получил. Типичные реакции на типичные ситуации передаются верно (приветствие, посыл, простой вопрос), а что реакции на нетипичные реплики странные — тоже правильно. Разбуди человека ночью и заяви ему, что лошади едят овёс и сено, что он ответит?

                  Дальнейшее направление исследований — это связать синтаксическую структуру, которую угадывает word2vec с онтологическими данными, что-бы отвечать верно. Взять реплику, и заменить в ней слова на более подходящие с точки зрения онтологии. (порошок->трава, желтый->зеленый).

                  Разумеется, качество — это больная тема, но я в целом научился с этим жить. По сути, что делается в приведённом примере — из миллионов фраз в базе отбираются наиболее похожие — то есть мы имеем дело с фильтром. Следующий уровень обработки — онтологический, ещё раз профильтрует результаты уже своим критерием подобия — и в результате качество системы в целом выше качества отдельных элементов.

                  А по нейронным сетям — моё убеждение в том, что это — очень крутая ассоциативная память, частный случай чего — классификация, но не более того. Даже показывающие удивительные результаты глубокие сетки по распознаванию образов — всего-лишь фильтры. Никакой обработки уровня — поиск, алгебраические операции, (заданная из-вне) последовательность преобразований, условные переходы и т.д. они не делают и научиться им не могут. Они только выделяют всё более и более обобщённые признаки.

                  А вот векторные репрезентации позволяют над собой алгебраические выражения, и это очень обнадёживающий результат. Я пока ещё не сделал чего-либо стоящего, основанного на алгебраических операциях с векторами, но вот приведённый пример основан на двух обученных на разных выборках w2v моделях — первая фильтрует исходную базу реплик, вторая — результаты первой.

                  Хочу поблагодарить за развёрнутый комментарий.
                    0
                    >А по нейронным сетям — моё убеждение в том, что это — очень крутая ассоциативная память, частный случай чего — классификация, но не более того.
                    Это относится к CNN и DNN, но не к RNN и LSTM ( и RLSTM ).
                    Как насчёт NTM — arxiv.org/pdf/1410.5401.pdf, например?

                    >А вот векторные репрезентации позволяют над собой алгебраические выражения
                    Да, но с композицией элементов у них зачастую проблемы (описанные выше).
                    Поэтому, мне кажется, на этом нестойком базисе многого не построить…
                    Более того, у меня даже не получилось сделать обобщение на word2vec. Конкретизацию — пожалуйста (животное -> кошка), а вот обобщения (кошка -> животное) — никак, как не складывай и не вычитай.
                      0
                      А кошка в животное и не должна обобщаться! Почему кошка не может быть обобщена в мебель, допустим? У кошки 4-ре ноги и у стола 4-ре. Операция обобщения не однозначна, и поэтому на одной только кошке не выполняется. Для обобщения нужно представить несколько образцов, и тогда можно по ним попытаться найти что-то общее у всех образцов.

                      Кошка+собака — можно обобщить, а вот одну кошку — увы. Вообще, дистрибутивная семантика плохо работает с холонимами, в первую очередь потому, что слова и их холонимы используются в разных контекстах.

                      Вот пробный запрос (отсюда):

                      Пример: найти слово, относящееся к германия(N3) так-же, как париж(N2) относится
                      ко франция(N1).

                      Введите слово N1 или слова через пробел: помидор

                      Введите слово N2 или слова через пробел: овощ

                      Введите слово N3 или слова через пробел: кошка
                      0 2 1 3
                      0.472403 кошка
                      0.391753 собака
                      0.364417 крыса
                      0.360809 кошла
                      0.360232 кощка
                      0.358643 кошечка
                      0.357764 обезьяна
                      0.354727 хорек
                      0.349705 кшка
                      0.345378 ккошка
                      0.338477 котенок
                      0.338374 свинья
                      0.330688 кошкка
                      0.328142 овощ
                      0.327775 соака
                      0.327326 ящерица
                      0.327241 корова
                      0.325841 когка
                      0.323104 когшка
                      0.321451 зверек
                      0.321205 песик
                      0.318688 соукок
                      0.318338 кожка
                      0.318013 клшка
                      0.317046 кошлка
                      0.316687 шиншила
                      0.316463 кот
                      0.316026 щенок
                      0.315154 кошку
                      0.314993 кошшка
                      0.314982 хомяк
                      0.314901 животное

                      Зверёк и животное есть. Не на первых местах, но первые среди слов-категорий. Так что результат есть.

                      Пример: найти слово, относящееся к германия(N3) так-же, как париж(N2) относится
                      ко франция(N1).

                      Введите слово N1 или слова через пробел: женщина

                      Введите слово N2 или слова через пробел: человек

                      Введите слово N3 или слова через пробел: автомобиль
                      0 2 1 3
                      0.450121 автомобиль
                      0.373478 автомабиль
                      0.371639 атомобиль
                      0.334057 автмобиль
                      0.329021 автомбиль
                      0.328257 автомобиь
                      0.319911 авомобиль
                      0.316612 грузовик
                      0.316434 автомоболь
                      0.312129 автомоюиль
                      0.311415 автомобил
                      0.310067 автомобилб
                      0.308379 автомобль
                      0.305905 автомобтль
                      0.30455 автоиобиль
                      0.298649 автомоиль
                      0.296978 внедорожник
                      0.286245 втомобиль
                      0.284361 автотранспорт
                      0.282785 автомашину
                      0.275992 человек
                      0.272112 транспорт
                      0.271725 автомобиля
                      0.269501 мотоцикл
                      0.268852 микроавтобус
                      0.268144 автомашины
                      0.267909 автомобильв
                      0.26704 спорткар
                      0.266921 автомоьиль
                      0.265216 автомобидь
                      0.264765 автобобиль
                      0.26319 автоьобиль

                        0
                        Вот и я ровно о том же. Существование ответа в результатах не означает возможность его выбрать (например, «спорткар» и «внедорожник» — это не обобщения автомобиля, да и «транспорт», кстати, тоже не идеален — «транспортное_средство» или «средство_передвижения» было бы более хорошим ответом). Получается, даже если не учитывать отсутствие терминов и проблему многозначности слов, пространство word2vec весьма своеобразно — даже онтологию из него никак не построить, разве что от обратного — по каждому слову строить листья. Можно порассуждать о его устройстве на основе данного эксперимента, кстати: видимо, действительно фиксируется наличие тех или иных тем и категорий, и гипонимы, холонимы и гиперонимы находится в другой категории, нежели само слово — а может, просто у нас нет «матрицы извлечения».
                        Поэтому, если рассуждать как инженер, к word2vec нужно сбоку ещё приделать базу функций (матричных преобразований), которые будут выполнять данные операции (и многие другие). И что интересно, LSTM и Memory Networks как раз при определённых условиях и научаются данным преобразованиям автоматически, и это также то, чем занимается сейчас MetaMind с Ричардом Сочером.
                        На мой взгляд, у графового представления есть «точность», но ценой многократного доступа к этому самому графу (и операций вида «поиск пересечения подграфов»). В случае НС это означает мышление наподобие человеческого, когда мы проходим по цепочке ассоциаций, сознательно следуя какой-либо цели. Способ весьма трудоёмкий для НС, но на алгоритмы тоже трудно полагаться: разных задач такого вида в лингвистике на самом деле тысячи (если не миллионы), и для каждого должен быть написан и отлажен алгоритм.
                        На мой взгляд, нейросети перспективнее, и я считаю, что алгоритмы тоже напишут — но уже на основе внутренностей нейросетей. Альтернативы нет — объём логической работы при ручном написании алгоритмов зашкаливает. Я сражён количеством затраченных тысяч человеко-лет командами IBM и ABBYY, но и они недалеко ушли на этом пути.
                          0
                          На самом деле, если не решать сфероконическую в вакууме задачу, а вполне практическую, то результат хороший. Количество категорий и их названия известны заранее, надо лишь выбрать наиболее подходящую категорию — что и решается.

                          Если у нас есть не только одно слово, а несколько (кошка+собака) мы можем сравнить их вектора, и выделить в них совпадающие части, замаскировав не совпадающие. Тогда эта маска и будет нам сигнализировать о том общем, что есть у кошки с собакой. Качество, соответственно, вырастет.

                          А в целом согласен, будущее за самообучением, но не только нейросети умеют самообучаться.

                          Я давно уже, сделал такую программку — на вход ей подаёшь просто текст, а она по нему учится — выделяет слова, объединяет словоформы в леммы, даже учитывает контекст использования слов. В общем, при достаточной вычислительной мощности вполне могла-бы на голых текстах самостоятельно построить модель грамматики и семантики. Но только таких мощностей у меня нет и сейчас. И от вычислительной бедноты приходится помогать самообучению, упрощаю ему задачу.
                            0
                            Ну, бывают простые практические задачи — с небольшим количеством вариантов выбора, а бывают сложные.
                            Всё же для сложных задач точность пока остаётся низкая.
                              0
                              Поскольку в дистрибутивной семантике всё в кучу свалено, и один вектор показывает отношения к совершенно разным классам, приходится использовать специальные приёмы. Один из приёмов — маскировать совпадающую часть вектора, игнорируя различия. Другой приём — проверять само слово (слова с опечатками отбрасываются расстоянием Левенштейна). Третий — вычислять для каждой пары слов расстояние не между ними, а расстояния от каждого слова до какого-либо известного класса.

                              В общем, работать с этим можно. И после тщательной фильтрации разными методами (в том числе, и комбинируя bag of words со skipgrams) можно получить достойный результат.
                                0
                                >маскировать совпадающую часть вектора, игнорируя различия
                                Это, кстати, очень близко к «умножение векторов + нормализация». Кажется, обобщает эта операция тоже плохо.
                                  0
                                  Тут есть нюанс. использовать просто метрику расстояний между двумя векторами — это самый первый уровень. Надо двигаться дальше. косинусная мера двух векторов — уже финальна, с ней ничего больше не сделаешь. А маска — это всё ещё вектор. И позволяет применять маску к другим векторам или маскам. В общем — добавляется ещё один слой абстракции.
            0
            Из дампа Википедии были сформированы параллельные корпуса на всех 18-ти википедишных языках. Полученный файл был обработан Word2Vec и получилась система контекстного перевода. Будет использоваться для поиска документов заданной тематики на языках, отличных от языка запроса.

            Введите слово или слова через пробел:RU_москва

            0.579093 IT_mosca
            0.570936 PL_moskwie
            0.557698 NL_moskou
            0.552103 TR_moskova
            0.536993 ES_moscu
            0.532674 TR_leningrad
            0.52744 ID_moskow
            0.52723 PT_moscou
            0.526843 CA_moscou
            0.524709 BG_терехова
            0.524614 JA_александр
            0.524121 FR_moscou
            0.523554 EN_moscow
            0.522341 PL_moskwy
            0.522106 PL_moskiewski
            0.520342 PL_moskiewskiego
            0.520249 TR_moskova'daki
            0.519362 NL_berdjajev
            Введите слово или слова через пробел:RU_танк

            0.657016 HU_harckocsi
            0.643691 CS_tank
            0.631459 KO_???
            0.623628 TR_tank?
            0.612579 EN_tank
            0.606415 TR_tank
            0.600694 NL_tank
            0.593738 NL_infanterietank
            0.59336 PL_czolgu
            0.584318 NL_p40
            0.580372 CS_tanku
            0.572931 PL_czolg
            0.570553 FR_char
            0.570018 TR_tanklar
            0.56356 TR_tank?n?n
            0.562542 CA_tanc
            0.562034 HU_harckocsit
            0.562034 IT_carro
            Введите слово или слова через пробел:RU_авианосец

            0.613862 PL_lotniskowiec
            0.588073 ES_portaaviones
            0.586264 KO_?????
            0.559015 IT_portaerei
            0.558327 NL_vliegdekschip
            0.556856 TR_kaga
            0.554292 KO_?????
            0.554128 ID_vikrant
            0.552238 KO_????
            0.551526 CS_hangarem
            0.547447 KO_?????
            0.545792 BG_самолетоносач
            0.543293 DE_flugzeugtrager
            0.525439 EN_dedalo
            0.525159 CA_portaavions
            0.51567 CS_hangar
            0.514644 KO_?????
            0.512221 KO_?????
            Введите слово или слова через пробел:RU_ведьмак

            0.664645 BG_вещер
            0.648184 IT_witcher
            0.614111 IT_geralt
            0.558545 BG_сапковски
            0.528345 EN_geralt
            0.514319 ES_geralt
            0.483989 ES_sapkowski
            0.483642 EN_sapkowski
            0.473411 EN_sap?k?fsk?i
            0.441887 NL_betrayal
            0.439278 JA_???????????
            0.439142 ES_tichy
            0.428241 NL_krondor
            0.427998 HU_lapozgatos
            0.425509 HU_novella
            0.420468 PT_neverwhere
            0.412127 TR_stanislaw
            0.408913 NL_pinhead
              0
              А вот это уже круто! Вот бы ещё сделать это а) для фраз и б) для смыслов, а в идеале, для в) смыслов фраз
              Собственно, и ту и другую работу по отдельности я видел, но вот если были бы смыслы фраз, это было бы вообще классно и революционно.
              По ведьмаку находит «новелла» и «сапковски», как я понимаю, в основе вики-заголовки?
                0
                Короткие абстракты, длинные абстракты, названия категорий и меток. Взято из дампа DBPedia, установлено соответствие по URI ресурса. Всего вырезано 4.4 Гб текстов, которые специально были подготовлены для обучения, в результате обучающий файл — 14.5 Гб. Примерно такого вида:

                RU_лангхаген DE_langhagen RU_нем RU_langhagen DE_ist RU_коммуна RU_германии DE_ein RU_земле RU_мекленбург DE_ortsteil RU_передняя RU_померания DE_der RU_входит RU_состав RU_района DE_gemeinde RU_гюстров RU_подчиняется DE_lalendorf RU_управлению RU_краков DE_süden RU_зее RU_население DE_des RU_составляет RU_659 DE_landkreises RU_человек RU_2009 RU_2003 DE_rostock RU_740. RU_занимает DE_mecklenburg RU_площадь RU_27,17 DE_vorpommern RU_км² RU_официальный DE_deutschland RU_код RU_049


                Планирую использовать для расширения поискового запроса словами этой-же тематики на других языках. Для поиска всех документов заданной тематики. Кстати, приведённый пример — это режим skipgrams, что производит впечатление внешне (много прямых переводов и синонимов), но не так хорошо подходит для тематического поиска. BagofWords — в этом смысле лучше.
                  0
                  Попробуйте заменить word2vec на https://github.com/sbos/AdaGram.jl — интересно будет посмотреть на улучшение качества.
                    0
                    Спасибо, знаю таких. Направление движения, в общем, правильное, но не на всех задачах хорошо применимое. На поисковом запросе в 2-3 слова не получится надёжно выделить значение каждого слова, особенно, учитывая, что слова могут быть вообще между собой никак не связаны.
                      0
                      Да, на поисковых запросах, увы, вообще качество тяжело померить и реальный прирост качества всегда намного меньше — ведь для N% запросов есть очевидный ответ, а для ещё M% запросов ответ весьма неочевиден (например, из-за ключевых слов, несоответствующих ответу) и разница есть только для остальных (100%-N%-M%) — а это величина порядка от 1% до 5%, как я понимаю?
                      Но это не значит, что нужно оставить всё как есть.
                      >На поисковом запросе в 2-3 слова не получится надёжно выделить значение каждого слова, особенно, учитывая, что слова могут быть вообще между собой никак не связаны.
                      Значение выделяется автоматически, и корреляции во многих случаях тоже достаточно — и это лучше, чем никогда не определять смысл при переводе — мне кажется, перевод в среднем должен получиться более точным даже для поисковых запросов, впрочем, это только гипотеза, требующая проверки.
                        0
                        Помимо точности важна и полнота. Если мы не можем определить, какое из автоматически нагенерённых значений использовать для слова в запросе, то единственный способ получить нормальную полноту — перебрать все значения. То есть — преимущества перед классическим W2V — нет.

                        Плюс, количество автоматически находимых значений — зависит от эмпирически выбираемых констант обучения, и связь между автоматически найденными смыслами и смыслами из словарей и онтологий — ещё предстоит установить.

                        В общем, надо, конечно, пробовать, но пока этот эксперимент не в приоритете из-за озвученных проблем.
              0
              Не могу кое-что понять. Каким образом утилита distance находит ближайший вектор так быстро? Не перебирать же весь миллион векторов каждый раз. Должна быть какая-то хитрость, вроде индекса? Можете объяснить «на пальцах»?
                0
                именно перебирает миллионы векторов подряд. безо всякой многопоточности, хотя задача прекрасно паралеллится.
                  0
                  В принципе, можно использовать всякие kd-деревья, bsp-деревья, и другие методы фильтрации в многомерном пространстве ( spatial index ), но в текущих реализациях их не используют, потому что для практических целей скорости обычно хватает.

                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                Самое читаемое