Exemple #1
0
        /// <summary>
        /// Parcours un arbre jusqu'à récupérer la catégorie prédite
        /// </summary>
        /// <param name="node">Noeud à évaluer</param>
        /// <param name="data">Tableau à prédire</param>
        /// <returns>Catégorie prédite pour ce tableau</returns>
        protected String getCategoryFromTree(RandomForestNode node, double[] data)
        {
            if (node.category != null)
            {
                return(node.category);
            }
            double f = getCosineSimilarity(data, node.classifier, node.paramThreshold);

            if (f > node.threshold)  // = ?
            {
                return(getCategoryFromTree(node.left, data));
            }
            else
            {
                return(getCategoryFromTree(node.right, data));
            }
        }
Exemple #2
0
        protected void makeLeftAndRightNodes(RandomForestNode node, int[] samplesIndexesInLearning)
        {
            //On sépare l'échantillon en deux
            byte[] indicator = splitSample(node, samplesIndexesInLearning);
            //On récupère l'échantillon séparé dans des tableaux left et right
            int nLeftVectors = 0;

            foreach (byte b in indicator)
            {
                if (b > 0)
                {
                    ++nLeftVectors;
                }
            }
            int[] left  = new int[nLeftVectors];
            int[] right = new int[indicator.Length - nLeftVectors];
            int   cntL  = 0;
            int   cntR  = 0;
            int   cnt   = 0;

            foreach (byte b in indicator)
            {
                if (b > 0)
                {
                    left[cntL++] = samplesIndexesInLearning[cnt];
                }
                else
                {
                    right[cntR++] = samplesIndexesInLearning[cnt];
                }
                ++cnt;
            }
            //On affecte les tableaux au noeud actuel après en avoir fait des noeuds
            node.left  = nodeFactory(left);
            node.right = nodeFactory(right);
            //Si les nouveaux noeuds ne sont pas des feuilles, on leur crée leurs neouds gauche et droite par récursivité
            if (node.left.category == null)
            {
                makeLeftAndRightNodes(node.left, left);
            }
            if (node.right.category == null)
            {
                makeLeftAndRightNodes(node.right, right);
            }
        }
Exemple #3
0
        protected byte[] splitSample(RandomForestNode node, int[] samplesIndexesInLearning)
        {
            byte[] indicator = new byte[samplesIndexesInLearning.Length];
            int    cnt       = 0;

            foreach (int x in samplesIndexesInLearning)
            {
                double f = getCosineSimilarity(this._learning[x], node.classifier, node.paramThreshold);
                indicator[cnt] = (byte)((f >= node.threshold) ? 1 : 0);
                ++cnt;
            }

            bool isAllZeros = true;

            for (int i = 0; i < samplesIndexesInLearning.Length; ++i)
            {
                if (indicator[i] != 0)
                {
                    isAllZeros = false;
                    break;
                }
            }
            if (isAllZeros == true)
            {
                indicator[0] = 1;
            }

            bool isAllOnes = true;

            for (int i = 0; i < samplesIndexesInLearning.Length; ++i)
            {
                if (indicator[i] == 0)
                {
                    isAllOnes = false;
                    break;
                }
            }
            if (isAllOnes == true)
            {
                indicator[0] = 0;
            }

            return(indicator);
        }
Exemple #4
0
        //Calcule le threshold d'un noeud en faisant la moyenne des similarités cosinus min et max
        protected double getThreshold(int[] samplesIndexesInLearning, RandomForestNode n)
        {
            double fmin = 1000.0;
            double fmax = -1.0;

            foreach (int x in samplesIndexesInLearning)
            {
                double f = getCosineSimilarity(this._learning[x], n.classifier, n.paramThreshold);
                if (f < fmin)
                {
                    fmin = f;
                }
                if (f > fmax)
                {
                    fmax = f;
                }
            }
            return((fmax + fmin) / 2.0);
        }
Exemple #5
0
        protected void populateForest(int forestSize, double[,] samples)
        {
            _EventsWorkerCompleted.Clear();
            //On trouve combien de thread créer
            int nbThreads = 8;

            for (int t = 0; t < nbThreads; t++)
            {
                _EventsWorkerCompleted.Add(new System.Threading.AutoResetEvent(false));
                int thread = t;
                Task.Run(() =>
                {
                    int nThread = thread;
                    List <RandomForestNode> trees = new List <RandomForestNode>();
                    for (int i = 0; i < forestSize / nbThreads; i++)
                    {
                        RandomForestNode result = createTree(samples);
                        trees.Add(result);
                        OnTreeCreated(EventArgs.Empty);
                    }
                    lock (_forest)
                        _forest.AddRange(trees);
                    _EventsWorkerCompleted[nThread].Set();
                });
            }
            foreach (var eventWait in _EventsWorkerCompleted)
            {
                eventWait.WaitOne();
            }

            //On ajoute les arbres manquants
            List <RandomForestNode> treesa = new List <RandomForestNode>();
            int manquants = forestSize - this._forest.Count;

            for (int i = 0; i < manquants; i++)
            {
                treesa.Add(createTree(samples));
                OnTreeCreated(EventArgs.Empty);
            }
            lock (_forest)
                _forest.AddRange(treesa);
        }
Exemple #6
0
        protected RandomForestNode nodeFactory(int[] samplesIndexesInLearning)
        {
            //On crée un objet node
            RandomForestNode node = new RandomForestNode();

            //Si il n'y a qu'un echantillon, on est sur une leaf
            if (samplesIndexesInLearning.Length == 1)
            {
                node.category = _learningCategories[(int)samplesIndexesInLearning[0]];
            }
            else //Sinon, on crée la condition
            {
                //On tire les paramètres aléatoires parmis tous les paramètres
                List <int> param = new List <int>();
                param.Clear();
                int cnt = 0;
                do
                {
                    int randomInt;
                    lock (syncLock)
                    {
                        randomInt = this._randomGenerator.Next(_nParameters);
                    }
                    if (!param.Contains(randomInt))
                    {
                        cnt++;
                        param.Add(randomInt);
                    }
                } while (cnt < _numberRandomParameters);
                //Ces paramètres aléatoires serviront à calculer le treshold
                node.paramThreshold = param;
                //On crée le classifier
                node.classifier = makeClassifier(samplesIndexesInLearning);
                //On calcule le threshold
                node.threshold = getThreshold(samplesIndexesInLearning, node);
            }
            return(node);
        }
Exemple #7
0
        protected RandomForestNode createTree(double[,] samples)
        {
            //On récupère les index dans le tableau _learning des _tailleDeSousEchantillonAleatoire échantillons tirés aléatoirement
            int[] randomSamplesIndexesOutOfTraining = this.getRandomSamplesOutOfTrainingSet(_learning.GetLength(0), _tailleDeSousEchantillonAleatoire);
            //On récupère une liste numérotée de 0 à _nParameters
            List <int> param = new List <int>();

            for (int j = 0; j < this._nParameters; j++)
            {
                param.Add(j);
            }
            //On crée un noeud à partir des échantillons aléatoires via la factory
            RandomForestNode node = this.nodeFactory(randomSamplesIndexesOutOfTraining);

            //Si on n'est pas arrivé sur une feuille de l'arbre
            if (node.category == null)
            {
                //On crée les branches droites et gauche du noeud
                this.makeLeftAndRightNodes(node, randomSamplesIndexesOutOfTraining);
            }
            //On retourne le noeud
            return(node);
        }