基于核方法的测试实例
- 是什么(基础理论)
核方法是一种常用的非线性特征变化方法,主要思想是将数据从原始空间特征映射到一个高维的特征空间,使得特征空间中线性不可分的问题转为线性可分的问题。
- 为什么(什么情况下用这个)
实际问题中,数据通常不是线性可分的,而是存在一定的非线性关系。例如:图像、语音和文本,存在大量非线性,而线性模型很难对其进行有效的建模和处理。因此需要一种能够处理非线性关系的建模技术,这就是核方法的主要应用场景。
它可以帮助处理高维稀疏数据和大规模数据,通过核方法将数据映射到高维空间中,从而将高维稀疏数据转化为低维密集数据,提高算法的效率和准确性。此外,还可以通过特定核函数和近似算法,提高准确性。
注意:什么是高维稀疏矩阵?什么又是低维密集矩阵呢?
在机器学习中,数据通常是表示为特征向量的形式,每个特征对应一个维度。例如,对于一个包含n个样本和m个特征的数据集,可以将每个样本表示为一个m维向量,整个数据集表示为一个n×m的矩阵。在这种情况下,如果数据集的维度很高(即m很大),则称其为高维数据。而如果数据集的维度相对较小,或者大部分特征都是零,称其为稀疏数据。传统的机器学习算法在处理高维稀疏数据时,通常需要解决两个问题:计算复杂度问题:高维稀疏数据会导致算法的计算复杂度变高,因为很多特征都是零,需要进行很多无用的计算。
过拟合问题:高维稀疏数据容易导致过拟合,因为在高维空间中,数据点之间的距离变得很大,很难将它们正确地分类或回归。
核方法可以通过将高维稀疏数据转化为低维密集数据来解决这些问题。具体来说,核方法使用一个核函数,将高维稀疏数据映射到一个高维稠密空间中。在这个高维稠密空间中,原来稀疏的数据点变得更加密集,更容易进行分类和回归。此外,由于使用了核函数,可以避免在低维空间中进行复杂的计算,从而降低算法的计算复杂度。这就是将高维稀疏数据转化为低维密集数据的过程。
需要注意的是,这里的低维空间不一定是实际存在的,而是一个虚拟的空间,通过核函数进行映射得到的。例如,可以使用高斯核函数将数据映射到一个无限维的空间中,然后使用内积等运算在这个空间中进行计算。虽然这个无限维的空间在实际中是不存在的,但是可以通过核函数计算得到,从而实现在高维空间中进行非线性建模的目的。
- 怎么用(证明核方法是有效的)
3.1 使用相同的数据集
回头看 为什么 ,数据通常不是线性可分的,而是存在一定的非线性关系,因此数据是线性不可分的情况时,可以证明核方法是有效的,故数据集为生成的线性不可分数据。代码及数据图如下:
#导入numpy库和matplotlib库,分别用于生成数据和绘制图表
import numpy as np
import matplotlib.pyplot as plt
#随机数种子
np.random.seed(0)
#生成500个2维的随机点,这些点的坐标都在【-1,1】范围内
X = np.random.uniform(-1,1,size=(500,2))
#计算每个点到原点的距离,使用numpy的sqrt函数计算欧几里得距离
distances = np.sqrt(X[:, 0]**2 + X[:, 1]**2)
#生成布尔数组,表示距离小于0.5的位置
mask = distances < 0.5
#将距离小于0.5的点存储在X1, y1中
X1 = X[mask]
y1 = np.zeros(len(X1))
#将距离大于0.5的点存储在X1, y1中
X2 = X[~mask]
y2 = np.ones(len(X2))
# 将X1和X2合并为X,将y1和y2合并为y 为什么?
#使用vstack函数将X1和X2垂直合并为X,使用concatenate函数将y1和y2合并为y。
#这样就可以得到一个包含距离小于0.5的点和距离大于等于0.5的点的X和y数组,可以用于训练和测试分类模型。
X = np.vstack([X1,X2])
y = np.concatenate([y1,y2])
#使用matplotlib的scatter函数绘制散点图,其中X[:, 0]表示所有点的x坐标,X[:, 1]表示所有点的y坐标,
#c=y表示使用标签数组y对数据点进行颜色编码,cmap='bwr'表示使用蓝白红三种颜色进行编码,
#表示0、1和中间的过渡值。最后使用show函数显示图表。
plt.scatter(X[:,0] ,X[:,1] , c=y, cmap="bwr")
plt.show()
可见,数据集为非线性数据。
注意,同样是拼接,为什么使用不同的函数呢?
np.vstack() 函数是 numpy 库中用于垂直(按照行的方向)合并两个数组的函数。它将两个输入的数组按照行的方向进行合并,并返回一个新的数组。该函数的使用方式如下:np.vstack((array1, array2, …)) 其中 array1、array2
等参数表示要合并的数组,可以是多个。这些数组必须具有相同的列数,但可以具有不同的行数。函数返回一个新的数组,其中包含输入数组按照行方向合并的结果。np.concatenate() 函数是 numpy 库中用于按照指定轴连接两个或多个数组的函数。它可以按照指定的轴(默认为
0,即最外层的维度)将多个输入的数组进行连接,并返回一个新的数组。该函数的使用方式如下:np.concatenate((array1, array2, …), axis=0) 其中array1、array2 等参数表示要连接的数组,可以是多个。axis 参数表示要连接的轴,可以是 0(按照行方向连接)或 1(按照列方向连接)。函数返回一个新的数组,其中包含输入数组按照指定轴连接的结果。在本例中,np.concatenate()函数用于将两个标签数组 y1 和 y2 进行连接,得到一个新的标签数组 y。
3.2 使用核方法
model = SVC(kernel='linear')
model.fit(X_train, y_train)
y_predict = model.predict(X_test)
accuracy = accuracy_score(y_test,y_predict)
print(f"Accuracy:{accuracy}")
得到:Accuracy:0.72
model = SVC(kernel=‘rbf’) 这行代码创建了一个支持向量机(Support Vector
Machine,SVM)分类器的实例,使用径向基函数(Radial Basis
Function,RBF)作为核函数(kernel),并将其赋值给变量model。具体来说,SVC是sklearn库(即Scikit-learn,一个常用的机器学习库)中实现SVM分类器的类,kernel参数指定了SVM使用的核函数,这里是RBF核函数。RBF核函数在SVM中是常用的核函数之一,它可以将原始特征空间映射到一个高维空间,从而使得数据更容易分离。
3.3 使用非核方法(线性方法)
model = SVC(kernel='rbf')
model.fit(X_train, y_train)
y_predict = model.predict(X_test)
accuracy = accuracy_score(y_test,y_predict)
print(f"Accuracy:{accuracy}")
得到:Accuracy:0.93
model = SVC(kernel=‘linear’) 这行代码创建了一个支持向量机(Support Vector
Machine,SVM)分类器的实例,使用线性核函数(linear kernel)作为核函数,并将其赋值给变量model。线性核函数在SVM中也是常用的核函数之一,它可以将原始特征空间映射到一个更高维度的特征空间,从而使得数据更容易被线性分割。与RBF核函数不同,线性核函数没有额外的超参数需要调整,因此通常比较容易训练和解释。
运行效果图: