Примесь Джини, растущие случайные деревья в opencv - PullRequest
1 голос
/ 19 марта 2012

Цель: добавить смещение-примесь к решению о разделении растущих деревьев в openCV.

В настоящее время в случайных деревьях opencv разделение выполняется следующим образом:

if( !priors )
{
    int L = 0, R = n1;

    for( i = 0; i < m; i++ )
        rsum2 += (double)rc[i]*rc[i];

    for( i = 0; i < n1 - 1; i++ )
    {
        int idx = responses[sorted_indices[i]];
        int lv, rv;
        L++; R--;
        lv = lc[idx]; rv = rc[idx];
        lsum2 += lv*2 + 1;
        rsum2 -= rv*2 - 1;
        lc[idx] = lv + 1; rc[idx] = rv - 1;

        if( values[i] + epsilon < values[i+1] )
        {
            double val = (lsum2*R + rsum2*L)/((double)L*R);
            if( best_val < val )
            {
                best_val = val;
                best_i = i;
            }
        }
    }
}

Его использованиепримесь Джини.

enter image description here

Любой, кто может объяснить, как код выполняет это, из того, что я получил: изначально он помещает все классы в правильный узел, и при перемещении одногоНапример, справа налево и обновите lsum2 и rsum2, вы найдете лучшее решение.Что я не понимаю, так это то, как p_j ^ 2 связан с lv * 2 +1 или rv * 2-1.

Реальный вопрос, если есть смещения, и он хотел бы добавить расщепление на основе примесисимуляция смещений.(смещения - это направление и расстояние от центра до текущего узла.

Я придумал что-то вроде этого, и если кто-то может указать на какие-либо недостатки, это было бы хорошо, потому что АТМ не дает хороших результатов.и я не уверен, с чего начать отладку.

    //Compute mean
    for(i = 0; i<n1;++i)
    {
        float* point = (float*)(points.data + rstep*sample_idx_src[sorted_indices[i]]);
        meanx[responses[sorted_indices[i]]] += point[0];
        meany[responses[sorted_indices[i]]] += point[1];
    }
    for(i = 0;i<m;++i)
    {
        meanx[i] /= rc0[i];
        meany[i] /= rc0[i];     
    }

    if(!priors)
    {
        int L = 0, R = n1;

        for(i=0;i<n1;i++)
        {
            float* point = (float*)(points.data + rstep*sample_idx_src[sorted_indices[i]]);
            double tmp = point[0] - meanx[responses[sorted_indices[i]]];
            rsum2 += tmp*tmp;
            tmp = point[1] -meany[responses[sorted_indices[i]]];
            rsum2 += tmp*tmp;


        }

        double minDist = DBL_MAX;

        for(i=0;i<n1;++i)
        {
            float* point = (float*)(points.data + rstep*sample_idx_src[sorted_indices[i]]);
            ++L; --R;
            double tmp = point[0] - meanx[responses[sorted_indices[i]]];
            lsum2 += tmp*tmp;
                tmp = point[1] -meany[responses[sorted_indices[i]]];
            lsum2 += tmp*tmp;
                tmp = point[0] -    meanx[responses[sorted_indices[i]]];
            rsum2 -= tmp*tmp;
                tmp = point[1] -meany[responses[sorted_indices[i]]];
            rsum2 -= tmp*tmp;

            if( values[i] + epsilon < values[i+1] )
            {
                double val = (lsum2 + rsum2)/((double)L*R);

                if(val < minDist )
                {
                    minDist = val;
                    best_val = -val;
                    best_i = i;
                }
            }
        }

1 Ответ

1 голос
/ 30 июля 2015

Хорошо, коэффициент Джини в этом случае прост, потому что есть только две группы, левая и правая. Таким образом, вместо большой суммы 1-sum(pj*pj) мы имеем 1-pl*pl-pr*pr. Доля элементов слева pl - это количество элементов слева lv, деленное на общее количество.

Теперь, когда мы сдвигаем разделение, pl*pl и pr*pr изменяются, но не потому, что изменяется общее количество элементов. Поэтому вместо оптимизации pr и pl (которые являются числами с плавающей запятой) мы оптимизируем lv and rv (которые являются простыми счетчиками).

Далее вопрос почему 2*lv+1. Это просто: мы увеличиваем lv = lv=1 для оптимизации lv*lv. Теперь (lv+1)*(lv+1) - (lv*lv) (увеличение) будет 2*lv+1, если вы напишите все условия. И уменьшение (rv-1)*(rv-1) - (rv*rv) оказывается -2*rv+1 или -(r*rv+1).

...