- PVSM.RU - https://www.pvsm.ru -

Data mining: Инструментарий — Theano

Data mining: Инструментарий — Theano
В предыдущих материалах этого цикла мы рассматривали методы предварительной обработки данных при помощи СУБД. Это может быть полезно при очень больших объемах обрабатываемой информации. В этой статье я продолжу описывать инструменты для интеллектуальной обработки больших объёмов данных, остановившись на использовании Python и Theano.

Рассмотрим задачи, которые мы будем решать, и какими инструментами для этого воспользуемся. Читать предыдущие части [1 [1],2 [2],3 [3]] желательно, но не обязательно. Исходные данные, которые были получены в результате выполнения предыдущих частей цикла статей можно взять отсюда[Исходные данные [4]].

Задачи

Если среди данных есть скрытые взаимосвязи, корреляция между признаками, структурные связи, то в таком случае возникает задача уменьшения размерности входных данных. Эта проблема особенно ярко себя проявляет в ситуации, когда обрабатывается большое число разреженных данных.
Для сравнения методов уменьшения размерности данных мы собираемся рассмотреть метод нейросетевого сжатия (Autoencoder) и метод главных компонент (PCA).
Классический путь решения этой задачи — метод анализа главных компонент (PCA). В википедии неплохо описано [4 [5]], там же есть ссылка [5 [6]] на сайт с примерами в Excel, и подробным и довольно понятным описанием. Вот еще ссылки на статьи на Хабре[6 [7],7 [8]].
Как правило, результаты уменьшения размерности входных данных, в первую очередь сравнивают именно с результатами применения этого метода.
В статье [8 [9]] описано что такое автоенкодер и как он работает, потому основной материал будет посвящен именно реализации и применению этого подхода.
Бангио и Йошуа написали хороший и внятный обзор применения нейросетевого сжатия, если вдруг кому-нибудь нужна библиография и ссылки на работы в этом направлении, чтобы сравнивать свои результаты с существующими, в работе [9 [10]], раздел 4.6, стр. 48 — 50.
В качестве инструментария, я решил применять Python и Theano[10 [11]]. Этот пакет я обнаружил после прослушивания курсов [курсера нейронные сети], изучая ссылки предоставленные преподавателем J. Hinton. При помощи этого пакета реализованы нейронные сети «глубокого обучения» (deep learning neural networks). Такого рода сети, как было описано в лекциях и статье [11 [12], 12 [13]] легли в основу системы для распознавания голоса, используемой Google в Android.
Этот подход к построению нейронных сетей по мнению некоторых ученых является достаточно перспективным, и уже показывает неплохие результаты. Потому мне стало интересно применить его для решения задач на Kaggle.
Также, на сайте deeplearning.net [14] достаточно много примеров построения систем машинного обучения с использованием именно этого пакета.

Инструменты

В документации разработчиков, дано такое определение:
Theano — это библиотека Python и оптимизирующий компилятор, которые позволяют определять, оптимизировать и вычислять математические выражения эффективно используя многомерные массивы
Возможности библиотеки:

  • тесная интеграция с NumPy;
  • прозрачное использование GPU;
  • эффективное дифференцирование переменных;
  • быстрая и стабильная оптимизация;
  • динамическая генерация кода на C;
  • расширенные возможности юнит-тестирования и самопроверок;

Theano используется в высокоинтенсивных вычислительных научных исследований с 2007 года.
По сути, программирование под Theano не является программированием в полном смысле этого слова, так как пишется программа на Python, которая создает выражение для Theano.
С другой стороны, это является программированием, так как мы объявляем переменные, создаем выражение которое говорит что делать с этими переменнымии компилируем эти выражения в функции, которые используются при вычислении.
Если кратко, то вот список того, что именно может делать Theano в отличии от NumPy.

  • оптимизация скорости выполнения: Theano может использовать g++ или nvcc для того чтобы откомпилировать части части вашего выражения в инструкции GPU или CPU, которые выполняются намного быстрее чистого Python;
  • диференциицирование переменных: Theano может автоматически строить выражения для вычисления градиента;
  • стабильность оптимизации: Theano может распознать некоторые численно неточно вычисляемые выражения и рассчитать их используя более надежные алгоритмы

Наиболее близкий к Theano пакет это sympy. Пакет sympy можно сравнить с Mathematica, в то время как NumPy более похож на пакет MATLAB. Theano является гибридом, разработчики которого попытались взять лучшие стороны обоих этих пакетов.
Скорее всего, в продолжение цикла, будет написана отдельная статью о том как настроить theano, подключить использование CUDA GPU к тренировке нейронных сетей и решать проблемы, возникающие при установке.
А пока, на моей операционной системе Linux Slackware 13.37 установлен python-2.6, setuptools-0.6c9-py2.6, g++, python-dev, NumPy, SciPy, BLAS. Подробный мануал по установке для распространеных ОС на английском языке: [12 [15]].
Прежде чем мы начнем снижать размерность данных, попытаемся реализовать простой пример использования Theano для написания функции, которая позволит нам решить нашу задачу о разбиении группы на две части.
В качестве метода для разбиения данных на два класса воспользуемся логистической регрессией[13 [16]].
Код примера основывается на [14 [17]] с некоторыми изменениями:

import numpy 
import theano
import theano.tensor as T
import csv as csv 

#Открываем и читаем csv файл
csv_file_object = csv.reader(open('./titanik_train_final.csv', 'rb'), delimiter='t')
data=[]                                     #Создаем переменную-массив
for row in csv_file_object:      # Каждую строку
    data.append(row)                # заносим в  массив data
data = numpy.array(data)        # Превращаем обычный массив в тип numpy.array 
data = data.astype('float')        # Конвертируем в тип float
Y = data[:,1]                            # Все строки первого столбца заносим в Y
X = data[:,2:]                           # Все строки со второго столбца и до последнего заносим в X 
#Аналогично для тестовой выборки, только без Y
csv_file_object = csv.reader(open('./titanik_test_final.csv', 'rb'), delimiter='t')
data_test=[]                         
for row in csv_file_object:     
    data_test.append(row)           
Tx = numpy.array(data_test)
Tx = Tx.astype('float')
Tx = Tx[:,1:]
#Создаем объект для получения случайных чисел
rng = numpy.random
#Количество строк
N = 891
#Количество столбцов
feats = 56
#Количество тренировочных шагов
training_steps = 10000

# Декларируем символьные переменные Theano 
x = T.matrix("x")
y = T.vector("y")
w = theano.shared(rng.randn(feats), name="w")
b = theano.shared(0., name="b")

# Создаем «выражение» Theano
p_1 = 1 / (1 + T.exp(-T.dot(x, w) - b))           # Вероятность того, что результат равен  1
prediction = p_1 > 0.5                                    # Порог для прогнозирования
xent = -y * T.log(p_1) - (1-y) * T.log(1-p_1) # Функция ошибки для перекрестной энтропии
cost = xent.mean() + 0.01 * (w ** 2).sum()  # Стоимость минимизации
gw,gb = T.grad(cost, [w, b])                          # Рассчитываем градиент стоимости
                                          
# Компилируем «выражение» Theano
train = theano.function(
          inputs=[x,y],
          outputs=[prediction, xent],
          updates=((w, w - 0.1 * gw), (b, b - 0.1 * gb)))
predict = theano.function(inputs=[x], outputs=prediction)

# Тренировка модели
for i in range(training_steps):
    pred, err = train(X, Y)

#Прогнозирование
P = predict(Tx)
#Сохраняем в файл
numpy.savetxt('./autoencoder.csv',P,'%i')
 

Наиболее интересными в этом коде являются строки:

# Создаем «выражение» Theano
p_1 = 1 / (1 + T.exp(-T.dot(x, w) - b))           # Вероятность того, что результат равен  1
prediction = p_1 > 0.5                                    # Порог для прогнозирования
xent = -y * T.log(p_1) - (1-y) * T.log(1-p_1) # Функция ошибки для перекрестной энтропии
cost = xent.mean() + 0.01 * (w ** 2).sum()  # Стоимость минимизации
gw,gb = T.grad(cost, [w, b])                          # Рассчитываем градиент стоимости
                                          
# Компилируем «выражение» Theano
train = theano.function(
          inputs=[x,y],
          outputs=[prediction, xent],
          updates=((w, w - 0.1 * gw), (b, b - 0.1 * gb)))
predict = theano.function(inputs=[x], outputs=prediction)
 

Здесь происходит следующее(разбираем с конца !): У нас есть два «выражения» train и predict. Они «компилируются»(это не только компиляция, но в начале изучения лучше будет упростить) при помощи theano.function в вид, который может быть потом вызван и исполнен.
Входными параметрами у нас для прогнозирования является x, а выходным — выражение prediction, которое равно p_1 > 0,5 — т. е. порог, который возвращает значение да/нет, т. е. значения 0 или 1. В свою очередь, выражение p_1 содержит сведения о том, что именно нужно делать с переменной х, а именно:

p_1 = 1 / (1 + T.exp(-T.dot(x, w) - b))

где x, w, b — переменные, при этом w и b мы определяем при помощи выражения train.
Для train входными данными будут x, y, а выходными prediction и xent. При этом мы будем обновлять(искать оптимальные значения) для w и b, обновляя их по формулам

w-0.1*gw, b-0.1*gb

где gw и gb — градиенты, связанные с ошибкой xent через выражение cost.
А ошибка, вычисляемая по формуле, получается из вот такого выражения:

xent = -y * T.log(p_1) - (1-y) * T.log(1-p_1)

И когда мы «компилируем» выражения predict и train, Theano берет все необходимые выражения, создает для них код на С для CPU/GPU и исполняет их соответствующим образом. Это дает заметный прирост в производительности, при этом не лишая нас удобств использования среды Python.
Результатом исолнения указанного кода будет качество прогноза, равное 0.765555 про правилам оценивания Kaggle для соревнования Titanik.
В следующих статьях цикла мы попытаемся уменьшить размерность задачи используя разные алгоритмы, а результаты сравним.

Автор: shadoof

Источник [18]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/python/33852

Ссылки в тексте:

[1] 1: http://habrahabr.ru/post/165001/

[2] 2: http://habrahabr.ru/post/165281/

[3] 3: http://habrahabr.ru/post/165283/

[4] Исходные данные: http://webfile.ru/6510765

[5] 4: http://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D1%8B%D1%85_%D0%BA%D0%BE%D0%BC%D0%BF%D0%BE%D0%BD%D0%B5%D0%BD%D1%82

[6] 5: http://www.chemometrics.ru/materials/textbooks/pca.htm

[7] 6: http://habrahabr.ru/post/146236/

[8] 7: http://habrahabr.ru/post/176257/

[9] 8: http://habrahabr.ru/post/134950/

[10] 9: http://www.iro.umontreal.ca/~lisa/publications2/index.php/publications/show/239

[11] 10: http://deeplearning.net/software/theano/

[12] 11: http://bgr.com/2013/03/13/google-speech-recognition-dnnresearch-373125/

[13] 12: http://research.google.com/pubs/SpeechProcessing.html

[14] deeplearning.net: http://deeplearning.net

[15] 12: http://deeplearning.net/software/theano/install.html#install

[16] 13: http://ru.wikipedia.org/wiki/%D0%9B%D0%BE%D0%B3%D0%B8%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B0%D1%8F_%D1%80%D0%B5%D0%B3%D1%80%D0%B5%D1%81%D1%81%D0%B8%D1%8F

[17] 14: http://deeplearning.net/software/theano/tutorial/examples.html

[18] Источник: http://habrahabr.ru/post/173819/