Nashev / TextBrain

experiments with AI;
http://innenashev.narod.ru
4 stars 1 forks source link

Хранить слова в словаре #161

Open Nashev opened 5 years ago

Nashev commented 5 years ago

Совать строчки (слова, словоформы, URI) в общее дерево, размазывая их по ветвям от корня. А указателем на строку иметь адрес финального листочка. Тогда можно раскатать от него до корня, и восстановить строчку.

Так в файловой системе, по сути, хранятся полные имена файлов — пути размазаны по дереву каталогов. Собственно, можно это дерево строк и на дерево папок отражать...

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

Предположительно, это даст сэкономить на памяти за счет однократного хранения строк.

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

Разматывание слова получится рекурсивным в квадрате...

Размазывание (интеграция в это дерево) получится тоже сложнее... Но, кажется, все равно возможно.

Для отвязки от памяти и облегчения сериализации, особенно независимой, можно ссылкой на такую строку считать не указатель на узел, а его индекс в массиве узлов дерева. Если он будет только расти, номера устаревать не будут. Хэндлы. Сериализуемые.

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

У узла нужны ссылки на соседа, первого ребёнка и на родителя. А так же ссылка на содержимое (строку у корневых узлов или хэндл строки у дочерних) и счётчик использований снаружи.

Хотя, счётчики можно и нужно иметь отдельно, в отдельной таблице. Они не нужны самому дереву, и могут быть контекстно-зависимыми...

Nashev commented 5 years ago

Хотя не, сильно дальше так не пройти: если строчку второго уровня уложить в то же дерево, получится строка, начинающаяся со своей первой буквы, ... хм.. надо пример расписать.

В пустое хранилище кладём «ехал», «ел», «еловый», «ехала», «ела» и «ехать». Это 6 слов длинной 4+2+6+5+3+4=24 символа.

Если не пойти:

В пустое хранилище кладём «ехал»

Добавляем туда «ел»

Добавляем «еловый»

Добавляем «ехала»

Добавляем «ела»

Добавляем «ехать»

А теперь то же самое, если пойти:

В пустое хранилище кладём «ехал»

Добавляем туда «ел»

Добавляем «еловый»

Добавляем «ехала»

Добавляем «ела»

Добавляем «ехать»

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

Интересно было б посчитать количество внешних использований слов, и количество внутренних переиспользований частей слов. И посмотреть топы обоих списков.

Nashev commented 5 years ago

Добавляем «нахал»

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

Добавляем «хахаль» - чтоб и начало было знакомым и середина, и новое окончание

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

Nashev commented 5 years ago

Что-то статистика не сильно вдохновляющая получается.

Символ - это 2 байта (юникод), а то и 1 (UTF-8 при латинице) и плюс накладных расходов на строчку по 12 байт

Узел, про том что номер узла (слова или фрагмента слова) - минимум 4 байта, получается 16 байт - родитель (начало этого слова), сосед (соседнее слово с тем же началом), ребёнок (варианты более длинных слов, начинающиеся на это) и содержимое (окончание этого слова). И куча рекурсивных накладных расходов на кодирование и декодирование.

Неоднозначненько для меня это всё по-прежнему. Надо смотреть, что получится по факту.