《Python金融大数据风控建模实战》 第16章 支持向量机模型
本章引言
在感知机模型中得到的超平面不是唯一的,每一次参数的更新都是向着分类错误的样本更近一些,直到完全分类正确为止。因此,虽然感知器模型在训练集上表现优异,但训练集中的“顽固样本”稍微增加一些噪声就会错误分类,导致在测试集上的表现很不理想。而支持向量机模型在训练集上得到了较好的表现,同时进一步提高了模型的泛化能力,并得到了唯一的最优超平面。
支持向量机由简单到复杂分为以下三种:
-
线性可分支持向量机
样本是线性可分,如感知器模型可以解决的问题。此时,对应的最大间隔类型为硬间隔最大化,即分类超平面要严格满足每个样本都分类正确。 -
线性支持向量机
当样本近似线性可分,引入松弛因子,可以得到一个线性分类器,如线性可分的样本中增加一些错分的噪声数据。对应的最大间隔类型为软间隔最大化,即战略性地将那些噪声数据放弃,得到一个对于大部分样本都可以正确分类的超平面。这里所说的样本近似线性可分,是通过放弃某些线性不可分的样本后,大部分样本都是线性可分的,这时依然采用线性超平面做分隔,如果不放弃那些线性不可分的样本,就是一个非线性问题。 -
非线性支持向量机
当样本非线性可分时,即使引入松弛因子也不能得到一个近似线性可分的结果时,采用核技术进行特征映射,在高维空间采用软间隔最大化方法得到一个非线性模型,如感知器模型解决不了的异或问题。对应的最大间隔类型为核映射+软间隔最大化。这里所说的样本非线性是在第二种情况中,当非线性样本更多时,我们无法放弃大部分样本而得到一个线性的超平面,所以这里采用核函数的方法进行空间转化,得到一个线性或近似线性的结果,然后再采用线性支持向量机的方法得到超平面。
在实际应用中很少有线性问题,因此支持向量机模型应用最多的就是第三种模型。
Python代码实现及注释
# 第16章:SVM模型
import os
import sys
#path = __file__
#path = os.path.abspath(path + ((os.sep + '..') * 2))
#sys.path.append(path)
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
import variable_encode as var_encode
import numbers
from sklearn.metrics import confusion_matrix,recall_score, auc, roc_curve,precision_score,accuracy_score
from sklearn.model_selection import GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.svm import LinearSVC,SVC
from sklearn.metrics import precision_recall_curve
import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['font.sans-serif']=['SimHei'] # 用黑体显示中文
matplotlib.rcParams['axes.unicode_minus']=False # 正常显示负号
import warnings
warnings.filterwarnings("ignore") ##忽略警告
##数据读取
def data_read(data_path,file_name):
df = pd.read_csv( os.path.join(data_path, file_name), delim_whitespace = True, header = None )
##变量重命名
columns = ['status_account','duration','credit_history','purpose', 'amount',
'svaing_account', 'present_emp', 'income_rate', 'personal_status',
'other_debtors', 'residence_info', 'property', 'age',
'inst_plans', 'housing', 'num_credits',
'job', 'dependents', 'telephone', 'foreign_worker', 'target']
df.columns = columns
##将标签变量由状态1,2转为0,1;0表示好用户,1表示坏用户
df.target = df.target - 1
##数据分为data_train和 data_test两部分,训练集用于得到编码函数,验证集用已知的编码规则对验证集编码
data_train, data_test = train_test_split(df, test_size=