我已经实现了朴素贝叶斯,但我在静态内存分配中实现了它。 我想转变为动态但我的小脑子无法做到这一点。
#define COLS 4 //including class label
#define BINS 100
#define CLASS_COL 0
#define CLASS 2
我们的想法是从配置文件中获取上述值,然后进行设置。
struct each_col //Probability for each feature based on classes
{
double col_PB[BINS][CLASS];
};
struct NB_Class_Map
{
char label[250];
unsigned int label_value;
double class_PB;
};
struct NB //Proabability for entire feature
{
struct NB_Class_Map classes[CLASS];
struct each_col cols[COLS];
};
NB nb = {0}; //gloabal value
训练NB的功能:
long strhash(const char *str)
{
long hash = 5381;
int c;
printf("IN: %s ",str);
while (c = *str++)
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
printf("OUT: %ld ||",hash);
return hash;
}
int setup_train_NB(vector<vector<string> > &data)
{
//Finding the feature count
static int class_label = -1;
for(unsigned int i=0;i<data.size();i++)
{
unsigned int Class;
printf("\n===========New ROW==============\n");
int k;
for(k=0;k<CLASS;k++)
{
if(strcmp(data[i][CLASS_COL].c_str(), nb.classes[k].label) == 0)
{
printf("MATCHED\n");
Class = nb.classes[k].label_value;
break;
}
}
if(k==CLASS)
{
printf("NOT MATCHED\n");
class_label++;
nb.classes[class_label].label_value = class_label;
strcpy( nb.classes[class_label].label, data[i][CLASS_COL].c_str());
Class = nb.classes[class_label].label_value;
}
printf("Class: %d ||\n", Class);
for(unsigned j=0;j<data[0].size();j++)
{
printf("\n===========New COLUMN==============\n");
if(j == CLASS_COL)
{
nb.classes[Class].class_PB++;
continue;
}
unsigned int bin = strhash((data[i][j].c_str()))%BINS;
printf("Bin: %d ||", bin);
printf("Class: %d ||\n", Class);
nb.cols[j].col_PB[bin][Class]++; //[feature][BINS][CLASS]
}
}
//Finding the feature PB
for(unsigned int i=0;i<COLS;i++)
{
if(i==CLASS_COL)
continue;
for(unsigned j=0;j<BINS;j++)
{
for(unsigned k=0;k<CLASS;k++)
{
// nb.cols[i].col_PB[j][k] /= nb.classes[k].class_PB; //without laplacian smoothing
nb.cols[i].col_PB[j][k] = (nb.cols[i].col_PB[j][k] + 1) / (nb.classes[k].class_PB + COLS - 1); //with laplace smoothing
}
}
}
int k = 0;
int sum = 0;
while(k<CLASS)
{
sum += nb.classes[k].class_PB;
k++;
}
//Finding the class PB
k = 0;
while(k<CLASS)
{
nb.classes[k].class_PB /= sum;
k++;
}
return 0;
}
该程序应该用C语言编写,但目前我使用vector从CSV文件中获取数据。请暂时忽略它。实际的问题是如何删除那些硬编码的定义值并仍然声明我的结构。
虽然没关系,但CSV文件看起来像这样,它可能会改变cols和标签。第一行被忽略,不会被放入数据中。
Person,height,weight,foot
male,654,180,12
female,5,100,6
female,55,150,8
female,542,130,7
female,575,150,9
我实际上在做什么,因为每个值被放入一个bin,然后对于每个值,我发现CLASS /标签的可预测性,即male = 0,female = 1
答案 0 :(得分:1)
基本上:
size_t cols; size_t bins;
等。NULL
!)和长度变量替换1维固定大小的数组。或者,您可以使用struct mytype_span { size_t length; mytype* data; }
NULL
)并将维度变量配对。同样,您可以使用结构。a[x][y]
,即a[x * row_length_of_a + y]
(或者你可以在带有相关参数的内联函数中执行此操作,或者{{1} })struct mytype_span
库函数分配正确的空间量;在使用指针值之前,请记得检查malloc()
返回值以确保它不为空!答案 1 :(得分:0)
你对struct的使用可能是错误的,除了struct NB_Class_Map
。你不应该在将大数组放在同一个变量中的目标中使用struct。除此之外,您应该为每个数组定义变量,而不是将其放在结构中,而不是使用数组,而是用指针替换它。然后,您可以为指针分配内存。例如:
struct mydata {
type1 field1;
type2 field2;
etc...
} *myarray;
myarray = calloc(number_of_record_you_need, sizeof(struct mydata));
// here, error checking code, etc.
现在,如果你真的想要,你可以把你的不同指针放到一个全局结构中,但你的每个表都应该单独分配。
编辑(关于你的变量):
NB
作为一种结构并没有真正的兴趣。这只是你粘在一起的两个变量:
struct NB_Class_Map classes[CLASS];
struct each_col cols[COLS];
NB.Cols
实际上不是一个结构。它只是一个三维数组
double cols[COLS][BINS][CLASS];
唯一真正的结构是
struct NB_Class_Map
{
char label[250];
unsigned int label_value;
double class_PB;
};
所以你只需要替换
struct NB_Class_Map classes[CLASS];
与
struct NB_Class_Map *classes;
和
double cols[COLS][BINS][CLASS];
带
double *cols[BINS][CLASS];
或者如果你想要一个类型名称:
typedef double each_col[BINS][CLASS];
each_cols *cols;
并使用classes
为colls
和calloc
分配内存空间。
现在,如果你真的想要这个struct NB
:
typedef double each_col[BINS][CLASS];
struct NB
{
struct NB_Class_Map *classes;
each_col *cols;
};