{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Automatically created module for IPython interactive environment\n"
     ]
    }
   ],
   "source": [
    "print(__doc__)\n",
    "\n",
    "from time import time\n",
    "import logging\n",
    "import pylab as pl\n",
    "import numpy as np\n",
    "\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.datasets import fetch_lfw_people\n",
    "from sklearn.model_selection import GridSearchCV\n",
    "from sklearn.metrics import classification_report\n",
    "from sklearn.metrics import confusion_matrix\n",
    "#from sklearn.decomposition import RandomizedPCA\n",
    "from sklearn.decomposition import PCA as RandomizedPCA\n",
    "from sklearn.svm import SVC"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Total dataset size:\n",
      "n_samples: 1288\n",
      "n_features: 1850\n",
      "n_classes: 7\n",
      "Extracting the top 300 eigenfaces from 966 faces\n",
      "done in 0.486s\n",
      "Projecting the input data on the eigenfaces orthonormal basis\n",
      "done in 0.021s\n",
      "Fitting the classifier to the training set\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/lzl/anaconda3/lib/python3.7/site-packages/sklearn/model_selection/_split.py:1978: FutureWarning: The default value of cv will change from 3 to 5 in version 0.22. Specify it explicitly to silence this warning.\n",
      "  warnings.warn(CV_WARNING, FutureWarning)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "done in 50.085s\n",
      "Best estimator found by grid search:\n",
      "SVC(C=1000.0, cache_size=200, class_weight='balanced', coef0=0.0,\n",
      "    decision_function_shape='ovr', degree=3, gamma=0.0005, kernel='rbf',\n",
      "    max_iter=-1, probability=False, random_state=None, shrinking=True,\n",
      "    tol=0.001, verbose=False)\n",
      "Predicting the people names on the testing set\n",
      "done in 0.149s\n",
      "                   precision    recall  f1-score   support\n",
      "\n",
      "     Ariel Sharon       0.53      0.69      0.60        13\n",
      "     Colin Powell       0.74      0.88      0.80        60\n",
      "  Donald Rumsfeld       0.76      0.70      0.73        27\n",
      "    George W Bush       0.89      0.86      0.87       146\n",
      "Gerhard Schroeder       0.85      0.68      0.76        25\n",
      "      Hugo Chavez       0.73      0.53      0.62        15\n",
      "       Tony Blair       0.78      0.78      0.78        36\n",
      "\n",
      "         accuracy                           0.80       322\n",
      "        macro avg       0.75      0.73      0.74       322\n",
      "     weighted avg       0.81      0.80      0.80       322\n",
      "\n",
      "[[  9   2   1   1   0   0   0]\n",
      " [  2  53   1   3   0   1   0]\n",
      " [  2   2  19   2   0   0   2]\n",
      " [  3   9   4 125   0   1   4]\n",
      " [  0   0   0   6  17   1   1]\n",
      " [  0   4   0   0   2   8   1]\n",
      " [  1   2   0   4   1   0  28]]\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 72088 characters]\n",
      "text/plain": [
       "<Figure size 518.4x518.4 with 12 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 54356 characters]\n",
      "text/plain": [
       "<Figure size 518.4x518.4 with 12 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Display progress logs on stdout\n",
    "logging.basicConfig(level=logging.INFO, format='%(asctime)s %(message)s')\n",
    "\n",
    "\n",
    "###############################################################################\n",
    "# Download the data, if not already on disk and load it as numpy arrays\n",
    "lfw_people = fetch_lfw_people(min_faces_per_person=70, resize=0.4)\n",
    "\n",
    "# introspect the images arrays to find the shapes (for plotting)\n",
    "n_samples, h, w = lfw_people.images.shape\n",
    "np.random.seed(42)\n",
    "\n",
    "# for machine learning we use the data directly (as relative pixel\n",
    "# position info is ignored by this model)\n",
    "X = lfw_people.data\n",
    "n_features = X.shape[1]\n",
    "\n",
    "# the label to predict is the id of the person\n",
    "y = lfw_people.target\n",
    "target_names = lfw_people.target_names\n",
    "n_classes = target_names.shape[0]\n",
    "\n",
    "print(\"Total dataset size:\")\n",
    "print(\"n_samples: %d\" % n_samples)\n",
    "print(\"n_features: %d\" % n_features)\n",
    "print(\"n_classes: %d\" % n_classes)\n",
    "\n",
    "\n",
    "###############################################################################\n",
    "# Split into a training and testing set\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=42)\n",
    "\n",
    "###############################################################################\n",
    "# Compute a PCA (eigenfaces) on the face dataset (treated as unlabeled\n",
    "# dataset): unsupervised feature extraction / dimensionality reduction\n",
    "n_components = 150\n",
    "\n",
    "print(\"Extracting the top %d eigenfaces from %d faces\" % (n_components, X_train.shape[0]))\n",
    "t0 = time()\n",
    "pca = RandomizedPCA(n_components=n_components, whiten=True).fit(X_train)\n",
    "print(\"done in %0.3fs\" % (time() - t0))\n",
    "\n",
    "eigenfaces = pca.components_.reshape((n_components, h, w))\n",
    "\n",
    "print(\"Projecting the input data on the eigenfaces orthonormal basis\")\n",
    "t0 = time()\n",
    "X_train_pca = pca.transform(X_train)\n",
    "X_test_pca = pca.transform(X_test)\n",
    "print(\"done in %0.3fs\" % (time() - t0))\n",
    "\n",
    "\n",
    "###############################################################################\n",
    "# Train a SVM classification model\n",
    "\n",
    "print(\"Fitting the classifier to the training set\")\n",
    "t0 = time()\n",
    "param_grid = {\n",
    "         'C': [1e3, 5e3, 1e4, 5e4, 1e5],\n",
    "          'gamma': [0.0001, 0.0005, 0.001, 0.005, 0.01, 0.1],\n",
    "          }\n",
    "# for sklearn version 0.16 or prior, the class_weight parameter value is 'auto'\n",
    "clf = GridSearchCV(SVC(kernel='rbf', class_weight='balanced'), param_grid)\n",
    "clf = clf.fit(X_train_pca, y_train)\n",
    "print(\"done in %0.3fs\" % (time() - t0))\n",
    "print(\"Best estimator found by grid search:\")\n",
    "print(clf.best_estimator_)\n",
    "\n",
    "\n",
    "###############################################################################\n",
    "# Quantitative evaluation of the model quality on the test set\n",
    "\n",
    "print(\"Predicting the people names on the testing set\")\n",
    "t0 = time()\n",
    "y_pred = clf.predict(X_test_pca)\n",
    "print(\"done in %0.3fs\" % (time() - t0))\n",
    "\n",
    "print(classification_report(y_test, y_pred, target_names=target_names))\n",
    "print(confusion_matrix(y_test, y_pred, labels=list(range(n_classes))))\n",
    "\n",
    "\n",
    "###############################################################################\n",
    "# Qualitative evaluation of the predictions using matplotlib\n",
    "\n",
    "def plot_gallery(images, titles, h, w, n_row=3, n_col=4):\n",
    "    \"\"\"Helper function to plot a gallery of portraits\"\"\"\n",
    "    pl.figure(figsize=(1.8 * n_col, 2.4 * n_row))\n",
    "    pl.subplots_adjust(bottom=0, left=.01, right=.99, top=.90, hspace=.35)\n",
    "    for i in range(n_row * n_col):\n",
    "        pl.subplot(n_row, n_col, i + 1)\n",
    "        pl.imshow(images[i].reshape((h, w)), cmap=pl.cm.gray)\n",
    "        pl.title(titles[i], size=12)\n",
    "        pl.xticks(())\n",
    "        pl.yticks(())\n",
    "\n",
    "\n",
    "# plot the result of the prediction on a portion of the test set\n",
    "\n",
    "def title(y_pred, y_test, target_names, i):\n",
    "    pred_name = target_names[y_pred[i]].rsplit(' ', 1)[-1]\n",
    "    true_name = target_names[y_test[i]].rsplit(' ', 1)[-1]\n",
    "    return 'predicted: %s\\ntrue:      %s' % (pred_name, true_name)\n",
    "\n",
    "prediction_titles = [title(y_pred, y_test, target_names, i)\n",
    "                         for i in range(y_pred.shape[0])]\n",
    "\n",
    "plot_gallery(X_test, prediction_titles, h, w)\n",
    "\n",
    "# plot the gallery of the most significative eigenfaces\n",
    "\n",
    "eigenface_titles = [\"eigenface %d\" % i for i in range(eigenfaces.shape[0])]\n",
    "plot_gallery(eigenfaces, eigenface_titles, h, w)\n",
    "\n",
    "pl.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**下面的代码输出了每个主成分的可释方差**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "the raio is  [0.19346525 0.15116832 0.0708368  0.05951807 0.05157493 0.02887155\n",
      " 0.02514483 0.02176463 0.0201938  0.01902122 0.0168221  0.01580598\n",
      " 0.01223363 0.01087936 0.01064451 0.00979653 0.00892398 0.00854845\n",
      " 0.00835711 0.00722635 0.00696569 0.00653856 0.00639558 0.00561317\n",
      " 0.00531107 0.00520152 0.00507466 0.00484209 0.00443588 0.0041783\n",
      " 0.00393705 0.00381728 0.00356061 0.00351201 0.00334556 0.00329931\n",
      " 0.00314626 0.00296217 0.00290136 0.00284723 0.00280004 0.00267555\n",
      " 0.00259901 0.00258401 0.00240919 0.00238994 0.00235403 0.00222587\n",
      " 0.00217508 0.00216566 0.00209064 0.00205426 0.00200421 0.00197396\n",
      " 0.0019383  0.00188764 0.00180173 0.00178897 0.00174819 0.00173054\n",
      " 0.00165647 0.00162947 0.00157409 0.00153429 0.00149965 0.00147262\n",
      " 0.00143931 0.00141882 0.00139698 0.00138147 0.00134005 0.00133169\n",
      " 0.00128811 0.00125595 0.00124247 0.00121864 0.00120948 0.00118305\n",
      " 0.00115092 0.00113676 0.00112622 0.00111621 0.00109399 0.00107175\n",
      " 0.00105669 0.0010436  0.00102396 0.00101696 0.00099776 0.00096374\n",
      " 0.00094236 0.00091984 0.00091323 0.00089209 0.00087176 0.00086249\n",
      " 0.00084313 0.00083927 0.00082853 0.00080313 0.00078747 0.00078228\n",
      " 0.00075691 0.00075292 0.00074768 0.0007347  0.00073158 0.00071689\n",
      " 0.00070577 0.00069715 0.00066866 0.00066503 0.00065623 0.00063944\n",
      " 0.00063688 0.00062721 0.00061795 0.00061033 0.00060175 0.00059334\n",
      " 0.00058297 0.00057581 0.00056649 0.00056236 0.00055077 0.00054499\n",
      " 0.00053279 0.00052337 0.00051409 0.00051363 0.00051042 0.00049526\n",
      " 0.00048876 0.00047817 0.00047104 0.00046536 0.00046507 0.00045444\n",
      " 0.00044802 0.00044516 0.00043847 0.00043143 0.00042947 0.00042014\n",
      " 0.00041234 0.0004096  0.0004038  0.00040279 0.00039076 0.00038592]\n"
     ]
    }
   ],
   "source": [
    "print (\"the raio is \", pca.explained_variance_ratio_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-30T03:03:49.715652Z",
     "start_time": "2019-08-30T03:01:27.405043Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Extracting the top 10 eigenfaces from 966 faces\n",
      "done in 0.052s\n",
      "Projecting the input data on the eigenfaces orthonormal basis\n",
      "done in 0.007s\n",
      "Fitting the classifier to the training set\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/lzl/anaconda3/lib/python3.7/site-packages/sklearn/model_selection/_split.py:1978: FutureWarning: The default value of cv will change from 3 to 5 in version 0.22. Specify it explicitly to silence this warning.\n",
      "  warnings.warn(CV_WARNING, FutureWarning)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "done in 49.981s\n",
      "Best estimator found by grid search:\n",
      "Predicting the people names on the testing set\n",
      "done in 0.014s\n",
      "Extracting the top 15 eigenfaces from 966 faces\n",
      "done in 0.048s\n",
      "Projecting the input data on the eigenfaces orthonormal basis\n",
      "done in 0.007s\n",
      "Fitting the classifier to the training set\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/lzl/anaconda3/lib/python3.7/site-packages/sklearn/model_selection/_split.py:1978: FutureWarning: The default value of cv will change from 3 to 5 in version 0.22. Specify it explicitly to silence this warning.\n",
      "  warnings.warn(CV_WARNING, FutureWarning)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "done in 16.526s\n",
      "Best estimator found by grid search:\n",
      "Predicting the people names on the testing set\n",
      "done in 0.013s\n",
      "Extracting the top 25 eigenfaces from 966 faces\n",
      "done in 0.059s\n",
      "Projecting the input data on the eigenfaces orthonormal basis\n",
      "done in 0.007s\n",
      "Fitting the classifier to the training set\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/lzl/anaconda3/lib/python3.7/site-packages/sklearn/model_selection/_split.py:1978: FutureWarning: The default value of cv will change from 3 to 5 in version 0.22. Specify it explicitly to silence this warning.\n",
      "  warnings.warn(CV_WARNING, FutureWarning)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "done in 8.275s\n",
      "Best estimator found by grid search:\n",
      "Predicting the people names on the testing set\n",
      "done in 0.027s\n",
      "Extracting the top 50 eigenfaces from 966 faces\n",
      "done in 0.223s\n",
      "Projecting the input data on the eigenfaces orthonormal basis\n",
      "done in 0.017s\n",
      "Fitting the classifier to the training set\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/lzl/anaconda3/lib/python3.7/site-packages/sklearn/model_selection/_split.py:1978: FutureWarning: The default value of cv will change from 3 to 5 in version 0.22. Specify it explicitly to silence this warning.\n",
      "  warnings.warn(CV_WARNING, FutureWarning)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "done in 7.747s\n",
      "Best estimator found by grid search:\n",
      "Predicting the people names on the testing set\n",
      "done in 0.026s\n",
      "Extracting the top 100 eigenfaces from 966 faces\n",
      "done in 0.094s\n",
      "Projecting the input data on the eigenfaces orthonormal basis\n",
      "done in 0.011s\n",
      "Fitting the classifier to the training set\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/lzl/anaconda3/lib/python3.7/site-packages/sklearn/model_selection/_split.py:1978: FutureWarning: The default value of cv will change from 3 to 5 in version 0.22. Specify it explicitly to silence this warning.\n",
      "  warnings.warn(CV_WARNING, FutureWarning)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "done in 15.724s\n",
      "Best estimator found by grid search:\n",
      "Predicting the people names on the testing set\n",
      "done in 0.050s\n",
      "Extracting the top 250 eigenfaces from 966 faces\n",
      "done in 0.201s\n",
      "Projecting the input data on the eigenfaces orthonormal basis\n",
      "done in 0.019s\n",
      "Fitting the classifier to the training set\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/lzl/anaconda3/lib/python3.7/site-packages/sklearn/model_selection/_split.py:1978: FutureWarning: The default value of cv will change from 3 to 5 in version 0.22. Specify it explicitly to silence this warning.\n",
      "  warnings.warn(CV_WARNING, FutureWarning)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "done in 43.009s\n",
      "Best estimator found by grid search:\n",
      "Predicting the people names on the testing set\n",
      "done in 0.135s\n"
     ]
    }
   ],
   "source": [
    "from sklearn.metrics import f1_score as f1\n",
    "f1_score = []\n",
    "n_com = [10, 15, 25, 50, 100, 250]\n",
    "for x in n_com:\n",
    "    # Compute a PCA (eigenfaces) on the face dataset (treated as unlabeled\n",
    "    # dataset): unsupervised feature extraction / dimensionality reduction\n",
    "    n_components = x\n",
    "\n",
    "    print(\"Extracting the top %d eigenfaces from %d faces\" % (n_components, X_train.shape[0]))\n",
    "    t0 = time()\n",
    "    pca = RandomizedPCA(n_components=n_components, whiten=True).fit(X_train)\n",
    "    print(\"done in %0.3fs\" % (time() - t0))\n",
    "\n",
    "    eigenfaces = pca.components_.reshape((n_components, h, w))\n",
    "\n",
    "    print(\"Projecting the input data on the eigenfaces orthonormal basis\")\n",
    "    t0 = time()\n",
    "    X_train_pca = pca.transform(X_train)\n",
    "    X_test_pca = pca.transform(X_test)\n",
    "    print(\"done in %0.3fs\" % (time() - t0))\n",
    "\n",
    "\n",
    "    ###############################################################################\n",
    "    # Train a SVM classification model\n",
    "\n",
    "    print(\"Fitting the classifier to the training set\")\n",
    "    t0 = time()\n",
    "    param_grid = {\n",
    "             'C': [1e3, 5e3, 1e4, 5e4, 1e5],\n",
    "              'gamma': [0.0001, 0.0005, 0.001, 0.005, 0.01, 0.1],\n",
    "              }\n",
    "    # for sklearn version 0.16 or prior, the class_weight parameter value is 'auto'\n",
    "    clf = GridSearchCV(SVC(kernel='rbf', class_weight='balanced'), param_grid)\n",
    "    clf = clf.fit(X_train_pca, y_train)\n",
    "    print(\"done in %0.3fs\" % (time() - t0))\n",
    "    print(\"Best estimator found by grid search:\")\n",
    "    #print(clf.best_estimator_)\n",
    "\n",
    "\n",
    "    ###############################################################################\n",
    "    # Quantitative evaluation of the model quality on the test set\n",
    "\n",
    "    print(\"Predicting the people names on the testing set\")\n",
    "    t0 = time()\n",
    "    y_pred = clf.predict(X_test_pca)\n",
    "    print(\"done in %0.3fs\" % (time() - t0))\n",
    "    f1_score.append(f1(y_test,y_pred,average=None))\n",
    "    \n",
    "    #print(classification_report(y_test, y_pred, target_names=target_names))\n",
    "    #print(confusion_matrix(y_test, y_pred, labels=list(range(n_classes))))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-30T03:05:02.522015Z",
     "start_time": "2019-08-30T03:05:02.515006Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The n_com:10\n",
      "The f1 score:0.117647\n",
      "\n",
      "\n",
      "The n_com:15\n",
      "The f1 score:0.324324\n",
      "\n",
      "\n",
      "The n_com:25\n",
      "The f1 score:0.642857\n",
      "\n",
      "\n",
      "The n_com:50\n",
      "The f1 score:0.689655\n",
      "\n",
      "\n",
      "The n_com:100\n",
      "The f1 score:0.714286\n",
      "\n",
      "\n",
      "The n_com:250\n",
      "The f1 score:0.666667\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "for x in range(0,len(n_com)):\n",
    "    print(\"The n_com:%d\\nThe f1 score:%f\\n\\n\" % (n_com[x],f1_score[x][0]))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "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.3"
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
