Привет, дорогой друг, ты всегда хотел попробовать машинное обучение, но эта область казалась загадочной и сложной? Я хотел бы поделиться с вами своей историей о том, как я сделал свои первые шаги в машинном обучении, имея нулевые знания Python и высшей математики, на небольшом примере.
Преамбула Я работаю веб-разработчиком в консалтинговой компании, и иногда наступает момент, когда один проект уже закончился, а следующий еще не назначен.
Каждый, кто оказывается на скамейке запасных, чтобы не сидеть сложа руки, должен внести свой вклад в интеллектуальную собственность компании.
Обычно это либо создание обучающих материалов по теме, которой владеет автор, либо изучение новой технологии с последующей демонстрацией или презентацией в конце недели.
Я решил, раз есть такая возможность, попробовать затронуть тему Machine Learning, ведь это стильно, модно и молодежно.
Из моих предыдущих знаний по этой теме у меня была всего пара презентаций от ведущего разработчика, носивших скорее популяризационный, а не информационный тон.
Я определил конкретную проблему, которую нужно решить с помощью машинного обучения, и начал копать.
Хочу отметить, что наличие конечной цели позволяло легче ориентироваться в потоке информации.
Мы втыкаем лопату
Первое, что я сделал, это зашёл на официальный сайт TensorFlow и прочитал ML для начинающих И TensorFlow для начинающих .Материалы на английском языке.
TensorFlow — продукт команды Google и самая популярная библиотека для работы с машинным обучением, поддерживающая Python, Java, C++, Go, а также возможность использовать вычислительные мощности видеокарты для расчета сложных нейронных сетей.
В поисках я нашел еще одну библиотеку для машинного обучения Scikit-обучение Ориентирован на Python. Преимущество этой библиотеки в том, что она прямо из коробки имеет большое количество алгоритмов машинного обучения, что в моем случае было несомненным плюсом, так как презентация была в пятницу, а мне очень хотелось продемонстрировать работающую модель.
В поисках готовых примеров наткнулся руководство путем определения языка, на котором написан текст, с помощью Scikit-learn. Итак, моей задачей было обучить модель обнаруживать наличие SQL-инъекции в текстовой строке.
(Конечно, можно решить эту задачу с помощью регулярных выражений, но в образовательных целях можно пострелять из пушки воробьев)
Прежде всего, прежде всего, наборы данных.
Тип проблемы, которую я пытаюсь решить, — это классификация, то есть алгоритм должен в ответ на поданные данные сообщить мне, к какой категории относятся эти данные.
Данные, в которых алгоритм будет искать закономерности, называются функции .
Категория, к которой принадлежит конкретный объект, называется этикетка .
Важно отметить, что входные данные могут иметь несколько признаков, но только одну метку.
В классическом примере машинного обучения, определяющего сорта цветов ириса на основе длины пестиков и тычинок, каждый отдельный столбец с информацией о размере особенность , а последний столбец, означающий, к какому из подвидов ирисов принадлежит цветок с такими значениями – этикетка
Способ, которым я решу задачу классификации, называется обучением с учителем.
Это означает, что в процессе обучения алгоритм получит как признаки, так и метки.
Шаг номер один в решении любой задачи с помощью машинного обучения — это сбор данных, на которых эта самая машина будет учиться.
В идеальном мире это должны быть реальные данные, но, к сожалению, мне не удалось найти в Интернете ничего, что меня удовлетворило бы.
Было решено сгенерировать данные самостоятельно.
Я написал сценарий, который генерировал случайные адреса электронной почты и выполнял SQL-инъекции.
В результате мой csv-файл содержал три типа данных: случайные электронные письма (20 тысяч), случайные электронные письма с SQL-инъекцией (20 тысяч) и чистые SQL-инъекции (10 тысяч).
Это выглядело примерно так:
Теперь необходимо прочитать исходные данные.
Функция возвращает лист X, который содержит объекты, лист Y, который содержит метки для каждого объекта, и лист label_names, который просто содержит текстовые определения меток, необходимые для удобства при отображении результатов.
Далее эти данные необходимо разделить на обучающую и тестовую выборку.import csv def get_dataset(): X = [] y = [] label_names = ["safe data","Injected email"] with open('trainingSet.csv') as csvfile: readCSV = csv.reader(csvfile, delimiter='\n') for row in readCSV: splitted = row[0].
split(',') X.append(splitted[0]) y.append(splitted[1]) print("\n\nData set features {0}".
format(len(X))) print("Data set labels {0}\n".
format(len(y))) print(X) return X, y, label_names
В этом нам поможет тщательно написанная для нас функция cross_validation.train_test_split(), которая перетасует записи и вернет нам четыре набора данных — два обучающих и два тестовых для признаков и меток.
# 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)
Затем мы инициализируем объект-векторизатор, который будет считывать передаваемые в него данные по одному символу, объединять их в N-граммы и перевести в числовые векторы, понятные алгоритму машинного обучения.
#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))
Точность модели определяется значением от 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 = ["[email protected]",
"[email protected]'",
"[email protected]",
"'",
"[email protected]",
"[email protected]",
"' OR 1=1",
"[email protected]'",
"andrew@mail' OR 1=1",
"an'[email protected]",
"[email protected]'"]
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'\n{} ----> {}'.
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')
Справочные материалы
Оставляю список полезных ресурсов, которые помогли мне в этом проекте (почти все на английском языке) Тензорный поток для новичков Учебные пособия по Scikit-Learn Создание детектора языка с помощью Scikit-Learn Нашел несколько отличных статьи на Medium включая серию из восьми статей, которые дают хорошее представление о машинном обучении на простых примерах.( UPD: Русский перевод тех же статей ) Теги: #python 3 #машинное обучение #python #машинное обучение
-
Какой Ipad 2 Или 3 Вы Выберете?
19 Oct, 24 -
Избавьтесь От Моли На Кухне
19 Oct, 24 -
Луркмор Заблокировали По 149-Фз
19 Oct, 24 -
Внедрение Стиля Кода В Существующий Проект
19 Oct, 24 -
Молодого Дворнягу Назвали Байнет.
19 Oct, 24