示例#1
0
        } //buildModel

        protected void InitializeSOMWeights(ModelSelfOrganizingMap model,
                                            long noOfWeights)
        {
            Parallel.For(0, _xdim,
                         new ParallelOptions {
                MaxDegreeOfParallelism = _maxParallelThreads
            },
                         xdim =>
            {
                Random rnd         = new Random();
                model.SomMap[xdim] = new SingleSOMNode[_ydim];
                //computedDistValues[xdim] = new double[_ydim];
                for (int ydim = 0; ydim < _ydim; ydim++)
                {
                    model.SomMap[xdim][ydim] = new SingleSOMNode(noOfWeights, xdim, ydim);
                    model.SomMap[xdim][ydim].InitWeights(rnd, _weightBaseValue);
                }
            });
        }
示例#2
0
        BuildModel(double[][] trainingData,
                   string[] attributeHeaders,
                   int indexTargetAttribute = -1)
        {
            if (indexTargetAttribute == -1)
            {
                indexTargetAttribute = attributeHeaders.Length - 1;
            }
            //Verify data and set variables
            VerifyData(trainingData, attributeHeaders, indexTargetAttribute);

            ModelSelfOrganizingMap model = new ModelSelfOrganizingMap(_missingValue,
                                                                      indexTargetAttribute,
                                                                      trainingData.Length);

            model.SomMap = new SingleSOMNode[_xdim][];
            long noOfWeights = trainingData.Length; //Equal to number of features

            //Choose as lower of dimension as distance diamter
            long   distanceDiameter = (_xdim < _ydim) ? _xdim : _ydim;
            double origRadius;

            if (_origRadius == double.MaxValue)      //Not set by user
            {
                origRadius = distanceDiameter / 2.0; //Radius of influence
                //Make it circluar so that Maps in immediate grid can be accomodated
                //origRadius = sqrt(x*x+y*y), x=y=oriRadiud
                origRadius = origRadius * Math.Sqrt(2.0);
            }
            else
            {
                origRadius = _origRadius;
            }

            double[][] computedDistValues = new double[_xdim][];

            //Initialize SOM Weights
            InitializeSOMWeights(model, noOfWeights);

            double learningRate = _learningRate;
            double radius       = origRadius;
            double timeConstant = (double)_maxEpoch / Math.Log(origRadius);

            //Start Convergence Loops
            for (int epoch = 0; epoch < _maxEpoch; epoch++) //Do not parallelize
            {
                for (int dataRow = 0; dataRow < trainingData[0].Length; dataRow++)
                {
                    double[] lowestDistance  = new double[_xdim];
                    long[]   lowestDistanceY = new long[_xdim];
                    double[] inputDataRow    = GetLinearArray(_trainingData, dataRow, _trainingData.Length - 1);
                    //Find Best Matching Unit (BMU) for training row
                    //Find lowest distance in xdim
                    Parallel.For(0, _xdim,
                                 new ParallelOptions {
                        MaxDegreeOfParallelism = _maxParallelThreads
                    }, xdim =>
                                 //for (long xdim = 0; xdim < _xdim; xdim++) //Parallelize this loop
                    {
                        double computedDistValue = double.MaxValue;
                        lowestDistance[xdim]     = double.MaxValue;
                        for (long ydim = 0; ydim < _ydim; ydim++)
                        {
                            //computedDistValues[xdim][ydim] =
                            computedDistValue =
                                model.SomMap[xdim][ydim].GetComputedDistance(inputDataRow);
                            if (computedDistValue < lowestDistance[xdim])
                            {
                                lowestDistance[xdim]  = computedDistValue;
                                lowestDistanceY[xdim] = ydim;
                            }
                        }//ydim
                    });//xdim

                    long   bmuX = 0, bmuY = 0;
                    double finalDistanceValue = double.MaxValue;
                    for (int xdim = 0; xdim < _xdim; xdim++) //Parallelize this loop
                    {
                        if (lowestDistance[xdim] < finalDistanceValue)
                        {
                            bmuX = xdim;
                            bmuY = lowestDistanceY[xdim];
                            finalDistanceValue = lowestDistance[xdim];
                        }
                    }


                    //Update Weights in neighborhood accounting for distance from BMU
                    for (long xdim = 0; xdim < _xdim; xdim++) //Parallelize this loop
                    {
                        for (long ydim = 0; ydim < _ydim; ydim++)
                        {
                            model.SomMap[xdim][ydim].UpdateWeights(model.SomMap[bmuX][bmuY],
                                                                   inputDataRow, radius, learningRate, _useDistanceInfluence == 1?true:false);
                        }
                    }
                } //row

                //Update learning rate and distance
                //Formula from: http://www.ai-junkie.com/ann/som/som3.html
                radius       = origRadius * Math.Exp(-(double)epoch / timeConstant); // Math.Pow(origRadius,((double)epoch/(double)_maxEpoch)); //;
                learningRate = _learningRate * Math.Exp(-(double)epoch / timeConstant);
            }

            return(model);
        } //buildModel