{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "

Методы машинного обучения

\n", "

Семинар: линейные модели классификации

\n", "

Методы понижения размерности

" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "%matplotlib inline" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "\n", "plt.style.use('ggplot')\n", "plt.rcParams['figure.figsize'] = (12,8)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Логистическая регрессия" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Игрушечный пример" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Сгенерируем выборку и опробуем логистическую регрессию" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "np.random.seed(0)\n", "X = np.r_[np.random.randn(20, 2) + [2, 2],\n", " np.random.randn(20, 2) + [-2, -2]]\n", "y = [-1] * 20 + [1] * 20" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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qv+Y9j/1sJLHjoyOJXo65JRFtOCmT/iYDABKB4cKPXRk83fGlJYkybga2POqP4EAoARRXB5KDR4fd9xNpwqcBABKF8XloZmX3zDuyhqR+Dwf0gBAaaK4PFTZtFR1l3xAoYrq7EAwqPK552rBn3zS32AAUEKYnOGxBTd9QrOvvFnHfvNvCtc3qG751cwoBAAPUVxTIDqzUXNXr/c7BgCUJA4VAgCsQnEBAKxCcQEArOJJcT377LNas2aN+vr6vHg7AAAmlHdxdXV1aceOHYrH417kAQDglPIurn/4h3/QRz/6UTmO40UeAABOKa/i2rJli+rq6rRw4UKP4gAAcGqnvY5r48aN6u3tzRlfu3atnn76af31X//1pDbU1tamtrY2SVJra2vOocVQKGTV4Ubb8kr2ZbYtr2RfZtvySvZlJq/3HGOMOZsvPHDggP7mb/5GkUhEktTd3a3a2lo99NBDqqmpOe3Xt7e3j3kcj8fV1dV1NlF8YVteyb7MtuWV7MtsW17JvszknbyGhoZJve6sV85oamrS17/+9dHHf/EXf6GHHnpIM2bMONu3BADgtLiOCwBgFc/WKty0aZNXbwUAwITY4wIAWOWsJ2cAAOCHotnjuvfee/2OcEZsyyvZl9m2vJJ9mW3LK9mXmbzeK5riAgBgMiguAIBVgp/5zGc+43eIdzQ3N/sd4YzYlleyL7NteSX7MtuWV7IvM3m9xeQMAIBVOFQIALCKZxcge+nZZ5/Vt771LX39618v6iWknnzySW3ZskWO46i6ulp33nmn6urq/I51St/85je1detWhUIhzZ49W3feeacqKir8jjWhl156SU899ZQOHTqkz33uczr33HP9jjSu7du367HHHpPrulq9erVuuukmvyOd0le+8hVt27ZN1dXVevjhh/2Oc1pdXV3atGmTent75TiOWlpadP311/sd65SSyaQ2bNigdDqtTCajyy+/XGvWrPE71mm5rqt7771XdXV1RTvDsKjOcUnZf6DPPfecMpmMWlpaRhfxLUbNzc264YYb9IEPfEADAwP65S9/qYsvvtjvWKd166236g//8A+1b98+vf7667rwwgv9jjQhx3F05ZVX6sCBA1qxYkVR/mDguq4+97nP6b777tPNN9+sxx57TMuWLSvqH7oqKiq0atUqvfLKK7ruuuv8jnNaiURCS5Ys0bp163TNNdfoa1/7mpYvX17U3+NAIKCrrrpK119/vVavXq0nnnhC8+fPV319vd/RTukHP/iB0um00um0rrrqKr/jjKvoDhXadGPKWCw2+vtEImFF5hUrVigYDEqSlixZop6eHp8Tndq8efMmvWK0X/bs2aM5c+Zo9uzZCoVCuuKKK/TKK6/4HeuUli1bpsrKSr9jTFptbe3ohIHy8nI1NjYW/b9dx3EUjUYlSZlMRplMpug/I7q7u7Vt2zatXr3a7yinVFSHCm28MeUTTzyhzZs3KxaLacOGDX7HOSPPP/+8rrjiCr9jWK+np2fMT9H19fXavXu3j4lKW2dnp/bt26dFixb5HeW0XNfVPffco8OHD+u6667T4sWL/Y50So8//rhuueUWDQ8P+x3llApeXF7dmLJQTpX30ksv1bp167Ru3To9/fTT+tGPflQUx7BPl1mSvvvd7yoYDOrqq68udLwck8lbzMabmFvsP1nbamRkRA8//LA+9rGPjTniUawCgYA+//nPa3BwUF/4whd04MABNTU1+R1rXFu3blV1dbWam5u1c+dOv+OcUsGL6/777x93/MCBA+rs7NSnPvUpSdld1nvuuWfSN6acKhPlPdlVV12l1tbWoiiu02V+4YUXtHXrVj3wwANF8QE72e9xsaqvr1d3d/fo43duqgpvpdNpPfzww7r66qv13ve+1+84Z6SiokLLli3T9u3bi7a4du3apS1btujVV19VMpnU8PCwHnnkEd11111+R8tRNIcKbbwxZUdHh+bOnSspe5iz2M/FSNnZb88884w++9nPFvXEF5uce+656ujoUGdnp+rq6vTiiy8W5X92mxlj9NWvflWNjY364Ac/6HecSenr61MwGFRFRYWSyaR27NihD33oQ37HmtD69eu1fv16SdLOnTv1/e9/v2j/HRdNcdno29/+tjo6OuQ4juLxuG6//Xa/I53Wo48+qnQ6rY0bN0qSFi9eXNS5X375ZX3jG99QX1+fWltbtXDhQt13331+xxojGAzqtttu04MPPijXdbVq1SrNnz/f71in9KUvfUmvvfaa+vv7dccdd2jNmjW69tpr/Y41oV27dmnz5s1qamoaPSqzbt06rVy50udkEzt27Jg2bdok13VljNH73vc+K2Yd24CVMwAAVim66fAAAJwKxQUAsArFBQCwCsUFALAKxQUAsArFBQCwCsUFALAKxQUAsMr/A8XRB1QcWd5qAAAAAElFTkSuQmCC\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig, ax = plt.subplots(figsize=(7, 7))\n", "ax.scatter(X[:, 0],\n", " X[:, 1],\n", " c=y,\n", " cmap=plt.cm.Paired)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "from sklearn.linear_model import LogisticRegression" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Обучим логистическую регрессию на этих данных и нарисуем разделяющую гиперплоскость" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n" ] }, { "data": { "text/plain": [ "LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,\n", " intercept_scaling=1, max_iter=100, multi_class='warn',\n", " n_jobs=None, penalty='l2', random_state=None, solver='warn',\n", " tol=0.0001, verbose=0, warm_start=False)" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model = LogisticRegression(C=1.0, \n", " fit_intercept=True, \n", " penalty='l2')\n", "model.fit(X, y)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "w_0 = -0.183954\n", "w_1, w_2 = [[-1.06097157 -1.00171289]]\n" ] } ], "source": [ "print('w_0 = %f' % model.intercept_)\n", "print('w_1, w_2 = ', model.coef_)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "# Нарисуем эту гиперплоскость\n", "w_0 = model.intercept_[0]\n", "w_1 = model.coef_[0][0]\n", "w_2 = model.coef_[0][1]\n", "\n", "x_1 = np.linspace(-4, 4, 10)\n", "x_2 = - (w_0 + w_1*x_1)/w_2" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig, ax = plt.subplots(figsize=(7, 7))\n", "ax.scatter(X[:, 0],\n", " X[:, 1],\n", " c=y,\n", " cmap=plt.cm.Paired)\n", "plt.plot(x_1, x_2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Пример с текстами" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Возьмем текстовые данные [отсюда](https://archive.ics.uci.edu/ml/machine-learning-databases/00331/). Архив содержит 3 файла с положительными и отрицательными отзывами с ресурсов\n", "* imdb.com\n", "* amazon.com\n", "* yelp.com\n", "\n", "Формат файла следующий:\n", "<отзыв>\\t<метка>\\n\n", "\n", "\n", "### Задача\n", "1. Загрузите тексты и метки классов в разные переменные\n", "2. Выберите меру качества классификации\n", "3. Обучите логистическую (без подбора гиперпараметров). Тексты представляются в виде мешка слов\n", "4. Выведите наиболее значимые слова из текста\n", "5. С помощью кросс-валидации найдите хорошие значения гиперпараметров для `CountVectorizer` и `LogisticRegression`" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "df = pd.read_csv('data/sentiment/imdb_labelled.txt', sep='\\t', header=None, names=['text', 'label'])" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "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", "
textlabel
0A very, very, very slow-moving, aimless movie ...0
1Not sure who was more lost - the flat characte...0
2Attempting artiness with black & white and cle...0
3Very little music or anything to speak of.0
4The best scene in the movie was when Gerardo i...1
\n", "
" ], "text/plain": [ " text label\n", "0 A very, very, very slow-moving, aimless movie ... 0\n", "1 Not sure who was more lost - the flat characte... 0\n", "2 Attempting artiness with black & white and cle... 0\n", "3 Very little music or anything to speak of. 0\n", "4 The best scene in the movie was when Gerardo i... 1" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.head()" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "from sklearn.feature_extraction.text import CountVectorizer\n", "from sklearn.pipeline import Pipeline\n", "from sklearn.model_selection import StratifiedKFold\n", "from sklearn.model_selection import RandomizedSearchCV, GridSearchCV" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [], "source": [ "model = Pipeline([\n", " ('vect', CountVectorizer(max_df=0.95, stop_words='english', ngram_range=(2,2))),\n", " ('clf', LogisticRegression())\n", "])" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [], "source": [ "X = df.text.values\n", "y = df.label.values" ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "scrolled": true }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n" ] }, { "data": { "text/plain": [ "Pipeline(memory=None,\n", " steps=[('vect', CountVectorizer(analyzer='word', binary=False, decode_error='strict',\n", " dtype=, encoding='utf-8', input='content',\n", " lowercase=True, max_df=0.95, max_features=None, min_df=1,\n", " ngram_range=(2, 2), preprocessor=None, stop_words='english',\n", " ...penalty='l2', random_state=None, solver='warn',\n", " tol=0.0001, verbose=0, warm_start=False))])" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model.fit(X, y)" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [], "source": [ "coefs = model.named_steps['clf'].coef_[0] # Веса линейной регрессии для каждого словa\n", "words = model.named_steps['vect'].get_feature_names()" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [], "source": [ "word_coefs = pd.Series(index=words, data=coefs).sort_values()" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "waste time -0.945444\n", "bad film -0.801509\n", "avoid costs -0.655693\n", "just bad -0.621132\n", "don waste -0.585915\n", "film just -0.565970\n", "worst series -0.554764\n", "90 minutes -0.549202\n", "hour half -0.545175\n", "cover girl -0.521187\n", "story stupid -0.513814\n", "avoid avoid -0.512680\n", "movie pretty -0.488534\n", "ve seen -0.462487\n", "just awful -0.456271\n", "acting bad -0.447700\n", "film started -0.444112\n", "really bad -0.424706\n", "hate movies -0.418471\n", "just didn -0.414149\n", "action scenes -0.413278\n", "couldn seriously -0.393361\n", "worse ticker -0.393361\n", "just lame -0.393361\n", "plot storyline -0.393361\n", "just painful -0.393361\n", "great disappointment -0.393361\n", "script script -0.393361\n", "plot whatsoever -0.393361\n", "engaging exciting -0.393361\n", " ... \n", "transfers good 0.408732\n", "like movie 0.412289\n", "rate movie 0.417140\n", "movie 10 0.417140\n", "film like 0.417562\n", "think disappointed 0.420384\n", "characters interesting 0.423554\n", "wonderful story 0.436351\n", "feel good 0.455643\n", "cinematography film 0.463604\n", "excellent job 0.487130\n", "thought provoking 0.487886\n", "excellent film 0.491852\n", "wind lion 0.496507\n", "short film 0.496581\n", "cast good 0.500491\n", "movie really 0.507134\n", "great film 0.519239\n", "music film 0.526220\n", "liked movie 0.540232\n", "definitely worth 0.559673\n", "highly recommended 0.568294\n", "saw film 0.573340\n", "movie good 0.574355\n", "long time 0.598076\n", "excellent performance 0.643658\n", "gave 10 0.643658\n", "worth checking 0.761545\n", "film great 0.837645\n", "10 10 1.126112\n", "Length: 5693, dtype: float64" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "word_coefs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Методы понижения размерности" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [], "source": [ "# Load data\n", "df_wine = pd.read_csv('data/winequality-red.csv', sep=';')\n", "\n", "# Make classification target feature\n", "df_wine.loc[:, 'quality_cat'] = (df_wine.quality > 5).astype(int)\n", "df_wine = df_wine.drop('quality', axis=1)\n", "\n", "# Get descriptive and target features\n", "X = df_wine.iloc[:, :-1].values\n", "y = df_wine.iloc[:, -1].values" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "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", " \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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
fixed acidityvolatile aciditycitric acidresidual sugarchloridesfree sulfur dioxidetotal sulfur dioxidedensitypHsulphatesalcoholquality_cat
07.40.700.001.90.07611.034.00.99783.510.569.40
17.80.880.002.60.09825.067.00.99683.200.689.80
27.80.760.042.30.09215.054.00.99703.260.659.80
311.20.280.561.90.07517.060.00.99803.160.589.81
47.40.700.001.90.07611.034.00.99783.510.569.40
\n", "
" ], "text/plain": [ " fixed acidity volatile acidity citric acid residual sugar chlorides \\\n", "0 7.4 0.70 0.00 1.9 0.076 \n", "1 7.8 0.88 0.00 2.6 0.098 \n", "2 7.8 0.76 0.04 2.3 0.092 \n", "3 11.2 0.28 0.56 1.9 0.075 \n", "4 7.4 0.70 0.00 1.9 0.076 \n", "\n", " free sulfur dioxide total sulfur dioxide density pH sulphates \\\n", "0 11.0 34.0 0.9978 3.51 0.56 \n", "1 25.0 67.0 0.9968 3.20 0.68 \n", "2 15.0 54.0 0.9970 3.26 0.65 \n", "3 17.0 60.0 0.9980 3.16 0.58 \n", "4 11.0 34.0 0.9978 3.51 0.56 \n", "\n", " alcohol quality_cat \n", "0 9.4 0 \n", "1 9.8 0 \n", "2 9.8 0 \n", "3 9.8 1 \n", "4 9.4 0 " ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_wine.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Recursive Feature Elimination" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [], "source": [ "from sklearn.feature_selection import RFECV\n", "from sklearn.pipeline import Pipeline\n", "from sklearn.model_selection import StratifiedKFold\n", "from sklearn.linear_model import LogisticRegression\n", "from sklearn.preprocessing import StandardScaler" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [], "source": [ "model_rfe = Pipeline([\n", " ('scaler', StandardScaler()),\n", " ('clf', RFECV(LogisticRegression(), step=1, cv=cv, verbose=1, scoring='roc_auc'))\n", "])\n", "\n", "cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=123)" ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "collapsed": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Fitting estimator with 11 features.\n", "Fitting estimator with 10 features.\n", "Fitting estimator with 9 features.\n", "Fitting estimator with 8 features.\n", "Fitting estimator with 7 features.\n", "Fitting estimator with 6 features.\n", "Fitting estimator with 5 features.\n", "Fitting estimator with 4 features.\n", "Fitting estimator with 3 features.\n", "Fitting estimator with 2 features.\n", "Fitting estimator with 11 features.\n", "Fitting estimator with 10 features.\n", "Fitting estimator with 9 features.\n", "Fitting estimator with 8 features.\n", "Fitting estimator with 7 features.\n", "Fitting estimator with 6 features.\n", "Fitting estimator with 5 features.\n", "Fitting estimator with 4 features.\n", "Fitting estimator with 3 features.\n", "Fitting estimator with 2 features.\n", "Fitting estimator with 11 features.\n", "Fitting estimator with 10 features.\n", "Fitting estimator with 9 features.\n", "Fitting estimator with 8 features.\n", "Fitting estimator with 7 features.\n", "Fitting estimator with 6 features.\n", "Fitting estimator with 5 features.\n", "Fitting estimator with 4 features.\n", "Fitting estimator with 3 features.\n", "Fitting estimator with 2 features.\n", "Fitting estimator with 11 features.\n", "Fitting estimator with 10 features.\n", "Fitting estimator with 9 features.\n", "Fitting estimator with 8 features.\n", "Fitting estimator with 7 features.\n", "Fitting estimator with 6 features.\n", "Fitting estimator with 5 features.\n", "Fitting estimator with 4 features.\n", "Fitting estimator with 3 features.\n", "Fitting estimator with 2 features.\n", "Fitting estimator with 11 features.\n", "Fitting estimator with 10 features.\n", "Fitting estimator with 9 features.\n", "Fitting estimator with 8 features.\n", "Fitting estimator with 7 features.\n", "Fitting estimator with 6 features.\n", "Fitting estimator with 5 features.\n", "Fitting estimator with 4 features.\n", "Fitting estimator with 3 features.\n", "Fitting estimator with 2 features.\n", "Fitting estimator with 11 features.\n", "Fitting estimator with 10 features.\n", "Fitting estimator with 9 features.\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n", "/Users/andrey.shestakov/anaconda3/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n", " FutureWarning)\n" ] }, { "data": { "text/plain": [ "Pipeline(memory=None,\n", " steps=[('scaler', StandardScaler(copy=True, with_mean=True, with_std=True)), ('clf', RFECV(cv=StratifiedKFold(n_splits=5, random_state=123, shuffle=True),\n", " estimator=LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,\n", " intercept_scaling=1, max_iter=100, multi_clas...m_start=False),\n", " min_features_to_select=1, n_jobs=None, scoring='roc_auc', step=1,\n", " verbose=1))])" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model_rfe.fit(X, y)" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [], "source": [ "rfe = model_rfe.named_steps['clf']" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0.75720164, 0.7955729 , 0.80091782, 0.81279034, 0.81248978,\n", " 0.81463012, 0.8164726 , 0.81848756, 0.81790802, 0.81704451,\n", " 0.81717928])" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rfe.grid_scores_ # Качество для 1, 2, 3 и тп признаков" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ True, True, True, False, True, True, True, False, False,\n", " True, True])" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rfe.support_" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [], "source": [ "num_of_features = range(1, 12)" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Text(0,0.5,'ROC AUC')" ] }, "execution_count": 58, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plt.plot(num_of_features, rfe.grid_scores_ )\n", "plt.xlabel('Num of features')\n", "plt.ylabel('ROC AUC')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## PCA" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Попробуем получить PCA разными способами" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## PCA через sklearn" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from sklearn.decomposition import PCA" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pca = PCA(n_components=5)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## PCA через ковариационную матрицу" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from numpy.linalg import eig" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Оценка качества при разных количествах компонент\n", "\n", "Реализуйте 2 пайплайнк:\n", " * StandartScaler + LogisticRegression\n", " * StandartScaler + PCA + LogisticRegression\n", "\n", "Оцените качество пайплайна с PCA при разных количествах компонент и сравните его с первым" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from sklearn.linear_model import LogisticRegression\n", "from sklearn.pipeline import Pipeline\n", "from sklearn.preprocessing import StandardScaler\n", "from sklearn.model_selection import StratifiedKFold, cross_val_score" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Singular Value Decomposition\n", "\n", "Для любой матрицы $A$ размера $n \\times m$ и ранга $r$ можно найти разложение вида:\n", "$$ A = U \\Sigma V^\\top ,$$\n", "где \n", "* $U$ - унитарная матрица, состоящая из собственных векторов $AA^\\top$\n", "* $V$ - унитарная матрица, состоящая из собственных векторов $A^\\top A$\n", "* $\\Sigma$ - диагональная матрица с сингулярными числами $s_i = \\sqrt{\\lambda_i}$\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## SVD via PCA\n", "Матрицы $U$ и $V$ ортогональны и могут быть использованы для перехода к ортогональному базису:\n", "$$ AV = U\\Sigma $$\n", "\n", "
" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from numpy.linalg import svd" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Рационы питания в странах" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Загрузите набор данных о пищевом рационе в разных странах мира `diet.csv`\n", "* Примените на данных PCA с 2 компонентами\n", "* Изобразите объекты в сжатом пространстве" ] }, { "cell_type": "code", "execution_count": 162, "metadata": { "collapsed": true }, "outputs": [], "source": [ "df = pd.read_csv('data/diet.csv', sep=';')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Скорее всего вы обнаружите некоторые выбросы, с этим ничего не поделать - PCA чувствителен к выбросам\n", "* Удалите объекты-выборосы и повторите процедуру" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# PCA для текстов\n", "#### Он же Latent Semantic Index или Latent Semantic Allocation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "* Когда мы работаем с текстами, бы обычно переходим к модели мешка слов\n", "* Что если мы ходим применить для текстов PCA?\n", "* Центрировать данные мы не можем, так как тогда наша огромная матрица с признаками будет плотной, а значит будет очень много весить\n", "* Давайте не будем центрировать! =D" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from sklearn.decomposition import TruncatedSVD" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# T-SNE" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Задание\n", "Сожмите признаковое пространство данных с цифрами с помощью tsne." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from sklearn.datasets import load_digits" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "## Your Code Here" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "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.7.0" }, "toc": { "base_numbering": 1, "nav_menu": { "height": "142px", "width": "252px" }, "number_sections": false, "sideBar": true, "skip_h1_title": false, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": false, "toc_position": {}, "toc_section_display": "block", "toc_window_display": false } }, "nbformat": 4, "nbformat_minor": 2 }