网站主机安全,phpnow安装wordpress,广州在线网站制作推荐,浅谈马云电子商务网站建设02-18 周六 图解机器学习之SMV 第五章5-2时间版本修改人描述2023年2月18日11:47:18V0.1宋全恒新建文档
环境 程序的基本环境#xff0c;是使用了jupyter#xff0c;在容器中运行的。
简介 本程序主要演示支持向量的获取#xff0c;支持向量是距离超平面最近的点组成的。程序…02-18 周六 图解机器学习之SMV 第五章5-2时间版本修改人描述2023年2月18日11:47:18V0.1宋全恒新建文档
环境 程序的基本环境是使用了jupyter在容器中运行的。
简介 本程序主要演示支持向量的获取支持向量是距离超平面最近的点组成的。程序的主要作用是将超平面和支持向量都绘制在同一个图上。
#%程序5-2名称sklearnsupportvectors.py
from sklearn.datasets import make_blobs
from sklearn.svm import SVC
import numpy as np
import matplotlib.pyplot as plt
X, y make_blobs(n_samples50, centers2,random_state0, cluster_std0.60)clf SVC(kernellinear)
clf.fit(X, y)def plot_svc_decision_function(clf, axNone):Plot the decision function for a 2D SVCif ax is None:ax plt.gca()x np.linspace(plt.xlim()[0], plt.xlim()[1], 30)y np.linspace(plt.ylim()[0], plt.ylim()[1], 30)Y, X np.meshgrid(y, x)P np.zeros_like(X)for i, xi in enumerate(x):for j, yj in enumerate(y):P[i, j] clf.decision_function([[xi, yj]])# plot the marginsax.contour(X, Y, P, colorsk,levels[-1, 0, 1], alpha0.5,linestyles[--, -, --])
plt.scatter(X[:, 0], X[:, 1], cy, s50, cmapspring)
plot_svc_decision_function(clf)
plt.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1],s200, facecolorsnone);
plt.show() 程序解读
数据生成
from sklearn.datasets import make_blobs
from sklearn.svm import SVC
import numpy as np
import matplotlib.pyplot as plt
X, y make_blobs(n_samples50, centers2,random_state0, cluster_std0.60)数据生成生成的样本数一共50个中心为2。因为make_blobs默认的参数n_features为2因此一共有两个特征。
拟合数据 SVM用于分类和回归目的是找到一个超平面使得离超平面最近的点都有很大的距离max(最小距离)。
clf SVC(kernellinear)
clf.fit(X, y)这是重点
clf.support_vectors_[:, 0], clf.support_vectors_[:, 1]这两是支持向量
根据官方code.py核必须是{‘linear’, ‘poly’, ‘rbf’, ‘sigmoid’, ‘precomputed’}之一或是自定义的。
核函数的选择
1、特征数量大和样本数量差不多此时选LR或者线性核SVM
2、特征数量少样本数量正常高斯核
3、特征数量小样本数量大手动添加特征变为第一种情况 在本小节生成的程序中特征数量为2样本数量为50。差不多一个量级。而且生成的数据是线性可分的。 可以这么理解 在经过SVM之后所有与职场向量机相关的数据均封装在了clf对象中了。上述我们打印了clf的支持向量可以看到一共有三个点是支持向量。
函数定义
def plot_svc_decision_function(clf, axNone):Plot the decision function for a 2D SVCif ax is None:ax plt.gca()x np.linspace(plt.xlim()[0], plt.xlim()[1], 30)y np.linspace(plt.ylim()[0], plt.ylim()[1], 30)Y, X np.meshgrid(y, x)P np.zeros_like(X)for i, xi in enumerate(x):for j, yj in enumerate(y):P[i, j] clf.decision_function([[xi, yj]])# plot the marginsax.contour(X, Y, P, colorsk,levels[-1, 0, 1], alpha0.5,linestyles[--, -, --])可以看到在函数定义中传入的参数为clfclassifier的简写。
plt.gca 进行坐标轴的移动 上述在参数中包含一个ax参数并且先进行了初始化意思就是说ax可以由外界传入如果不传入我会初始化一个。‘
利用plt.gca进行坐标轴支柱的移动。 上图中用红色标识出的黑色边界框线在Matplotlib中被称为spines中文翻译为脊柱…在我理解看来意思是这些边界框线是坐标轴区域的“支柱”。
那么我们最终要挪动的其实就是这四个“支柱” 且所有的操作均在plt.gca( )中完成gca就是get current axes的意思
import matplotlib.pyplot as plt# 这里建立的画布大小是5*5的并不是坐标轴范围使用“十字按钮”拖动你就懂了
plt.figure(figsize (5,5))
plt.plot() # 画个只有坐标系的图因为没有传参数所以显示空白ax plt.gca()# 获取你想要挪动的坐标轴这里只有顶部、底部、左、右四个方向参数
ax.xaxis.set_ticks_position(bottom) # 要挪动底部的X轴所以先目光锁定底部# 在这里position位置参数有三种这里用到了“按Y轴刻度位置挪动”
# data表示按数值挪动其后数字代表挪动到Y轴的刻度值
ax.spines[bottom].set_position((data,0))plt.show()主要用于进行坐标轴四个支柱的移动。 xlim和ylim
plt.xlim() 显示的是x轴的作图范围同时plt.ylim() 显示的是y轴的作图范围而 plt.xticks() 表达的是x轴的刻度内容的范围可以看出无参数的xlim默认的范围为从0.01到1.0通过修改参数进行控制 np.linespace生成等差数列
def linspace(start, stop, num50, endpointTrue, retstepFalse, dtypeNone):生成指定范围内指定个数的一维数组
1.在指定的间隔[“start”,“stop”]内均匀地返回数字。 2.返回“num”个等间距的样本。 3.endpoint是一个bool类型的值如果为Ture,“stop是最后一个值如果为False”,生成的数组不会包含stop值 4.retstep是一个bool类型的值如果为Ture会返回样本之间的间隙。 np.meshgrid(y, x) 用于生成网格矩阵
np.meshgrid(y, x) X, Y np.meshgrid(x, y) 代表的是将x中每一个数据和y中每一个数据组合生成很多点,然后将这些点的x坐标放入到X中,y坐标放入Y中,并且相应位置是对应的 nx,ny (3,2)#从0开始到1结束返回一个numpy数组,nx代表数组中元素的个数x np.linspace(0,1,nx)#[ 0. 0.5 1. ]y np.linspace(0,1,ny)# [0. 1.]xv,yv np.meshgrid(x,y)xv[[ 0. 0.5 1. ][ 0. 0.5 1. ]]yv[[ 0. 0. 0.][ 1. 1. 1.]]通过上面的例子其实可以发现meshgrid函数将两个输入的数组x和y进行扩展前一个的扩展与后一个有关后一个的扩展与前一个有关**前一个是竖向扩展后一个是横向扩展。**因为y的大小为2所以x竖向扩展为原来的两倍而x的大小为3所以y横向扩展为原来的3倍。通过meshgrid函数之后输入由原来的数组变成了一个矩阵。通过使用meshgrid函数可以产生一个表格矩阵 注 meshgrid不仅可以用来生成二维网格还可以用来生成三维网格。 参见meshgrid生成网格
np.zeros_like(X) 主要用于生成0数组形状与x相同。
numpy.zeros_like(a, dtypeNone, orderK, subokTrue, shapeNone)[source]Return an array of zeros with the same shape and type as a given array.
aarray_likeThe shape and data-type of a define these same attributes of the returned array.dtypedata-type, optionalOverrides the data type of the result.New in version 1.6.0.order{‘C’, ‘F’, ‘A’, or ‘K’}, optionalOverrides the memory layout of the result. ‘C’ means C-order, ‘F’ means F-order, ‘A’ means ‘F’ if a is Fortran contiguous, ‘C’ otherwise. ‘K’ means match the layout of a as closely as possible.New in version 1.6.0.subokbool, optional.If True, then the newly created array will use the sub-class type of ‘a’, otherwise it will be a base-class array. Defaults to True.shapeint or sequence of ints, optional.Overrides the shape of the result. If order’K’ and the number of dimensions is unchanged, will try to keep order, otherwise, order’C’ is implied.演示理解 x np.arange(6)x x.reshape((2, 3))x
array([[0, 1, 2],[3, 4, 5]])np.zeros_like(x)
array([[0, 0, 0],[0, 0, 0]]) y np.arange(3, dtypefloat)y
array([0., 1., 2.])np.zeros_like(y)
array([0., 0., 0.])enumerate 枚举列表
enumerate在字典赏识枚举、列举的意思 enumerate参数为可遍历/可迭代的对象如列表、字符串 enumerate多用于在for循环中得到计数利用它可以同时获得索引和值即需要 index 和 value 值的时候可以使用enumerate enumerate()返回的是一个enumerate对象 。
s [1, 2, 3, 4, 5]
e enumerate(s)
print(e)
# enumerate object at 0x0000028246E94C28
示例: 索引从0开始。
s [1, 2, 3, 4, 5]
x enumerate(s)
for index,value in x:print(%s,%s%(index,value))# 0,1
# 1,2
# 2,3
# 3,4
# 4,5
示例 索引从1开始
s [1, 2, 3, 4, 5]
# 索引从1开始
for index,value in enumerate(s, 1):print(%s,%s %(index,value))# 1,1
# 2,2
# 3,3
# 4,4
# 5,5
示例 将一组字典列表中的某一对字典元素与另一组字典列表中某一对字典元素组成一组新的字典列表
notes [{id: 11111111111, content: lalallalalalallala}, {id: 2222222222222, content: qqqqqqqqqqqqqqqqqqq}, {id: 33333333333333333, content: aaaaaaaaaaaaaaaaa}]
ids [one_note[id] for one_note in notes]
contents [one_note[content] for one_note in notes]
print(type(ids)) # class list
print(ids)
# [11111111111, 2222222222222, 33333333333333333]
print(type(contents)) # class list
print(contents)
# [lalallalalalallala, qqqqqqqqqqqqqqqqqqq, aaaaaaaaaaaaaaaaa]
result [{id: 11111111111, label: positive}, {id: 2222222222222, label: positive}, {id: 33333333333333333, label: negative}]
finally_result [{id: ids[index], label: label[label]} for index,label in enumerate(result)]
print(type(finally_result)) # class list
print(finally_result)
# [{id: 11111111111, label: positive}, {id: 2222222222222, label: positive}, {id: 33333333333333333, label: negative}]注 index, label in enumerate(result)其中每次index为序号0lable为每个字典。 clf.decision_function() def plot_svc_decision_function(clf, axNone):Plot the decision function for a 2D SVCif ax is None:ax plt.gca()x np.linspace(plt.xlim()[0], plt.xlim()[1], 30)y np.linspace(plt.ylim()[0], plt.ylim()[1], 30)Y, X np.meshgrid(y, x)P np.zeros_like(X)for i, xi in enumerate(x):for j, yj in enumerate(y):P[i, j] clf.decision_function([[xi, yj]])# plot the marginsax.contour(X, Y, P, colorsk,levels[-1, 0, 1], alpha0.5,linestyles[--, -, --])没看懂参见 scikit-learn工具包中分类模型predict_proba、predict、decision_function用法详解
classes_属性按顺序保存着训练样本的类别标记。predict_proba: 模型预测输入样本属于每种类别的概率概率和为1每个位置的概率分别对应classes_中对应位置的类别标签。以上述类别标签为[2 4 6 8]的那个分类器为例查看一下分类模型预测的概率。 输入的[-1, -1]刚好是训练分类器时使用的数据训练数据中[-1, -1]属于类别6在predict_proba输出概率中最大概率值出现在第三个位置上第三个位置对应的classes_类别刚好也是类别6。这也就是说predict_proba输出概率最大值索引位置对应的classes_元素就是样本所属的类别。下面就来看一下predict的预测结果与predict_proba的预测结果是否一致。
predict:模型预测输入样本所述的类别是则输出1不是则输出0.
在上一步中知道了predict_proba是输出样本属于各个类别的概率且取概率最大的类别作为样本的预测结果下面看一下predict的预测结果与predict_proba的最大值是否一致。 predict的预测结果为类别6对应于classes_中的第三个元素也同时对应于predict_proba中的第三个元素且是概率值最大的元素
decision_functinon The confidence score for a sample is the signed distance of that sample to the hyperplane. 说了两件事情其一是说评估样本X的的decision_function等于没说哈哈哈其二是说如果decision_dunction_shape**‘ovr’,则输出的decison_function形状是(n_samples, n_classes)**, n_samples是输入样本的数量n_classes是训练样本的类别数。这里再补充一点如果decision_dunction_shapeovo,则输出的decison_function形状是(n_samples, n_classes * (n_classes - 1) / 2)。‘ovr’和‘ovo’又是啥莫急莫急。暂且知道是用于训练多分类的就行。
大致解释下decison_function就是用来衡量待预测样本到分类模型各个分隔超平面的距离没找到太直观的解释方法。 我们常见的分类器比如LR和SVM都是只能支持二分类的回想一下LR分类器通过判断线性模型的预测结果是否大于0进而判断sigmoid的输出结果是否大于0.5来判断模型属于正类还是负类。SVM也一样前面讲了SVM通过分隔超平面将样本分到两边去也就是进行二分类。那么怎么能将二分类的分类算法应用到多分类任务上去呢这就是‘ovr’和‘ovo’要解决的问题。 ‘ovr’全称是One-vs-Rest。就是一个人和对面一群人干一次架群殴。假如我们训练数据中包含[0, 1, 2, 3]四个分类那么分别将0, 1, 2, 3作为正样本其余的123 023 013 012作为负样本理解 分解就是0为正类123为负类1为正类023为负类依次类推。训练4个分类器每个分类器预测的结果表示属于对应正类也就是0 1 2 3 的概率。这样对于一个输入样本就相当于要进行4个二分类然后取输出结果最大的数值对应的classes_类别。 ‘ovo’全称是One-vs-One。就是一个人分别和对面的每个人干一次架单挑车轮战术。同样假如我们训练数据中包含[0, 1, 2, 3]四个分类先将类别0作为正样本类别1类别2类别3依次作为负样本训练3个分类器理解: 0为正1,2,3为负训练3个分类器然后以类别1为正样本类别0类别2 类别3作为负样本训练3个分类器以此类推。由于类别0为正样本类别1为负样本和类别1为正样本、类别0为负样本实质上是一样的所以不需要重复训练。 注 对于ovr不再过多解释容易理解。 对于ovo做二分类0正 1 2, 3 负类这样就是3种情况即01 02 03 1正 0 23为负 又是三种情况0正1负和0负1正样本实际是一样的不再重复训练。 12 13 2正 0,1,2负 则情况为23. 一共123 4*3/2 通过上面的描述可知假如训练样本有n_classes个类别则’ovr’模式需要训练n_classes个分类器‘ovo’模式需要训练n_classes * (n_classes - 1) / 2 个分类器。那么问题来了有多少个分类器是不是就得有多少个分隔超平面有多少个分隔超平面是不是就得有多少个decision_function值。这也就对应了“他是谁”那部分所说的decison_function输出形状的描述。
二分类的decision_function 二分类模型中decision_function返回的数组形状等于样本个数也就是一个样本返回一个decision_function值。 import numpy as np
from sklearn.svm import SVCx np.array([[1,2,3],[1,3,4],[2,1,2],[4,5,6],[3,5,3],[1,7,2]])y np.array([3, 3, 3, 2, 2, 2])clf SVC(probabilityTrue)
clf.fit(x, y)
print(clf.decision_function(x))# 返回array([2, 3])其中2为negetive3为positive
print(clf.classes_)还记得前面讲过的decision_function是有符号的吧大于0表示正样本的可信度大于负样本否则可信度小于负样本。所以对于前3个样本decison_function都认为是正样本的可信度高后3个样本是负样本的可信度高。那么再看一下predict的结果前3个预测为正样本3ps二分类情况下正样本对应的是classes_中的第二个类别后3个样本预测为负样本2。再看一下predict_proba预测的样本所属的类别概率可以看到前3个样本属于类别3的概率更大后3个样本属于类别2的概率更大。
多分类的decision_function 多分类模型中decision_function返回的数组形状依据使用的模式是**‘ovr’还是‘ovo’**而分别返回n_classes个和n_classes * (n_classes - 1) / 2个数值。
ovr
import matplotlib.pyplot as plt
import numpy as np
from sklearn.svm import SVC
# 样本
X np.array([[-1, -1],[-2, -1],[1, 1],[2, 1],[-1, 1],[-1, 2],[1, -1],[1, -2]]
)
# 类别一共四类
y np.array([2, 2, 3, 3, 0, 0, 1, 1])
# SVC多分类模型默认采用ovr模式
clf SVC(probabilityTrue, decision_function_shapeovr)
clf.fit(X, y)# 计算样本距离每个分类边界的距离
# One-vs-One 按照decision_function的得分[01, 02, 03, 12, 13, 23]判断每个分类器的分类结果然后进行投票
# One-vs-Rest 选择decision_function的得分[0-Rest, 1-Rest, 2-Rest, 3-Rest]最大的作为分类结果
print(decision_function:\n, clf.decision_function(X))
# precidt预测样本对应的标签类别
print(predict:\n, clf.predict(X))
# predict_proba 预测样本对应各个类别的概率
print(predict_proba:\n, clf.predict_proba(X)) #这个是得分,每个分类器的得分取最大得分对应的类。
print(classes_:, clf.classes_)在Jupyter中输出如下 在ovr场景下decision_function输出的最大值对应的正样本类别就是decision_function认为置信度最高的预测类别。 ovo 在ovr代码中只要把代码行
# SVC多分类模型默认采用ovr模式
clf SVC(probabilityTrue, decision_function_shapeovo)
clf.fit(X, y)即可将分类器转换为ovo模式。 模型在训练集上的decision_function以及predict_procaba、predict结果如下 ovo模式下4个类别的训练数据需要训练6个二分类器得到6个decition_function值依照classes_的类别顺序6个二分类器分别是[01, 02, 03, 12, 13, 23]前面的数字表示正类后面的表示负类。以decision_function的第一行输出结果为例 -0.07609727 对应 01分类器且数值小于0则分类结果为后者即类别1 -1.00023294 对应 02分类器且数值小于0则分类结果为后者即类别2 0.27849207 对应 03分类器且数值大于0则分类结果为前者即类别0 -0.834258626 对应 12分类器且数值小于0则分类结果为后者即类别2 0.24756982 对应 13分类器且数值大于0则分类结果为前者即类别1 1.00006256 对应 23分类器且数值大于0则分类结果为前者即类别2 最终得票数{类别0: 1 类别1: 2, 类别2: 3 类别3: 0} 对以上分类结果voting投票多数获胜即最终分类结果为类别2。 注 要理解这个投票的机制很重要。对于ovo模式仅仅通过decision_function无法得出最终判定类别。 总结: 通过上面讲的这些大概也能得出decision_function、predict_procaba、predict之间的联系了 decision_function输出样本距离各个分类器的分隔超平面的置信度并由此可以推算出predict的预测结果 predict_procaba输出样本属于各个类别的概率值并由此可以推算出predict的预测结果 predict输出样本属于具体类别的预测结果 还是以SVM分类器为例SVM分类器有个参数用来控制是否输出预测样本的概率值probabilityTrue时SVM分类器具有predict_proba函数可以输出样本的预测概率但是当probabilityFalseSVM分类器没有predict_proba函数也就没办法得到样本预测结果的置信度简单理解为概率。但是我们又知道当我们想要计算分类器的性能时常常需要用到ROC和AUCROC曲线表示分类器预测结果FPR和TPR的变化趋势AUC表示ROC曲线以下的面积。也就是说要想得到ROC和AUC就需要得到一组FPR和TPRFPR和TPR的计算通常是基于一组样本的预测置信度分别选择不同的置信度阈值得到一组FPR和TPR值然后得到ROC曲线的。现在没有predict_proba就得不到样本预测的置信度。But还记得我们前面解释decison_function时说过的**decision_function表示通过度量样本距离分隔超平面距离的来表示置信度。**那么我们是不是可以使用decision_function的置信度来计算ROC呢答案当然是可以的啦。
ax.contour 绘制等高线 官方文档
contour(z);
contour(xyz)
contour(—levels)
contour(—ineSpec)
contour(—Name,Value)
contour(ax—
Mcontour(—
[MC]contour(__)contour(Z) 创建一个包含矩阵Z的等值线的等高线图其中Z包含X-Y平面上的高度值。
contour(X,Y,Z) 指定Z中各值得X和Y坐标。
contour(—levels) 将要显示得等高线指定为上述任一语法中得最后一个参数。将levels指定为标量n以在n个自动选择的层级上显示等高线。要在某些特定高度绘制等高线请将levels指定为单调递增值的向量。
contour(—LineSpec) 指定等高线的线型和颜色。
contour(—NameValue) 使用一个或多个名称—值对组参数指定等高线图的其他选项。
contour(ax—在目标坐标区中显示等高线图。将坐标区指定为上述任一语法中的第一个参数。
Mcontour(—返回等高线矩阵M其中包含每个层级的顶点的X,Y坐标。
[Mc]contour(—返回等高线矩阵和等高线对象c。显示等高线后使用c设置属性。参考Python Matplotlib.axes.Axes.contour()用法及代码示例 函数功能用来绘制等高线和决策边界 参考matplotlib可视化之等高线图plt.contourf()与机器学习中绘制决策边界 参考 网格理解 matplotllib绘图值得认真查看有代码有图对于熟悉matplot的库由许多帮助。 记录linestyle和marker contour理解 python 等高线与等高线填充图 较为准确的。
contour函数用于绘制等高线和等高线之间的填充等高线的理解就是对于一个函数等高线就是假如有一个函数zf(x,y)你在平面上所有的x,y取值都会对应一个z值如果f是连续的那么把z值相同的点(x,y)连接起来就会形成一条曲线这就是这个z值的等高线。等高线的理解参见 等高线
def plot_svc_decision_function(clf, axNone):Plot the decision function for a 2D SVCif ax is None:ax plt.gca()x np.linspace(plt.xlim()[0], plt.xlim()[1], 30)y np.linspace(plt.ylim()[0], plt.ylim()[1], 30)Y, X np.meshgrid(y, x)P np.zeros_like(X)for i, xi in enumerate(x):for j, yj in enumerate(y):P[i, j] clf.decision_function([[xi, yj]])# plot the marginsax.contour(X, Y, P, colorsk,levels[-1, 0, 1], alpha0.5,linestyles[--, -, --])绘制等高线levels表示要关注的高度值。linestyles则可以取值实线点斜线点线等。把levels修改为[-1, 0, 1, 2]则会出现四根线。 8.Matplotlib绘图–等高线
绘制散点图 scatter文档参考
plt.scatter(X[:, 0], X[:, 1], cy, s50, cmapspring)
plot_svc_decision_function(clf)
plt.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1],s2000, facecolorsnone);
plt.show()从上图中可以看出c用于表示点的颜色。在进行支持向量的绘制的时候描述了所有的点。 因此我觉得在绘制等高线时matplot应该是对网格内进行了插值插入了许多点来进行绘制等高线。网格仅用来圈定散点的范围。二维上的许多特征点也可以理解在高纬空间中只不过恰好在同一个平面上而已。绘制散点图的工作就不做进一步分析了因为之前已经总结过了。
总结 图解机器学习这个书呢自己也是痛苦了许久因为情绪也不怎么好吧所以自我提升也一直没有不愿意开展。刚刚完成了对于甘地自传的阅读接下来就是希望3月份能完成这本《图解机器学习》的阅读。 本文中对于ovo和ovr的理解还是很重要的。发现虽然是尝试理解机器学习但是好像都是在熟悉sklearn和matplot画图和机器学习算法也都封装好了。先会用再说吧。 参考支持向量机代码实现_sklearn实现支持向量机