Создавайте искусственные нейронные сети с помощью Java-фреймворка Neuroph.

Нейронные сети Java

Создавайте искусственные нейронные сети с помощью Java-фреймворка Neuroph.

Победите в викторине «Мартовское безумие»!

Этот учебник объединяет три интересующие меня области: язык Java, искусственные нейронные сети и ежегодный чемпионат NCAA Division I по баскетболу (также известный как «Мартовское безумие»). Имея это в виду, в этом уроке я рассмотрю следующие четыре темы:

  • Концепция искусственной нейронной сети (ИНС)
  • Многослойный персептрон (MLP)
  • Neuroph Java Нейросетевой фреймворк
  • Пример из практики: мартовское безумие

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

ПОЖАЛУЙСТА, ОБРАТИТЕ ВНИМАНИЕ: статья посвящена некоторой математике, но будет показана только в случае крайней необходимости или в более кратком виде. Иногда уравнение стоит тысячи слов, но я стараюсь экономно использовать уравнения.

Концепция искусственной нейронной сети

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

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

Рисунок 1. Описание слоев искусственной нейронной сети (источник:Википедия)
人工神经网络层描述

В этом руководстве «слой» иногда называют «слоем выше» и «слоем ниже» его соседей. Как вы можете видеть на рисунке 1, я называю входной слой слоем над скрытым слоем, который является слоем над выходным слоем. По аналогии, выходной слой — это слой под скрытым слоем, а скрытый слой — это слой под входным слоем.

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

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

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

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

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

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

Вы все поняли? Неважно, если вы не понимаете. Только что я упомянул ряд понятий, а теперь подробно объясним эти понятия.

искусственный нейрон

Ядром нейронной сети является искусственный нейрон. Он имеет три основные характеристики:

  • Соединения: в различных сетях, показанных в этом руководстве, каждый нейрон в данном слое подключен к любому другому нейрону в непосредственном соседнем слое.
  • Входной сигнал: относится к набору цифровых значений, полученных каждым нейроном в предыдущем слое, или для нейронов во входном слое,Нормализованныйvalue мы рассмотрим нормализацию позже.
  • Выходной сигнал: относится к одному числовому значению, которое нейрон отправляет каждому нейрону в следующем слое, или, когда этот нейрон находится в выходном слое, к «ответу».

контролируемое обучение

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

Это также можно объяснить следующим образом, как я объяснял своим детям:

  1. Поток известных данных в сеть.
  2. Q: Сеть сгенерировала правильный ответ?
    • Да (в пределах допустимой погрешности): перейдите к шагу 3.
    • нет:
      1. Отрегулируйте веса соединений сети.
      2. Перейти к шагу 1
  3. Заканчивать.

(На данный момент дети не могут не перевернуться, но они полностью понимают.)

Для более формального обсуждения обучения с учителем ознакомьтесь с этой веткой, посвященной машинному обучению.Руководства по IBM developerWorks.

Многослойный персептрон (MLP)

Многослойный персептрон (MLP) — это нейронная сеть с входным слоем и выходным слоем с одним или несколькими скрытыми слоями между ними. Количество нейронов в каждом слое может варьироваться, но является фиксированным (т. е. после определения структуры сети это количество фиксируется на время всех обучающих циклов).

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

веса нейронов

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

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

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

Обобщенно следующим образом, учитывая каждый нейрон в сетевом слое:

  1. связаны с каждым нейроном в предыдущем слое (кроме входных нейронов, у которых нет предыдущего слоя)
  2. связаны с каждым нейроном следующего слоя (кроме выходных нейронов, у которых нет следующего слоя)
  3. Каждый имеет вес (используемый для имитации уровня сигнала на выходе), связанный с его выходным соединением.

входная функция

Может быть несколько (называемыхn) сигналы в искусственные нейроны (см.рисунок 1), сети необходимо преобразовать все эти сигналы в одно оцениваемое значение. Вот что делает функция ввода: преобразует набор входных сигналов в одно значение (обычно число от -1 до 1).

Наиболее распространенный класс входных функций называетсявзвешенная сумма. гипотетический нейронNподключен к верхнему слою сетиnнейроны. нейроныNВзвешенная сумма входовAРассчитывается по следующей формуле: поставить всеnвходное значение для каждого соединения входовaс соединительными грузикамиwСложите произведения из . Формула выглядит следующим образом:

加权和公式

Ничего себе, используя математическую формулу! Оно делает. Возьмем пример. гипотетический нейронNсоединен с 3 нейронами в предыдущем слое, так что в приведенной выше формуле имеется n = 3 входных значенияaравно {0,3, 0,5, 0,6}, и его соответствующий весwЗначения {0,4, -0,2, 0,9} соответственно. Следовательно, нейроныNвзвешенная суммаAбудет:

加权和示例

функция выхода (активации)

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

Наиболее часто используемый тип функции активации в сетях MLP:Сигмовидная функция. для любой взвешенной суммы данного нейронаA,AСигмовидное значениеVРассчитайте по следующей формуле:

Sigmoid 公式

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

ты сможешьздесьУзнайте больше о сигмовидной функции.

функция сетевой ошибки

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

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

Математическая формула выглядит следующим образом:

均方误差公式

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

Проще говоря: допустим, ваша цель — метнуть дротик так, чтобы он попал в центр мишени (в яблочко). При каждом броске дротика расстояние между положением дротика на мишени и мишенью равноd(Центр яблочка означает, чтоd = 0).

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

Хотя нейронная сеть не так проста, как метание дротика, то же самое верно: в каждом цикле обучения тренер будет вычислять значение, вычисленное сетью (полученное из данных обучения).Aexpected) "расстояние" от мишени (ошибкаE), а затем соответствующим образом отрегулируйте веса сети. В принципе, величина коррекции пропорциональна ошибке в сети. Или возьмем в качестве примера метательные дротики: если дротик находится дальше от центра мишени, то требуется большая коррекция, если ближе к центру мишени, требуется лишь небольшая коррекция.

Обратное распространение ошибки

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

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

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

Теперь хорошие новости: вам не нужно знать реализацию, чтобы использовать обратное распространение! Обратное распространение можно использовать для обучения некоторых довольно крутых сетей (поверьте мне), если у вас есть интуитивное понимание принципов.

Однако, если вы хотите увидеть всю математику, вы можете проверить этот пост Майкла Нильсена.Этот замечательный контент.

Neuroph Java Нейросетевой фреймворк

Ладно, хватит теоретической части. Давайте поговорим о том, как его использовать.

К счастью для нас, существует фреймворк на основе Java под названием Neuroph, в котором реализованы все малоизвестные детали (большинство из них), затронутые в предыдущем разделе. В этом разделе я хочу представить структуру Neuroph и кратко объяснить, почему она была выбрана для исследования.

Несколько причин, по которым мне нравится фреймворк Neuroph:

  • Чистое Java-кодирование: нужно ли что-то еще говорить? Если нужно, поговорим об этом ниже. Язык Java — самый популярный язык в мире (микрофон упал).
  • Поддерживаются несколько типов сетей: в том числе многослойные персептроны.
  • Neuroph API очень прост в использовании, что является большим плюсом, поскольку по нему меньше документации.

Скачайте и установите Нейроф

Чтобы загрузить Neuroph, посетитеэта страница, выберите ZIP-файл платформы Neuroph.

Разархивируйте файл .zip на своем компьютере и найдите файл .jar ядра Neuroph, который на момент написания был назван neuroph-core-2.94.jar.

На момент написания этой статьи последняя версия Neuroph (2.94) отсутствует в Maven Central, и для ее использования ее необходимо установить в локальном репозитории Maven. Я покажу, как это сделать в видео.

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

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

Кроме того, я люблю программировать, и Neuroph API идеально соответствует его теоретическим концепциям, поэтому я включил Eclipse и начал писать код!

Практический пример: видео

人工神经网络与 Neuroph

Нажмите, чтобы посмотреть видео-демонстрациюПосмотреть расшифровку

Пример из практики: мартовское безумие

Несколько лет назад у меня возникла идея использовать ИНС для предсказания победителя чемпионата NCAA Division I по баскетболу (также известного как «Мартовское безумие»). Но я не знаю, с чего начать.

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

Но я не могу положить эту идею на полку. «Должно быть что-то в данных», — говорю я себе. У меня есть академическое образование, и я и трое моих детей завершили (на первый взгляд) миллион проектов научных выставок. Поэтому я решил применить науку и задал следующий вопрос: «Можно ли точно (> 75%) выбрать чемпиона спортивного события, используя только данные регулярного сезона?»

Мое предположение: да. возможный.

После нескольких лет спотыканий я создал процесс, описанный в этом тематическом исследовании, чтобы предсказать победителя чемпионата NCAA Division I по баскетболу 2017 года.

Используя ценные исторические данные, охватывающие 21 статистическую категорию и 5 сезонов, я обучил более 30 независимых сетей, запустив их одновременно как «массив» сетей (чтобы исключить ошибки через несколько сетей) для оценки турнира. .

Я поражен тем, насколько хороши эти сети. Из 67 событий мой сетевой массив правильно предсказал 48 (около 72%). Неплохо, но, к сожалению, мое предположение оказалось неверным. Теперь, оглядываясь назад, можно сказать, что это было хорошо для науки: неудачи мотивируют нас продолжать попытки.

Без лишних слов давайте рассмотрим процесс обучения и запуска сетевого массива. Примечание. Этот процесс очень продвинутый. То, что я покажу здесь, является осуществимым, а не учебным пособием. Однако, если вы обнаружите ошибку в коде или процессе, который я показываю, или захотите предложить улучшения (или поделиться своим успехом с использованием кода), пожалуйста, оставьте комментарий.

1

загрузить базу данных

Чтобы создать данные для обучения сети (обучающие данные), сначала нужно получить статистику за весь регулярный сезон. После тщательного поиска сайтов, которые предоставляют бесплатные доступные данные, я остановился на ncaa.com, который предоставляет исторические данные регулярного сезона почти для всех событий, включая мужской баскетбол (данные бесплатны только для некоммерческого использования, прежде чем что-либо загружать Пожалуйста, прочтите это тщательно передУсловия использования).

Скачать данные

Ncaa.com предоставляет пользователям сложный (возможно, менее интуитивный) интерфейс для загрузки всех типов больших данных. Я подтверждаю, что мне нужны данные команды регулярного сезона (не личные данные), начиная с 2010 года. В общей сложности использовались исторические данные за 8 лет (включая регулярный сезон 2017 г.), когда проект был завершен в марте 2017 г.

Я прошел через несколько экранов (посмотрите видео, если хотите узнать больше), чтобы загрузить данные, и загрузил данные команды с 2010 года, включая следующие категории статистики:

  • Среднее количество очков за игру
  • процент попаданий с игры
  • процент штрафных бросков
  • Шаг каждой игры
  • обороты за игру

и многое другое (см.Гитхаб исходный код вдля получения полной информации). Эти данные охватывают три основные области: нападение (например, процент попаданий с игры), защиту (например, количество перехватов за игру) и потери (например, потери за игру).

Ncaa.com предлагает различные форматы загрузки, но я выбрал формат переменных с разделителями-запятыми (CSV), чтобы можно было использоватьOpenCSVдля обработки. Вся статистика за сезон находится в одном файле с разделителем в заголовке, указывающим, к какой категории относятся данные. За этим следует следующая комбинация заголовка/данных и так далее. В видео я покажу, как выглядят данные CSV, так что обязательно посмотрите!

Прочитав изображение ниже, вы поймете, как форматируются данные.

Во-первых, это данные в верхней части файла. Он начинается с нескольких пустых строк, за которыми следует 3-строчный заголовок, статистическая категория (подчеркнутая) в строке 2 заголовка, за которой следуют пустые строки, за которыми следуют данные CSV для этой статистической категории (включая заголовок) Строка ).

Рис. 2. Файл начинается с данных CSV за сезон 2011 г.

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

Рисунок 3. Дополнительные данные CSV за сезон 2011 г.
2011 CSV 数据

Создание скриптов загрузки SQL

Зная макет файла CSV, я подумал, что смогу обработать данные программно, и решил использоватьРежим политикидля обработки данных. Таким образом, даже если ИТ-персонал Ncaa.com меняет порядок статистики в файле каждый год, если он поддерживает{ { header, data }, { header, data } ...}кортежей, реализация шаблона моей стратегии невосприимчива к изменениям порядка данных.

StrategyИнтерфейс определяется следующим образом:

package com.makotojava.ncaabb.sqlgenerator;
 
import java.util.List;
 
public interface Strategy {
  String generateSql(String year, List<String[]> data);
 
  String getStrategyName();
 
  int getNumberOfRowsProcessed();
}

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

Программа, используемая для генерации SQL, называетсяSqlGenerator, его основная задача состоит в том, чтобы проанализировать CSV-файл, найти заголовок категории статистики, выбрать подходящую стратегию для обработки этого раздела, делегировать обработку этой стратегии, повторять процесс до тех пор, пока не будет достигнут конец файла, а затем написать SQL загрузить скрипт. Если для определенной категории статистики не найдено соответствующей стратегии (ncaa.com предоставляет больше категорий статистики, чем я решаю использовать), то программа переходит к следующему заголовку.

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

После написания программы (и всех стратегий) я написал программу под названиемrun-sql-generator.shскрипт для запуска программы, затем запускать этот скрипт на все годы, чтобы он загружался.

Соответствующий сценарий SQL для 2011 года (названныйload_season_data-2011.sql)Следующее:

INSERT INTO won_lost_percentage(YEAR, TEAM_NAME, NUM_WINS, NUM_LOSSES, WIN_PERCENTAGE)VALUES(2011,'San Diego St',32,2,0.941);
INSERT INTO won_lost_percentage(YEAR, TEAM_NAME, NUM_WINS, NUM_LOSSES, WIN_PERCENTAGE)VALUES(2011,'Kansas',32,2,0.941);
INSERT INTO won_lost_percentage(YEAR, TEAM_NAME, NUM_WINS, NUM_LOSSES, WIN_PERCENTAGE)VALUES(2011,'Ohio St',32,2,0.941);
INSERT INTO won_lost_percentage(YEAR, TEAM_NAME, NUM_WINS, NUM_LOSSES, WIN_PERCENTAGE)VALUES(2011,'Utah St',30,3,0.909);
INSERT INTO won_lost_percentage(YEAR, TEAM_NAME, NUM_WINS, NUM_LOSSES, WIN_PERCENTAGE)VALUES(2011,'Duke',30,4,0.882);
.
(更多数据)
.
INSERT INTO won_lost_percentage(YEAR, TEAM_NAME, NUM_WINS, NUM_LOSSES, WIN_PERCENTAGE)VALUES(2011,'Toledo',4,28,0.125);
INSERT INTO won_lost_percentage(YEAR, TEAM_NAME, NUM_WINS, NUM_LOSSES, WIN_PERCENTAGE)VALUES(2011,'Centenary LA',1,29,0.033);
.
INSERT INTO scoring_offense(YEAR, TEAM_NAME, NUM_GAMES, NUM_POINTS, AVG_POINTS_PER_GAME)VALUES(2011,'VMI',31,2726,87.9);
INSERT INTO scoring_offense(YEAR, TEAM_NAME, NUM_GAMES, NUM_POINTS, AVG_POINTS_PER_GAME)VALUES(2011,'Oakland',34,2911,85.6);
INSERT INTO scoring_offense(YEAR, TEAM_NAME, NUM_GAMES, NUM_POINTS, AVG_POINTS_PER_GAME)VALUES(2011,'Washington',33,2756,83.5);
INSERT INTO scoring_offense(YEAR, TEAM_NAME, NUM_GAMES, NUM_POINTS, AVG_POINTS_PER_GAME)VALUES(2011,'LIU Brooklyn',32,2643,82.5);
INSERT INTO scoring_offense(YEAR, TEAM_NAME, NUM_GAMES, NUM_POINTS, AVG_POINTS_PER_GAME)VALUES(2011,'Kansas',34,2801,82.3);
.
(你们懂了吧)
.

В строке 1 показан первый из статистической категории «% выигрышей / проигрышей».SQL INSERT, в строке 12 показан первый результат в статистической категории «Засчитанное нарушение».SQL INSERT. Сравните этот код с рис. 2 и рис. 3, чтобы увидеть, как преобразовать данные CSV вSQL INSERT.

После создания всех сценариев SQL из данных CSV я готов загрузить данные.

Загрузить данные в базу данных PostgreSQL

Я написал скрипт для загрузки данных в базу данных PostgreSQL. В приведенном ниже примере я запустилpsqlинтерактивная оболочка. Сначала я создалncaabbбазу данных и выйти из оболочки.

Ix:~ sperry$ "/Applications/Postgres.app/Contents/Versions/9.6/bin/psql" -p5432 -d "sperry"
psql (9.6.1)
Type "help" for help.
 
sperry=# create database ncaabb;
CREATE DATABASE
sperry=# \q
Ix:~ sperry$

Затем я подключаюсь кncaabbбазу данных и запуститьbuild_db.sqlсценарий:

Ix:~ sperry$ "/Applications/Postgres.app/Contents/Versions/9.6/bin/psql" -p5432 -d "ncaabb"
psql (9.6.1)
Type "help" for help.
 
ncaabb=# begin;
BEGIN
ncaabb=# \i /Users/sperry/home/development/projects/developerWorks/NcaaMarchMadness/src/main/sql/build_db.sql
BUILDING DB...
脚本变量:
ROOT_DIR ==>  /Users/sperry/home/development/projects/developerWorks/NcaaMarchMadness/src/main
SQL_ROOT_DIR ==>  /Users/sperry/home/development/projects/developerWorks/NcaaMarchMadness/src/main/sql
DATA_ROOT_DIR ==>  /Users/sperry/home/development/projects/developerWorks/NcaaMarchMadness/src/main/data
LOAD_SCRIPT_ROOT_DIR ==>  /Users/sperry/l/MarchMadness/data
CREATING ALL TABLES...
CREATING ALL VIEWS...
LOADING ALL TABLES: 
YEAR: 2010...
YEAR: 2011...
YEAR: 2012...
YEAR: 2013...
YEAR: 2014...
YEAR: 2015...
YEAR: 2016...
YEAR: 2017...
LOADING TOURNAMENT RESULT DATA FOR ALL YEARS...
FIND MISSING TEAM NAMES...
DATABASE BUILD COMPLETE.
ncaabb=# commit;
COMMIT
ncaabb=#

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

2

Создание обучающих данных

Я написал программу под названиемDataCreatorпрограмма для создания обучающих данных за конкретный год. Как и другие утилиты, которые я написал, я также написал сценарий оболочки для управления этим и назвал сценарийrun-data-creator.sh.

бегатьDataCreatorочень простой. Я просто указываю год, за который я хочу получить данные обучения, и программа прочитает базу данных и сгенерирует данные для меня. Конечно, мне нужно написать несколько классов поддержки, чтобы сделатьDataCreatorВышеприведенное реализовано с помощью набора объектов доступа к данным (DAO, используемых для чтения данных из базы данных) и некоторых объектов модели Java (используемых для хранения данных).

Обязательно просмотрите их в исходном коде, особенно вcom.makotojava.ncaabb.daoиcom.makotojava.ncaabb.modelв упаковке.

бежатьrun-data-creator.sh, я открыл окно терминала на своем Mac и указал создать данные за 2010-2017 годы:

Ix:$ ./run-data-creator.sh 2010 2011 2012 2013 2014 2015 2015 2017
 
Number of arguments: 8
Script arguments: 2010 2011 2012 2013 2014 2015 2015 2017
INFO: Properties file 'network.properties' loaded.
2017-09-28 15:40:38 INFO  DataCreator:72 - *********** CREATING TRAINING DATA **************
2017-09-28 15:40:44 INFO  DataCreator:132 - *********** SAVING TRAINING DATA **************
2017-09-28 15:40:44 INFO  DataCreator:136 - Saved 128 rows of training data 'NCAA-BB-TRAINING_DATA-2010.trn'
2017-09-28 15:40:51 INFO  DataCreator:132 - *********** SAVING TRAINING DATA **************
2017-09-28 15:40:51 INFO  DataCreator:136 - Saved 134 rows of training data 'NCAA-BB-TRAINING_DATA-2011.trn'
2017-09-28 15:40:57 INFO  DataCreator:132 - *********** SAVING TRAINING DATA **************
2017-09-28 15:40:57 INFO  DataCreator:136 - Saved 134 rows of training data 'NCAA-BB-TRAINING_DATA-2012.trn'
2017-09-28 15:41:04 INFO  DataCreator:132 - *********** SAVING TRAINING DATA **************
2017-09-28 15:41:04 INFO  DataCreator:136 - Saved 134 rows of training data 'NCAA-BB-TRAINING_DATA-2013.trn'
2017-09-28 15:41:10 INFO  DataCreator:132 - *********** SAVING TRAINING DATA **************
2017-09-28 15:41:10 INFO  DataCreator:136 - Saved 134 rows of training data 'NCAA-BB-TRAINING_DATA-2014.trn'
2017-09-28 15:41:17 INFO  DataCreator:132 - *********** SAVING TRAINING DATA **************
2017-09-28 15:41:17 INFO  DataCreator:136 - Saved 134 rows of training data 'NCAA-BB-TRAINING_DATA-2015.trn'
2017-09-28 15:41:23 INFO  DataCreator:132 - *********** SAVING TRAINING DATA **************
2017-09-28 15:41:23 INFO  DataCreator:136 - Saved 134 rows of training data 'NCAA-BB-TRAINING_DATA-2015.trn'
2017-09-28 15:41:29 INFO  DataCreator:132 - *********** SAVING TRAINING DATA **************
2017-09-28 15:41:29 INFO  DataCreator:136 - Saved 134 rows of training data 'NCAA-BB-TRAINING_DATA-2017.trn'
Ix:~/home/development/projects/developerWorks/NcaaMarchMadness/src/main/script sperry$

После создания обучающих данных следующим шагом будет обучение и проверка сетей, которые я буду использовать для выбора команд чемпионата NCAA Division I.

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

Причина нормализации всех входных данных заключается в том, что не все данные создаются одинаково (с точки зрения числового представления). Например, статистическая категория Win/Loss Per Team представляет собой процент, который, как и следовало ожидать, имеет значение от 0 до 1. И наоборот, количество фолов за игру (усредненное по всем играм) имеет нижнюю границу 0 и вообще не имеет верхней границы.

Сравнивать два необработанных числа с разными диапазонами бессмысленно. Поэтому данные необходимо нормализовать, особенно с использованиемМасштабирование функцийметод нормализации. Уравнение, которое я использую, простое:

特征缩放公式

для любого примитивного значенияX, расчетное нормализованное значениеX'Диапазон значенийXminприбытьXmax. Конечно, это означает, что мне нужно рассчитать максимальные и минимальные значения для всех статистических категорий. Но поскольку данные находятся в базе данных, легко определить представление, чтобы PostgreSQL делал это (см.v_season_analyticsвид и егоcreate_views.sqlопределение в ).

DataCreatorОтвечает за нормализацию всех обучающих данных. Теперь я, наконец, готов приступить к обучению сети.

3

Обучите и проверьте сеть

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

  • Какую из 23 доступных категорий статистики я буду использовать?
  • Сколько скрытых слоев я хочу иметь в сети?
  • Сколько нейронов должно быть в каждом скрытом слое?
  • Как должен выглядеть результат сети?

В итоге я выбрал 21 из 23 категорий. Таким образом, имеется 42 входа (по одному на каждую команду). Для вывода, я думаю, это должен быть нормализованный счет, основанный на примере матча между двумя командами: для любого заданного фиктивного матча побеждает команда с более высоким нормализованным счетом.

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

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

Вот как я это делаю: я направляюMlpNetworkTrainerСеть была обучена на данных за 2010–2014 годы, затем проверена на данных за 2015 и 2016 годы, и были сохранены те, у кого была хорошая догадка выше порогового значения (70%).

Если скорость угадывания сети превышает пороговое значение (70%), программа сохранит сеть как сеть в массиве сетей угадывания турнира. В противном случае сеть будет сброшена.

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

4

Пробный турнир

После регулярного сезона (примерно 10 марта) я скачал данные в формате CSV черезSqlGeneratorДанные были запущены и загружены в базу данных.

После того, как «Отборочный комитет турнира NACC» отбирает команды для участия в турнире 2017 года, я создаю файл с именем tourney_teams_file_2017.txt, в котором содержатся все команды, которые будут участвовать в турнире (эту операцию я проделал для команд 2010-2016 годов) .

Я запустил программу, которую написал для созданияSQL INSERT, поэтому я могу загрузить команды 2017 года вtournament_participantв таблице. Я делал это в течение последних нескольких лет, чтобы создать данные, необходимые для проверки сети.

Теперь все готово. У меня есть 31 обученная и проверенная сеть, и у меня есть данные за сезон 2017 года. Теперь все препятствия устранены. Но мне также нужен способ визуализировать, как команды играют парами.

Поэтому я написал имя, называемоеTournamentMatrixPredictorпрограмма для создания файла CSV для каждой команды, участвующей в турнире, который я могу загрузить в Open Office Calc. Каждый файл содержит прогнозируемые результаты смоделированного матча между определенной командой и другими командами турнира. .

На изображении ниже показан командный файл Университета штата Средний Теннесси, который будет загружен в Open Office в виде электронной таблицы Calc.

Рисунок 4. Сетевые прогнозы для команды штата Средний Теннесси
中田纳西州州立大学队的网络预测

Нажмите, чтобы увеличить изображение

Эти электронные таблицы показывают смоделированный матч между КОМАНДОЙ и любой другой командой (ПРОТИВ ПРОТИВНИКА) в турнире (включая саму MTSU), а также средние прогнозы по 31 сети, среди которых команда штата Средний Теннесси выиграет (ПОБЕДА %), проигрыш (LOSS %) или ничья (PUSH %), а также результаты отдельных сетей.

Вправо (за пределы кадра) идут прогнозы одной сети (только предсказанная команда-победитель). Например, сеть со структурой 42x42x107x49x10x14x2x2 — 42 входных нейрона, 6 скрытых слоев (42 нейрона в первом слое, 107 нейронов в следующем слое и т. д.) и 2 выходных нейрона — показывает прогнозируемую команду. каждый матч.

В первом туре 5 семян штата Университет штата Теннесси № 5 в первом раунде Теннесси очень оптимистична (чем ниже номер семян, тем больше он оптимистичен отборочным комитетом NCAA). Среднее значение массива немного недопустимо: 31 сеть обычно предсказывают, что вероятность 37,14%, 17,14% и 45,71% команды штата Китая Государственной университета в Китае выигрывает, потерянные или чертежи соответственно.

Я совершенно не уверен, что делать. Обманула ли меня наука? Посмотрим правде в глаза, спортивные события по своей природе случайны (что объясняет «сумасшествие» в «Мартовском безумии»). Поэтому об окончательном результате столь близкой игры можно только догадываться. В то время как большинство сетей в массиве не смогли выбрать явного победителя (45,71%), предсказанный победитель был в два раза более вероятен (37,14% против 17,14%), чем в двух других случаях.

В конце концов, я выбрал штат Мидл Теннесси в списках по двум причинам: они только что выиграли в своей лиге (Центральная часть США), у них есть автоматическая квалификация на турнир, и моя глубокая сеть (эта глубокая сеть работы) подавляющим большинством выбрала Команда штата Средний Теннесси. Поэтому я выбираю штат Средний Теннесси, чтобы победить штат Миннесота. Судя по конечному результату, сеть правильная. Я прошел этот процесс для всех команд турнира, заполняя таблицу и надеясь на лучшее.

Как я уже говорил ранее, выбор сети (и, следовательно, мой) был правильным примерно в 72% случаев. Эта точность неплохая. И это весело.

заключительные замечания

В этом уроке я затронул концепцию искусственных нейронных сетей (ИНС), затем обсудил многослойные персептроны и, наконец, познакомил вас со случаем, когда я обучил множество сетей MLP, чтобы выбрать 2017. Команда-победитель мужского дивизиона NCAA I Championship. .

связанная тема