Русский
Русский
English
Статистика
Реклама

Sklearn

Подбор гиперпараметров ML-модели с помощью HYPEROPT

16.02.2021 12:20:24 | Автор: admin

В машинном обучении гиперпараметрами называют параметры модели, значения которых устанавливаются перед запуском процесса её обучения. Ими могут быть, как параметры самого алгоритма, например, глубина дерева в random forest, число соседей в knn, веса нейронов в нейронный сетях, так и способы обработки признаков, пропусков и т.д. Они используются для управления процессом обучения, поэтому подбор оптимальных гиперпараметров очень важный этап в построении ML-моделей, позволяющий повысить точность, а также бороться с переобучением. На сегодняшний день существуют несколько популярных подходов к решению задачи подбора, например:

1. Поиск по решётке. В этом способе значения гиперпараметров задаются вручную, затем выполняется их полный перебор. Популярной реализацией этого метода являетсяGrid Searchиз sklearn. Несмотря на свою простоту этот метод имеет и серьёзные недостатки:

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

Часто в целях экономии времени приходится укрупнять шаг перебора, что может привести к тому, что оптимальное значение параметра не будет найдено. Например, если задан диапазон значений от 100 до 1000 с шагом 100 (примером такого параметра может быть количество деревьев в случайном лесе, или градиентном бустинге), а оптимум находится около 550, то GridSearch его не найдёт.

2. Случайный поиск. Здесь параметры берутся случайным образом из выборки с указанным распределением. В sklearn он этот метод реализован какRandomized Search. В большинстве случаев он быстрее GridSearch, к тому же значения параметров не ограничены сеткой. Однако, даже это не всегда позволяет найти оптимум и не защищает от перебора заведомо неудачных комбинаций.

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

В этой статье приведён обзорhyperopt популярной python-библиотеки для подбора гиперпарметров. В ней реализовано 3 алгоритма оптимизации: классический Random Search, метод байесовской оптимизацииTree of Parzen Estimators (TPE), иSimulated Annealing ещё одна версия Random Search. Hyperopt может работать с разными типами гиперпараметров непрерывными, дискретными, категориальными и т.д, что является важным преимуществом этой библиотеки.

Установить hyperopt очень просто:

pip install hyperopt

Оценим работу этой библиотеки в реальнойзадаче предсказать, зарабатывает ли человек больше $50 тыс. Это может быть полезно, например, в кредитном скоринге. Загрузим необходимые библиотеки, и подготовим данные на вход модели:

from functools import partialimport numpy as npimport pandas as pdimport matplotlib.pyplot as plt%matplotlib inlineimport seaborn as snsfrom sklearn.model_selection import cross_val_score, StratifiedKFoldfrom sklearn.linear_model import LogisticRegressionfrom sklearn.preprocessing import StandardScaler, OneHotEncoderfrom sklearn.pipeline import Pipelinefrom sklearn.impute import SimpleImputerfrom sklearn.compose import ColumnTransformerfrom hyperopt import hp, fmin, tpe, Trials, STATUS_OK# загружаем данныеdf = pd.read_csv('adult.data.csv')# удаляем дубликатыdf.drop_duplicates(inplace=True, ignore_index=True)# готовим признаки и целевую переменную X = df.drop(labels=['salary', 'native-country'], axis=1).copy()y = df['salary'].map({'<=50K':0,'>50K':1}).values

В данных есть признаки разных типов, которые, соответственно, требуют и разной обработки. Для этого воспользуемся методом ColumnTransformer из библиотеки sklearn, который позволяет задать свой способ обработки для каждой группы признаков. Для категориальных признаков (тип object) будем использовать методы SimpleImputer (заменяет пропуски, которые обозначены символом ?) и OneHotEncoder (выполняетdummy-кодирование). Числовые признаки (остальные типы) будем масштабировать с помощью StandardScaler. В качестве модели выберем логистическую регрессию.

# выбираем категориальные (тип object)# и численные признаки (остальные типы)num_columns = np.where(X.dtypes != 'object')[0]cat_columns = np.where(X.dtypes == 'object')[0]# пайплайн для категориальных признаковcat_pipe = Pipeline([('imputer', SimpleImputer(missing_values='?',                             strategy='most_frequent')),                     ('ohe', OneHotEncoder(sparse=False,                         handle_unknown='ignore'))])# пайплайн для численных признаковnum_pipe = Pipeline([('scaler', StandardScaler())])# соединяем пайплайны вместеtransformer = ColumnTransformer(                           transformers=[('cat', cat_pipe, cat_columns),                                         ('num', num_pipe, num_columns)],                                          remainder='passthrough') # итоговая модельmodel = Pipeline([('transformer', transformer),                  ('lr', LogisticRegression(random_state=1, n_jobs=-1,                             solver='liblinear'))])

Сформируем пространство поиска параметров для hyperopt:

search_space = {                'lr__penalty' : hp.choice(label='penalty',                           options=['l1', 'l2']),                'lr__C' : hp.loguniform(label='C',                         low=-4*np.log(10),                         high=2*np.log(10))                }

Здесь параметр регуляризацииCвыбирается из лог-равномерного распределения [-4ln10, 2ln10], и может принимать значения [10-4, 102], а тип регуляризации равновероятно выбирается из [l1, l2]. Можно выбрать идругиетипы распределений, например, равномерное, или нормальное.

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

def objective(params, pipeline,  X_train, y_train):    """    Кросс-валидация с текущими гиперпараметрами    :params: гиперпараметры    :pipeline: модель    :X_train: матрица признаков    :y_train: вектор меток объектов    :return: средняя точность на кросс-валидации    """     # задаём модели требуемые параметры        pipeline.set_params(**params)    # задаём параметры кросс-валидации (стратифицированная 4-фолдовая с перемешиванием)    skf = StratifiedKFold(n_splits=4, shuffle=True, random_state=1)    # проводим кросс-валидацию      score = cross_val_score(estimator=pipeline, X=X_train, y=y_train,                             scoring='roc_auc', cv=skf, n_jobs=-1)    # возвращаем результаты, которые записываются в Trials()    return   {'loss': score.mean(), 'params': params, 'status': STATUS_OK}

Укажем объект для сохранения истории поиска (Trials). Это очень удобно, т.к. можно сохранять, а также прерывать и затем продолжать процесс поиска гиперпараметров. И, наконец, запускаем сам процесс подбора с помощью функции fmin. Укажем в качестве алгоритма поиска tpe.suggest байесовскую оптимизацию. Для Random Search нужно указать tpe.rand.suggest.

# запускаем hyperopttrials = Trials()best = fmin(           # функция для оптимизации              fn=partial(objective, pipeline=model, X_train=X, y_train=y),          # пространство поиска гиперпараметров              space=search_space,          # алгоритм поиска            algo=tpe.suggest,          # число итераций           # (можно ещё указать и время поиска)             max_evals=40,          # куда сохранять историю поиска            trials=trials,          # random state            rstate=np.random.RandomState(1),          # progressbar            show_progressbar=True        )

Выведем результаты в pandas DataFrame с помощью специальной функции и визуализируем:

def df_results(hp_results):    """    Отображаем результаты hyperopt в формате DataFrame     :hp_results: результаты hyperop    :return: pandas DataFrame    """     results = pd.DataFrame([{**x, **x['params']} for x in  hp_results])    results.drop(labels=['status', 'params'], axis=1, inplace=True)    results.sort_values(by=['loss'], ascending=False, inplace=True)    return resultsresults = df_results(trials.results)sns.set_context("talk")plt.figure(figsize=(8, 8))ax = sns.scatterplot(x='lr__C', y='loss', hue='lr__penalty',                                                    data=results);ax.set_xscale('log')ax.set_xlim(1e-4, 2e2)ax.grid()

На графике видно, что Hyperopt почти не исследовал районы, где получались низкие значения roc auc, а сосредоточился на районе с наибольшими значениями этой метрики.

Таким образом, hyperopt мощный инструмент для настройки модели, которым легко и удобно пользоваться. Дополнительные материалы можно найти в репозитории(для нескольких моделей), а также в1,2,3,4.

Подробнее..

Перевод 5 алгоритмов регрессии в машинном обучении, о которых вам следует знать

12.08.2020 20:21:34 | Автор: admin

Источник: Vecteezy

Да, линейная регрессия не единственная

Быстренько назовите пять алгоритмов машинного обучения.

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

Команда Mail.ru Cloud Solutions перевела статью, автор которой описывает 5 алгоритмов регрессии. Их стоит иметь в своем наборе инструментов наряду с популярными алгоритмами классификации, такими как SVM, дерево решений и нейронные сети.

1. Нейросетевая регрессия


Теория


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

Каждый нейрон передает значения из предыдущей связи через функцию активации, служащую цели обобщения и нелинейности. Обычно активационная функция это что-то вроде сигмоиды или функции ReLU (выпрямленный линейный блок).


Источник. Свободное изображение

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

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

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

Реализация


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

model = Sequential()
model.add(Dense(100, input_dim=3, activation='sigmoid'))
model.add(ReLU(alpha=1.0))
model.add(Dense(50, activation='sigmoid'))
model.add(ReLU(alpha=1.0))
model.add(Dense(25, activation='softmax'))

#IMPORTANT PART
model.add(Dense(1, activation='linear'))

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

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

2. Регрессия дерева решений


Теория


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


Иллюстрация автора

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

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

Реализация


Регрессия дерева решений может быть легко создана в sklearn:

from sklearn.tree import DecisionTreeRegressormodel = DecisionTreeRegressor()model.fit(X_train, y_train)

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

При формальной оценке производительности используйте тестирование K-fold вместо стандартного train-test-split, чтобы избежать случайности последнего, которая может нарушить чувствительные результаты модели с высокой дисперсией.

Бонус: близкий родственник дерева решений, алгоритм random forest (алгоритм случайного леса), также может быть реализован в качестве регрессора. Регрессор случайного леса может работать лучше или не лучше, чем дерево решений в регрессии (в то время как он обычно работает лучше в классификации) из-за тонкого баланса между избыточным и недостаточным в природе алгоритмов построения дерева.

from sklearn.ensemble import RandomForestRegressormodel = RandomForestRegressor()model.fit(X_train, y_train)

3. Регрессия LASSO


Метод регрессии лассо (LASSO, Least Absolute Shrinkage and Selection Operator) это вариация линейной регрессии, специально адаптированная для данных, которые демонстрируют сильную мультиколлинеарность (то есть сильную корреляцию признаков друг с другом).

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


Иллюстрация автора. Упрощенная визуализация процесса сжатия

Процесс сжатия добавляет регрессионным моделям несколько преимуществ:

  • Более точные и стабильные оценки истинных параметров.
  • Уменьшение ошибок выборки и отсутствия выборки.
  • Сглаживание пространственных флуктуаций.

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

Регрессия лассо использует регуляризацию L1, то есть взвешивает ошибки по их абсолютному значению. Вместо, например, регуляризации L2, которая взвешивает ошибки по их квадрату, чтобы сильнее наказывать за более значительные ошибки.

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

Реализация


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

from sklearn.linear_model import LassoCVmodel = LassoCV()model.fit(X_train, y_train)

4. Гребневая регрессия (ридж-регрессия)


Теория


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

Однако самое большое различие между ними в том, что гребневая регрессия использует регуляризацию L2, то есть ни один из коэффициентов не становится нулевым, как это происходит в регрессии LASSO. Вместо этого коэффициенты всё больше приближаются к нулю, но не имеют большого стимула достичь его из-за природы регуляризации L2.


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

В лассо улучшение от ошибки 5 до ошибки 4 взвешивается так же, как улучшение от 4 до 3, а также от 3 до 2, от 2 до 1 и от 1 до 0. Следовательно, больше коэффициентов достигает нуля и устраняется больше признаков.

Однако в гребневой регрессии улучшение от ошибки 5 до ошибки 4 вычисляется как 5 4 = 9, тогда как улучшение от 4 до 3 взвешивается только как 7. Постепенно вознаграждение за улучшение уменьшается; следовательно, устраняется меньше признаков.

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

Реализация


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

from sklearn.linear_model import RidgeCVmodel = Ridge()model.fit(X_train, y_train)

5. Регрессия ElasticNet


Теория


ElasticNet стремится объединить лучшее из гребневой регрессии и регрессии лассо, комбинируя регуляризацию L1 и L2.

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

  1. Если = 0, то задача становится аналогичной простой линейной регрессии, достигая тех же коэффициентов.
  2. Если = , то коэффициенты будут равны нулю из-за бесконечного веса на квадрате коэффициентов. Всё, что меньше нуля, делает цель бесконечной.
  3. Если 0 < < , то величина определяет вес, придаваемый различным частям объекта.

К параметру регрессия ElasticNet добавляет дополнительный параметр , который измеряет, насколько смешанными должны быть регуляризации L1 и L2. Когда параметр равен 0, модель является чисто гребневой регрессией, а когда он равен 1 это чистая регрессия лассо.

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

Реализация


ElasticNet можно реализовать с помощью модели перекрестной валидации sklearn:
from sklearn.linear_model import ElasticNetCVmodel = ElasticNetCV()model.fit(X_train, y_train)

Что еще почитать по теме:

  1. Анализ больших данных в облаке: как компании стать дата-ориентированной.
  2. Форматы файлов в больших данных.
  3. Наш телеграм-канал о цифровой трансформации.
Подробнее..

Из песочницы Ищем Троллей. Алгоритм шинглов amp косинусное сходство

25.09.2020 18:15:34 | Автор: admin

Думаю, многие в напряженных дискуссиях в интернете сталкивались с обвинением людей в том, что они боты, тролли и проплачены Кремлем, Киевом или Вашингтоном. Но как действительно выявить таковых или просто людей пытающихся активно донести своё мнение до остальных?

Возьмём, к примеру четыре текста (комментария):

text_1 = 'Комментарий в первой теме характеризующий Михаил Михайловича умным, целеустремленным и ответственным человеком'text_2 = 'Комментарий из второй темы про Михаил Михайловича, описывающий его как умного, ответственного и упорного человека'text_3 = 'Случайный текст похожей длинны с первыми двумя комментариями не несущей какой либо смысловой нагрузки'text_4 = 'Комментарий из другой темы, не касающийся Михаила, но тоже про умного человека, ответственно подходящего к работе'

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

Как прийти к такому же результату с точки зрения математики?
Банально сравнить количество одинаковых слов в обоих текстов. Но сразу появляется проблема как сравнить слова умный и умного? Лемматизация текста подходит не всегда, так как готовые библиотеки не поддерживают многие языки.

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

Пример:

Текст 1 при n = 3
['ком', 'омм', 'мме', 'мен', 'ент', 'нта', 'тар', 'ари', 'рий', 'ий ', 'й в', ' в ', 'в п', ' пе', 'пер', 'ерв', 'рво', 'вой', 'ой ', 'й т', ' те', 'тем', 'еме', 'ме ', 'е х', ' ха', 'хар', 'ара', 'рак', 'акт', 'кте', 'тер', 'ери', 'риз', 'изу', 'зую', 'ующ', 'ющи', 'щий', 'ий ', 'й м', ' ми', 'мих', 'иха', 'хаи', 'аил', 'ил ', 'л м', ' ми', 'мих', 'иха', 'хай', 'айл', 'йло', 'лов', 'ови', 'вич', 'ича', 'ча ', 'а у', ' ум', 'умн', 'мны', 'ным', 'ым ', 'м ц', ' це', 'цел', 'еле', 'леу', 'еус', 'уст', 'стр', 'тре', 'рем', 'емл', 'мле', 'лен', 'енн', 'нны', 'ным', 'ым ', 'м и', ' и ', 'и о', ' от', 'отв', 'тве', 'вет', 'етс', 'тст', 'ств', 'тве', 'вен', 'енн', 'нны', 'ным', 'ым ', 'м ч', ' че', 'чел', 'ело', 'лов', 'ове', 'век', 'еко']


Текст 1 при n = 5
['комме', 'оммен', 'ммент', 'мента', 'ентар', 'нтари', 'тарий', 'арий ', 'рий в', 'ий в ', 'й в п', ' в пе', 'в пер', ' перв', 'перво', 'ервой', 'рвой ', 'вой т', 'ой те', 'й тем', ' теме', 'теме ', 'еме х', 'ме ха', 'е хар', ' хара', 'харак', 'аракт', 'ракте', 'актер', 'ктери', 'териз', 'еризу', 'ризую', 'изующ', 'зующи', 'ующий', 'ющий ', 'щий м', 'ий ми', 'й мих', ' миха', 'михаи', 'ихаил', 'хаил ', 'аил м', 'ил ми', 'л мих', ' миха', 'михай', 'ихайл', 'хайло', 'айлов', 'йлови', 'лович', 'овича', 'вича ', 'ича у', 'ча ум', 'а умн', ' умны', 'умным', 'мным ', 'ным ц', 'ым це', 'м цел', ' целе', 'целеу', 'елеус', 'леуст', 'еустр', 'устре', 'стрем', 'тремл', 'ремле', 'емлен', 'мленн', 'ленны', 'енным', 'нным ', 'ным и', 'ым и ', 'м и о', ' и от', 'и отв', ' отве', 'ответ', 'тветс', 'ветст', 'етств', 'тстве', 'ствен', 'твенн', 'венны', 'енным', 'нным ', 'ным ч', 'ым че', 'м чел', ' чело', 'челов', 'елове', 'ловек', 'овеко']


Рассчитаем сходство первого и второго / первого и четвертого текстов при n (1,9) по формуле:

sim = len(set(Shingles_1) & set(Shingles_2)) / len(set(Shingles_1) | set(Shingles_2)))

ShingleSize: 10.9166666666666666 / 0.7857142857142857ShingleSize: 20.5196078431372549 / 0.40350877192982454ShingleSize: 30.3404255319148936 / 0.2375ShingleSize: 40.28205128205128205 / 0.18497109826589594 ShingleSize: 50.2289156626506024 / 0.13812154696132597ShingleSize: 60.1896551724137931 / 0.10752688172043011ShingleSize: 70.15730337078651685 / 0.07894736842105263ShingleSize: 80.13333333333333333 / 0.057291666666666664ShingleSize: 90.10989010989010989 / 0.04145077720207254

Закономерная картина, при увеличение длины увеличивается общее количество шинглов и падает отношение общих шинглов к совокупному объёму. Так при больших объёмах текстов лучше использовать длину шинглов от 5 до 8, а при работе с короткими, например твиты или комментарии 2-4.

Но вернемся к практике, возьмём предварительно собранные данные, с популярного российского, развлекательного портала. Ссылка на kaggle.

Для сбора максимально жарких дискуссий был выбран тэг (раздел) Политика, итого собрано:

  • 944 поста с тегом политика
  • 267000 комментариев к ним
  • из них длиннее 100 символов ~ 140 тысяч

Перейдем к коду:

Очистка текста и разделение на шинглы:

def clean_text(text):    text = text.split('\n')    text = list(filter(None, text))    text = ' '.join(text)    text = re.sub(r"http\S+", "", text)    text = re.sub(r'[^\w\s]', '', text)    shingle = [text[i:i + ShingleSize] for i in range(len(text))][:-ShingleSize]    return ','.join(shingle)

Если мы берем только комментарии длиннее 100 символов, то количество итераций сравнения составляет: $inline$140000!/((140000 - 2)!*2! )$inline$, что довольно много и обработка даже в мультипоточном режиме займет достаточно продолжительное время.

Поэтому сравнивать будем не попарно, а матрицами m*n, используя косинусное сходство
где m число строк, которое подбирается опционально в зависимости от объёма оперативной памяти, а n число столбцов, общее количество всех шинглов;

Реализация алгоритма:

csrMatrix = []idArray = []textArray = []for i in range(ChunkSize, sparse_matrix.shape[0] + ChunkSize, ChunkSize):    temp = sparse_matrix[i - ChunkSize:i - 1]    idArray.append(corpusId[i - ChunkSize:i - 1])    textArray.append(OriginalCorpus[i - ChunkSize:i - 1])    csrMatrix.append(temp)matrixCombinations = itertools.combinations_with_replacement(range(len(csrMatrix)), 2)

При m = 20000 и длинной шингла = 8, получаем 7 матриц размером 20000 * 8800000 и следовательно 21 итерации сравнения. Уже намного лучше.

def Sim(A, B, C, D):    similarities = cosine_similarity(B[A[0]].astype(np.float32), B[A[1]].astype(np.float32))    x, y = np.where(similarities > similarityPercent)    res = []    for k, j in zip(x, y):        if D[A[0]][k] != D[A[1]][j]:            res.append((D[A[0]][k], C[A[0]][k], similarities[k][j].item(), D[A[1]][j], C[A[1]][j]))    return ress = pool.starmap(Sim, zip(matrixCombinations, itertools.repeat(csrMatrix), itertools.repeat(textArray), itertools.repeat(idArray)))s = [item for sublist in s for item in sublist]

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

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

SELECT FirstText, SUM(sim) as c FROM pikabu.similarity GROUP BY FirstId ORDER BY c DESC

Топ совпадений:

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

Стандартная ситуация для политических дискуссий в интернете.

Отбрасывая ссылки, сообщения администрации, прочий шум переходим непосредственно к анализу смысловой нагрузки комментариев:

Восемь совпадений
DaimosShip,2020-08-14 23:03:48,
Ермошина подтвердила, что Тихановская записывала свое обращение в ее кабинете в ЦИКе
DaimosShip,2020-08-14 23:05:41,
Ермошина подтвердила, что Тихановская записывала свое обращение в ее кабинете в ЦИКе
DaimosShip,2020-08-14 23:05:52,
Ермошина подтвердила, что Тихановская записывала свое обращение в ее кабинете в ЦИКе
DaimosShip,2020-08-14 23:05:26,
Ермошина подтвердила, что Тихановская записывала свое обращение в ее кабинете в ЦИКе
DaimosShip,2020-08-14 23:05:22,
Ермошина подтвердила, что Тихановская записывала свое обращение в ее кабинете в ЦИКе
DaimosShip,2020-08-14 23:07:02,
Ермошина подтвердила, что Тихановская записывала свое обращение в ее кабинете в ЦИКе
DaimosShip,2020-08-14 23:06:53,
Ермошина подтвердила, что Тихановская записывала свое обращение в ее кабинете в ЦИКе
DaimosShip,2020-08-14 23:06:18,
Ермошина подтвердила, что Тихановская записывала свое обращение в ее кабинете в ЦИКе

Человек за пять минут написал 8 одинаковых сообщений в одной и той же теме, касающихся событий в Белоруссии. Всего в базу попало 260 сообщения данного автора, беглый взгляд на них даёт понять явное негативное отношение к ситуации в Белоруссии, так же сам пользователь идёт на опережения и в качестве аргументов сам называет своих оппонентов ботами.

А ещё у него брат был наблюдателем на выборах:

DaimosShip,2020-08-18 22:52:41
У меня брат был наблюдателем никуда не пустили


Ещё 6 совпадений
NoisePanzer,2017-11-20 14:58:26,
Остаётся ещё около 17 миллионов Вермахта и СС.Не буду утверждать точно, но читал немецкого исследователя, он пишет, что 80% вермахта (НЕ СС!) участвовали в актах геноцида и других военных преступлениях.

NoisePanzer,2017-11-20 15:33:26,
Вы не правы. Читал книгу немецкого исследователя о добровольческом батальоне вермахта. Люди (подавляющее большинство!) добровольно шли убивать невиновных. Работ на эту тему, явно доказывающих, что БОЛЬШИНСТВО немцев было не против массовых убийств очень много. Если вы (вполне резонно) не верите мне, ссылки откопаю и приведу вам.

NoisePanzer,2017-11-20 15:26:55,
Нет. Вы не правы. Читал книгу немецкого исследователя о добровольческом батальоне вермахта. Люди (подавляющее большинство!) добровольно шли убивать невиновных. Работ на эту тему, явно доказывающих, что БОЛЬШИНСТВО немцев было не против массовых убийств очень много. Если вы (вполне резонно) не верите мне, ссылки откопаю и приведу вам.

NoisePanzer,2017-11-21 03:51:46,
Нет. Вы не правы. Читал книгу немецкого исследователя о добровольческом батальоне вермахта. Люди (подавляющее большинство!) добровольно шли убивать невиновных. Работ на эту тему, явно доказывающих, что БОЛЬШИНСТВО немцев было не против массовых убийств очень много. Если вы (вполне резонно) не верите мне, ссылки откопаю и приведу вам.

NoisePanzer,2017-11-21 03:52:14,
Нет. Вы не правы. Читал книгу немецкого исследователя о добровольческом батальоне вермахта. Люди (подавляющее большинство!) добровольно шли убивать невиновных. Работ на эту тему, явно доказывающих, что БОЛЬШИНСТВО немцев было не против массовых убийств очень много. Если вы (вполне резонно) не верите мне, ссылки откопаю и приведу вам.

NoisePanzer,2017-11-21 03:53:22,
Читал книгу немецкого исследователя о добровольческом батальоне вермахта. Люди (подавляющее большинство!) добровольно шли убивать невиновных. Работ на эту тему, явно доказывающих, что БОЛЬШИНСТВО немцев было не против массовых убийств очень много. Если вы (вполне резонно) не верите мне, ссылки откопаю и приведу вам.

Автор явно любитель немецкой исторической литературы

И ещё 4
Kumuj,2018-03-25 01:46:10,
Интересная тенденция на Пикабу вырисовывается, последние пару дней замечаю все больше заплюсованых постов с негативным отношением к императору. Неужели фабрика троллей сбавила обороты и мы можем видеть реальные настроения в интернете?

Kumuj,2018-03-25 01:53:56,
Интересная тенденция на Пикабу вырисовывается, последние пару дней замечаю все больше заплюсованых постов с негативным отношением к императору. Неужели фабрика троллей сбавила обороты и мы можем видеть реальные настроения в интернете?

Kumuj,2018-03-25 01:46:26,
Интересная тенденция на Пикабу вырисовывается, последние пару дней замечаю все больше заплюсованых постов с негативным отношением к императору. Неужели фабрика троллей после выборов сбавила обороты и мы можем видеть реальные настроения юзеров в интернете?

Kumuj,2018-03-25 01:42:29,
Интересная тенденция на Пикабу вырисовывается, последние пару дней замечаю все больше заплюсованых постов с негативным отношением к императору. Неужели фабрика троллей сбавила обороты и мы можем видеть реальные настроения в интернете?

Человек ищет следы фабрики троллей. Привет, коллега.

Идём дальше: 6 человек цитируют одну и туже книгу в разных темах - Осторожно, мат!!!
Strannik196,2018-03-21 23:53:00,
на мой взгляд здесь будет кстати цитата из Пелевина:"Так вот, уловка-22 заключается в следующем: какие бы слова ни произносились на политической сцене, сам факт появления человека на этой сцене доказывает, что перед нами блядь и провокатор. Потому что если бы этот человек не был блядью и провокатором, его бы никто на политическую сцену не пропустил там три кольца оцепления с пулемётами. Элементарно, Ватсон: если девушка сосёт хуй в публичном доме, из этого с высокой степенью вероятности следует, что перед нами проститутка. Я почувствовал обиду за свое поколение. Почему обязательно проститутка, сказал я. А может это белошвейка. Которая только вчера приехала из деревни. И влюбилась в водопроводчика, ремонтирующего в публичном доме душ. А водопроводчик взял её с собой на работу, потому что ей временно негде жить. И там у них выдалась свободная минутка.Самарцев поднял палец: Вот на этом невысказанном предположении и держится весь хрупкий механизм нашего молодого народовластия"

Fynjif18,2020-09-09 13:44:56,
Ну что же вы это прям по Пелевину. Правильно, сказал Самарцев. Так вот, уловка-22 заключается в следующем: какие бы слова ни произносились на политической сцене, сам факт появления человека на этой сцене доказывает, что перед нами блядь и провокатор. Потому что если бы этот человек не был блядью и провокатором, его бы никто на политическую сцену не пропустил там три кольца оцепления с пулеметами. Элементарно, Ватсон: если девушка сосет хуй в публичном доме, из этого с высокой степенью вероятности следует, что перед нами проститутка.

wakeonlan,2020-06-23 01:38:29,
уловка-22 заключается в следующем: какие бы слова ни произносились на политической сцене, сам факт появления человека на этой сцене доказывает, что перед нами б**дь и провокатор. Потому что если бы этот человек не был б**дью и провокатором, его бы никто на политическую сцену не пропустил там три кольца оцепления с пулеметами. Элементарно, Ватсон: если девушка сосет х*й в публичном доме, из этого с высокой степенью вероятности следует, что перед нами проститутка.

KKirill1992,2017-06-18 00:06:30,
Знаете, в книге Хеллера "Уловка-22" есть один персонаж по имени Орр. Так вот, он прикидывался идиотом, но только для того, чтобы спасти себе жизнь. Это я понимаю.Но вы-то с какой целью прикидываетесь идиотом в комментариях на пикабу? У вас что, за спиной стоит фсбшник с волыной?

nezabuddha,2018-11-01 15:29:56,
ru.m.wikipedia.org/wiki/Уловка-22 Нет. Пелевин лишь цитирует принцип, описанный гораздо раньше.

ihateyou,2016-09-19 02:52:14,
Так вот, уловка-22 заключается в следующем: какие бы слова ни произносились на политической сцене, сам факт появления человека на этой сцене доказывает, что перед нами блядь и провокатор. Потому что если бы этот человек не был блядью и провокатором, его бы никто на политическую сцену не пропустил там три кольца оцепления с пулеметами. Элементарно, Ватсон: если девушка сосет хуй в публичном доме, из этого с высокой степенью вероятности следует, что перед нами проститутка. Я почувствовал обиду за свое поколение. Почему обязательно проститутка, сказал я. А может это белошвейка. Которая только вчера приехала из деревни. И влюбилась в водопроводчика, ремонтирующего в публичном доме душ. А водопроводчик взял ее с собой на работу, потому что ей временно негде жить. И там у них выдалась свободная минутка. Самарцев поднял палец: Вот на этом невысказанном предположении и держится весь хрупкий механизм нашего молодого народовластияПелевин "Empire V"

Автор пытается донести до остальных данные о росте уровня поддержки СССР
EtovamneTo,2020-08-18 01:50:22,
Наверное то, что реальность противоположна твоим словам точно не потому что ты здесь откровенно врешь в надежде на то, что сонмы таких же малолетних пизд Совков тебя заплюсуют.По данным опроса Левады центра уровень поддержки СССР сильно вырос за два десятилетия. Сильнее всего у тех, кому сейчас 18-24 годаВне зависимости от того, как мы разбиваем совокупность респондентов, наиболее сильный рост поддержки от 2008-го к 2019-му году фиксируется в отношении двух позиций, характеризующих Советский Союз как государство социальной справедливости и патернализма. Наиболее заметные изменения в поддержке фиксируются в молодежной средеОдно из самых устойчивых представлений, характеризующих положение дел в Советском Союзе, это представление населения о дружбе народов, поддержка которого во всех трех опросах находилась на идентичном уровне. Уверенность в отсутствии межнациональных конфликтов всегда входила в тройку самых популярных суждений о СССР. При этом, например, вопросы о депортации народов в советский период давали высокую долю затруднившихся ответить до трети, что является свидетельством незнания этой страницы в истории своей страны (среди 18-24-летних более половины уходят от содержательного ответа на вопросы о депортациях). Если, напротив, обратиться к суждениям, заметно теряющим поддержку, то на первом месте среди них направляющая роль коммунистической партии (на 14 п.п.) и очереди, дефицит, карточки (на 18 п.п.).https://www.levada.ru/2019/06/24/chernovik/

EtovamneTo,2020-08-18 00:50:15,
Каждый раз, когда я кидаю пруфы, я получаю только тишину, оскорбления и демагогию от коммунистов, изучивших историю страны по выпускам Гоблина и пикабушечкам. Естественно, ни и какой культуре или адекватном уровне IQ речи там и нет.Вот вы посмотрите: комментатор выше ничем не подкрепляет свои слова. А теперь посмотрим это: По данным опроса Левады центра уровень поддержки СССР сильно вырос за два десятилетия. Сильнее всего у тех, кому сейчас 18-24 годаВне зависимости от того, как мы разбиваем совокупность респондентов, наиболее сильный рост поддержки от 2008-го к 2019-му году фиксируется в отношении двух позиций, характеризующих Советский Союз как государство социальной справедливости и патернализма. Наиболее заметные изменения в поддержке фиксируются в молодежной средеОдно из самых устойчивых представлений, характеризующих положение дел в Советском Союзе, это представление населения о дружбе народов, поддержка которого во всех трех опросах находилась на идентичном уровне. Уверенность в отсутствии межнациональных конфликтов всегда входила в тройку самых популярных суждений о СССР. При этом, например, вопросы о депортации народов в советский период давали высокую долю затруднившихся ответить до трети, что является свидетельством незнания этой страницы в истории своей страны (среди 18-24-летних более половины уходят от содержательного ответа на вопросы о депортациях). Если, напротив, обратиться к суждениям, заметно теряющим поддержку, то на первом месте среди них направляющая роль коммунистической партии (на 14 п.п.) и очереди, дефицит, карточки (на 18 п.п.).https://www.levada.ru/2019/06/24/chernovik/

EtovamneTo,2020-08-27 23:22:35,
Нет. Сейчас социалисты те самые малолетние дол*****(с). А это еще в статистику нельзя включать людей моложе 18 лет.По данным опроса Левады центра уровень поддержки СССР сильно вырос за два десятилетия. Сильнее всего у тех, кому сейчас 18-24 годаВне зависимости от того, как мы разбиваем совокупность респондентов, наиболее сильный рост поддержки от 2008-го к 2019-му году фиксируется в отношении двух позиций, характеризующих Советский Союз как государство социальной справедливости и патернализма. Наиболее заметные изменения в поддержке фиксируются в молодежной средеОдно из самых устойчивых представлений, характеризующих положение дел в Советском Союзе, это представление населения о дружбе народов, поддержка которого во всех трех опросах находилась на идентичном уровне. Уверенность в отсутствии межнациональных конфликтов всегда входила в тройку самых популярных суждений о СССР. При этом, например, вопросы о депортации народов в советский период давали высокую долю затруднившихся ответить до трети, что является свидетельством незнания этой страницы в истории своей страны (среди 18-24-летних более половины уходят от содержательного ответа на вопросы о депортациях). Если, напротив, обратиться к суждениям, заметно теряющим поддержку, то на первом месте среди них направляющая роль коммунистической партии (на 14 п.п.) и очереди, дефицит, карточки (на 18 п.п.).https://www.levada.ru/2019/06/24/chernovik/

EtovamneTo,2020-09-10 03:32:13,
Каких? что популярность тематики резко выросла? Погугли тег СССР с рейтингом выше 25.За август 2010 было 44 таких поста.За август 2020 было 274 таких поста.Или что среди молодежи? Да вотПо данным опроса Левады центра уровень поддержки СССР сильно вырос за два десятилетия. Сильнее всего у тех, кому сейчас 18-24 годаhttps://www.levada.ru/2019/06/24/chernovik/

EtovamneTo,2020-09-09 19:00:42,
По данным опроса Левады центра уровень поддержки СССР сильно вырос за два десятилетия. Сильнее всего у тех, кому сейчас 18-24 годаВне зависимости от того, как мы разбиваем совокупность респондентов, наиболее сильный рост поддержки от 2008-го к 2019-му году фиксируется в отношении двух позиций, характеризующих Советский Союз как государство социальной справедливости и патернализма. Наиболее заметные изменения в поддержке фиксируются в молодежной средеОдно из самых устойчивых представлений, характеризующих положение дел в Советском Союзе, это представление населения о дружбе народов, поддержка которого во всех трех опросах находилась на идентичном уровне. Уверенность в отсутствии межнациональных конфликтов всегда входила в тройку самых популярных суждений о СССР. При этом, например, вопросы о депортации народов в советский период давали высокую долю затруднившихся ответить до трети, что является свидетельством незнания этой страницы в истории своей страны (среди 18-24-летних более половины уходят от содержательного ответа на вопросы о депортациях). Если, напротив, обратиться к суждениям, заметно теряющим поддержку, то на первом месте среди них направляющая роль коммунистической партии (на 14 п.п.) и очереди, дефицит, карточки (на 18 п.п.).https://www.levada.ru/2019/06/24/chernovik/

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

GitHub

P.S. Обработка матрицы 140000 * 8800000 заняла примерно 7 минут на процессоре rayzen 5 1600

В дальнейшем планирую продолжать данную тему, буду рад критике и предложениям.
Подробнее..

Перевод Понимание деревьев решений в машинном обучении и их реализация с помощью Python

09.11.2020 18:08:51 | Автор: admin
Совсем скоро, 20 ноября, у нас стартует новый поток Математика и Machine Learning для Data Science, и в преддверии этого мы делимся с вами полезным переводом с подробным, иллюстрированным объяснением дерева решений, разъяснением энтропии дерева решений с формулами и простыми примерами, вводом понятия информационный выигрыш, которое игнорируется большинством умозрительно-простых туториалов. Статья рассчитана на любящих математику новичков, которые хотят больше разобраться вработе дерева принятия решений. Для полной ясности взят совсем маленький набор данных. В конце статьи ссылка на код на Github.





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


Корневой узел самый верхний узел в дереве решений называется корневой узел.
Узел принятия решения подузел, который разделяется на дополнительные подузлы, известен как узел принятия решения.

Лист/терминальный узел узел, который не разделяется на другие узлы, называется терминальный узел, или лист.

Набор данных



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

Представление набора данных



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


Вот так в дереве решений происходит разбиение.

Важные теоретические определения


Энтропия


Энтропия это мера случайности или неопределенности. Уровень энтропии колеблется от 0 до 1. Когда энтропия равна 0, это означает, что подмножество чистое, то есть в нем нет случайных элементов. Когда энтропия равна 1, это означает высокую степень случайности. Энтропия обозначается символами H(S).

Формула энтропии


Энтропия вычисляется так: -(p(0) * log(P(0)) + p(1) * log(P(1)))

P(0) Вероятность принадлежности к класу 0
P(1) Вероятность принадлежности к классу 1

Связь между энтропией и вероятностью




Когда энтропия равна 0, это означает, что подмножество чистое, то есть в нем нет энтропии: либо все да, либо все голоса нет. Когда она равна 1, то это означает высокую степень случайности. Построим график вероятности P(1) вероятности принадлежности к классу 1 в зависимости от энтропии. Из объяснения выше мы знаем, что:

Если P(1) равно 0, то энтропия равна 0
Если P(1) равно 1, то энтропия равна 0
Если P(1) равно 0,5, то энтропия равна 1


Уровень энтропии всегда находится в диапазоне от 0 до 1.

Информационный выигрыш


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


H(S) Энтропия
A Атрибут
S Множество примеров {x}
V Возможные значения A
Sv Подмножество

Как работает дерево решений


В нашем наборе данных два атрибута, BMI и Age. В базе данных семь записей. Построим дерево решений для нашего набора данных.

1. Корневой узел


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


В корневом узле наблюдаем три голоса за и четыре против.
Вероятность принадлежности к классу 0 равна 4/7. Четыре из семи записей принадлежат к классу 0.
P(0) = 4/7
Вероятность принадлежности к классу 1 равна 3/7. То есть три из семи записей принадлежат классу 1.
P(1) = 3/7.

Вычисляем энтропию корневого узла:


2. Как происходит разбиение?


У нас есть два атрибута BMI и Age. Как на основе этих атрибутов происходит разбиение? Как проверить эффективность разбиения?

1. При выборе атрибута BMI в качестве переменной разделения и 30 в качестве точки разделения мы получим одно чистое подмножество.

Точки разбиения рассматриваются для каждой точки набора данных. Таким образом, если точки данных уникальны, то для n точек данных будет n-1 точек разбиения. То есть в зависимости от выбранных точки и переменной разбиения мы получаем высокий информационный выигрыш и выбираем разделение с этим выигрышем. В большом наборе данных принято считать только точки разделения при определенных процентах распределения значений: 10, 20, 30%. У нас набор данных небольшой, поэтому, видя все точки разделения данных, я выбрала в качестве точки разделения значения 30.


Энтропия чистого подмножества равна нулю. Теперь рассчитаем энтропию другого подмножества. Здесь у нас три голоса за и один против.

P(0)=1/4 [одна из четырех записей)
P(1)=3/4 [три из четырех записей)


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


2. Выберем атрибут Age в качестве переменной разбиения и 45 в качестве точки разбиения.


Давайте сначала вычислим энтропию подмножества True. У него есть одно да и одно нет. Это высокий уровень неопределенности. Энтропия равна 1. Теперь рассчитаем энтропию подмножества False. В нем два голоса за и три против.

Image for post

3. Рассчитаем информационный выигрыш.

Image for post

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


Итак, мы создали дерево решений с чистыми подмножествами.

Напишем это на Python с помощью sklearn


1. Импортируем библиотеки.

import numpy as npimport pandas as pd import matplotlib.pyplot as pltimport seaborn as sns

2. Загрузим данные.

df=pd.read_csv("Diabetes1.csv")df.head()


3. Разделим переменные на x и y.

Атрибуты BMI и Age принимаются за x.
Атрибут Diabetes (целевая переменная) принимается за y.

x=df.iloc[:,:2]y=df.iloc[:,2:]x.head(3)


y.head(3)


4. Построим модель с помощью sklearn

from sklearn import treemodel=tree.DecisionTreeClassifier(criterion="entropy")model.fit(x,y)

Вывод: DecisionTreeClassifier (criterion=entropy)

5. Оценка модели

model.score(x,y)

Вывод: 1.0. Мы взяли очень маленький набор данных, поэтому оценка равна 1.

6. Прогнозирование с помощью модели

Давайте предскажем, будет ли диабет у человека 47 лет с ИМТ 29. Напомню, что эти данные есть в нашем наборе данных.

model.predict([[29,47]])

Вывод: array([no], dtype=object)
Прогноз нет, такой же, как и в наборе данных. Теперь спрогнозируем, будет ли диабет у человека 47 лет с индексом массы тела 45. Отмечу, что этих данных в нашем наборе нет.

model.predict([[45,47]])

Вывод: array([yes], dtype=object)

Прогноз положительный.

7. Визуализация модели:

tree.plot_tree(model)


Код и набор данных из этой статьи доступны на GitHub.

Приходите изумать математику к нам, на курс Математика и Machine Learning для Data Science а промокод HABR, добавит 10 % к скидке на баннере.

image



Рекомендуемые статьи


Подробнее..

Перевод Запускаем модель машинного обучения на iPhone

18.04.2021 18:19:42 | Автор: admin

Чего уж только на Хабре не было, и DOOM на осциллографе, тесте на беременности и калькуляторе запускали, даже сервер Minecraftна зеркалке Canon 200D поднимали. Сегодня же, специально к старту нового потока курса по Machine Learning и углубленного Machine Learning и Deep Learning, попробуем описать кратчайший путь от обучения модели машинного обучения на Python до доказательства концепции iOS-приложения, которое можно развернуть на iPhone. Цель статьи дать базовый скаффолдинг, оставляя место для дальнейшей настройки, подходящей для конкретного случая использования.


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

Шаг 1. Настройка среды

Во-первых, давайте создадим виртуальную среду Python под названием .core_ml_demo, а затем установим необходимые библиотеки: pandas, scikit-learn и coremltools. Чтобы создать виртуальную среду, выполните в терминале эти команды:

python3 -m venv ~/.core_ml_demosource  ~/.core_ml_demo/bin/activatepython3 -m pip install \pandas==1.1.1 \scikit-learn==0.19.2 \coremltools==4.0

Далее установим Xcode. XCode это инструментарий разработки для продуктов Apple. Обратите внимание, что Xcode довольно большой (больше 10 ГБ). Я бы порекомендовал выпить чашку кофе или запустить установку на ночь.

Примечание: в этом туториале используется Xcode 12.3 (12C33) на MacOS Catalina 10.15.5.

Шаг 2. Обучение модели

Мы будем использовать набор данных Boston Housing Price от scikit-learn для обучения модели линейной регрессии и прогнозирования цен на жильё на основе свойств и социально-экономических атрибутов.

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

import pandas as pdfrom sklearn.linear_model import LinearRegressionfrom sklearn.datasets import load_boston# Load databoston = load_boston()boston_df = pd.DataFrame(boston["data"])boston_df.columns = boston["feature_names"]boston_df["PRICE"]= boston["target"]y = boston_df["PRICE"]X = boston_df.loc[:,["RM", "AGE", "PTRATIO"]]# Train a modellm = LinearRegression()lm.fit(X, y)

Шаг 3. Преобразование модели в Core ML

Apple предоставляет два способа разработки моделей для iOS. Первый, Create ML, позволяет создавать модели полностью в рамках экосистемы Apple. Второй, Core ML, позволяет интегрировать модели от третьих лиц в платформу Apple, преобразовав их в формат Core ML. Поскольку мы заинтересованы в запуске обученной модели на iOS, воспользуемся вторым способом.

Перед импортом в Xcode мы преобразуем нашу модель sklearn в формат Core ML (.mlmodel) с помощью пакета python coremltool; coremltools позволяет назначать метаданные объекту модели, такие как информация об авторстве, описание функций модели и результатов.

# Convert sklearn model to CoreMLimport coremltools as cmlmodel = cml.converters.sklearn. \convert(lm,        ["RM", "AGE", "PTRATIO"],        "PRICE")# Assign model metadatamodel.author = "Medium Author"model.license = "MIT"model.short_description = \"Predicts house price in Boston"# Assign feature descriptionsmodel.input_description["RM"] = \"Number of bedrooms"model.input_description["AGE"] = \"Proportion of units built pre 1940"model.input_description["PTRATIO"] = \"Pupil-teacher ratio by town"# Assign the output descriptionmodel.output_description["PRICE"] = \"Median Value in 1k (USD)"# Save modelmodel.save('bhousing.mlmodel')

Шаг 4. Создание нового проекта в Xcode

С Python мы закончили. Теперь можно завершить прототип приложения при помощи только Xcode и Swift. Это можно сделать так:

  1. Откройте Xcode и создайте новый проект.

  2. Выберите iOS как тип мультиплатформы.

  3. Выберите тип приложения App.

Создание нового проекта Xcode для iOSСоздание нового проекта Xcode для iOS

4. Дайте проекту название и выберите интерфейс SwiftUI.

Конфигурация проектаКонфигурация проекта

Теперь просто перетащите созданный на третьем шаге файл модели .ml в каталог Xcode. Xcode автоматически сгенерирует класс Swift для вашей модели, как показано в редакторе ниже. Если вы посмотрите на класс, то заметите, что он содержит детали, которые мы ввели при сохранении нашей модели на Python с помощью coremltools, такие как описания объектов и целевых полей. Это удобно при управлении моделью.

Импорт файла .coreml в проект XcodeИмпорт файла .coreml в проект Xcode

Шаг 5. Создание UI модели

Далее создадим базовый пользовательский интерфейс, изменив файл contentView.swift. Приведённый ниже код на Swift отображает пользовательский интерфейс, который позволяет пользователям настраивать атрибуты дома, а затем прогнозировать его цену. Есть несколько элементов, которые мы можем здесь рассмотреть.

NavigationView содержит необходимый пользовательский интерфейс. Он включает:

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

  • Кнопку на панели навигации (строки 3140) для вызова нашей модели из функции predictPrice (строка 46). На экране появится предупреждающее сообщение с прогнозируемой ценой.

За пределами NavigationView у нас есть функция predictPrice (строки 4662). Она создаёт экземпляр класса Swift Core ML model и генерирует прогноз в соответствии с хранящимися в состояниях объектов значениями.

import SwiftUIimport CoreMLimport Foundationstruct ContentView: View {  @State private var rm = 6.5  @State private var age = 84.0  @State private var ptratio = 16.5      @State private var alertTitle = ""  @State private var alertMessage = ""  @State private var showingAlert = false      var body: some View {      NavigationView {        VStack {        Text("House Attributes")            .font(.title)        Stepper(value: $rm, in: 1...10,                step: 0.5) {            Text("Rooms: \(rm)")          }          Stepper(value: $age, in: 1...100,              step: 0.5) {          Text("Age: \(age)")          }          Stepper(value: $ptratio, in: 12...22,              step: 0.5) {          Text("Pupil-teacher ratio: \(ptratio)")          }          .navigationBarTitle("Price Predictor")          .navigationBarItems(trailing:              Button(action: predictPrice) {                  Text("Predict Price")              }          )          .alert(isPresented: $showingAlert) {              Alert(title: Text(alertTitle),                    message: Text(alertMessage),              dismissButton: .default(Text("OK")))          }        }      }  }            func predictPrice() {    let model = bhousing()    do { let p = try      model.prediction(          RM: Double(rm),          AGE: Double(age),          PTRATIO: Double(ptratio))        alertMessage = "$\(String((p.PRICE * 1000)))"      alertTitle = "The predicted price is:"  } catch {    alertTitle = "Error"    alertMessage = "Please retry."  }    showingAlert = true}}struct ContentView_Previews: PreviewProvider {    static var previews: some View {        ContentView()    }}

И, наконец, самое интересное: мы можем создать и запустить симуляцию приложения в Xcode, чтобы увидеть нашу модель в действии. В приведённом ниже примере я создал симуляцию с помощью iPhone 12.

Симуляция модели работает на iOS.Симуляция модели работает на iOS.

Заключение

И это всё. Первый прототип завершён. Здесь есть что добавить, например валидацию модели, тесты для подтверждения ожидаемой производительности после импорта в iOS и более гладкий/дружественный пользовательский интерфейс. Тем не менее я надеюсь, что статья послужит полезным справочником по развёртыванию машинного обучения на мобильном устройстве.

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

Если вы кодите на Python и столкнулись в работе с задачами машинного обучения обратите внимание на наш курс Machine Learning, на котором вы сможете систематизировать и углубить полученные самостоятельно знания, пообщаться с профессионалами и применить модели Machine Learning на практике. Даже можно будет ворваться на хакатоны Kaggle.

Если же есть намерение сменить сферу деятельности и погрузиться в ML более плотно то можно посмотреть на продвинутый курс Machine Learning и Deep Learning, на котором вы освоите основные алгоритмы машинного обучения, обучите рекомендательную систему и создадите несколько нейронных сетей.

Узнайте, как прокачаться и в других специальностях или освоить их с нуля:

Другие профессии и курсы
Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru