{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "## Открытый курс по машинному обучению\n", "
Автор материала: Плаксина Елена Константиновна, Levka." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "##
Обзор библиотеки для генерации временных признаков tsfresh
\n", "###
Time Series FeatuRe Extraction based on Scalable Hypothesis tests
" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "Библиотека используется для извлечения признаков из временных рядов. Практически все признаки, которые могут прийти вам в голову, уже внесены в расчёт этой библиотеки и нет никакого смысла создавать их самому, когда это можно сделать парой строчек кода из библиотеки.\n", "\n", "Извлечённые признаки могут быть использованы для описания или кластеризации временных рядов. Также их можно использовать для задач классификации/регрессии на временных рядах." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Процесс расчёта признаков состоит из двух этапов:\n", "- Расчёт всех возможных признаков\n", "\n", "```python\n", "from tsfresh import extract_features\n", "extracted_features = extract_features(timeseries, column_id=\"id\", column_sort=\"time\")\n", "```\n", "- Отбор релевантных признаков и удаление константных/нулевых признаков\n", "\n", "```python\n", "from tsfresh import select_features\n", "from tsfresh.utilities.dataframe_functions import impute\n", "\n", "impute(extracted_features) # удаление константных признаков\n", "features_filtered = select_features(extracted_features, y) # отбор признаков\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Процедура отбора признаков\n", "#### Стадия 1\n", "Расчёт признаков\n", "#### Стадия 2\n", "Проверка на значимость каждого признака, расчёт p-value\n", "#### Стадия 3\n", "Поправка на множественную проверку гипотез Бенджамини-Иекутиели" ] }, { "cell_type": "markdown", "metadata": { "ExecuteTime": { "end_time": "2018-04-24T18:18:21.873848Z", "start_time": "2018-04-24T18:18:21.870343Z" } }, "source": [ "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Приведём пример генерации признаков на основе датасета Human Activity Recognition" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "ExecuteTime": { "end_time": "2018-04-24T18:35:06.604259Z", "start_time": "2018-04-24T18:35:06.592741Z" } }, "outputs": [], "source": [ "import matplotlib.pylab as plt\n", "%matplotlib inline\n", "from tsfresh.examples.har_dataset import download_har_dataset, load_har_dataset, load_har_classes\n", "import seaborn as sns\n", "from tsfresh import extract_features, extract_relevant_features, select_features\n", "from tsfresh.utilities.dataframe_functions import impute\n", "from tsfresh.feature_extraction import ComprehensiveFCParameters\n", "from sklearn.tree import DecisionTreeClassifier\n", "from sklearn.model_selection import train_test_split\n", "from sklearn.metrics import classification_report\n", "import pandas as pd\n", "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Загрузка и отрисовка данных**" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "ExecuteTime": { "end_time": "2018-04-24T18:32:59.112311Z", "start_time": "2018-04-24T18:32:40.608378Z" } }, "outputs": [], "source": [ "download_har_dataset()" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "ExecuteTime": { "end_time": "2018-04-24T18:32:59.373712Z", "start_time": "2018-04-24T18:32:59.113813Z" } }, "outputs": [], "source": [ "df = load_har_dataset()" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "ExecuteTime": { "end_time": "2018-04-24T18:35:03.282511Z", "start_time": "2018-04-24T18:35:03.191846Z" } }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plt.title('accelerometer reading')\n", "plt.plot(df.iloc[0,:])\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Извлечение признаков**" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "ExecuteTime": { "end_time": "2018-04-24T18:37:44.151891Z", "start_time": "2018-04-24T18:37:44.148384Z" } }, "outputs": [], "source": [ "# расчёт только определённого набора параметров, заданного в ComprehensiveFCParameters\n", "extraction_settings = ComprehensiveFCParameters()" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "ExecuteTime": { "end_time": "2018-04-24T18:40:36.723372Z", "start_time": "2018-04-24T18:40:36.712868Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
01
00.0001810
10.0101390
20.0092760
30.0050660
40.0108100
\n", "
" ], "text/plain": [ " 0 1\n", "0 0.000181 0\n", "1 0.010139 0\n", "2 0.009276 0\n", "3 0.005066 0\n", "4 0.010810 0" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# переформируем данные 500 первых показаний сенсоров column-wise, как этого требует формат библиотеки\n", "N = 500\n", "master_df = pd.DataFrame({0: df[:N].values.flatten(),\n", " 1: np.arange(N).repeat(df.shape[1])})\n", "master_df.head()" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "ExecuteTime": { "end_time": "2018-04-24T18:41:33.544564Z", "start_time": "2018-04-24T18:40:57.405324Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Feature Extraction: 100%|██████████████████████████████████████████| 20/20 [00:34<00:00, 1.74s/it]\n", "WARNING:tsfresh.utilities.dataframe_functions:The columns ['0__fft_coefficient__coeff_65__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_65__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_65__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_65__attr_\"real\"'\n", " '0__fft_coefficient__coeff_66__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_66__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_66__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_66__attr_\"real\"'\n", " '0__fft_coefficient__coeff_67__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_67__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_67__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_67__attr_\"real\"'\n", " '0__fft_coefficient__coeff_68__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_68__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_68__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_68__attr_\"real\"'\n", " '0__fft_coefficient__coeff_69__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_69__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_69__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_69__attr_\"real\"'\n", " '0__fft_coefficient__coeff_70__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_70__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_70__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_70__attr_\"real\"'\n", " '0__fft_coefficient__coeff_71__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_71__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_71__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_71__attr_\"real\"'\n", " '0__fft_coefficient__coeff_72__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_72__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_72__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_72__attr_\"real\"'\n", " '0__fft_coefficient__coeff_73__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_73__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_73__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_73__attr_\"real\"'\n", " '0__fft_coefficient__coeff_74__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_74__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_74__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_74__attr_\"real\"'\n", " '0__fft_coefficient__coeff_75__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_75__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_75__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_75__attr_\"real\"'\n", " '0__fft_coefficient__coeff_76__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_76__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_76__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_76__attr_\"real\"'\n", " '0__fft_coefficient__coeff_77__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_77__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_77__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_77__attr_\"real\"'\n", " '0__fft_coefficient__coeff_78__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_78__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_78__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_78__attr_\"real\"'\n", " '0__fft_coefficient__coeff_79__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_79__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_79__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_79__attr_\"real\"'\n", " '0__fft_coefficient__coeff_80__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_80__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_80__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_80__attr_\"real\"'\n", " '0__fft_coefficient__coeff_81__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_81__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_81__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_81__attr_\"real\"'\n", " '0__fft_coefficient__coeff_82__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_82__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_82__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_82__attr_\"real\"'\n", " '0__fft_coefficient__coeff_83__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_83__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_83__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_83__attr_\"real\"'\n", " '0__fft_coefficient__coeff_84__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_84__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_84__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_84__attr_\"real\"'\n", " '0__fft_coefficient__coeff_85__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_85__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_85__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_85__attr_\"real\"'\n", " '0__fft_coefficient__coeff_86__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_86__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_86__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_86__attr_\"real\"'\n", " '0__fft_coefficient__coeff_87__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_87__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_87__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_87__attr_\"real\"'\n", " '0__fft_coefficient__coeff_88__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_88__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_88__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_88__attr_\"real\"'\n", " '0__fft_coefficient__coeff_89__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_89__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_89__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_89__attr_\"real\"'\n", " '0__fft_coefficient__coeff_90__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_90__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_90__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_90__attr_\"real\"'\n", " '0__fft_coefficient__coeff_91__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_91__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_91__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_91__attr_\"real\"'\n", " '0__fft_coefficient__coeff_92__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_92__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_92__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_92__attr_\"real\"'\n", " '0__fft_coefficient__coeff_93__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_93__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_93__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_93__attr_\"real\"'\n", " '0__fft_coefficient__coeff_94__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_94__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_94__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_94__attr_\"real\"'\n", " '0__fft_coefficient__coeff_95__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_95__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_95__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_95__attr_\"real\"'\n", " '0__fft_coefficient__coeff_96__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_96__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_96__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_96__attr_\"real\"'\n", " '0__fft_coefficient__coeff_97__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_97__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_97__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_97__attr_\"real\"'\n", " '0__fft_coefficient__coeff_98__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_98__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_98__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_98__attr_\"real\"'\n", " '0__fft_coefficient__coeff_99__attr_\"abs\"'\n", " '0__fft_coefficient__coeff_99__attr_\"angle\"'\n", " '0__fft_coefficient__coeff_99__attr_\"imag\"'\n", " '0__fft_coefficient__coeff_99__attr_\"real\"'] did not have any finite values. Filling with zeros.\n" ] } ], "source": [ "X = extract_features(master_df, column_id=1, impute_function=impute, default_fc_parameters=extraction_settings)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "ExecuteTime": { "end_time": "2018-04-24T18:42:22.275690Z", "start_time": "2018-04-24T18:42:22.272685Z" } }, "outputs": [ { "data": { "text/plain": [ "'Число рассчитанных признаков: 794.'" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"Число рассчитанных признаков: {}.\".format(X.shape[1])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Обучение классификатора**" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "ExecuteTime": { "end_time": "2018-04-24T18:45:36.391311Z", "start_time": "2018-04-24T18:45:36.384788Z" } }, "outputs": [ { "data": { "text/plain": [ "(500,)" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y = load_har_classes()[:N]\n", "y.shape" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "ExecuteTime": { "end_time": "2018-04-24T18:45:43.110969Z", "start_time": "2018-04-24T18:45:43.100963Z" } }, "outputs": [], "source": [ "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.2)" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "ExecuteTime": { "end_time": "2018-04-24T18:45:47.906376Z", "start_time": "2018-04-24T18:45:47.813708Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " precision recall f1-score support\n", "\n", " 1 1.00 1.00 1.00 29\n", " 2 1.00 1.00 1.00 9\n", " 3 1.00 1.00 1.00 14\n", " 4 0.36 0.36 0.36 14\n", " 5 0.26 0.36 0.30 14\n", " 6 0.60 0.45 0.51 20\n", "\n", "avg / total 0.73 0.71 0.72 100\n", "\n" ] } ], "source": [ "cl = DecisionTreeClassifier()\n", "cl.fit(X_train, y_train)\n", "print(classification_report(y_test, cl.predict(X_test)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Отберём признаки для каждого класса отдельно и решим задачу бинарной классификации**" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "ExecuteTime": { "end_time": "2018-04-24T18:49:57.768306Z", "start_time": "2018-04-24T18:49:43.341016Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "WARNING:tsfresh.feature_selection.relevance:Infered classification as machine learning task\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Number of relevant features for class 5: 216/794\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:tsfresh.feature_selection.relevance:Infered classification as machine learning task\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Number of relevant features for class 4: 202/794\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:tsfresh.feature_selection.relevance:Infered classification as machine learning task\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Number of relevant features for class 6: 188/794\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:tsfresh.feature_selection.relevance:Infered classification as machine learning task\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Number of relevant features for class 1: 216/794\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:tsfresh.feature_selection.relevance:Infered classification as machine learning task\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Number of relevant features for class 3: 220/794\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "WARNING:tsfresh.feature_selection.relevance:Infered classification as machine learning task\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Number of relevant features for class 2: 166/794\n" ] } ], "source": [ "relevant_features = set()\n", "\n", "for label in y.unique():\n", " y_train_binary = y_train == label\n", " X_train_filtered = select_features(X_train, y_train_binary)\n", " print(\"Number of relevant features for class {}: {}/{}\".format(label, X_train_filtered.shape[1], X_train.shape[1]))\n", " relevant_features = relevant_features.union(set(X_train_filtered.columns))" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "ExecuteTime": { "end_time": "2018-04-24T18:50:01.727717Z", "start_time": "2018-04-24T18:50:01.724211Z" } }, "outputs": [ { "data": { "text/plain": [ "264" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(relevant_features)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Мы уменьшили количество признаков с 794 до 264." ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "ExecuteTime": { "end_time": "2018-04-24T18:50:10.141904Z", "start_time": "2018-04-24T18:50:10.136905Z" } }, "outputs": [], "source": [ "X_train_filtered = X_train[list(relevant_features)]\n", "X_test_filtered = X_test[list(relevant_features)]" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "ExecuteTime": { "end_time": "2018-04-24T18:50:16.432864Z", "start_time": "2018-04-24T18:50:16.429357Z" } }, "outputs": [ { "data": { "text/plain": [ "((400, 264), (100, 264))" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "X_train_filtered.shape, X_test_filtered.shape" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "ExecuteTime": { "end_time": "2018-04-24T18:50:24.694811Z", "start_time": "2018-04-24T18:50:24.649243Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " precision recall f1-score support\n", "\n", " 1 1.00 1.00 1.00 29\n", " 2 1.00 1.00 1.00 9\n", " 3 1.00 1.00 1.00 14\n", " 4 0.27 0.29 0.28 14\n", " 5 0.29 0.36 0.32 14\n", " 6 0.62 0.50 0.56 20\n", "\n", "avg / total 0.72 0.71 0.71 100\n", "\n" ] } ], "source": [ "cl = DecisionTreeClassifier()\n", "cl.fit(X_train_filtered, y_train)\n", "print(classification_report(y_test, cl.predict(X_test_filtered)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Качество модели практически не изменилось, однако модель стала намного проще." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Сравнение с классификатором на стандартных признаках**" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "ExecuteTime": { "end_time": "2018-04-24T18:53:10.252470Z", "start_time": "2018-04-24T18:53:10.248964Z" } }, "outputs": [ { "data": { "text/plain": [ "(500, 128)" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "X_1 = df.iloc[:N,:]\n", "X_1.shape" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "ExecuteTime": { "end_time": "2018-04-24T18:53:11.053575Z", "start_time": "2018-04-24T18:53:11.049569Z" } }, "outputs": [], "source": [ "X_train, X_test, y_train, y_test = train_test_split(X_1, y, test_size=.2)" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "ExecuteTime": { "end_time": "2018-04-24T18:53:17.756822Z", "start_time": "2018-04-24T18:53:17.720767Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " precision recall f1-score support\n", "\n", " 1 0.55 0.58 0.56 19\n", " 2 0.69 0.52 0.59 21\n", " 3 0.75 0.46 0.57 13\n", " 4 0.42 0.57 0.48 14\n", " 5 0.65 0.50 0.56 22\n", " 6 0.20 0.36 0.26 11\n", "\n", "avg / total 0.57 0.51 0.53 100\n", "\n" ] } ], "source": [ "cl = DecisionTreeClassifier()\n", "cl.fit(X_train, y_train)\n", "print(classification_report(y_test, cl.predict(X_test)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Как видимо, качество модели значительно улучшилось по сравнению с наивным классификатором." ] } ], "metadata": { "anaconda-cloud": {}, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.4" } }, "nbformat": 4, "nbformat_minor": 1 }