Monday 29 June 2015

C program to construct tree using Id3 algorithm.

GitHub : https://github.com/ShivamSaluja/ML-ID3

 

Link to golf database.

Steps to run the code :
1] Save the data file with name golf.data .
2] Save the below code in a C file and name it id3.c
3] Save both database and c code in the same folder.
4] Run the code and tree will be printed as output.

C Program for Id3 :

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>


struct node
{
    int data;
    char name[15];
    struct node *next;
};

struct deci_tree
{
    int data;
    int datasetCol;
    double ent;
    int pos;
    int childno;
    int ivalue;
    struct deci_tree *c[50];
}root;


struct node  *createnewnode(struct node *head,char name[15],int d)
{
    struct node *ptr=head,*temp;

    temp=(struct node *)malloc(sizeof(struct node));
    strcpy(temp->name,name);
    temp->data=d;
    temp->next=NULL;
    if(head==NULL)
        head=temp;

    else
    {
        while(ptr->next!=NULL)
        {
            ptr=ptr->next;
        }
        ptr->next=temp;
    }

    return head;
}


int search(struct node *head,char name[15])
{
    struct node *temp=head;
    while(temp!=NULL)
    {
        if(strcmp(temp->name,name)==0)
            return temp->data;
        else
            temp=temp->next;
    }

    if(temp==NULL)
        return 3;
    else
return 0;
}


void display(struct node *head)// function to display the mapping of name and integer
{
    struct node *temp=head;

    if(temp==NULL)
        return;
    while(temp!=NULL)
    {
        printf("%d->%s\n",temp->data,temp->name);
        temp=temp->next;
    }
}


double entropy(int a[500][500],int obj,int attr,int attrpos,int val,struct deci_tree *head1)
{
    int x,k;
    x = a[1][attr-1];
    struct deci_tree *temp;
    temp = head1;
    int i;
    double b,c,d,total= 1.0;
    double count1 = 0,count2 = 0 ;

    if(temp == NULL && attrpos == attr-1)
    {
        for(i=1;i<obj;i++)
        {
            if(a[i][attrpos]==x)
                count1++;
            else
                count2++;
        }
    }

    if(temp==NULL  && attrpos != attr-1)
    {

        for(i=1; i<obj; i++)
        {
            if(a[i][attrpos] == val)
            {
                if(a[i][attr-1] == x)    
                    count1 = count1 + 1;

                else
                    count2 = count2 + 1;
            }
        }
    }
    b = count1/(count1+count2);
    c = count2/(count1+count2);


    if(count1 == 0.000000 || count2 == 0.000000)
        d = 0 ;
    else
        d =  ((count1+count2)/(obj-1)) *(-(b*(log(b)/log(2)) + c*(log(c)/log(2))));

    return d;
}

void findk(int a[500][500], int b[50][50],int obj,int attr){

    int i,j,k,count = 1;
    int flag  =0 ;

 
    for(k = 0; k < attr;k++)
    {
        b[k][1] = a[1][k];
        i = 1;
        while(i < obj){
            for(j = 1 ; j < count; j++){
                if(a[i][k] == b[k][j])
                {
                    flag = 1;  
                }
            }
            if(flag  == 0 ){
                b[k][count] = a[i][k];
                count++;
            }
            flag =0;
            i++;

        }
        b[k][0] = count-1;

        count = 1;
    }
}  


int findmax(double *gain1 , int attr){

    int i = 0 ;
    int max1 = 0 ;
    double max;
    max = gain1[0];
    for(i = 1; i <= attr; i++ ){
        if(gain1[i] > max){
            max1 = i;
            max = gain1[i];
        }
    }
    return max1;
}


double findsum(double col1[50],int len){

    int i,j;
    double sum =0;  
    for(i = 0;i < len ;i ++){
        sum =sum +col1[i];
    }      
    return sum;
}


int* funcModiA(int a[500][500],int modifiedA[500][500],int max1,int attr,int obj,int val,int dim[2]){

    int i,j,k;  
    int row = 0,col =0,temp=0,col2=0;
 
    for(j = 0 ; j < obj ; j++){
        if(j == 0 ){
            for(k =0 ; k < attr ; ){
                if(k == max1 ){
                    k++;
                }
                else{
                    modifiedA[row][col2] = a[j][k];
                    k++;
                    col2++;
                }  
            }
            row++;
        }
        else{
            if(a[j][max1] == val){
                for(i = 0 ; i < attr ;){
                    if(i == max1){
                        i++;
                    }  
                    else {              
                        modifiedA[row][col] = a[j][i];
                        temp = col++;
                        i++;
                    }
                }  
                col = 0;      
                row++;
            }
        }      
    }
    dim[0] = row;
    dim[1] = attr-1;  
    return dim;
}

struct deci_tree* infoGainRecursive(int Z[500][500],int b[50][50],struct deci_tree * parent,double entr,int max1,int attr,int obj,int flag,int initattr,int a[500][500]){

    int i =0 ;
    int j;
    int modifiedA[500][500],modifiedB[50][50];
    double col3[50],col1[50],entr1[50],entropy1[50][50],gain1[50];
    int dim[2];
    if(flag == 1){
        flag = 0;
        parent->ent = entr;
        parent->data = 0;
        for(i = 0 ; i  < attr ;i++){
            for(j = 0 ; j <  obj;j++){
                modifiedA[j][i] = Z[j][i];
            }
        }          
        findk(modifiedA,modifiedB,obj,attr);

 
    }
 
    else{

          for(i = 0 ; i  < attr ;i++){

            for(j = 0 ; j <  obj;j++){
                modifiedA[j][i] = Z[j][i];

            }
        }

        funcModiA(modifiedA,modifiedA,max1,attr,obj,parent->pos,dim);
        obj = dim[0];
        attr = dim[1];
        parent->ent = entropy(modifiedA,obj,attr,i,modifiedB[i][j],NULL);
        if(parent->ent == 0 ){
             int sd =  parent->data ;
             parent->data = modifiedA[1][attr-1];
             parent->datasetCol = attr-1;
             parent->childno = 0;      
             printf("\n\tnode %d is terminated with row value %d ,  child of %d i posotion value %d\n",parent->data , parent->pos ,sd,parent->ivalue);
             return 0;
        }
        else{
            findk(modifiedA,modifiedB,obj,attr);      
        }  
    }

    for(i= 0; i < attr-1 ; i++){
        for(j= 1 ; j <= modifiedB[i][0]; j++){  
            col3[j-1] = entropy(modifiedA,obj,attr,i,modifiedB[i][j],NULL);
     
        }
        entr1[i] =  findsum(col3,modifiedB[i][0]);
        gain1[i] =  parent->ent  - entr1[i];
    }

    int temp = max1;
    max1 = findmax(gain1,attr-1);
    parent->data = modifiedA[0][max1];
    parent->childno = modifiedB[max1][0];

    for(i = 0; i <= initattr;i++){
        if(parent->data    == a[0][i]){
            parent->datasetCol = i;
            break;
        }  
    }

    printf("\n\tCurrent node is %d and is child of %d , through  row value %d,i position %d coloum number %d \n", parent->data,Z[0][temp],parent->pos,parent->ivalue,parent->datasetCol);
 
    for(i = 1; i <= modifiedB[max1][0] ;i++) {
        parent->c[i] = (struct deci_tree *)malloc(sizeof(struct deci_tree ));  
        parent->c[i]->pos = modifiedB[max1][i];        
        parent->c[i]->data = modifiedA[0][max1];
        parent->c[i]->ent = parent->ent;
        parent->c[i]->ivalue = i;
        infoGainRecursive(modifiedA,modifiedB,parent->c[i],parent->c[i]->ent,max1,attr,obj,flag,initattr,a);
    }

    return parent;
}

int* get_test_value(int a[500][500],int attr,int obj){
 
    int i,j,flag = 0,*class,temp,counter=1;
    temp = a[1][attr-1];
    class = (int *)malloc(obj*sizeof(int));

    class[1] = temp;

    for(i = 2; i <= obj; i++ ){
        for(j = 1; j <= counter ; j++){
               if(a[i][attr-1] == class[j] ){
                    flag = 1;
                    break;
               }
        }
        if(flag == 0){
            counter++;
            class[counter] = a[i][attr-1];              
        }
        flag = 0;
    }

    class[0]=counter;
        printf("\n");
    return class;
}

int classification(int a[500][500],struct deci_tree *head,int test_data_pos,int *test_value){

    int temp,store,flag=0,class,i;
     
    struct deci_tree *ptr;
    ptr = head;
                                 
    while(flag != 1){  
        temp = a[test_data_pos][ptr->datasetCol];
        for(i =1 ; i <= ptr->childno;i++ ){
                if(ptr->c[i]->pos == temp){
                    ptr = ptr->c[i];

              }  
            }
             for(i = 1; i <= test_value[0] ; i++){
                 if(test_value[i] == ptr->data){
                    class = test_value[i];
                    flag = 1;
                 }                        
                }
    }
    return class;
}


int main(){

    struct node *first = NULL;
    struct deci_tree *head = NULL,*parent = NULL,*temphead = NULL;

    int i,j,k,t;      
    int a[500][500],obj,attr,x,*d,training,test, *test_value,class;
     
    double r,database,error=0,accuracy=0,total;

    FILE *fp;

    char *tok;  
    const char s[2]=",";

    char buff[200];

    fp=fopen("golf.data","r");

    k=4;i=0;

    while(fgets(buff,200,fp)!=NULL)
    {
        j=0;
        tok=strtok(buff,s);
        while(tok != NULL)
        {
            t=search(first,tok);
            if(t!=3)
            {
                a[i][j]=t;
                j++;
            }    
            if(t==3)// this value is understood if it is checked in search method
            {
                first= createnewnode(first,tok,k);
                a[i][j]=k;
                j++;
                k++;
            }
            tok=strtok(NULL,s);
        }

        i++;
        attr=j;
    }
    obj=i;
    display(first);

    fclose(fp);

    d = (int *)malloc(attr * sizeof(int));
    for(k = 0 ; k < attr ; k++){
        d[k] = k;
    }
    for(i=0;i<obj;i++)
    {
        printf("\n");
        for(j=0;j<attr;j++)
        {
            printf("%d\t", a[i][j]);
        }
    }

        training =obj*75/100;
        test=training;
    printf("\nTraining Data\n");
    for(i=0;i<training;i++)
    {
        printf("\n");
        for(j=0;j<attr;j++)
        {
            printf("%d\t", a[i][j]);
        }
    }
        printf("\nTest Data");
    for(i=test;i<obj;i++){
        printf("\n");
        for(j=0;j<attr;j++){
                printf("%d\t",a[i][j]);
        }
    }  


    database =  entropy(a , training,attr, attr-1,0,NULL);
    int flag = 1;
     
    parent =(struct deci_tree *)malloc(sizeof(struct deci_tree));

    head = infoGainRecursive(a,NULL,parent,database,attr,attr,training,flag,attr,a);
    return 0;
}

Sunday 28 June 2015

Golf Database used for ID3

outlook,temperature,humidity,wind,e_tennis
sunny, 85, 85, false, Don't Play
sunny, 80, 90, true, Don't Play
overcast, 83, 78, false, Play
rain, 70, 96, false, Play
rain, 68, 80, false, Play
rain, 65, 70, true, Don't Play
overcast, 64, 65, true, Play
sunny, 72, 95, false, Don't Play
sunny, 69, 70, false, Play
rain, 75, 80, false, Play
sunny, 75, 70, true, Play
overcast, 72, 90, true, Play
overcast, 81, 75, false, Play
rain, 71, 80, true, Don't Play

Monday 26 January 2015

C Program to find all Relative Prime Numbers toa given number.(less than that number)

#include<stdio.h>

void main(){
        int p,i,j;
        int remainder = 2;
        int divident,divisor;

        printf("Enter Number\n");
        scanf("%d",&p);

        for(i = 2 ; i < p ; i++){

                divident  = p;
                divisor = i;

                while(divisor != 0){

                        remainder = divident % divisor;
                        divident  = divisor;
                        divisor  = remainder;
                }
       
                if(divident  == 1){
                        printf("Relatively Prime Number is : %d \n" ,i);
                }
        }

}

A C program to perform 3 binary Set Operations i.e Union , Intersection and Set Differance.

#include<stdio.h>
#include<stdlib.h>

int  insert(int *A, int a,int size){       
    int flag = 0;
    int i;

    for(i = 0; i <= size ; i++){
        if(A[i] == a){
            flag = 1;
            printf("Dulicate not allowed in Set\n");
        }   
    }
   
    if(flag == 0){
        A[size] = a;
        return 1;
    }
    else
        return 0;
}

void  intersection(int *A,int *B,int sizeA,int sizeB){   
    int ni,i,j;
    int sizei=0;
    if(sizeA < sizeB)
        ni = sizeA;
    else   
        ni = sizeB;
    int itr = 0;
    int *intsec = malloc(ni * sizeof(int));
    for(i = 0;i < sizeA;i++){
        for(j = 0;j < sizeB;j++){
            if(A[i] == B[j]){
                intsec[sizei] = A[i];
                sizei++;   
                    continue;           
            }
            itr++;
        }
    }

    printf("\nIntersection Result is\n");
    for(i = 0; i < sizei ; i++)   
        printf("%d \n",intsec[i]);
   
}

void setdifferance(int *A,int *B,int sizeA,int sizeB,int ch){
    int i ,j,ni;
    int flag =0;
    int k = 0;

    if(sizeA > sizeB)
                ni = sizeA;
        else
                ni = sizeB;

    int *setdiff = malloc(ni * sizeof(int));   

    if(ch == 1) {
      for(i = 0 ; i < sizeA ; i++){
        for(j = 0 ; j < sizeB; j++){
            if(A[i] == B[j]){
                flag = 1;
            }   
        }           
        if(flag == 0){
            setdiff[k] = A[i];
            k++;
        }
        flag = 0;   
       }
    }
    if(ch == 2){
      for(i = 0 ; i < sizeB ; i++){
                for(j = 0 ; j < sizeA ; j++){
                        if(B[i] == A[j]){
                                flag = 1;
                        }
        }
               if(flag == 0){
                      setdiff[k] = B[i];
                      k++;
               }
               flag = 0;
      }
    }

    printf("\nSet Differance Result is\n");
   
    if(k == 0)
        printf("NULL\n");
       
        for(i = 0; i < k ; i++)
                printf("%d \n",setdiff[i]);
}

void unionOp(int *A,int *B,int sizeA, int sizeB){
    int size = sizeA + sizeB;
    int *uni = malloc(size * sizeof(int));
    int i,j;
    int k=0;
    int flag =0;
    for(i = 0 ; i < sizeA; i++){
        uni[i] = A[i];   
    }
        for(j = 0 ; j < sizeB ; j++){
        for(i = 0 ; i < sizeA ; i++){
            if(B[j] == A[i]){
                flag =1;
            }
        }
        if(flag == 0){
            k++;
            uni[sizeA+k-1] = B[j];
        }
        flag = 0;
    }

   
    printf("\nUnion Result is\n");
       
    for(i = 0; i < sizeA+k ; i++)
                printf("%d \n",uni[i]);
          
}

void main(){
    int na,nb,a,b,sizeA,sizeB,flag,diffch;
    int ch=1;
    //struct set *s, *B;
    sizeA = 0;
    sizeB = 0;
    printf("Enter number of elements of set 1\n");
    scanf("%d",&na);
    int *A = malloc(na * sizeof(int));
    int *B = malloc(nb * sizeof(int));
    while(sizeA < na){
        printf("\nInsert elements in set 1\n");
        scanf("%d",&a);
        sizeA +=  insert(A,a,sizeA);
    }
   
    printf("\nEnter number of elements of set 2\n");
        scanf("%d",&nb);

    while(sizeB < nb){
        printf("Insert elements in set 2\n");   
        scanf("%d",&b);
        sizeB += insert(B,b,sizeB);
    }

    while(ch){
    printf("\nPress 1 for intersection\n"
        "Press 2 for union\n"
        "Press 3 for set differance\n"
        "Press 0 for exit \n");

    scanf("%d",&ch);

    switch(ch){
        case 1:
            intersection(A,B,sizeA,sizeB);
            break;
        case 2:
            unionOp(A,B,sizeA,sizeB);
            break;       
        case 3:
            printf("\nFor (Set 1 - set2) press 1 "
                "Else press 2\n");
            scanf("%d",&diffch);
            setdifferance(A,B,sizeA,sizeB,diffch);
            break;
        case 0:
            printf("Good-Bye\n");
            break;   
        default:
            printf("Invalid Input\n");   
        }
    }
}