机器学习:支持向量机2

本文来自同步博客

P.S. 不知道简书怎么显示数学公式以及更好的排版内容。所以如果觉得文章下面格式乱的话请自行跳转到上述链接。后续我将不再对数学公式进行截图,毕竟行内公式截图的话排版会很乱。看原博客地址会有更好的体验。

上一篇文章介绍了机器学习中支持向量机的基本原理,并且在文章末尾介绍了一种利用Python求解二项规划问题极值的方法。这篇文章我将利用这种方法一步步求解上文中提及的-\vec{\alpha}--\vec{w}--b-,借此复习和验证支持向量机的知识点。

数据

下面看一组测试数据:

data = {
    '+': [
        [1, 7],
        [2, 8],
        [3, 8],
        [2, 6.5]
    ],
    '-': [
        [5, 1],
        [6, -1],
        [7, 3]
    ]
}

数据data是拥有两种已经分好类的数据,每种类型的数据的元素都是二维向量,可以在笛卡尔坐标系中表示。

依照上一篇文章讲述的原理,我们需要利用这些数据求解一个-\vec{\alpha}-向量。也就是我们需要求解使得二项规划方程值最小时的-\vec{\alpha}-向量:
F(\vec{\alpha}) = \frac{1}{2}\vec{\alpha}\_{T}H\vec{\alpha} + \vec{c}\vec{\alpha} + c_0, \vec{y}^{T}\vec{\alpha} = 0, \vec{\alpha} \ge 0

很明显,在支持向量机中,-c_0 = 0-

参数求解

首先利用输入的测试data准备上述方程中出现的变量-H,c,c_0-。参考下面代码:

def parseXYC(d):
    X = []
    y = []
    c = []
    for _, v in enumerate(d['+']):
        X.append(np.array(v))
        y.append(1)
        c.append(-1)
    for _, v in enumerate(d['-']):
        X.append(np.array(v))
        y.append(-1)
        c.append(-1)
    return X, y, c, 0

X, y, c, c0 = parseXYC(data)

parseXYC函数把data格式化成-X, y, c, c_0-

然后计算-H-矩阵的值。比较简单,一行代码就可以得到:

H = np.array([y[i] * y[j] * np.dot(X[i], X[j]) for i in range(len(X)) for j in range(len(X))]).reshape(len(X), len(X))

求解-\vec{\alpha}-

所有数据都准备好了,接下来就是带入optimize.minimize函数中计算结果。

这里有几个超出本文描述范围的难点需要简单提及一下:

  1. optimize.minimize函数求解二项规划使用的SLSQP方法既需要用到二项方程的雅各比导函数,也需要用到约束条件函数的雅各比导函数。不清楚这点导致我在测试过程中一直无法求解到正确的值。
  2. 不等式约束条件-\vec{\alpha} \ge 0-无法在作为约束条件参数constraints传递给optimize.minimize函数。我猜测是因为我构造的不等式参数是错误的,因此无法让不等式约束条件生效。我尚无法解决这个问题,希望了解该问题的同学能留言赐教。作为一种补救方法,我利用边界约束参数bounds描述-\vec{\alpha} \ge 0-这个不等式。
  3. 求解出来的-\vec{\alpha}-向量中,部分应该为0的元素无法完整精确到0。我观察测试结果总结出来的精确度应该在1e-16,因此在负16次方这个精确度下的值我都假设它就是0。经过绘图验证,我发现这个假设是合理的。

下面开代码实现:

# 定义二项规划方程fun及其雅各比方程jac
def fun(x, sign=1.):
    return sign * (0.5 * np.dot(x.T, np.dot(H, x))+ np.dot(c, x) + c0)
def jac(x, sign=1.):
    return sign * (np.dot(x.T, H) + c)

# 定义等式约束条件方程feq及其雅各比方程jeq
def feq(x):
    return np.dot(y, x)
def jeq(x):
    return np.array(y)

# 生成相关参数
diff = 1e-16
bounds = [(0, None) for _ in range(len(y))] # x >= 0
constraints = [{ 'type': 'eq', 'fun': feq, 'jac': jeq }]# y*x = 0
options = { 'ftol': diff, 'disp': True }
guess = np.array([0 for _ in range(len(X))])

# 计算结果
res_cons = optimize.minimize(fun, guess, method='SLSQP', jac=jac, bounds=bounds, constraints=constraints, options=options)
alpha = [ 0 if abs(x - 0) <= diff else x for x in res_cons.x ]

# 输出结果与校验y*alpha的值是否为0
print('raw alpha: ', res_cons.x)
print('fmt alpha: ', alpha)
print('check y*alpha: ', 'is 0'if (abs(np.dot(y, res_cons.x) - 0) < diff ) else 'is not 0')

求解-\vec{w}--b-

# 计算w = sum(xi*yi*Xi)
w = np.sum([ np.array([0, 0]) if alpha[i] == 0 else (alpha[i] * y[i] * X[i]) for i in range(len(alpha))], axis=0)
print('w: ', w)

# 计算b,对support vector有:yi(w*xi + b) = 1,既有:b = 1/yi - w*xi
B = [( 0 if alpha[i] == 0 else ( 1 / y[i] - np.dot(w, X[i]) ) ) for i in range(len(alpha))]
B = list(filter(lambda x: x != 0, B))
b = 0 if len(B) <= 0 else B[0]
print('b: ', b)

至此支持向量机的参数求解过程完毕。

运行结果如下图所示:


运行结果

绘图

最后把数据绘制成图像。

limit = 11
plt.xlim(-2, limit)
plt.ylim(-2, limit)
# 绘制数据点
[plt.scatter(X[i][0],X[i][1], s=100, color=('r' if y[i] > 0 else 'y')) for i in range(len(X))]
# 绘制分割超平面L: wx + b = 0
plt.plot([i for i in range(limit)], [(-b - w[0]*i)/w[1] for i in range(limit)])
# 绘制上下边: wx + b = 1/-1
plt.plot([i for i in range(limit)], [(1-b - w[0]*i)/w[1] for i in range(limit)])
plt.plot([i for i in range(limit)], [(-1-b - w[0]*i)/w[1] for i in range(limit)])
plt.show()

效果如下图。其中红点为'+'样本,绿点为'-'样本。中间的蓝色线为分类的标准线。边界线,即红色线和绿色线分别穿过各自类别中最靠近分类标准线的点。这些点就是支持向量,只有这些向量所对应的-vec{\alpha}-分量才为非零值。

图像

本文源码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容