Пример #1
0
        /// <summary>
        /// Создает массив атрибутов, на основе которых и будем строить дерево решений
        /// </summary>
        ///  <param name="samples">Таблица c измерениями</param>
        ///  <param name="counOfParameter">ключ первого параметра</param>
        /// <param name="parametersCount">Количество параметров учавствующих в анализе</param>
        /// <param name="curveCount">Количество дуг,задаваемые пользователем</param>
        /// <returns>Массив атрибутов</returns>
        private Attribute[] CreateAttribute(List <OneRow> samples, int parametersCount, Dictionary <int, string> parameterNames, int curveCount, int defectParameter)
        {
            Attribute[] attributes = new Attribute[parametersCount];
            int         i          = 0;

            foreach (KeyValuePair <int, string> parameterName in parameterNames)
            {
                TupleList <decimal, decimal> bordersValue = Borders.AddBordersValue(parameterName.Key, samples, parametersCount, curveCount, defectParameter);
                attributes[i] = new Attribute(parameterName.Key, bordersValue);
                i++;
            }
            return(attributes);
        }
Пример #2
0
        /// <summary>
        /// Создает массив атрибутов, на основе которых и будем строить дерево решений
        /// </summary>
        ///  <param name="samples">Таблица c измерениями</param>
        ///  <param name="counOfParameter">ключ первого параметра</param>
        /// <param name="parametersCount">Количество параметров учавствующих в анализе</param>
        /// <param name="curveCount">Количество дуг,задаваемые пользователем</param>
        /// <returns>Массив атрибутов</returns>
        private Attribute[] CreateAttribute(List <OneRow> samples, int parametersCount, int curveCount, int defectParameter)
        {
            Attribute[] attributes = new Attribute[samples[0].Input.Count];
            int         i          = 0;

            foreach (var item in samples[0].Input)
            {
                TupleList <decimal, decimal> bordersValue = Borders.AddBordersValue(item.Key, samples, parametersCount, curveCount, defectParameter);
                attributes[i] = new Attribute(item.Key, bordersValue);
                i++;
            }
            return(attributes);
        }
Пример #3
0
        /// <summary>
        /// Упрощает массив пороговых значений
        /// </summary>
        /// /// <param name="border">Весь список пороговых значений</param>
        /// /// <returns>массив пороговых значений </returns>
        private static TupleList <decimal, decimal> ChangeBorder(List <decimal> border, int parameterNumber)
        {
            double accurateStep = SearchStep(border.Count, parameterNumber);
            var    borderValues = new TupleList <decimal, decimal>();
            double sumOfValue   = 0;

            for (int i = 0; i < parameterNumber - 1; i++)
            {
                if (i == parameterNumber - 2)
                {
                    borderValues.Add(border[(int)sumOfValue], border[border.Count - 1]);
                    sumOfValue += accurateStep;
                }
                else
                {
                    borderValues.Add(border[(int)sumOfValue], border[(int)(sumOfValue + accurateStep)]);
                    sumOfValue += accurateStep;
                }
            }
            return(borderValues);
        }
Пример #4
0
        /// <summary>
        /// Этот метод является основным в построении дерева решений
        /// </summary>
        /// <param name="samples">Строит дерево решений на основе предоставленных измерений</param>
        /// <param Name="attributes"> Список атрибутов на основе которых мы строим дерево</param>
        /// <returns>Узел  дерева </returns></returns?>
        private TreeNode IMountTree(List <OneRow> samples, Attribute[] attributes, Dictionary <int, string> parameterName, int defectParameterID, int curveCount, int depth)
        {
            if (AllSamplesPositives(samples, defectParameterID))
            {
                return(new TreeNode(new Attribute(true), parameterName, samples.Count, 0, depth));
            }

            if (AllSamplesNegatives(samples, defectParameterID))
            {
                return(new TreeNode(new Attribute(false), parameterName, 0, samples.Count, depth));
            }

            mTotal          = samples.Count;
            mTotalPositives = CountTotalPositives(samples, defectParameterID);
            mEntropySet     = Entropy.Calculate(mTotalPositives, mTotal - mTotalPositives);

            Entropy   entropy       = new Entropy(samples, attributes, mTotal, mEntropySet, defectParameterID);
            Attribute bestAttribute = entropy.GetBestAttribute();

            //Attribute bestAttribute = GetBestAttribute(samples, attributes);
            if (bestAttribute == null)
            {
                double percent = (double)mTotalPositives / (double)mTotal;
                if (percent > 0.5)
                {
                    return(new TreeNode(new Attribute(true), parameterName, mTotalPositives, mTotal - mTotalPositives, depth));
                }
                return(new TreeNode(new Attribute(false), parameterName, mTotalPositives, mTotal - mTotalPositives, depth));
            }

            TreeNode root = new TreeNode(bestAttribute, parameterName, mTotalPositives, mTotal - mTotalPositives, depth);

            for (int i = 0; i < bestAttribute.values.Count; i++)
            {
                int           newDepth = depth + 1;
                List <OneRow> aSample  = new List <OneRow>();

                //Выбирает все элементы с отрезком значений этого атрибута
                var query = samples.Where(measurement => (measurement.Input[bestAttribute.AttributeName] >= bestAttribute.values[i].Item1 && measurement.Input[bestAttribute.AttributeName] <= bestAttribute.values[i].Item2));
                foreach (var item in query)
                {
                    aSample.Add(item);
                }
                //Выбирает все элементы с отрезком значений этого атрибута


                //Создает новый список атрибутов, убирая из этого списка лучший атрибут
                List <Attribute> aAttributes = new List <Attribute>(attributes.Length - 1);
                for (int j = 0; j < attributes.Length; j++)
                {
                    if (attributes[j].AttributeName != bestAttribute.AttributeName)
                    {
                        //редактирует пороговые значения атрибута
                        TupleList <decimal, decimal> bordersValue = Borders.AddBordersValue(attributes[j].AttributeName, aSample, aAttributes.Capacity, curveCount, defectParameterID);
                        Attribute att = new Attribute(attributes[j].AttributeName, bordersValue);
                        aAttributes.Add(att);
                        //редактирует пороговые значения атрибута
                    }
                }
                //Создает новый список атрибутов, убирая из этого списка лучший атрибут

                RandomForest c45       = new RandomForest();
                TreeNode     ChildNode = c45.IMountTree(aSample, (Attribute[])aAttributes.ToArray(), parameterName, defectParameterID, curveCount, newDepth);
                root.AddTreeNode(ChildNode, bestAttribute.values[i]);
            }
            return(root);
        }
Пример #5
0
 public void ChangeValue(TupleList <decimal, decimal> value)
 {
     mValues = value;
 }
Пример #6
0
 /// <summary>
 /// Инициализация нового класса атрибут
 /// </summary>
 /// <param name="label"> может принимать два значения true или false</param>
 public Attribute(object Label)
 {
     mLabel  = Label;
     mName   = -1;
     mValues = null;
 }
Пример #7
0
 /// <summary>
 /// Инициализация нового класса атрибут
 /// </summary>
 /// <param name="name">Указывает имя атрибута</param>
 /// <param name="values">Указывает пороговые значения этого атрибута</param>
 public Attribute(int name, TupleList <decimal, decimal> values)
 {
     mName   = name;
     mValues = values;
     mValues.Sort();
 }
Пример #8
0
 public Attribute(SerializationInfo sInfo, StreamingContext contextArg)
 {
     this.mLabel  = (object)sInfo.GetValue("mLabel", typeof(object));
     this.mName   = (int)sInfo.GetValue("mName", typeof(int));
     this.mValues = (TupleList <decimal, decimal>)sInfo.GetValue("MValues", typeof(TupleList <decimal, decimal>));
 }
Пример #9
0
        /// <summary>
        /// Создает массив пороговых значений
        /// </summary>
        /// <param name="key">ключ атрибута у которого строятся пороговые значения</param>
        /// <param name="samples">Таблица с измерениями</param>
        /// <returns>Массив пороговых значений </returns>
        public static TupleList <decimal, decimal> AddBordersValue(int key, List <OneRow> samples, int parametersCount, int curveCount, int keyOutput)
        {
            //TODO: переделать критерий разбиений. Разбиение должно быть более осмысленное.
            TupleList <decimal, decimal> groceryList       = new TupleList <decimal, decimal>();
            Dictionary <decimal, int>    borderValuesTrue  = new Dictionary <decimal, int>();
            Dictionary <decimal, int>    borderValuesFalse = new Dictionary <decimal, int>();
            //Создается множество уникальных значений
            Dictionary <decimal, int> borderValues = new Dictionary <decimal, int>();

            for (int i = 0; i < samples.Count; i++)
            {
                decimal valueParameter = samples[i].Input.First(paramater => paramater.Key == key).Value;
                if (samples[i].OutputBool[keyOutput])
                {
                    if (borderValuesTrue.ContainsKey(valueParameter))
                    {
                        borderValuesTrue[valueParameter] += 1;
                    }
                    else
                    {
                        borderValuesTrue.Add(valueParameter, 1);
                    }
                }
                if (!samples[i].OutputBool[keyOutput])
                {
                    if (borderValuesFalse.ContainsKey(valueParameter))
                    {
                        borderValuesFalse[valueParameter] += 1;
                    }
                    else
                    {
                        borderValuesFalse.Add(valueParameter, 1);
                    }
                }

                if (borderValues.ContainsKey(valueParameter))
                {
                    borderValues[valueParameter] += 1;
                }
                else
                {
                    borderValues.Add(valueParameter, 1);
                }
            }
            List <decimal> bordersValuesTrueList  = borderValuesTrue.Keys.ToList();
            List <decimal> bordersValuesFalseList = borderValuesFalse.Keys.ToList();

            bordersValuesTrueList.Sort();
            bordersValuesFalseList.Sort();
            List <decimal> newWaveBorderValues = new List <decimal>();
            //создается множество уникальных значений
            int indexTrue  = 0;
            int indexFalse = 0;
            int automation = 0;

            indexTrue = ReworkBorderValues(bordersValuesTrueList, indexTrue, bordersValuesFalseList, newWaveBorderValues, ref indexFalse, ref automation);
            bool end = true;

            while (end)
            {
                if ((indexTrue == bordersValuesTrueList.Count) && (indexFalse == bordersValuesFalseList.Count))
                {
                    break;
                }

                if (indexTrue == bordersValuesTrueList.Count)
                {
                    if (indexFalse == bordersValuesFalseList.Count - 1)
                    {
                        newWaveBorderValues.Add(bordersValuesFalseList[bordersValuesFalseList.Count - 1]);
                        break;
                    }
                    newWaveBorderValues.Add(bordersValuesFalseList[indexFalse]);
                    newWaveBorderValues.Add(bordersValuesFalseList[bordersValuesFalseList.Count - 1]);
                    break;
                }
                if (indexFalse == bordersValuesFalseList.Count)
                {
                    if (indexTrue == bordersValuesTrueList.Count - 1)
                    {
                        newWaveBorderValues.Add(bordersValuesTrueList[bordersValuesTrueList.Count - 1]);
                        break;
                    }
                    newWaveBorderValues.Add(bordersValuesTrueList[indexTrue]);
                    newWaveBorderValues.Add(bordersValuesTrueList[bordersValuesTrueList.Count - 1]);
                    break;
                }
                decimal trueNumber  = bordersValuesTrueList[indexTrue];
                decimal falseNumber = bordersValuesFalseList[indexFalse];
                switch (automation)
                {
                case 0:    //Case когда на прошлом этапе мы выбрали False элемент
                    if (falseNumber < trueNumber)
                    {
                        indexFalse++;
                    }
                    else if (falseNumber > trueNumber)
                    {
                        newWaveBorderValues.Add(trueNumber);
                        indexTrue++;
                        automation = 1;
                    }
                    else if (falseNumber == trueNumber)
                    {
                        newWaveBorderValues.Add(falseNumber);
                        indexTrue++;
                        indexFalse++;
                        automation = 2;
                    }
                    break;

                case 1:
                    if (falseNumber > trueNumber)
                    {
                        indexTrue++;
                    }
                    else if (falseNumber < trueNumber)
                    {
                        newWaveBorderValues.Add(falseNumber);
                        indexFalse++;
                        automation = 0;
                    }
                    else if (falseNumber == trueNumber)
                    {
                        newWaveBorderValues.Add(falseNumber);
                        indexTrue++;
                        indexFalse++;
                        automation = 2;
                    }
                    break;

                case 2:
                    if (falseNumber > trueNumber)
                    {
                        newWaveBorderValues.Add(trueNumber);
                        indexTrue++;
                        automation = 1;
                    }
                    else if (falseNumber < trueNumber)
                    {
                        newWaveBorderValues.Add(falseNumber);
                        indexFalse++;
                        automation = 0;
                    }
                    else if (falseNumber == trueNumber)
                    {
                        newWaveBorderValues.Add(trueNumber);
                        indexTrue++;
                        indexFalse++;
                        automation = 2;
                    }
                    break;
                }
            }
            newWaveBorderValues = newWaveBorderValues.Distinct().ToList();
            Dictionary <decimal, int> borderValuesWithPartipition = new Dictionary <decimal, int>();
            int countTrue  = 0;
            int countFalse = 0;

            if (borderValuesTrue.ContainsKey(newWaveBorderValues[0]))
            {
                countTrue = borderValuesTrue[newWaveBorderValues[0]];
            }
            if (borderValuesFalse.ContainsKey(newWaveBorderValues[0]))
            {
                countFalse = borderValuesFalse[newWaveBorderValues[0]];
            }
            borderValuesWithPartipition.Add(newWaveBorderValues[0], countTrue + countFalse);
            for (int index = 1; index < newWaveBorderValues.Count; index++)
            {
                borderValuesWithPartipition.Add(newWaveBorderValues[index], 0);
                foreach (KeyValuePair <decimal, int> pair in borderValuesTrue)
                {
                    if ((pair.Key > newWaveBorderValues[index - 1]) && (pair.Key <= newWaveBorderValues[index]))
                    {
                        borderValuesWithPartipition[newWaveBorderValues[index]] += pair.Value;
                    }
                }
                foreach (KeyValuePair <decimal, int> pair in borderValuesFalse)
                {
                    if ((pair.Key > newWaveBorderValues[index - 1]) && (pair.Key <= newWaveBorderValues[index]))
                    {
                        borderValuesWithPartipition[newWaveBorderValues[index]] += pair.Value;
                    }
                }
            }

            //List<decimal> bordersValues = borderValues.Keys.ToList();
            List <decimal> bordersValues = borderValuesWithPartipition.Keys.ToList();

            bordersValues.Sort();
            if ((bordersValues.Count > parametersCount) || (bordersValues.Count > curveCount))
            {
                if (parametersCount >= curveCount)
                {
                    bordersValues = ThresHoldValue(borderValues, curveCount, samples.Count);
                }
                else
                {
                    bordersValues = ThresHoldValue(borderValues, parametersCount, samples.Count);
                }
            }
            else if (bordersValues.Count == 1)
            {
            }

            //int numberBorders = NumberBorders(bordersValues.Count);

            // TODO: Если количество разветлений будет больше 3 то надо будет переписать весь последующий кусок кода в более адекватном формате
            if ((bordersValues.Count > parametersCount) || (bordersValues.Count > curveCount))
            {
                if (parametersCount >= curveCount)
                {
                    groceryList = ChangeBorder(bordersValues, curveCount);
                }
                else
                {
                    groceryList = ChangeBorder(bordersValues, parametersCount);
                }
            }
            else if (bordersValues.Count == 1)
            {
                groceryList.Add(bordersValues[0], bordersValues[0]);
            }
            else
            {
                for (int i = 0; i < bordersValues.Count - 1; i++)
                {
                    if (i != bordersValues.Count - 2)
                    {
                        groceryList.Add(bordersValues[i], bordersValues[i + 1] - 0.001M);
                    }
                    else
                    {
                        groceryList.Add(bordersValues[i], bordersValues[i + 1]);
                    }
                }
            }
            return(groceryList);
        }