Прогнозирование

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

Разглядывать буду прогнозирование последовательности байтов либо же текста UTF-8. Прогнозирование последовательности дробных чисел графиков во многом сходственно, лишь необходимо значения ассоциировать не на равенство, а на принадлежность окрестностям.

Пусть будет поток байтов (либо так текст UTF-8) входящие предсказуемые сведения. Поступающие сведения бережем во множество сохраненной истории. Каждое еще одно поступающее значение учитываем в структуре для скопления статистики:
Я теснее черкал, для чего необходимо экое прогнозирование Творенье искусственного интеллекта.
Тут же я буду обрисовывать лишь метод прогнозирования, без излишней лирики.

Осматривать буду прогнозирование последовательности байтов либо же текста UTF-8. Прогнозирование последовательности дробных чисел графиков во многом сходственно, лишь необходимо значения сопоставлять не на равенство, а на принадлежность окрестностям.

Пусть будет поток байтов (либо так текст UTF-8) входящие предсказуемые сведения. Поступающие сведения бережем во множество сохраненной истории. Каждое еще одно поступающее значение учитываем в структуре для скопления статистики:

struct Stat { uint value; // прогнозируемое значение uint count; // число прошедших эких значений // функция index употребляется шаблонным классом Index — ключ для rb-дерева static uint index(const Stat& s) { return s.value; } Ptrn* owner; double probability() const { return (double)count/(double)owner->sum_count_of_stat; }};// шаблонный класс Index это rb-дерево,// 1-ый параметр шаблона тип значения по тот или другой происходит сортировка,// 2-ой, это класс хранимых значений в участках. Этот класс соответствен держать// функцию index.struct Ptrn { // отдел, подсчитывающий, какое распределение вероятностей будет // руководствоваться за значением value uint value; Index<uint,Stat> index_of_stat; // распределение вероятностей uint sum_count_of_stat; // методом прибавления к текущему value еще в лево // будут образовываться паттерны Index<uint,Ptrn> index_of_prev; static uint index(const Ptrn& s) { return s.value; } Ptrn* owner; // owner->index_of_prev->find(value) == this, // для root этот owner одинаков nullptr};Ptrn root;

В участке root считаем статистику цельных прошедших значений. Возможность каждого из значений будет число этого значения разделять на число цельных значений. Сумма вероятностей Stat находящихся в root равноправна единице распределение вероятностей значений во входящем потоке. Избрав Stat из root с наивеличайшей вероятностью, приобретаем 1-ый прогноз очередной знак на входе в наш метод вероятнее всего будет конкретно этот, с вероятностью посчитанной в этом участке Stat.

Поступает на вход еще одно значение. Его поначалу добавим в статистику участка root. Опосля, для сохраненного входящего значения предшествующего шага, обретаем либо создаем в root в index_of_prev отдел Ptrn подходящий предыдущему значению, и в этот отдел так же прибавляем в статистику текущее значение.

Отдел root будем нарекать нулевым степенью прогнозирования. Множество index_of_prev в root будем нарекать главным степенью прогнозирования.

1-ый ватерпас хранит наиболее исполнительные прогнозы, чем нулевой вероятности прогнозирования значений, при соглашении что предыдущее значение водилось этаким-то. Но сумма вероятностей в каждом участке все одинаково остается единицей.

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

И так будем ветвить от root сквозь index_of_prev. Каждый Ptrn идентифицирует паттерн цепочка поочередных значений складываемая от текущего Ptrn до root сквозь свойство owner, и распределение вероятностей значений прогноза должно за сиим паттерном.

Чем длинее паттерн, тем преимущественно определенности, что конкретно за ним последует. Но чем выше паттерн, тем пореже он встречается, и может не набраться довольно статистики по определенному паттерну. Т.е. какой-то паттерн в скопленной истории встретился итого трижды навряд ли застыл из 3-х случаев будет показательным, какое значение последует за ним, и необходимо употреблять наиболее маленький паттерн, обладающий великую определенность, но наиболее размытое распределение прогноза, пока наиболее высокий не накопит довольно статистики.

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

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

Разделим скопленные статистики на определившиеся и не определившиеся. Так, ежели sum_count_of_stat в Ptrn делается преимущественно 100, то его начинаем считать определившимся, и по нему начинаем считать подветви index_of_prev. (Жаждая не для цельных случаев надо накапливать до 100).

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

В корпоративном, накапливаем дерево паттернов, и подсчитываем прогнозы для ситуаций тот или другой они идентифицируют.

Сейчас будем считать сходства прогноза. Для тех паттернов, для тот или другой из-за дефицитности либо неимения статистики не можем найти прогноз, но по каким-или признакам, можем найти, что его прогноз будет сходствен прогнозу второго паттерна, тот или другой теснее определен, и будем брать прогноз из сходственного.

У каждого определившегося паттерна глодать множество подветвей в index_of_prev. Что бы разуметь, что экое подветвь, вот метод ее получения от паттерна:
// к паттерну ptrn прибавляем слева паттерн sub_branch,// и ежели этакий достающийся паттерн теснее определен в дереве паттернов,// то отдаваем его, по другому nullptrPtrn* get_sub_branch(Ptrn* ptrn, Ptrn* sub_branch) { if (sub_branch->owner == nullptr) return ptrn; Ptrn* lev = get_sub_branch(ptrn, sub_branch->owner); if (lev == nullptr) return nullptr; return lev->index_of_prev.find(sub_branch->value);}

Можнож группировать паттерны в группы по сходству их веток. Вторыми словами классифицировать множество скопленных паттернов.

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

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

Обращаю интерес, что сходственна едва лишь количество подветвей. Так, что бы водилось сходственно все множество подветвей это чрезвычайно редкий вариант сходства.

Как определяем для новейших паттернов, для тот или другой статистика по подветвям еще не определилась, что они принадлежат ли какой-или группе:

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

Для этого обретаем все паттерны, для тот или другой конкретно эти две подветви сходственны. И для цельных отысканных паттернов, глядим, все ли они принадлежат тестируемой группе. Ежели какие-то из отысканных не принадлежат группе, из-за, что какая-то их подветвь не сходственна подходящей подветви в группе, и у этого не принадлежного, эта подветвь располагает определившуюся статистику, то следовательно тех 2-ух определившихся подветвей недостаточно для конкретной идентификации принадлежности к группе.

В каких-то вариантах будет довольно 2-ух идентификационных подветвей, в каких-то 3-х либо наиболее.

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

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

Для каждого новейшего паттерна, иной раз его прогноз делается определенным, и ежели он глодан, то включаем его в группу Group, в объект postfix_root (этот класс разделен, так как чуток позднее это будет деревом):
struct Postfix { List<Ptrn*> list_of_ptrn; // сюда добавляется паттерн с четким прогнозом uint count_on_prev_calc_similarity; // это для метода ветвления чуток позже uint value; // значение откушенного постфикса Index<uint,Postfix> index_of_next; static uint index(const Postfix& s) { return s.value; } Postfix* owner; // для postfix_root это одинаково nullptr};struct Group { uint value; // значение исполнительного прогноза Postfix postfix_root; static uint index(const Group& s) { return s.value; }};Index<uint,Group> index_of_groups;

При накоплении в группе некоторого малого числа паттернов, так 100 штук, будем запускать метод пересчета сходств (про тот или другой далее). А так же, при предстоящем накоплении паттернов в группе, при достижении числа в дважды большего, чем водилось при прошедшем увольнении (бережем в count_on_prev_calc_similarity), так же запускаем пересчет.

Из чего же состоит метод поиска сходств.

Вот в одной из групп в postfix_root накопилось множество паттернов для их для цельных прогноз глодан и схож. Из postfix_root создаем надлежащий ватерпас Postfix для каждого паттерна, берем его последнее левое значение, и по нему создаем в postfix_root->index_of_next подходящий Postfix, в тот или другой прибавляем тот паттерн, от тот или иной забрали последний левый знак. Лишь прибавляем без этого левого знака.

Вышло, что расщепили множество list_of_ptrn на подмножества, по последнему левому значению, убрав из новейших множеств это левое значение. И так рекурсивно расщепляем все, для тот или другой в образовывающихся Postfix число list_of_ptrn преимущественно 100. Паттерны в этих обильях при всем этом от степени к степени делаются младше отщепляются последние левые, и ежели паттер уперся в root длина опосля откусываний стала нулевой, то этакий паттерн на надлежащий ватерпас не пойдет.

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

Далее, для каждого множества в Postfix, от получившегося множества, начинаем исследовать вероятные ветки от паттернов, по цельным, кроме той ветки, по тот или другой был заработан обратным ходом от Group текущий Postfix. Перебираем ветки виртуального дерева, состоящего из соединенья веток входящих во множество паттернов:
struct ScanItem { Ptrn* ptrn_of_postfix; // начальный забранный из postfix паттерн Ptrn* ptrn_of_scan; // а это интеллигентный от начального прибавлением сканируемого};struct Scan { uint value; List<ScanItem> list_of_items; Index<uint,Scan> index_of_next; static uint index(const Scan& s) { return s.value; } Scan* owner;};// в класс Postfix прибавляем объект:Scan scan_root;

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

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

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

При сканировании могут находится дубли поначалу обратным ходом прошли по ветки А, а опосля при сканировании заработали Б. Далее, обратным ходом начали от Б, и пришли к А. Дублирования исследовать нет смысла и их необходимо отсекать.

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

Для чего это: это будет находить группы паттернов, для тот или другой прогноз схож. Он быть может различным для различных префиксов, но в границах один-одинехонек он схож. И ежели для этакий группы разыскали новейший префикс, для тот или иной убедились по признакам идентификации, что он функционирует, то теснее не непременно дожидаться определившейся статистики для целой группы. Приводить воссоздание класса и метода не буду, довольно огласить, что симметричен поиску постфиксов.

Иной раз мы отыскивали постфиксы, мы выводили дистанции на тот или другой действует одна и та же функция: паттерн Х однозначно отображался на прогноз У для цельных дистанций в группе. Иной раз мы разыскиваем префиксы, мы разыскиваем сходства не дистанций, а значений множество значений, для тот или другой прогноз схож.

Иной раз мы обретаем еще одно отображение Х-У по постфиксам, то в итоге скапливаются типизированные множества Х и У. Метод решения границ значений этих множеств, тот или другой не прилегают к дистанции, еще пока под вопросцем. И пока например без него. Посреди множеств обретаемых функций, некие будут обладать однообразное множество Х. Тогда значение Х делается объектом, располагающим немножко параметров любая функция это отдельное свойство. При всем этом сходственные дистанции для получения какой-или из этих функций делаются методами получения параметров этого объекта. На самом деле, это глодать базисный принцип преображения текста (либо второго разновидности инфы) в основу принесенных в таблички с их качествами.

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

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

Описанные принципы, это едва лишь кусок от полной картины, какие сходства необходимо находить:

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

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

Необходимо сделать, что бы сканер веток мог перебегать не от знака к символу, а по разметкам групп, и при всем этом не непременно лишь в один-одинехонек направлении, а так скачем сквозь группу, разворачиваемся, и начинаем исследовать ингредиент группы посимвольно но с второго точки.

Позже еще занятие со обильями, на предмет непрерывностей и упорядочивания.

И т.д и т.п.

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

На описанный метод с постфиксами у меня теснее глодать исходники на С++, но они не подготовлены как окончательный итог и призывают некой доработки на данный момент на это нет поры, поэтому не прилагаю. Но ежели будут особо желающие разбирать не приготовленные и не упорядоченные исходники могу скинуть собственно. (под QT x64 памяти жрут немерено, но функционирует живо). Используя его к тексту, можнож созидать, что он выделяет зависимости окончаний и группы существительных по родам, прилагательных и глаголов. Что бы выделить 1-ые зависимости словечек, у меня не хватило оперативки необходимо переделывать под основу принесенных на диске.

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

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