周末AI课堂非线性降维方法 代码篇: 机器学习你会遇到的“坑”

 人参与 | 时间:2024-03-29 02:36:59

AI课堂开讲,坑就差你了!周末

很多人说,课堂校园灵异事件看了再多的非线法代文章,可是性降学习没有人手把手地教授,还是维方很难真正地入门AI。为了将AI知识体系以最简单的码篇方式呈现给你,从这个星期开始,机器芯君邀请AI专业人士开设“周末学习课堂”——每周就AI学习中的坑一个重点问题进行深度分析,课程会分为理论篇和代码篇,周末理论与实操,课堂一个都不能少!非线法代

来,性降学习退出让你废寝忘食的维方游戏页面,取消只有胡吃海塞的码篇周末聚会吧。未来你与同龄人的差异,也许就从每周末的这堂AI课开启了!

读芯术读者交流群,校园灵异事件请加小编微信号:zhizhizhuji。等你。后台回复“周末AI课堂”,查阅相关源代码

全文共2202字,预计学习时长6分钟

收收心,上课时间到啦。

我们在上周的《线性降维方法(代码篇)》中对IRIS数据和WINE数据利用了PCA和LDA这两种线性降维方法,似乎取得了一定的效果,一方面体现在低维空间不同类的样本分的足够开,另一方面体现在经过降维后,分类器的表现更好了。

而非线性降维的一个重要前提就是,数据的分布本身就不是高维的,而是一个嵌在高维空间的低维流形,而这样的低维我们可能只需要将其展开,而不需要将其变换。比如,地球表面近似为一个球面,球面上的我们对球面的感受不会是三维的,而是二维的,但却不得不用三维的语言去描述它而已。如果我们想研究它的内在结构,可能只需要将其展开为二维。我们将其展开的过程,就是降维。

我们在IRIS和WINE的数据里很难发现这样的结构,一方面因为实际数据中完美的流形并不存在,另一方面因为,我们最多只能在三维空间可视化,而特征数一旦巨大,我们通过特征的组合去观察每一个三维空间的数据结构,将是不可能的任务。

但我们可以通过非线性降维的方法,来逆推整个结构,如果我们的非线性降维取得了比线性降维的更好的效果,那么很可能本身的数据就是一个低维流形。

我们可以构造一个简单的样例数据,来可视化一个二维流形:

import matplotlib.pyplot as plt

from mpl_toolkits.mplot3d import Axes3Dfrom sklearn import datasetsX, c = datasets.samples_generator.make_s_curve(1000, random_state=2018)ax = Axes3D(plt.figure())ax.scatter(X[:,0],X[:,1],X[:,2],c=c,cmap=plt.cm.hsv)plt.title('Sample')plt.show()

从这个角度看,平平无奇,但我们换个角度来看它:

对于这样一个S形,其实就是嵌在三维空间的二维流形,我们如果要从三维降到二维,非线性降维只是将其展开,会尽可能保持流形的内在结构,而数据分布本身近似为流形,内在结构就非常重要。

以PCA和ISOMAP为例,我们分别对样例数据做降维:

from sklearn.decomposition import PCA

X_PCA=PCA(2).fit(X).transform(X)

from sklearn.manifold import Isomap

X_ISO=Isomap(10,2).fit(X).transform(X)

PCA的降维结果是一个S形,其实近似于一个嵌在二维空间的一维流形。很多初学者或者不理解降维的意义的同学,反而会以为PCA处理之后,样例数据保持了S形,就是一个好的处理。

其实呢,这样的看法是错误的。因为对于这样一个三维空间的二维流形,因为流形本身就是二维的,我们只需要将其“展开”和“铺平”,这样才最大程度上保留了信息,PCA这种线性的降维方式只是选取了一个投影空间,大量的样本在低维空间没有得到表达。

举个不太恰当的例子,如果我们把国家作为我们的数据点,那么这些数据点就分布地球表面,也就是一个嵌在三维空间的二维流形上。如果我们为球面寻找一个低维空间,PCA会把球面映射到一个圆(损失大量信息),而ISOMAP会映射成一张世界地图。(事实上,要想达到这一效果,对地球表面的数据分布做更多的假设,但道理相同)

我们可以换另外一组数据来取得相似的效果:

n_points = 1000

X, color = datasets.samples_generator.make_swiss_roll(n_points,random_state=2018)X_PCA=PCA(2).fit(X).transform(X)X_ISO=Isomap(10,2).fit(X).transform(X)ax = Axes3D(plt.figure())ax.scatter(X[:,0],X[:,1],X[:,2],\c=color,cmap=plt.cm.hsv)ax.set_title('Sample')bx=plt.figure()plt.scatter(X_PCA[:,0],X_PCA[:,1],c=color,cmap=plt.cm.hsv)plt.title('PCA of Swiss Roll')cx=plt.figure()plt.scatter(X_ISO[:,0],X_ISO[:,1],c=color,cmap=plt.cm.hsv)plt.title('ISOMAP of Swiss Roll')plt.show()

我们尝试用更多的方法如MDS和LLE(locally linear embedding,局部线性嵌入),对swiss roll数据进行降维:

值得注意的是,MDS(多维缩放)本质上还是一个线性算法,虽然它的初衷是在低维空间保持高维空间的距离,但仍然把欧几里得距离作为度量,所以从图中来看,MDS的效果几乎与PCA的一致。而LLE是利用了流形的局部等价于欧氏空间,每一个点都可以被周围的点进行线性表示(这也是线性空间的性质),降到低维空间后,要保持拟合系数的不变。

接下来,我们把非线性降维方法用到实际的数据中,我们在WINE数据上,对线性降维和非线性降维方法进行对比:以低维空间的维度作为超参数,仍然选取k-近邻作为分类器,通过观察测试集上表现来对降维效果有定性的认识。

import numpy as np

from sklearn import datasetsfrom sklearn.model_selection import cross_validatefrom sklearn.manifold import Isomap,MDSfrom sklearn.manifold import locally_linear_embedding as LLEfrom sklearn.decomposition import PCAfrom sklearn.preprocessing import StandardScalerfrom sklearn.neighbors import KNeighborsClassifier as KNCimport seaborn as snsimport matplotlib.pyplot as pltdata=datasets.load_wine()X=StandardScaler().fit(data['data']).transform(data['data'])y=data['target']def dim_reductor(n,X):reductor=dict(PCA=PCA(n).fit(X).transform(X),\ISOMAP=Isomap(10,n).fit(X).transform(X),\MDS=MDS(n).fit_transform(X),\LLE=LLE(X,10,n)[0])return(reductor)mse_mat=np.zeros((4,X.shape[1]))for nin range(1,X.shape[1]+1):reductor=dim_reductor(n,X)test_mse=[]for name, methodin reductor.items():X_new=reductor[name]clf=KNC()clf_dict=cross_validate(clf,X_new,y,\

cv=5,scoring='accuracy')test_mse.append(clf_dict['test_score'].mean())mse_mat[:,n-1]=test_msesns.set(style='darkgrid')for idex,namein enumerate(reductor.keys()):plt.plot(range(1,X.shape[1]+1),mse_mat[idex],label=name)plt.xlabel('dimensions')plt.ylabel('accuracy')plt.legend()plt.show()

我们发现,无论在哪一个维度,LLE的表现均是最差的,而且LLE并不会随着维度波动,而是一直在上升。而其他三种降维方法,MDS在维度为3的时候表现最好,PCA在维度为5的时候表现最好,ISOMAP在维度为6的时候表现最好。这能否说明,WINE数据并没有明显的流形结构,或者ISOMAP的结果告诉我们,WINE数据其实可能是一个嵌在13维空间的6维流形,这些我们无从得知。从工程上来说,我们可能需要将各类流形学习用进去,直到降低合适维度可以得到我们需要的性能。

这些算法看起来并没有太大的差异,我们也可以看到MDS,ISOMAP,PCA三种方法交缠在一起,难分高下,那么我们大胆地来试一种虽然不属于流形学习,但却属于非线性降维——加了kernel的PCA:

from sklearn.decomposition import KernelPCA

def dim_reductor(n,X):...KPCA=KernelPCA(n,'rbf').fit_transform(X)#添加到前文的dim_reductor函数中.........

我们惊奇地发现,Kernel PCA的曲线几乎一直在其他曲线的上方!这说明,在几乎所有的维度上,Kernel PCA的表现要好于其他的降维算法(针对WINE数据),维度等于2时,我们还可以比较各类降维的算法的表现:

sns.barplot(mse_mat[:,1],list(reductor.keys()))

那么为什么PCA加了Kernel,性能就要比原始的PCA算法更好呢?以及,Kernel到底是什么?为什么会加了Kernel就使得PCA从一个线性算法变成了非线性?下周我们再见吧,《机器学习的核技巧(kernel trick)》会为大家来解答。

读芯君开扒

课堂TIPS

•当数据处在一个高维空间的低维流形时,我们就可以方便的使用内禀坐标,即流形中的坐标就可以很好的描述数据,流形学习的出发点就在于此。

•流形学习除了ISOMAP和LLE,常见的流形学习方法还有 Hessian Eigenmapping,t-SNE, Laplacian Eigenmaps ,Local tangent space alignment。但流形学习需要克服最大的问题在于,流形的局部空间等价于欧氏空间,而在局部往往就要进行密采样的操作,而这一条件往往得不到满足。

•特征选择和降维本身虽然并不相同,但也并不矛盾,我们在实际工程中,可以先做特征选择,再做降维,对于不同的数据,可能会有不同的效果。但可以预见的是,当存在多余特征的时候,高维空间的点会变得更加稀疏,密采样会遇到更大的困难,先做特征选择去除掉多余特征是非常有必要的。

留言 点赞 发个朋友圈

我们一起探讨AI落地的最后一公里

作者:唐僧不用海飞丝

如需转载,请后台留言,遵守转载规范
顶: 783踩: 2