keymasterviriya1150

ID3

Apr 19th, 2016
140
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.27 KB | None | 0 0
  1. using namespace std;
  2. #include <iostream>
  3. #include <string>
  4. #include <fstream>
  5. #include <vector>
  6. #include <cmath>
  7. #include <time.h>
  8.  
  9. #define ROWS 1000000
  10. #define COLUMNS 6
  11.  
  12. class Atrib {
  13.     public:
  14.         int count;
  15.         string nome;
  16.  
  17.         Atrib() {
  18.             count = 0;
  19.         }
  20. };
  21.  
  22. class ColecaoAtrib {
  23.     public:
  24.         vector<Atrib> atribs;
  25.  
  26.         ColecaoAtrib () {
  27.         }
  28.  
  29.         int searchAtrib (string nome) {
  30.             for(int i=0; i<(atribs.size()); i++) {
  31.                 if (atribs[i].nome.compare(nome) == 0) return i;
  32.             }
  33.             return -1;
  34.         }
  35.  
  36.         void processaAtrib (string nome) {
  37.             int pos = searchAtrib(nome);
  38.             if (pos == -1) {
  39.                 atribs.resize(((int) atribs.size())+1);
  40.                 atribs[((int) atribs.size()) - 1].nome = nome;
  41.                 atribs[((int) atribs.size()) - 1].count++;
  42.                 //cout << atribs[((int) atribs.size()) - 1].count << '\n';
  43.             } else {
  44.                 atribs[pos].count++;
  45.                 //cout << atribs[pos].count << '\n';
  46.             }
  47.         }
  48. };
  49.  
  50.  
  51. class Decisao {
  52.     public:
  53.         vector<vector<string> > matriz;
  54.         vector<ColecaoAtrib> colecaoAtribs;
  55.         double entropia;
  56.         int rows;
  57.         int columns;
  58.  
  59.         Decisao () {
  60.             colecaoAtribs.resize(COLUMNS);
  61.         }
  62.  
  63.         Decisao (int numCols) {
  64.             colecaoAtribs.resize(numCols);
  65.             columns = colecaoAtribs.size();
  66.         }
  67.  
  68.         void imprimeDecisao () {
  69.             for(int i=0; i<matriz.size(); i++) {
  70.                 for(int j=0; j<matriz[i].size(); j++) {
  71.                      cout << matriz[i][j] << '|';
  72.                 }
  73.                 cout << '\n';
  74.             }
  75.         }
  76.  
  77.         Decisao retiraAtributo (int col, string nome, int count) {
  78.             Decisao novaDecisao (colecaoAtribs.size()-1);
  79.             novaDecisao.matriz.resize(count);
  80.             novaDecisao.rows = count;
  81.             for (int i=0; i<novaDecisao.rows; i++) {
  82.                 novaDecisao.matriz[i].resize(novaDecisao.colecaoAtribs.size());
  83.             }
  84.             novaDecisao.columns = novaDecisao.colecaoAtribs.size();
  85.  
  86.             //cout << nome << " " << count << " " << novaDecisao.columns <<  '\n';
  87.  
  88.             int tempi = 0;
  89.             for (int i=0; i<this->rows; i++) {
  90.                 int oldj = 0;
  91.                 if (matriz[i][col] == nome) {
  92.                     for (int j=0; j<novaDecisao.columns; j++) {
  93.                         if (j == col) oldj++;
  94.                         novaDecisao.matriz[tempi][j] = matriz[i][oldj];
  95.  
  96.                         oldj++;
  97.                     }
  98.                     tempi++;
  99.                 }
  100.             }
  101.  
  102.             return novaDecisao;
  103.         }
  104.  
  105.  
  106.         void montaDeArquivo (string arquivo) {
  107.             matriz.resize(ROWS);
  108.             for (int i=0; i<ROWS; ++i)
  109.                 matriz[i].resize(COLUMNS);
  110.             rows = ROWS;
  111.             columns = COLUMNS;
  112.  
  113.             fstream myfile ("entrada.txt");
  114.  
  115.             for(int i=0; i<ROWS; i++) {
  116.                 string line;
  117.                 getline(myfile, line);
  118.  
  119.                 int aux1 = 0;
  120.                 int aux2 = line.find(',', aux1);
  121.  
  122.                 for(int j=0; j<COLUMNS; j++) {
  123.                     matriz[i][j] = line.substr(aux1, aux2-aux1);
  124.                     aux1 = aux2+1;
  125.                     aux2 = line.find(',', aux1);
  126.                 }
  127.             }
  128.         }
  129.  
  130.         void contaProb () {
  131.             for (int i=0; i<this->columns; i++) {
  132.                 for (int j=0; j<this->rows; j++) {
  133.                     //cout << "Processando " << matriz[j][i] << ": ";
  134.                     colecaoAtribs[i].processaAtrib(matriz[j][i]);                    
  135.                 }
  136.             }
  137.         }
  138.  
  139.         void calculaEntropiaGeral () {
  140.             contaProb();
  141.             double entropiaPar = 0;
  142.             //cout << "teste " << colecaoAtribs[colecaoAtribs.size()-1].atribs.size() << '\n';
  143.             for (int i=0; i<colecaoAtribs[colecaoAtribs.size()-1].atribs.size(); i++) {
  144.                 Atrib * tempAtrib = &colecaoAtribs[colecaoAtribs.size()-1].atribs[i];
  145.                 double quociente = (double) (tempAtrib->count)/matriz.size();
  146.                 entropiaPar += -((quociente)*(log2(quociente)));
  147.             }
  148.             //cout << "Entropia geral :" << entropiaPar << '\n';
  149.             this->entropia = entropiaPar;
  150.         }
  151.  
  152.         double calculaGanhoColuna (int col) {
  153.             double ganho = this->entropia;
  154.             for (int i=0; i<colecaoAtribs[col].atribs.size(); i++) {
  155.                 Decisao decisaoPar(this->colecaoAtribs.size());
  156.                 Atrib * tempAtrib = &colecaoAtribs[col].atribs[i];
  157.                 //cout << "Tratando: " << tempAtrib->nome << '\n';
  158.                 decisaoPar.matriz.resize(tempAtrib->count);
  159.                 decisaoPar.rows = tempAtrib->count;
  160.                 for (int j = 0; j < tempAtrib->count; ++j) {
  161.                     decisaoPar.matriz[j].resize(this->columns);
  162.                 }
  163.                 decisaoPar.columns = this->columns;
  164.                 int aux = 0;
  165.                 for (int j=0; j<this->rows; j++) {
  166.                     if(this->matriz[j][col] == tempAtrib->nome) {
  167.                         decisaoPar.matriz[aux++] = this->matriz[j];
  168.                     }
  169.                 }
  170.                 //decisaoPar.imprimeDecisao();
  171.                 decisaoPar.calculaEntropiaGeral();
  172.                 //cout.precision(3);
  173.                 //cout << fixed << decisao.entropia << '\n';
  174.                 //cout << "Porcentagem: " << fixed << (double) tempAtrib->count/matriz.size() << " " << decisaoPar.entropia <<'\n';
  175.                 ganho -= ((double)tempAtrib->count/matriz.size())*(decisaoPar.entropia);
  176.             }
  177.             //cout << ganho << '\n';
  178.             return ganho;
  179.         }
  180.  
  181. };
  182.  
  183. typedef struct No * Apontador;
  184.  
  185. class No {
  186.     public:
  187.         Decisao decisao;
  188.         vector<Apontador> apontadores;
  189.  
  190.         No () {
  191.             decisao;
  192.         }
  193.  
  194.         No * id3 () {
  195.             //cout << "comecei!\n";
  196.             if (this->decisao.columns == 1) {
  197.                 cout << this->decisao.matriz[0][0] << '\n';
  198.                 return NULL;
  199.             }
  200.             decisao.calculaEntropiaGeral();
  201.             int colParcial = 0;
  202.             double ganhoParcial = 0;
  203.             for (int i=0; i<((decisao.matriz[0].size())-1); i++) {
  204.                 double ganho = decisao.calculaGanhoColuna(i);
  205.                 if (ganho > ganhoParcial) {
  206.                     colParcial = i;
  207.                     ganhoParcial = ganho;
  208.                 }
  209.             }
  210.             //cout.precision(3);
  211.             //cout << fixed << colParcial << " " << ganhoParcial << '\n';
  212.  
  213.             ColecaoAtrib * colecao = &decisao.colecaoAtribs[colParcial];
  214.             apontadores.resize(colecao->atribs.size());
  215.             //cout << colecao->atribs.size() << "\n";
  216.             for (int i=0; i<apontadores.size(); i++) {
  217.                 No no;
  218.                 no.decisao = decisao.retiraAtributo(colParcial, colecao->atribs[i].nome, colecao->atribs[i].count);
  219.                 //no.decisao.imprimeDecisao();
  220.                 apontadores[i] = new No;
  221.                 //apontadores[i] = &no;
  222.                 apontadores[i] = no.id3();
  223.                 //(*apontadores[i]).decisao.imprimeDecisao();
  224.                 //else return (*apontadores[i]).id3();
  225.                 //cout << "------------------------\n";
  226.             }
  227.             return this;
  228.         }
  229. };
  230.  
  231. class Arvore {
  232.     public:
  233.         Apontador raiz;
  234.         int profundidade;
  235.  
  236.         Arvore (int rows, int columns, string arquivo) {
  237.             No raizArvore;
  238.             raizArvore.decisao.montaDeArquivo(arquivo);
  239.             //raizArvore.decisao.imprimeDecisao();
  240.             raiz = new No;
  241.             raiz = raizArvore.id3();
  242.             profundidade = 0;
  243.         }
  244. };
  245.  
  246.  
  247. int main() {
  248.     clock_t start, end;
  249.     start = clock();
  250.     Arvore arvore(ROWS, COLUMNS, "entrada.txt");
  251.     //arvore.raiz->id3();
  252.     end = clock();
  253.     cout << "Time required for execution: "
  254.     << (double)(end-start)/CLOCKS_PER_SEC
  255.     << " seconds." << "\n";
  256. }
  257. //http://scriptslines.com/blog/example-generate-decision-tree-by-id3/
Advertisement
Add Comment
Please, Sign In to add comment