支持向量分类器(SVC)是支持向量机(SVM)的一种实现,通常用于分类任务。其主要参数包括:
C: 正则化参数,控制分类器在训练时对误差的容忍度。较小的C值会导致较大的间隔,但可能会增加误分类的风险;较大的C值则会使分类器更关注于所有样本,可能导致过拟合。
kernel: 核函数,用于将输入数据映射到高维空间。常用的核函数包括:
‘linear’: 线性核
‘poly’: 多项式核
‘rbf’: 径向基函数核(高斯核)
‘sigmoid’: Sigmoid核
degree: 仅在使用多项式核时有效,表示多项式的阶数。
gamma: 用于径向基函数核和sigmoid核的参数,控制样本点对分类边界的影响。较小的gamma值意味着更远的样本点才会影响决策边界,较大的值则意味着更近的样本点影响更大。
coef0: 在使用多项式核和sigmoid核时,控制高阶项的影响。它可以影响多项式的形状及其在不同特征间的相互作用。
shrinking: 布尔值,表示是否使用启发式的收缩技术,能够加速优化过程。
tol: 停止训练的阈值,即当目标函数的变化小于该值时停止训练。
max_iter: 最大迭代次数,指定训练时的迭代上限。
class_weight: 用于处理类别不平衡,可以指定每个类别的权重。
今天我们要学的是支持向量机SVM,听名字可能有点抽象,不过使用python分析的话,我们不用那么深入地了解,我们先将底层原理视为黑盒子去使用就好,那我们开始吧。
支持向量机的思想就是:将数据视为多维空间中的点,求解一个最优的超平面(f = w1x1+w2x2+w3x3+…+wn-1xn-1+b------>n为维度,也就是超平面的参数一定比特征量的维度少1),将两种不同类别的点分割开来。但是存在多个分割平面,我们应该怎么找到最优的那个呢?使得分割面到两类点的间隔较大。适用于分类问题,将数据集划分为两个子集。
其实还有一个问题,那就是一些低维空间其实没有办法通过一个超平面进行划分,这个时候可以采用核函数(Kernel Function)将低维数据映射到高维空间。
基本的原理就介绍完了,接下来我们来看看具体的SVM实现
#读入数据
import pandas as pd
filename = 'data/bankpep.csv'
#很明显可以看出id这一列与我们的预测结果关系不大,直接作为索引即可
data = pd.read_csv(filename, index_col = 'id')
print( data.iloc[0:5,:])
# SVM算法只能使用数值型变量进行输入,所以要将所有特征值转化为数字
#将最数据中的‘YES’和‘NO'转换成代表分类的整数 1 和 0
seq = ['married', 'car', 'save_act', 'current_act', 'mortgage', 'pep']
for feature in seq : # 逐个特征进行替换
data.loc[ data[feature] == 'YES', feature ] =1
data.loc[ data[feature] == 'NO', feature ] =0
#将性别转换为整数1和0
data.loc[ data['sex'] == 'FEMALE', 'sex'] =1
data.loc[ data['sex'] == 'MALE', 'sex'] =0
print(data[0:5])
#将离散特征数据进行独热编码,转换为dummies矩阵
dumm_reg = pd.get_dummies( data['region'], prefix='region' )
#print(dumm_reg[0:5])
'''
这个时候我们好好观察,就会发现region和children的取值超过两个,并且最重要的是,他的取值与排序无关(孩子个数为什么比较无关,确实有点难以理解,可能是孩子的数量确实对银行投资的影响小),所以我们要采用独热编码(区别于数字编码)进行转化。
>独热编码(One-Hot Encoding)
使用条件:
1无序分类变量:当分类变量的不同取值之间没有自然的顺序关系时,使用独热编码是合适的。例如,颜色(红、绿、蓝)和城市(北京、上海、广州)等。
2避免模型假设关系:独热编码能够防止模型误解类别之间的关系(例如,认为2大于1),从而更有效地训练模型。
3较少的类别:当类别数目相对较少时,独热编码的开销比较小,可以有效使用。
特点:
1每个类别都被转换为一个新的二进制特征。
2适用于线性模型和很多非线性模型。
>数字编码(Label Encoding)
使用条件:
1有序分类变量:当分类变量的取值之间具有自然的顺序关系时,例如教育水平(小学、初中、高中、大学)。这时数字编码能够保留这些关系。
2类别数量较多:当类别数目较多且独热编码会导致特征维度显著增加时,数字编码更为便捷。
3某些类型的模型:某些树模型(例如决策树、随机森林)能够自动处理数字编码的顺序,因此数字编码可能是合理的选择。
特点:
1将每个类别映射为一个唯一的整数值。
2有可能导致模型误解类别之间的关系(将数值顺序视为大小关系)。
'''
#prefix是后续独立编码后名字的前缀
dumm_child = pd.get_dummies( data['children'], prefix='children' )
#先删除dataframe中原来的两列后再 join dummies
df1 = data.drop(['region','children'], axis = 1)
df2 = df1.join([dumm_reg,dumm_child], how='outer')
#准备训练输入变量
X = df2.drop(['pep'], axis=1).values.astype(float)
y = df2['pep'].values.astype(int)
#训练模型,评价分类器性能
from sklearn import svm
from sklearn import metrics
clf = svm.SVC(kernel='rbf', gamma=0.6, C = 1.0)
#将数据集拆分为训练集和测试集,在测试集上查看分类效果
from sklearn import model_selection
#对不同方差的数据标准化,可以提高准确度(内部实现是让样本各个特征对距离的贡献相同)
from sklearn import preprocessing
X_scale = preprocessing.scale(X)
#将标准化后的数据集拆分为训练集和测试集,在测试集上查看分类效果
X_train, X_test, y_train, y_test = model_selection.train_test_split(X_scale, y, test_size=0.3, random_state=1)
clf = svm.SVC(kernel='poly', gamma=0.6, C = 0.001)
clf.fit(X_train, y_train)
print( clf.score(X_test, y_test) )
#查看在测试集上混淆矩阵,Precision、Recall和F1
y_predicted = clf.predict(X_test)
print("Classification report for %s" % clf)
print (metrics.classification_report(y_test, y_predicted) )
print( "Confusion matrix:\n", metrics.confusion_matrix(y_test, y_predicted) )
'''
注意分类报告和混淆矩阵的参数是俩个y(一真一预测)
而score的是真实的x与y
'''