python 非线性规划_支持向量机:Stata 和 Python 实现

田原 (北京交通大学)
godfreytian@163.com

? 连享会主页:lianxh.cn
扫码查看最新推文和分享

2f14db5996a3ce1c0f7aa81638ae043b.png

NEW!连享会·推文专辑:
Stata资源 | 数据处理 | Stata绘图 | Stata程序
结果输出 | 回归分析 | 时间序列 | 面板数据 | 离散数据
交乘调节 | DID | RDD  |  因果推断 |  SFA-TFP-DEA
文本分析+爬虫 | 空间计量 | 学术论文 | 软件工具


目录

  • 1. SVM 介绍

    • 1.1 SVM 简介

    • 1.2 SVM 基本概念

    • 1.3 SVM 算法特征

  • 2. SVM 求解过程

  • 3. 核函数

    • 3.1 使用核函数的原因

    • 3.2 常用核函数

    • 3.3 核函数的选择

  • 4. SVM 的 Python 实现

  • 5. SVM 的 Stata 实现

  • 6. 参考文献


连享会 - 生存分析 (Survival Analysis) 专题,2020年6月6日

主讲嘉宾:王存同教授 (中央财经大学)
课程详情

dbdb449dc6b7329b57035f8cfa44ac09.png
连享会-生存分析专题直播
连享会直播 - 二元选择与计数数据

2020年5月23日,19:00-21:00, 88元
主讲嘉宾:司继春 ;课程主页

74ea75b63ff4f9f999aca0bfe6efcccc.png

1. SVM 介绍

1.1 SVM 简介

支持向量机(support vector machines, SVM)的基本模型是定义在特征空间上的间隔最大的线性分类器,间隔最大使它有别于感知机;SVM 还包括核技巧,这使它成为实质上的非线性分类器。SVM 的学习策略就是间隔最大化,可形式化为一个求解凸二次规划的问题,也等价于正则化的合页损失函数的最小化问题。SVM 的学习算法就是求解凸二次规划的最优化算法。

1.2 SVM 基本概念

了解 SVM 算法之前,首先需要了解一下线性分类器这个概念。比如给定一系列的数据样本,每个样本都有对应的一个标签。为了使得描述更加直观,我们以二维平面为例,将特征向量映射为空间中的一些点,就是如下图的实心点和空心点,它们属于不同的两类。

那么 SVM 的目的就是想要画出一条线,以“最好地”区分这两类点,以至如果以后有了新的点,这条线也能做出很好的分类,也就是说要使条直线能够达到最好的泛化能力。那么能够画出多少条线对样本点进行区分?线是有无数条可以画的,区别就在于效果好不好。比如下图中绿线就不好,蓝线一般,红线看起来会更好。我们所希望找到的这条效果最好的线叫作划分超平面,它是一个能使两类之间的空间大小最大的一个超平面。

6f97d4dc5330ce995a234cd01ba36bab.png

为什么要叫作“超平面”呢?因为样本的特征很可能是高维的,此时样本空间的划分就需要“超平面”。这个超平面在二维平面上看到的就是一条直线,在三维空间中就是一个平面,因此,我们把这个划分数据的决策边界统称为超平面。离这个超平面最近的点就叫做支持向量。支持向量机就是要使超平面和支持向量之间的间隔尽可能的大,这样超平面才可以将两类样本准确的分开,而保证间隔尽可能的大就是保证分类器误差尽可能的小。

那么画线的标准是什么?如何才能画出效果好的线?SVM 将会寻找可以区分两个类别并且能使边际(margin)最大的超平面(hyper plane),即划分超平面。边际就是分类的超平面和对应类别最近的样本点之间的距离。5b42faf011403e7e62f07c6ce0c46526.png

如上图所示,所有坐落在边际超平面上的点被称为支持向量(support vectors),它们是用来定义边际的,是距离划分超平面最近的点。支持向量支撑了边际区域,并且用于建立划分超平面。值得注意是,支持向量每一侧可能不止一个,有可能一侧有多个点都落在边际平面上。如下图所示,SVM的目标就是使这个边际()最大化,其中是向量的范数(norm)。7e1078aa0325f99b6b96e434853d8a5e.png

1.3 SVM 算法特征

SVM 所训练出的模型,其算法复杂度是由支持向量的个数决定的,而不是由数据的维度决定的,当然支持向量的个数多少也和训练集的大小有关。因此 SVM 可以一定程度上避免过拟合(overfitting)的现象。SVM 训练出来的模型完全依赖于支持向量,即使训练集里面所有非支持向量的点都被去除,重复训练过程,结果依然会得到完全相同的模型。若一个 SVM 训练得出的支持向量个数比较少,那么 SVM 训练出的模型具有较好的泛化能力。

2. SVM 求解过程

SVM的目标就是找出边际最大的超平面,那么如何找出这个最大边际的超平面呢(MMH)?利用 Karush-Kuhn-Tucker(KKT)条件和拉格朗日公式,可以推出 MMH 可以被表示为以下决定边界(decision boundary)

该方程就表示边际最大化的划分超平面。

  • 是支持向量点的个数,因为其实大多数点并不是支持向量点,只有落在边际超平面上的点才是支持向量点。因此我们就只对属于支持向量点的进行求和;
  • 为支持向量点的特征值;
  • 是支持向量点 的类别标记(class label),比如+1还是-1;
  • 是要测试的实例,想知道它应该属于哪一类,把它带入该方程;
  • 和 都是单一数值型参数,由以上提到的最优算法得出, 是拉格朗日乘数。

每当有新的测试样本 ,将它带入该方程,看该方程的值是正还是负,根据符号进行归类。

3. 核函数

3.1 使用核函数的原因

在线性 SVM 中转化为最优化问题时求解的公式计算是以内积(dot product)形式出现的,假设原始的数据是非线性的,我们通过一个映射 将其映射到一个高维空间中,数据则变得线性可分了。但是映射之后得到的新空间的维度是更高的,甚至是无穷维的,这是内积的计算就会变得非常麻烦,因此需要利用核函数(kernel function)来取代计算非线性映射函数的内积。以下核函数和非线性映射函数的内积等同,但核函数 K 的运算量要远少于求内积。

3.2 常用核函数

  • h 度多项式核函数(polynomial kernel of degree h)

这核所对映的映射是可以表示出来的,该空间的维度是,其中 m 是原始空间的维度。

  • 高斯径向基核函数(Gaussian radial basis function kernel)

这个核就会将原始空间映射为无穷空间,不过,如果 选的很大,高次特征上的权重实际上衰减的非常快,因此实际上相当于一个低维的子空间;反之,如果 选的很小,则可以将任意的数据映射为线性可分,但也会伴随严重的过拟合问题。但总的来说,通过调控参数 ,高斯核具有相当高的灵活性,也是使用最广泛的核函数之一。

  • S 型核函数(Sigmoid function kernel)

这个核存在的主要目的是使得“映射后空间中的问题”和“映射前空间中的问题”两者在形式上统一起来。

连享会 - 文本分析与爬虫 - 专题视频

主讲嘉宾:司继春 || 游万海

1b0908216edef75c892a130c41a48ab0.png
连享会-文本分析与爬虫-专题视频教程

3.3 核函数的选择

在选取核函数解决实际问题时,通常采用的方法有两种:一是利用专家的先验知识预先选定核函数 二是采用 Cross-Validation 方法,即在进行核函数选取时,分别试用不同的核函数,归纳选取误差最小的核函数。

4. SVM 的 Python 实现

以预测中小企业信用风险为例,选取 2019 年在中小板上市的企业为样本,预测其是否具有违约风险,我们将上市企业中 ST 或 *ST 的企业认为是有违约风险的企业,选取 6 项财务指标进行预测,财务指标分别为:流动比率、速动比率、利润率、ROA、总资产增长率、现金比率。

# 首先要调用需要的模块
import numpy as np   #调用numpy模块
import pandas as pd  #调用Pandas模块
# 读取数据
X1=pd.ExcelFile('dataset.xlsx')  #读取数据
X1.sheet_names
# 设置特征变量
X_Features = pd.read_excel(X1, sheet_names="Sheet1", usecols=[1,2,3,4,5,6])
X_Features.head()    #可以查看特征变量,该步骤可以省略

输出的结果为 6 项用于预测的财务指标,仅展示出前 5 行数据。

current ratioprofit marginquick ratioROAassets growth ratecash ratio
01.2575-444.36000.9753-142.4324-75.214656.3938
10.4772-41.06340.3112-5.094626.38444.7799
22.1478-60.33311.3147-28.1622-7.494975.0185
30.2740-24.00820.1667-18.8108-43.27433.8674
40.7362-101.30080.5202-36.2078-44.983626.0609
X_Features.info()      #可以查看特征变量的数据类型,该步骤可以省略
# 设置标签
Y_Response = pd.read_excel(X1, sheet_names="Sheet1", usecols=[7])
Y_Response = Y_Response["risk"].ravel()  #设置标签
# 设置训练集和测试集
from sklearn import model_selection
X_Train, X_Test, Y_Train, Y_Test = model_selection.train_test_split(X_Features, Y_Response, test_size=0.3, shuffle=True)     #划分出训练集和测试集,test_size表示测试集的比例,这里是30%,该数字可以更改;shuffle=True是将序列的所有元素随机排序
X_Train.head()   #查看训练集,该步骤可省略

X_Test.head()    #查看测试集,该步骤可省略
# 调用 SVM 算法
from sklearn.svm import SVC    #调用Scikit learn中的SVM算法
# 设置参数进行拟合
C = 1e5     #惩罚因子,该数字可以更改
clf = SVC(C=C, kernel='rbf', gamma=20, decision_function_shape='ovr')  #kernel='rbf'时(default),为高斯核,gamma值越小,分类界面越连续;gamma值越大,分类界面越“散”,分类效果越好,但有可能会过拟合。decision_function_shape='ovr'时,为one v rest,即一个类别与其他类别进行划分。
clf.fit(X_Train, Y_Train.ravel())   #对训练集进行拟合
# 对测试集数据进行预测
y_pred = clf.predict(X_Test)  #对测试集数据进行预测
#查看预测的准确度
from sklearn.metrics import classification_report
print (classification_report(Y_Test, y_pred))     #查看预测的准确率(Accuracy)、精确率(Precision)、召回率(Recall)和F值(F-Measure)等指标

              precision    recall  f1-score   support

           0       0.98      1.00      0.99       270
           1       0.00      0.00      0.00         6

    accuracy                           0.98       276
   macro avg       0.49      0.50      0.49       276
weighted avg       0.96      0.98      0.97       276

从预测结果来看,预测的准确率(Accuracy)为 98%,虽然整体上预测的准确度较高,但是在测试集中有违约风险的 6 家企业却没有预测出来,主要是因为在整体的样本中,有违约风险的企业数量过少,这也说明在进行信用风险预测时,有信用风险的企业样本不能太少。

5. SVM 的 Stata 实现

使用 Stata自带的 1978 Automobile Data 数据,预测汽车类型是“Domestic”还是“Foreign”。在这一例子中,使用2项指标进行预测,分别是 price 和 gear_ratio。在 Stata 中的 SVM 实现需要安装外部命令 svmachines,具体实现过程如下。

* 在使用 Stata 进行 SVM 实现之前,需要先安装外部命令:svmachines
ssc install svmachines, replace
* 第一步需要做的是区分训练集和测试集
sysuse auto, clear 
set seed 9876
generate u = runiform()
sort u
local split = floor(_N/2)
local train = "1/`=`split'-1'"
local test = "`split'/`=_N'"
* 在训练集中利用SVM进行训练:
svmachines foreign price gear_ratio if !missing(rep78) in `train'
* 测试集里进行预测,并统计准确率:
predict P in `test'
generate err = foreign != P in `test'
tab err in `test'
        err |      Freq.     Percent        Cum.
------------+-----------------------------------
          0 |         28       73.68       73.68
          1 |         10       26.32      100.00
------------+-----------------------------------
      Total |         38      100.00

以上输出结果中,0 表示预测正确,1 表示预测错误。根据以上输出结果,就可以进一步计算出准确率等指标。在这一例子中,预测的准确率(Accuracy)为:28 ÷ 38 = 73.68%

下面我们使用 Stata 的另一组数据进行 SVM 的 Stata 实现。使用 Stata 自带的 nlsw88.dta 数据,该数据包含了 1988 年采集的 2246 个美国妇女的资料。在这一示例中,我们使用美国妇女的工资“wage”去预测“union”是否为工会成员,具体实现过程如下。

*-S1: 第一步和上一个例子相同,我们需要做的是区分训练集和测试集
sysuse nlsw88.dta, clear 
set seed 9876
generate u = runiform()
sort u
local split = floor(_N/2)
local train = "1/`=`split'-1'"
local test = "`split'/`=_N'"

*-S2: 在训练集中利用SVM进行训练:
svmachines union wage if !missing(union) in `train'  
* Note: if !missing(union) 的目的是为了在进行机器学习时忽略缺失的数据项,
*       也可以事先使用 drop 的功能将有缺失的数据 drop 掉
*-S3: 测试集里进行预测,并统计准确率:
predict P in `test'
generate err = union != P in `test'
tab err in `test'
        err |      Freq.     Percent        Cum.
------------+-----------------------------------
          0 |        709       63.08       63.08
          1 |        415       36.92      100.00
------------+-----------------------------------
      Total |      1,124      100.00

以上输出结果中,0 表示预测正确,1 表示预测错误。根据以上输出结果,就可以进一步计算出准确率等指标。在这一例子中,预测的准确率(Accuracy)为:709 ÷ 1124 = 63.08%,相较于上一个例子,准确率有所下降。这主要是因为在这一例子中,我们中主要为了展示 SVM 的实现,因此只选取了 wage 这一个变量对 union 进行预测,大家在做预测时通常会选取更多的变量。

6. 参考文献

  • Guenther N, Schonlau M. Support Vector Machines[J]. Stata Journal, 2016, 16(4):917-937. [PDF]

连享会-在线课堂
      http://lianxh.duanshu.comd9eda3759c6e5c5492e0ceb16df96639.png

免费公开课:

  • 直击面板数据模型 - 连玉君,时长:1小时40分钟
  • Stata 33 讲 - 连玉君, 每讲 15 分钟.
  • 部分直播课 课程资料下载 (PPT,dofiles等)

温馨提示: 文中链接在微信中无法生效。请点击底部

连享会 - 效率分析专题

2020年5月29-31日 (此时点后仍可购买回放视频)
? 主讲嘉宾:连玉君 | 鲁晓东 | 张宁
?   课程主页:https://gitee.com/arlionn/TE

704b186b3ff947843df1e7b8e9e86d2d.png
连享会-效率分析专题视频

关于我们
  • ? 连享会 ( 主页:lianxh.cn ) 由中山大学连玉君老师团队创办,定期分享实证分析经验。
  • ? 直达连享会:百度一下:连享会】即可直达连享会主页。亦可进一步添加 主页,知乎,面板数据,研究设计 等关键词细化搜索。
  • ? 公众号推文分类: 历史推文分为多个专辑,主流方法介绍一目了然:DID, RDD, IV, GMM, FE, Probit 等。

    连享会 · 推文专辑:
    Stata资源 | 数据处理 | Stata绘图 | Stata程序
    结果输出 | 回归分析 | 时序 | 面板 | 离散数据
    交乘调节 | DID | RDD  |  因果推断 |  SFA-TFP-DEA
    文本分析+爬虫 | 空间计量 | 学术论文 | 软件工具

  • 公众号关键词搜索/回复 功能已经上线。大家可以在公众号左下角点击键盘图标,输入简要关键词,以便快速呈现历史推文,获取工具软件和数据下载。常见关键词:
    • 课程, 直播, 视频, 客服, 模型设定, 研究设计,
    • stata, plus,Profile, 手册, SJ, 外部命令, profile, mata, 绘图, 编程, 数据, 可视化
    • DID,RDD, PSM,IV,DID, DDD, 合成控制法,内生性, 事件研究
    • 交乘, 平方项, 缺失值, 离群值, 缩尾, R2, 乱码, 结果
    • Probit, Logit, tobit, MLE, GMM, DEA, Bootstrap, bs, MC, TFP
    • 面板, 直击面板数据, 动态面板, VAR, 生存分析, 分位数
    • 空间, 空间计量, 连老师, 直播, 爬虫, 文本, 正则, python
    • Markdown, Markdown幻灯片, marp, 工具, 软件, Sai2, gInk, Annotator, 手写批注
    • 盈余管理, 特斯拉, 甲壳虫, 论文重现
    • 易懂教程, 码云, 教程, 知乎

112f19f82216830d2617d5275390c7ba.png
连享会主页  lianxh.cn

?  连享会小程序:扫一扫,看推文,看视频……

f8a4ee98cd53202cb4de22788244eca0.png

? 扫码加入连享会微信群,提问交流更方便

752a6c0bd2350d49ffa01c43b5695364.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值