我正在为C中的决策树编写代码。现在它给了我正确的结果(0%训练错误,低测试错误),但是运行需要很长时间。
问题在于我运行qsort的频率。我的基本算法是:
for every feature
sort that feature column using qsort
remove duplicate feature values in that column
for every unique feature value
split
determine entropy given that split
save the best feature to split + split value
for every training_example
if training_example's value for best feature < best split value, store in Left[]
else store in Right[]
recursively call this function, using only the Left[] training examples
recursively call this function, using only the Right[] training examples
因为最后两行是迭代调用,并且因为树可以扩展数十个和几十个分支,所以对qsort的调用次数很大(特别是对于具有&gt; 1000个特征的数据集)。
我减少运行时的想法是创建一个二维数组(在一个单独的函数中),其中每列是一个排序的特征列。然后,只要我为每个递归调用在Left []和Right []中维护训练样例的行号向量,我就可以调用这个单独的函数,在预先排序的特征向量中抓取我想要的行,并节省每次qsort的成本。
我对C很新,所以我不确定如何编写代码。在MatLab中,我可以拥有一个全局数组,任何函数都可以更改或访问,在C中查找类似的内容。
答案 0 :(得分:0)
C中的全局数组是完全可能的。实际上有两种方法可以做到这一点。在第一种情况下,数组的尺寸对于应用程序是固定的:
#define NROWS 100
#define NCOLS 100
int array[NROWS][NCOLS];
int main(void)
{
int i, j;
for (i = 0; i < NROWS; i++)
for (j = 0; j < NCOLS; j++)
{
array[i][j] = i+j;
}
return 0;
}
在第二个示例中,维度可能取决于输入值。
#include <stdlib.h>
int **array;
int main(void)
{
int nrows = 100;
int ncols = 100;
int i, j;
array = malloc(nrows*sizeof(*array));
for (i = 0; i < nrows; i++)
{
array[i] = malloc(ncols*sizeof(*(array[i])));
for (j = 0; j < ncols; j++)
{
array[i][j] = i+j;
}
}
}
尽管两个示例中对数组的访问看起来都很相似,但数组的实现却大不相同。在第一个示例中,数组位于一个内存中,访问行的步幅是整行。在第二个示例中,每个行访问是指向一行的指针,该行是一块内存。然而,各行可以位于存储器的不同区域中。在第二个示例中,行也可能具有不同的长度。在这种情况下,您还需要将每行的长度存储在某处。
我不完全理解你想要实现的目标,因为我不熟悉决策树,功能的术语以及培训的标准方法集。但您可能还想查看其他数据结构以维护已排序的数据:
P.S1:来自Matlab你可能想要考虑一种与C语言不同的语言。 C ++具有支持上述数据结构的标准库。如果你大胆的话,可以想到Java,Python甚至是Haskell。 C中的指针处理可能非常繁琐且容易出错。
P.S2:我无法在StackOverflow上的URL中包含-
。所以红黑树的链接有点偏,无法点击。如果有人可以编辑我的帖子来修复它,那么我会很感激。