#coding:utf-8# from __future__ import print_functionfrom time import time #有些步驟要計時,看每一個步驟花多長時間import logging #打印出來progress程序進展import matplotlib.pyplot as plt #pyplot程序最後把咱們預測出來的人臉打印出來,強大的繪圖工具from sklearn.cross_validation import train_test_splitfrom sklearn.datasets import fetch_lfw_peoplefrom sklearn.grid_search import GridSearchCVfrom sklearn.metrics import classification_reportfrom sklearn.metrics import confusion_matrixfrom sklearn.decomposition import RandomizedPCAfrom sklearn.svm import SVCprint(__doc__)# Display progress logs on stdout#打印程序進展的信息logging.basicConfig(level=logging.INFO,format='%(asctime)s %(message)s') #這個等下能夠不用了#下載數據集,數據的參數能夠參考文檔lfw_people = fetch_lfw_people(min_faces_per_person=70,resize=0.4) ##下面介紹數據預處理和分類#返回多少個圖n_samples,h,w = lfw_people.images.shape#X是特徵向量的矩陣,每一行是個實例,每一列是個特徵值X = lfw_people.data#n_featers表示的就是維度n_features = X.shape[1] #維度:每一個人會提取多少的特徵值#提取每一個實例對應每一個人臉,目標分類標記,不一樣的人的身份y = lfw_people.targettarget_names = lfw_people.target_namesn_classes = target_names.shape[0] #多少行,shape就是多少行,多少我的,多少類print("Total dataset size:")print("n_samples:%d" % n_samples) #實例的個數print("n_features:%d" % n_features) #特徵向量的維度print("n_classes:%d" % n_classes) #總共有多少人#下面開始拆分數據,分紅訓練集和測試集,有個現成的函數,經過調用train_test_split;來分紅兩部分X_train,X_test,y_train,y_test = train_test_split( X,y,test_size=0.25)#數據降維,由於特徵值的維度仍是比較高n_components = 150print("Extracting the top %d eigenfaces from %d faces" %(n_components,X_train.shape[0]))t0 = time() #計算出打印每一步須要的時間#經典算法,高維下降爲低維的pca = RandomizedPCA(n_components=n_components,whiten=True).fit(X_train)print("done in %0.3fs" % (time() - t0))#對於人臉的一張照片上提取的特徵值名爲eigenfaceseigenfaces = pca.components_.reshape((n_components,h,w))print("Projecting the inpyt data on the eigenfaces orthonormal basis")t0 = time()X_train_pca = pca.transform(X_train) #特徵量中訓練集全部的特徵向量經過pca轉換成更低維的矩陣X_test_pca = pca.transform(X_test)print("done in %0.3fs" % (time() - t0))print("Fitting the classifier to the training set")t0 = time()#param_grid把參數設置成了不一樣的值,C:權重;gamma:多少的特徵點將被使用,由於咱們不知道多少特徵點最好,選擇了不一樣的組合param_grid = {'C':[1e3,5e3,1e4,5e4,1e5], 'gamma':[0.0001,0.0005,0.001,0.005,0.01,0.1],}#把全部咱們所列參數的組合都放在SVC裏面進行計算,最後看出哪一組函數的表現度最好clf = GridSearchCV(SVC(kernel='rbf',class_weight='auto'),param_grid)#其實建模很是很是簡單,主要是數據的預處理麻煩clf = clf.fit(X_train_pca,y_train)print("done in %0.3fs" % (time() - t0))print("Best estimator found by grid search:")print(clf.best_estimator_)#測試集預測看看準確率能到多少print("Predicting people's names on the test set")t0 = time()y_pred = clf.predict(X_test_pca)print("done in %0.3fs" % (time() - t0))print(classification_report(y_test,y_pred,target_names=target_names))print(confusion_matrix(y_test,y_pred,labels=range(n_classes)))#把數據可視化的能夠看到,把須要打印的圖打印出來def plot_gallery(images,titles,h,w,n_row=3,n_col=4): """Helper function to plot a gallery of portraits""" #在figure上創建一個圖當背景 plt.figure(figsize=(1.8*n_col,2.4*n_row)) plt.subplots_adjust(bottom=0,left=.01,right=.99,top=.90,hspace=.35) for i in range(n_row * n_col): plt.subplot(n_row,n_col,i+1) plt.imshow(images[i].reshape((h,w)),cmap=plt.cm.gray) plt.title(titles[i],size=12) plt.xticks(()) plt.yticks(())#把預測的函數歸類標籤和實際函數歸類標籤,好比布什def title(y_pred,y_test,target_names,i): pred_name = target_names[y_pred[i]].rsplit(' ',1)[-1] true_name = target_names[y_test[i]].rsplit(' ',1)[-1] return 'predicted: %s\ntrue: %s'% (pred_name,true_name)#把預測出來的人名存起來prediction_titles = [title(y_pred,y_test,target_names,i) for i in range(y_pred.shape[0])]#plot_gallery(X_test,prediction_titles,h,w)eigenface_titles = ['eigenface %d' %i for i in range(eigenfaces.shape[0])]#提取過特徵向量以後的臉是什麼樣子plot_gallery(eigenfaces,eigenface_titles,h,w)plt.show()