SVM系列(四)SVM python应用实例(一)随机数据+人脸识别

目前先不给出SVM的算法的python代码,先用python自带的SVM进行分类、感谢该视频的相关内容https://www.youtube.com/watch?v=EySkC36W9hE&t=1631s

线性可分数据

from sklearn.svm import SVC
import matplotlib.pyplot as plt
%matplotlib inline
from sklearn import datasets
import numpy as np
from sklearn.model_selection import train_test_split
## 利用自带的点数据,进行分类
X,y = datasets.make_blobs(n_samples=300,n_features= 2,centers= 2)
X_train,X_test, y_train,y_test = train_test_split(X,y,test_size = 0.2)
## 采用的是线性分类器,tol 就是 我们说的loss,这里非常小,相当于hard-margin
svc = SVC(kernel= 'linear')
svc.fit(X_train,y_train)
y_ = svc.predict(X_test)
## 数据可视化
w1 , w2= svc.coef_[0]
b = svc.intercept_
x1 = np.linspace(-4,6,100)
x2 = (-b - w1*x1)/w2
x2_1 = (1-b - w1*x1)/w2
x21 = (-1-b - w1*x1)/w2
support_vectors = svc.support_vectors_   ## 得到支持向量
plt.scatter(X_train[:,0],X_train[:,1],c = y_train)
plt.scatter(X_test[:,0],X_test[:,1],c = y_)
plt.plot(x1,x2)
plt.plot(x1,x2_1,'--')
plt.plot(x1,x21,'--')
plt.scatter(support_vectors[:,0],support_vectors[:,1],marker= 'o',s = 300,alpha=  0.3 , c='red')

输出结果,可见准确率100%,因为我们将预测数据以预测标签颜色输出,如果分错了就会再各自的位置出现对方颜色的标签。红色标记的就是向量机

SVM系列(四)SVM python应用实例(一)随机数据+人脸识别_第1张图片

 线性不可分数据

接下来讨论线性不可分数据

1. 生成数据,随机产生符合正态分布的数据,400个训练,400个测试,可视化训练数据的情况,可见目标按照主对角线分为2类

from sklearn.svm import SVC
import matplotlib.pyplot as plt
%matplotlib inline
from sklearn import datasets
import numpy as np
from sklearn.model_selection import train_test_split

X = np.random.randn(800,2)
y = X [:,0] * X [:,1] >0
X_train,X_test, y_train,y_test = train_test_split(X,y,test_size = 0.5)
plt.scatter(X_train[:,0],X_train[:,1],c = y_train)

SVM系列(四)SVM python应用实例(一)随机数据+人脸识别_第2张图片

2.针对这种数据,线性不可分,而且符合正太分布,所以应该是 高斯核函数更有效。  接下来就比较一下,不同核函数的分类效果,结果与我们预测是一致的,最好的就是径向函数,和高斯函数很像的一个,最差的就是线性,一共就两类,0.5的准确率,其实就是蒙的概率

estimators = {}
'''    
It must be one of 'linear', 'poly', 'rbf', 'sigmoid', 'precomputed' or a callable.
    '''
estimators['linear'] = SVC(kernel='linear',C= 0.1)
estimators['rbf'] = SVC(kernel='rbf')
estimators['poly'] = SVC(kernel='poly',degree= 4)
estimators['sigmoid'] = SVC(kernel='sigmoid')

for key,val in estimators.items():
    val.fit(X_train,y_train)
    score = val.score(X_test,y_test)
    print(key,score)
linear 0.505
rbf 0.9225
poly 0.8275
sigmoid 0.5425

3.针对rdf的结果可视化,并标记错分点,可见错分的点主要集中在坐标轴上,也就是两个类别的分界处

y_ = estimators['rbf'] .predict(X_test)
plt.scatter(X_test[:,0],X_test[:,1],c = y_)
cond = y_ == y_test
plt.scatter(X_test[~cond,0],X_test[~cond,1],c = 'red',marker = 'o', s = 200, alpha = 0.4)

SVM系列(四)SVM python应用实例(一)随机数据+人脸识别_第3张图片

x1_min, x1_max = X[:,0].min(),X[:,0].max()
x2_min, x2_max = X[:,1].min(),X[:,1].max()
x1 = np.linspace(x1_min,x1_max,100)
y1 = np.linspace(x2_min,x2_max,100)
X1,Y1 = np.meshgrid(x1,y1)
d_ =  estimators['rbf'].decision_function(np.c_[X1.ravel(),Y1.ravel()])
y1_ =  estimators['rbf'].predict(X1_test)
plt.figure(figsize=(8,8))
plt.contourf(X1,Y1,d_.reshape(100,100),cmap = plt.cm.PuOr_r)
plt.contour(X1,Y1,d_.reshape(100,100))
#plt.scatter(X_train[:,0],X_train[:,1],s=30,c = y_train ,cmap = plt.cm.Paired,edgecolors = 'k')
plt.scatter(X_test[:,0],X_test[:,1],s=30,c = y_ ,cmap = plt.cm.Paired,edgecolors = 'k')
plt.axis('off')

SVM系列(四)SVM python应用实例(一)随机数据+人脸识别_第4张图片

利用SVM实现多分类- 人脸识别

1.加载数据

from sklearn.svm import SVC
import matplotlib.pyplot as plt
%matplotlib inline
from sklearn import datasets
import numpy as np
from sklearn.model_selection import train_test_split
## 该数据集有2000多个人的人脸图像,每个人的图像个数不同,这里只对照片个数超过80的进行分析,resize = 1,不压缩图像
datasets = datasets.fetch_lfw_people(min_faces_per_person= 80,resize = 1)
## 数据中 data,images,target, target_names
X = datasets.data
y = datasets.target
name = datasets.target_names
# 加入Name 是为了可视化的时候知道这人是谁
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size = 0.2)

2. 数据展示,

随便显示一个数据,每一个图像的像素点都是一个特征,满足80张以上照片的人一共有5个...

array(['Colin Powell', 'Donald Rumsfeld', 'George W Bush',
       'Gerhard Schroeder', 'Tony Blair'], dtype='
index = 1
image = datasets['images'] 
plt.imshow(image[index],cmap = plt.cm.gray)
name[y[index]]
'Gerhard Schroeder'

SVM系列(四)SVM python应用实例(一)随机数据+人脸识别_第5张图片

 3. 不同核函数分类结果对比 

estimators = {}
'''    
It must be one of 'linear', 'poly', 'rbf', 'sigmoid', 'precomputed' or a callable.
    '''
estimators['linear'] = SVC(kernel='linear',C= 1)
estimators['rbf'] = SVC(kernel='rbf')
estimators['poly'] = SVC(kernel='poly',degree= 4)
estimators['sigmoid'] = SVC(kernel='sigmoid')
%%time
for key,val in estimators.items():
    val.fit(X_train,y_train)
    score = val.score(X_test,y_test)
    print('model:%s   score:%s'%(key,score))
看到结果之后我都要哭了,居然是线性的结果最好......  
model:linear   score:0.8508771929824561
model:rbf   score:0.4605263157894737
model:poly   score:0.8333333333333334
model:sigmoid   score:0.4605263157894737
Wall time: 1min 15s

4. PCA降维

X.shape= (1140, 11750),表示数据有11750个特征,所以我们可以用PCA对其进行降维,从而减少算法的运行时间,并提高预测精度
from sklearn.decomposition import PCA
pca = PCA(n_components= 0.90,whiten = True) 
X2 = pca.fit_transform(X)
X2.shape
(1140, 111),对比可见11600多的特征的作用只有10% ,留着简直浪费,这时候要注意PCA之后数据,已经经过了变换,不是以前的像素数据了,不能成像
%%time
X_train,X_test,y_train,y_test = train_test_split(X2,y,test_size = 0.2)
for key,val in estimators.items():
    val.fit(X_train,y_train)
    score = val.score(X_test,y_test)
    print('model:%s   score:%s'%(key,score))
model:linear   score:0.793859649122807
model:rbf   score:0.8377192982456141
model:poly   score:0.47368421052631576
model:sigmoid   score:0.8201754385964912
Wall time: 858 ms

结果可见,PCA不仅仅增加了rbf ,sigmoid的分类效率,而且运行时间提高了近100倍?,反正就是提高了很多

5.数据过采样

查看每个特征的数据的个数,可见最多的是2号嘉宾,530张,最小的是3号嘉宾,109张,显然数据是不平衡的,所以通过SMOTE将数据过采样,使得每个人数据都是530个

import collections
collections.Counter(y)
Counter({2: 530, 3: 109, 1: 121, 4: 144, 0: 236})
import imblearn
from imblearn.over_sampling import SMOTE
smote = SMOTE()
X3,y3 = smote.fit_sample(X,y)
collections.Counter(y3)
Counter({2: 530, 3: 530, 1: 530, 4: 530, 0: 530}) 每个人数据都是530个了
pca = PCA(n_components= 0.90,whiten = True) 
X3_pca = pca.fit_transform(X3)
%%time
X_train,X_test,y_train,y_test = train_test_split(X3_pca,y3,test_size = 0.2)
for key,val in estimators.items():
    val.fit(X_train,y_train)
    score = val.score(X_test,y_test)
    print('model:%s   score:%s'%(key,score))
model:linear   score:0.9264150943396227
model:rbf   score:0.969811320754717
model:poly   score:0.8735849056603774
model:sigmoid   score:0.8773584905660378
Wall time: 2.63 s

经过一系列操作之后,预测精度最高已经到了0.96,rbf的精度从0.46提高到了0.96,并且整体运行时间大幅度降低。

6.交叉验证获取较好参数

以上实例中,参数都是默认设置的,现在利用交叉验证看看参数选择什么会效果比较好,

from sklearn.model_selection import GridSearchCV
C = [0.2,0.5,1,2,10]
tol = [1e-4,1e-3,0.01]
clf = GridSearchCV(estimators['rbf'],param_grid={'C':C,'tol':tol})
clf.fit(X_train,y_train)
score = clf.score(X_test,y_test)
print('score:%s   best_params:%s'%(score,clf.best_params_))
score:0.9886792452830189   best_params:{'C': 2, 'tol': 0.0001}

交叉验证结果表明rbf在C=2,tol=0.001时候得到的结果最好,高达0.988

该例题可得到如下结论:

1. 脸部信息可能是近似线性的关系

2. 数据的不平衡对四次,poly的精度影响最大,从0.47到0.87,对sigmoid影响较小

3.可以通过对数据的处理(降维,升采样),得到更好的分类精度和运行效率

 

 

你可能感兴趣的:(python,算法,机器学习,python)