Первые шаги в машинном обучении

МЕНЮ


Искусственный интеллект. Новости
Поиск
Регистрация на сайте

ТЕМЫ


Новости ИИРазработка ИИРабота разума и сознаниеВнедрение ИИРобототехника, БПЛАТрансгуманизмОбработка текстаТеория эволюцииДополненная реальностьЖелезоКиберугрозыНаучный мирИТ индустрияРазработка ПОТеория информации

Авторизация



RSS


RSS новости

Новостная лента форума ailab.ru

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

Преамбула

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

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

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

Втыкаем лопату

Первым делом я отправился на официальный сайт TensorFlow и прочитал ML for Beginners и TensorFlow for beginners. Материалы на английском.

TensorFlow это поделка команды Google и наиболее популярная библиотека для работы с машинным обучением, которая поддерживает Python, Java, C++, Go, а также возможность использования вычислительных мощностей графической видеокарты для расчетов сложных нейросетей.

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

В поисках готовых примеров я наткнулся на туториал по определению языка на котором написан текст с помощью Scikit-learn.

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

Первым делом, первым делом датасеты...

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

Данные в которых алгоритм будет искать закономерности называются features.
Категория, к которой относится та или иная feature, называется label. Важно отметить, что входные данные могут иметь несколько features, но всего один label.

В классическом примере машинного обучения, определения разновидностей цветков ириса по длине пестиков и тычинок, каждый отдельный столбец с информацией о размере это feature, а последний столбец, который означает к какому из подвидов ириса относится цветок с такими значениями это label

Способ, которым я буду решать проблему классификации, называется supervised learning, или обучение под надзором. Это значит, что в процессе обучения алгоритм будет получать и features и labels.

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

Я написал скрипт, который генерировал случайные адреса электронной почты и SQL инъекции. В итоге в моем csv файле получалось три типа данных: случайные имейлы (20 тыс.), случайные имейлы с SQL инъекцией (20 тыс.) и чистые SQL инъекции (10 тыс.). Выглядело это примерно вот так:

Теперь исходные данные нужно считать. Функция возвращает лист X, в котором содержатся features, лист Y, в котором содержатся labels для каждой feature и лист label_names, который просто содержит текстовое определения для labels, нужен для удобства при выводе результатов.

import csv  def get_dataset():    X = []    y = []    label_names = ["safe data","Injected email"]    with open('trainingSet.csv') as csvfile:        readCSV = csv.reader(csvfile, delimiter=' ')        for row in readCSV:            splitted = row[0].split(',')            X.append(splitted[0])            y.append(splitted[1])                         print("  Data set features {0}". format(len(X)))    print("Data set labels   {0} ". format(len(y)))     print(X)     return X, y, label_names 

Далее эти данные нужно разбить на тренировочный сет и на тестовый. В этом нам поможет заботливо написанная для нас функция cross_validation.train_test_split(), которая перетасует записи и вернет нам четыре сета данных — два тренировочных и два тестовых для features и labels.

# Split the dataset on training and testing sets X_train, X_test, y_train, y_test = cross_validation.train_test_split(X,y,test_size=0.2,random_state=0)

Затем мы инициализируем объект vectorizer, который будет считывать переданные в него данные по одному символу, комбинировать их в N-граммы и переводить в числовые векторы, который способен воспринимать алгоритм машинного обучения.

#Setting up vectorizer that will convert dataset into vectors using n-gram vectorizer = feature_extraction.text.TfidfVectorizer(ngram_range=(1, 4), analyzer='char') 

Скармливаем данные

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

#Setting up pipeline to flow data though vectorizer to the liner model implementation pipe = pipeline.Pipeline([('vectorizer', vectorizer), ('clf', linear_model.LogisticRegression())]) 

Модель готова к перевариванию данных. Теперь просто передаем тренировочные сеты features и labels в наш pipeline и модель начинает обучение. Следующей строкой мы пропускаем тестовый сет features через pipeline, но теперь мы используем predict, чтобы получить число правильно угаданных данных.

#Pass training set of features and labels though pipe. pipe.fit(X_train, y_train)  #Test model accuracy by running feature test set y_predicted = pipe.predict(X_test) 

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

print(metrics.classification_report(y_test, y_predicted,target_names=label_names))

Точность модели определяется величиной от 0 до 1, и можно перевести в проценты. Эта модель дает правильный ответ в 100% случаев. Конечно, используя реальные данные, подобного результата будет добиться не так просто, да и задача достаточно простая.

Последний финальный штрих это сохранить модель в обученном виде, чтоб ее можно было без повторного обучения использовать в любой другой python программе. Мы сериализуем модель в pickle файл с помощью встроенной в Scikit-learn функции:

#Save model into pickle. Built in serializing tool joblib.dump(pipe, 'injection_model.pkl') 

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

import numpy as np from sklearn.externals import joblib  #Load classifier from the pickle file clf = joblib.load('injection_model.pkl')  #Set of test data input_data = ["aselectndwdpyrey@gmail.com",            "andrew@microsoft.com'",            "a.johns@deloite.com",            "'",            "select@mail.jp",            "update11@nebuzar.com",            "' OR 1=1",            "asdasd@sick.com'",            "andrew@mail' OR 1=1",            "an'drew@bark.1ov111.com",            "andrew@gmail.com'"]  predicted_attacks = clf.predict(input_data).astype(np.int) label_names = ["Safe Data", "SQL Injection"]  for email, item in zip(input_data, predicted_attacks):  print(u' {} ----> {}'.format(label_names[item], email)) 

На выходе мы получим вот такой результат:

Как видите, модель достаточно уверенно определяет SQL инъекции.

Заключение

В итоге мы имеем тренированную модель для определения SQL инъекций, в теории, мы можем воткнуть ее в серверную часть, и в случае определения инъекции перенаправлять все запросы за фальшивую базу данных, чтоб отвадить взгляд от других возможных уязвимостей. Для демонстрации в конце недели я написал небольшой REST API на Flask.

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

Полный код

 from sklearn import ensemble from sklearn import feature_extraction from sklearn import linear_model from sklearn import pipeline from sklearn import cross_validation from sklearn import metrics from sklearn.externals import joblib  import load_data import pickle  # Load the dataset from the csv file. Handled by load_data.py. Each email is split in characters and each one has label assigned X, y, label_names = load_data.get_dataset()  # Split the dataset on training and testing sets X_train, X_test, y_train, y_test = cross_validation.train_test_split(X,y,test_size=0.2,random_state=0)  #Setting up vectorizer that will convert dataset into vectors using n-gram vectorizer = feature_extraction.text.TfidfVectorizer(ngram_range=(1, 4), analyzer='char')  #Setting up pipeline to flow data though vectorizer to the liner model implementation pipe = pipeline.Pipeline([('vectorizer', vectorizer), ('clf', linear_model.LogisticRegression())])  #Pass training set of features and labels though pipe. pipe.fit(X_train, y_train)  #Test model accuracy by running feature test set y_predicted = pipe.predict(X_test)  print(metrics.classification_report(y_test, y_predicted,target_names=label_names))  #Save model into pickle. Built in serializing tool joblib.dump(pipe, 'injection_model.pkl') 

Справочные Материалы

Оставляю список полезных ресурсов, которые помогли мне с данным проектом (почти все они на английском)

Tensorflow for begginers
Scikit-Learn Tutorials
Building Language Detector via Scikit-Learn

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


Источник: habrahabr.ru



Поддержи проект ai-news рублем. Машины верят в тебя! >>



Комментарии: