给定训练集D,在样本空间上找到最鲁棒的超平面,将不同类别的样本分开。对于线性可分问题,超平面的线性方程为,样本空间内任一点x到平面的距离为。若超平面分类正确,则对应y=+1为正类,否则y=-1。距离超平面最近的几个样本称为支持向量,两个异类支持向量到超平面的距离之和为,称为间隔。
优化目标:找到参数w和b在划分正确的前提下使得间隔最大,即
上述问题等价于:
此为支持向量机(SVM)的基本型,将参数求解问题转化为凸二次规划问题,为了方便求解且易于推广到非线性情况下的核函数,采用拉格朗日乘子法引入对偶问题,实为目标函数加入了惩罚项,对于支持向量,故,而非支持向量为使惩罚项小,。对偶问题最终求得(SMO算法):
训练完成后,大部分训练样本都不需要保留,最终模型仅有支持向量有关。对于新点的预测,只需与支持向量进行内积运算后叠加。从海量数据中筛选出最有效的少数样本,节约学习内存,提高预测性能,但付出计算代价。
对于线性不可分问题,将样本从原始空间映射到一个更高维的特征空间,使其变为线性可分。对于高维样本的内积计算比较困难,故利用原始空间的核函数来表示在特征空间的内积,将映射和计算合二为一,在低维计算,实质分类效果体现在高维,避免复杂运算。
常用的核函数有线性核,多项式核,高斯核等,一般来说文本数据通常采用线性核,情况不明时采用高斯核。
在现实任务中往往很难确定合适的核函数,也很难确定是否线性可分,故允许支持向量机在一些样本上出错,但尽量的少,为此,引入软间隔的概念,优化目标变为:
每个样本对应一个松弛变量,称为软间隔支持向量机。
代码实践:使用逻辑回归和随机梯度预测疾病
# 从sklearn.datasets里导入手写体数字加载器。
from sklearn.datasets import load_digits
# 从通过数据加载器获得手写体数字的数码图像数据并储存在digits变量中。
digits = load_digits()
# 检视数据规模和特征维度。
digits.data.shape
# 从sklearn.cross_validation中导入train_test_split用于数据分割。
from sklearn.model_selection import train_test_split
# 随机选取75%的数据作为训练样本;其余25%的数据作为测试样本。
X_train, X_test, y_train, y_test = train_test_split(digits.data,digits.target, test_size=0.25, random_state=33)
y_train.shape
y_test.shape
# 从sklearn.preprocessing里导入数据标准化模块。
from sklearn.preprocessing import StandardScaler
# 从sklearn.svm里导入基于线性假设的支持向量机分类器LinearSVC。
from sklearn.svm import LinearSVC
# 仍然需要对训练和测试的特征数据进行标准化。
ss = StandardScaler()
X_train = ss.fit_transform(X_train)
X_test = ss.transform(X_test)
# 初始化线性假设的支持向量机分类器LinearSVC。
lsvc = LinearSVC()
#进行模型训练
lsvc.fit(X_train, y_train)
# 利用训练好的模型对测试样本的数字类别进行预测,预测结果储存在变量y_predict中。
y_predict = lsvc.predict(X_test)
# 使用模型自带的评估函数进行准确性测评。
print('The Accuracy of Linear SVC is', lsvc.score(X_test, y_test))
# 依然使用sklearn.metrics里面的classification_report模块对预测结果做更加详细的分析。
from sklearn.metrics import classification_report
print(classification_report(y_test, y_predict,target_names=digits.target_names.astype(str)))
--来自《Python机器学习及实践 —— 从零开始通往Kaggle竞赛之路》