一、SVM深入理解
1.对月亮数据集
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.preprocessing import PolynomialFeatures,StandardScaler
from sklearn.svm import LinearSVC
from sklearn.pipeline import Pipeline
from sklearn.svm import SVC
def PolynomialSVC(degree,C=1.0):
return Pipeline([
("poly",PolynomialFeatures(degree=degree)),
("std_scaler",StandardScaler()),
("linearSVC",LinearSVC(C=C))
])
def plot_decision_boundary(model, axis):
x0, x1 = np.meshgrid(
np.linspace(axis[0], axis[1], int((axis[1]-axis[0])*100)).reshape(-1,1),
np.linspace(axis[2], axis[3], int((axis[3]-axis[2])*100)).reshape(-1,1)
)
X_new = np.c_[x0.ravel(), x1.ravel()]
y_predict = model.predict(X_new)
zz = y_predict.reshape(x0.shape)
from matplotlib.colors import ListedColormap
custom_cmap = ListedColormap(['#EF9A9A','#FFF59D','#90CAF9'])
plt.contourf(x0, x1, zz, cmap=custom_cmap)
def PolynomialKernelSVC(degree,C=1.0):
return Pipeline([
("std_scaler",StandardScaler()),
("kernelSVC",SVC(kernel="poly"))
])
def RBFKernelSVC(gamma=1.0):
return Pipeline([
('std_scaler',StandardScaler()),
('svc',SVC(kernel='rbf',gamma=gamma))
])
x_moom, y_moom = datasets.make_moons()
plt.scatter(x_moom[y_moom==0,0],x_moom[y_moom==0,1])
plt.scatter(x_moom[y_moom==1,0],x_moom[y_moom==1,1])
plt.show()
多项式拟合
poly_svc_moom = PolynomialSVC(degree=5,C=10)
poly_svc_moom.fit(x_moom,y_moom)
print("权重w:",poly_svc_moom.named_steps['linearSVC'].coef_[0])
print("截距b:",poly_svc_moom.named_steps['linearSVC'].intercept_[0])
plot_decision_boundary(poly_svc_moom,axis=[-1.5,2.5,-1.5,2.5])
plt.scatter(x_moom[y_moom==0,0],x_moom[y_moom==0,1])
plt.scatter(x_moom[y_moom==1,0],x_moom[y_moom==1,1])
plt.show()
高斯核拟合
rbf_svc_moom = RBFKernelSVC(1)
rbf_svc_moom.fit(x_moom,y_moom)
print("系数w:",rbf_svc_moom.named_steps['svc'].dual_coef_)
print("截距b:",rbf_svc_moom.named_steps['svc'].intercept_)
plot_decision_boundary(rbf_svc_moom,axis=[-1.5,2.5,-1.0,1.5])
plt.scatter(x_moom[y_moom==0,0],x_moom[y_moom==0,1])
plt.scatter(x_moom[y_moom==1,0],x_moom[y_moom==1,1])
plt.show()
2.对鸢尾花数据集
iris = datasets.load_iris()
x_iris = iris.data
y_iris = iris.target
x_iris = x_iris [y_iris<2,:2]
y_iris = y_iris[y_iris<2]
plt.scatter(x_iris[y_iris==0,0],x_iris[y_iris==0,1])
plt.scatter(x_iris[y_iris==1,0],x_iris[y_iris==1,1])
plt.show()
多项式拟合
poly_svc_iris = PolynomialSVC(degree=5,C=10)
poly_svc_iris.fit(x_iris,y_iris)
print("权重w:",poly_svc_iris.named_steps['linearSVC'].coef_[0])
print("截距b:",poly_svc_iris.named_steps['linearSVC'].intercept_[0])
plot_decision_boundary(poly_svc_iris,axis=[4,7.5,1,4.5])
plt.scatter(x_iris[y_iris==0,0],x_iris[y_iris==0,1])
plt.scatter(x_iris[y_iris==1,0],x_iris[y_iris==1,1])
plt.show()
高斯核拟合
rbf_svc_iris = RBFKernelSVC(1)
rbf_svc_iris.fit(x_iris,y_iris)
print("系数w:",rbf_svc_iris.named_steps['svc'].dual_coef_)
print("截距b:",rbf_svc_iris.named_steps['svc'].intercept_)
plot_decision_boundary(rbf_svc_iris,axis=[4,7.5,1,4.5])
plt.scatter(x_iris[y_iris==0,0],x_iris[y_iris==0,1])
plt.scatter(x_iris[y_iris==1,0],x_iris[y_iris==1,1])
plt.show()
二、人脸特征提取
1.绘制特征点
import numpy as np
import cv2
import dlib
import os
import sys
import random
# dlib预测器
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
ok = True
# 打开摄像头 参数为输入流,可以为摄像头或视频文件
camera = cv2.VideoCapture(0)
#camera = cv2.VideoCapture('video.mp4')
while ok:
# 读取摄像头中的图像,ok为是否读取成功的判断参数
ok, img = camera.read()
# 转换成灰度图像
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
rects = detector(img_gray, 0)
for i in range(len(rects)):
landmarks = np.matrix([[p.x, p.y] for p in predictor(img, rects[i]).parts()])
# 矩阵转为列表
point_list=landmarks.getA()
# 点坐标
point_37 = (point_list[37][0],point_list[37][1])
point_38 = (point_list[38][0], point_list[38][1])
# 比例系数,37,38两点距离
size = (pow(pow(point_38[1] - point_37[1], 2) + pow(point_38[0] - point_37[0], 2), 0.5))
# 点坐标
point_39 = (point_list[39][0], point_list[39][1])
point_42 = (point_list[42][0], point_list[42][1])
# 画特征点
for idx, point in enumerate(landmarks):
# 68点的坐标
pos = (point[0, 0], point[0, 1])
# 利用cv2.circle给每个特征点画一个圈,共68个
cv2.circle(img, pos, 1, color=(0, 255, 0))
# 利用cv2.putText输出1-68
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img, str(idx + 1), pos, font, 0.3, (0, 0, 255), 1, cv2.LINE_AA)
cv2.imshow('video', img)
k = cv2.waitKey(1)
if k == 27: # 按下ESC退出
break
camera.release()
cv2.destroyAllWindows()
运行效果
2.墨镜特效
import numpy as np
import cv2
import dlib
import os
import sys
import random
# dlib预测器
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor('D:\shape_predictor_68_face_landmarks.dat')
ok = True
# 打开摄像头 参数为输入流,可以为摄像头或视频文件
#camera = cv2.VideoCapture(0)
camera = cv2.VideoCapture('D:/video.mp4')
while ok:
# 读取摄像头中的图像,ok为是否读取成功的判断参数
ok, img = camera.read()
# 转换成灰度图像
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
rects = detector(img_gray, 0)
for i in range(len(rects)):
landmarks = np.matrix([[p.x, p.y] for p in predictor(img, rects[i]).parts()])
# 矩阵转为列表
point_list=landmarks.getA()
# 点坐标
point_37 = (point_list[37][0],point_list[37][1])
point_38 = (point_list[38][0], point_list[38][1])
# 比例系数,37,38两点距离
size = (pow(pow(point_38[1] - point_37[1], 2) + pow(point_38[0] - point_37[0], 2), 0.5))
# 点坐标
point_39 = (point_list[39][0], point_list[39][1])
point_42 = (point_list[42][0], point_list[42][1])
cv2.circle(img, (point_list[41][0], point_list[41][1]), int(3 * size), (0, 0, 0), -1)
cv2.circle(img, (point_list[46][0], point_list[46][1]), int(3 * size), (0, 0, 0), -1)
# 画眼镜框
cv2.line(img, point_39, point_42, (0, 0, 0), 4)
cv2.imshow('video', img)
k = cv2.waitKey(1)
if k == 27: # 按下ESC退出
break
camera.release()
cv2.destroyAllWindows()
三、总结
SVM的优缺点
1、SVM算法对大规模训练样本难以实施
SVM的空间消耗主要是存储训练样本和核矩阵,由于SVM是借助二次规划来求解支持向量,而求解二次规划将涉及m阶矩阵的计算(m为样本的个数),当m数目很大时该矩阵的存储和计算将耗费大量的机器内存和运算时间。针对以上问题的主要改进有有J.Platt的SMO算法、T.Joachims的SVM、C.J.C.Burges等的PCGC、张学工的CSVM以及O.L.Mangasarian等的SOR算法。如果数据量很大,SVM的训练时间就会比较长,如垃圾邮件的分类检测,没有使用SVM分类器,而是使用了简单的naive bayes分类器,或者是使用逻辑回归模型分类。
2、用SVM解决多分类问题存在困难
经典的支持向量机算法只给出了二类分类的算法,而在数据挖掘的实际应用中,一般要解决多类的分类问题。可以通过多个二类支持向量机的组合来解决。主要有一对多组合模式、一对一组合模式和SVM决策树;再就是通过构造多个分类器的组合来解决。主要原理是克服SVM固有的缺点,结合其他算法的优势,解决多类问题的分类精度。如:与粗集理论结合,形成一种优势互补的多类问题的组合分类器。
3、对缺失数据敏感,对参数和核函数的选择敏感
支持向量机性能的优劣主要取决于核函数的选取,所以对于一个实际问题而言,如何根据实际的数据模型选择合适的核函数从而构造SVM算法。目前比较成熟的核函数及其参数的选择都是人为的,根据经验来选取的,带有一定的随意性.在不同的问题领域,核函数应当具有不同的形式和参数,所以在选取时候应该将领域知识引入进来,但是目前还没有好的方法来解决核函数的选取问题。
四、参考
1.基于Sklearn+matlab绘制SVM决策函数
2.基于OpenCv+Python+Dlib实现简单人脸数据采集