我有一个 n x m 的数据集,其中有 n 个观测,每个观测包含 m 个属性的 m 个值。每个观测还被分配了一个观测结果。m 的值很大,对我的任务来说太大了。我试图找到一个最佳且最小的 m 属性子集,这个子集仍然能很好地代表整个数据集,这样我就可以只使用这些属性来训练神经网络。
我想使用遗传算法来解决这个问题。问题在于适应度函数。它应该能够说明生成的模型(属性子集)在多大程度上仍然反映了原始数据。我不知道如何评估某个属性子集与整个数据集的对比。当然,我可以使用神经网络(反正之后会使用这些选定的数据)来检查子集的质量——误差越小,子集越好。但是,在我的情况下,这需要大量的时间,我不想使用这种解决方案。我正在寻找其他方法,最好是只在数据集上操作的方法。
我考虑过的是:对于遗传算法找到的子集 S,将数据集修剪,使其只包含子集 S 的值,并检查在这个数据集中有多少观测不再可区分(对于相同的属性具有相同的值)但具有不同的结果值。这个数字越大,子集就越差。但这对我来说似乎计算量有点大。
还有其他方法可以评估属性子集在多大程度上仍然代表整个数据集吗?
回答:
这个成本函数应该能满足你的需求:对每个子集中的特征对应的因子载荷进行求和。
这个和值越高,这些特征解释响应变量变异性的份额就越大。如果我理解原帖者的意思,这个成本函数忠实地翻译了原帖中“代表整个数据集相当好”的意思。
将其简化为代码是直接的:
-
计算你的数据集的协方差矩阵(首先移除包含响应变量的列,即可能是最后一列)。如果你的数据集是m x n(列 x 行),那么这个协方差矩阵将是n x n,主对角线上是“1”。
-
接下来,对这个协方差矩阵进行特征值分解;这将给你每个特征值(每个特征值对应一个特征或列)对响应变量总变异性贡献的比例。[注意,奇异值分解(SVD)通常用于这一步,但这是不必要的——特征值分解要简单得多,只要你的矩阵是方阵,协方差矩阵总是方阵,这总是能完成任务]。
-
你的遗传算法将在每次迭代时返回一组候选解(在你的情况下是特征子集)。GA 或任何组合优化中的下一个任务是根据它们的成本函数得分对这些候选解进行排序。在你的情况下,成本函数是对该子集中每个特征的特征值比例进行简单的求和。(我想你可能希望对这个计算进行缩放/归一化,以便更高的数字表示适应度较低。)
一个示例计算(使用python + NumPy):
>>> # 有很多方法可以进行特征值分解,这只是其中一种方法>>> import numpy as NP>>> import numpy.linalg as LA>>> # 计算数据集的协方差矩阵(不包括响应变量列)>>> C = NP.corrcoef(d3, rowvar=0)>>> C.shape (4, 4)>>> C array([[ 1. , -0.11, 0.87, 0.82], [-0.11, 1. , -0.42, -0.36], [ 0.87, -0.42, 1. , 0.96], [ 0.82, -0.36, 0.96, 1. ]])>>> # 现在计算协方差矩阵的特征值和特征向量:>>> eva, evc = LA.eig(C)>>> # 现在只获取每个特征值的比例值:>>> # 首先,对特征值进行排序,从高到低:>>> eva1 = NP.sort(eva)[::-1]>>> # 获取每个特征值的比例值:>>> eva2 = NP.cumsum(eva1/NP.sum(eva1)) # "cumsum" 只是累积和>>> title1 = "ev value proportion">>> print( "{0}".format("-"*len(title1)) )------------------->>> for row in q : print("{0:1d} {1:3f} {2:3f}".format(int(row[0]), row[1], row[2])) ev value proportion 1 2.91 0.727 2 0.92 0.953 3 0.14 0.995 4 0.02 1.000
所以,就是上面第三列的值(每个特征一个)根据成本函数评估的子集中包含哪些特征进行选择性求和。