2010年的一道题,做了2天。。。对文件操作的处理,还是不够熟练。还得多熟悉才行,不然心里没底。
从文本文件里读取训练样本的方法始终没有想出好的解决办法,目前很笨,先读取有多少行,就是说有多少个训练样本,再从头一行一行的读取到数组里。
KNN的描述大致为:
在一个文本文件里,每一行保存一个训练样本,有N_DIM个属性值,用空格分开,最后是一个分类,用“+”或“-”来表示。例如:
1.2 3.2 6.6 +
3.3 5.6 1.9 -
2.7 3.9 5.2 +
。。。
待分类实例也有N_DIM个属性,分别与训练样本计算出距离值SIM,然后选出SIM值最小的前K个训练样本来,以这K个训练样本分类数多的作为待分类实例的分类值。
SIM值是按向量的余弦值来计算,公式为sim=SUM(V1*V2) / [sqrt(V1*V1)*sqrt(V2*V2)]。
在 KNN.h头文件里定义常量和相关读取数据、计算的函数:
#ifndef __HJDSAMPLE_INCLUDE__
#define __HJDSAMPLE_INCLUDE__
#define N_DIM 3 //每行3个属性值
#define N_KNN 3 //取最近的3个训练样本
//定义训练样本的结构
typedef struct SampleStruct
{
double rProperties[N_DIM];
char cType;
double rSim; //距离
} SampleStructType;
//对训练样本数组进行快速排序,以便找到距离最小的前k个训练样本
void SampleStructType_qsort(SampleStructType ar_samples[], int nS, int nE)
{
if(nS<nE)
{
double rKey = ar_samples[nS].rSim;
//printf("\nqsort(%d, %d).\n", nS, nE);
int i=nS, j=nE;
while(i<j)
{
if(ar_samples[j].rSim<rKey)
{
if(ar_samples[i].rSim>rKey)
{
SampleStructType_swap(&ar_samples[i], &ar_samples[j], N_DIM);
j--;
i++;
}
else
{
i++;