Теория обучения машин (machine learning, машинное обучение) находится на стыке прикладной статистики, численных методов оптимизации, дискретного анализа, и за последние 50 лет оформилась в самостоятельную математическую дисциплину. Методы машинного обучения составляют основу еще более молодой дисциплины — интеллектуального анализа данных (data mining). Перенося эти определения на automated machine learning (AML), можно сказать, что это − «Теория автоматического / автоматизированного обучения машин».
Чтобы применять машинное обучение для решения конкретных кейсов, необходимо постоянно:
От этих рутинных операций, как и от части операций в подготовке и очистке данных, аналитиков или data scientist’ов можно избавить с помощью автоматизации.
Автоматизированный алгоритм может перебрать все стандартные комбинации и выдать некоторое базовое решение, которое квалифицированный специалист сможет взять за основу и дальше улучшать. Однако во многих случаях результатов работы автоматизированного алгоритма окажется достаточно и без дополнительных улучшений, и их можно будет использовать непосредственно.
На сегодняшний день можно выделить два наиболее результативных пакета автоматизированного машинного обучения. Оба они используют библиотеку машинного обучения sklearn языка Python и активно разрабатываются. Первый из них — библиотека Auto-sklearn, разработанный во Фрайбургском университете. Вторым лидирующим решением в области автоматизированного машинного обучения выступает библиотека TeaPOT (TPOT).
Как определяют TPOT сами авторы - это инструмент Python, который автоматически создает и оптимизирует конвейеры (pipeline) машинного обучения с использованием генетического программирования. TPOT автоматизирует самую утомительную часть машинного обучения, исследуя тысячи возможных конвейеров, чтобы найти лучший для ваших данных.
Требует предварительной установки следующих пакетов: NumPy, SciPy, scikit-learn, DEAP, update_checker, tqdm, pywin32 (для Windows), xgboost, scikit-mdr и skrebate:
import numpy as np
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from tpot import TPOTClassifier
iris = load_iris()
X_train, X_test, y_train, y_test = train_test_split(iris.data.astype(np.float64),
iris.target.astype(np.float64), train_size=0.75, test_size=0.25)
tpot = TPOTClassifier(generations=5, population_size=50, verbosity=2)
tpot.fit(X_train, y_train)
print(tpot.score(X_test, y_test))
tpot.export('tpot_iris_pipeline.py')
#Содержание 'tpot_iris_pipeline.py' (может отличаться - не зафиксировала random seed):
#import numpy as np
#from sklearn.model_selection import train_test_split
#from sklearn.naive_bayes import GaussianNB
#from sklearn.pipeline import make_pipeline
#from sklearn.preprocessing import Normalizer
# NOTE: Make sure that the class is labeled 'class' in the data file
#tpot_data = np.recfromcsv('PATH/TO/DATA/FILE', delimiter='COLUMN_SEPARATOR', dtype=np.float64)
#features = np.delete(tpot_data.view(np.float64).reshape(tpot_data.size, -1), tpot_data.dtype.names.index('class'), axis=1)
#training_features, testing_features, training_classes, testing_classes = \
# train_test_split(features, tpot_data['class'], random_state=42)
#exported_pipeline = make_pipeline(
# Normalizer(norm="l2"),
# GaussianNB()
#)
#exported_pipeline.fit(training_features, training_classes)
#results = exported_pipeline.predict(testing_features)
Получаем точность при тестировании примерно 97%.
import pandas as pd
# загрузим обучающую и тестовую выборки
train_df = pd.read_csv('../../data/websites_train_sessions.csv',
index_col='session_id')
test_df = pd.read_csv('../../data/websites_test_sessions.csv',
index_col='session_id')
# приведем колонки time1, ..., time10 к временному формату
times = ['time%s' % i for i in range(1, 11)]
train_df[times] = train_df[times].apply(pd.to_datetime)
test_df[times] = test_df[times].apply(pd.to_datetime)
# отсортируем данные по времени
train_df = train_df.sort_values(by='time1')
# посмотрим на заголовок обучающей выборки
train_df.head()
import pickle
# приведем колонки site1, ..., site10 к целочисленному формату и заменим пропуски нулями
sites = ['site%s' % i for i in range(1, 11)]
train_df[sites] = train_df[sites].fillna(0).astype('int')
test_df[sites] = test_df[sites].fillna(0).astype('int')
# загрузим словарик сайтов
with open(r"../../data/site_dic.pkl", "rb") as input_file:
site_dict = pickle.load(input_file)
# датафрейм словарика сайтов
sites_dict = pd.DataFrame(list(site_dict.keys()), index=list(site_dict.values()), columns=['site'])
print(u'всего сайтов:', sites_dict.shape[0])
sites_dict.head()
# создадим отдельный датафрейм, где будем работать со временем
time_df = pd.DataFrame(index=train_df.index)
time_df['target'] = train_df['target']
# найдем время начала и окончания сессии
time_df['min'] = train_df[times].min(axis=1)
time_df['max'] = train_df[times].max(axis=1)
# вычислим длительность сессии и переведем в секунды
time_df['seconds'] = (time_df['max'] - time_df['min']) / np.timedelta64(1, 's')
#time_df.head()
# наша целевая переменная
train_df.rename(columns={'target': 'class'}, inplace=True)
y_train = train_df['class']
# объединенная таблица исходных данных
full_df = pd.concat([train_df.drop('class', axis=1), test_df])
# индекс, по которому будем отделять обучающую выборку от тестовой
idx_split = train_df.shape[0]
# табличка с индексами посещенных сайтов в сессии
full_sites = full_df[sites]
full_sites.head()
from scipy.sparse import csr_matrix, hstack
# последовательность с индексами
sites_flatten = full_sites.values.flatten()
# искомая матрица
full_sites_sparse = csr_matrix(([1] * sites_flatten.shape[0],
sites_flatten,
range(0, sites_flatten.shape[0] + 10, 10)))[:, 1:]
from tpot import TPOTClassifier
def get_tpot(X, y,seed=42, ratio = 0.9):
# разделим выборку на обучающую и валидационную
idx = round(X.shape[0] * ratio)
# обучение классификатора
tpot = TPOTClassifier(generations = 2, population_size = 3, verbosity=2,max_time_mins=3, max_eval_time_mins=0.04)
tpot.fit(X[:idx, :], y[:idx])
return tpot
%%time
# выделим из объединенной выборки только обучающую (для которой есть ответы)
X_train = full_sites_sparse[:idx_split, :]
tpot = get_tpot(X_train, y_train)
# функция для записи прогнозов в файл
def write_to_submission_file(predicted_labels, out_file,
target='target', index_label="session_id"):
predicted_df = pd.DataFrame(predicted_labels,
index = np.arange(1, predicted_labels.shape[0] + 1),
columns=[target])
predicted_df.to_csv(out_file, index_label=index_label)
X_test = full_sites_sparse[idx_split:,:]
y_test = tpot.predict(X_test)
write_to_submission_file(y_test, 'tpot_baseline.csv')
В результате не удалось побить даже первый бейзлайн. Score = 0.5. Возможно TPOT так работает на разреженных матрицах. В любом случае дальше нужно подбирать параметры классификатора самостоятельно, либо давать свой словарь TPOT-у (параметр config_dict)