예제 #1
0
        public static void Calibrate(List <CalibrationLine> points, bool isSecondOrder)
        {
            double m2 = 0;
            double m  = 0;
            double q  = 0;

            var centroids   = points.Select(x => x.Centroid).ToArray();
            var energies    = points.Select(x => x.Energy).ToArray();
            var areas       = points.Select(x => x.Area);
            var totalWeight = areas.Sum();
            var weights     = areas.Select(x => x / totalWeight).ToArray();

            var fittedModel = Fit.PolynomialWeighted(centroids, energies, weights, isSecondOrder ? 2 : 1);

            q = fittedModel[0];
            m = fittedModel[1];
            if (isSecondOrder)
            {
                m2 = fittedModel[2];
            }
            using (StreamWriter writetext = new StreamWriter(String.Format("data/{0}.calibration", "last")))
            {
                writetext.WriteLine("{0} {1} {2}", q, m, m2);
            }
        }
예제 #2
0
 // HELPER METHODS
 private static double[] FitWeightedPolynomial(
     Dictionary <double, double> xy,
     Dictionary <double, double> weights,
     int polynomialDegree)
 {
     double[] xs = xy.Keys
                   .OrderBy(x => x)
                   .ToArray();
     double[] ys = xs
                   .Select(x => xy[x])
                   .ToArray();
     double[] ws = xs
                   .Select(x => weights[x])
                   .ToArray();
     try
     {
         double[] polynomial = Fit.PolynomialWeighted(
             x: xs,
             y: ys,
             w: ws,
             order: polynomialDegree);
         return(polynomial);
     }
     catch (Exception e)
     {
         string filename = @"C:\Users\EBJ\Desktop\FitPolynomialWeighted.csv";
         File.Delete(filename);
         using (TextWriter tw = File.AppendText(filename))
         {
             tw.WriteLine("xs;ys;ws");
             xs
             .ForEach((x, index) =>
             {
                 tw.WriteLine($"{x};" +
                              $"{ys[index].ToString(CultureInfo.InvariantCulture)};" +
                              $"{ws[index].ToString(CultureInfo.InvariantCulture)}");
             });
             tw.Flush();
             tw.Close();
         }
         throw;
     }
 }
예제 #3
0
 public void Add(Vector2 point, DateTime time)
 {
     if (AddTimeSeriesPoint(point, time))
     {
         IsReady = true;
         var timeMatrix = ConstructTimeDesignMatrix();
         var x          = ConstructTargetMatrix(Axis.X);
         var y          = ConstructTargetMatrix(Axis.Y);
         try
         {
             this.xCoeff = new Polynomial(Fit.PolynomialWeighted(timeMatrix, x, this.weights, Complexity));
             this.yCoeff = new Polynomial(Fit.PolynomialWeighted(timeMatrix, y, this.weights, Complexity));
         }
         catch
         {
             Log.Write("MLCore", "Error in calculation", LogLevel.Error);
             IsReady = false;
         }
     }
 }
예제 #4
0
        public void FitsToOrder2PolynomialWeighted()
        {
            // Mathematica: LinearModelFit[{{1,4.986},{2,2.347},{3,2.061},{4,-2.995},{5,-2.352},{6,-5.782}}, {1, x, x^2}, x, Weights -> {0.5, 1.0, 1.0, 1.0, 1.0, 0.5}]
            // -> 7.01451 - 2.12819 x + 0.0115 x^2

            var x = Enumerable.Range(1, 6).Select(Convert.ToDouble).ToArray();
            var y = new[] { 4.986, 2.347, 2.061, -2.995, -2.352, -5.782 };

            var respUnweighted = Fit.PolynomialWeighted(x, y, new[] { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 }, 2);

            Assert.AreEqual(3, respUnweighted.Length);
            Assert.AreEqual(6.9703, respUnweighted[0], 1e-4);
            Assert.AreEqual(-2.05564, respUnweighted[1], 1e-4);
            Assert.AreEqual(-0.00426786, respUnweighted[2], 1e-6);

            var resp = Fit.PolynomialWeighted(x, y, new[] { 0.5, 1.0, 1.0, 1.0, 1.0, 0.5 }, 2);

            Assert.AreEqual(3, resp.Length);
            Assert.AreEqual(7.01451, resp[0], 1e-4);
            Assert.AreEqual(-2.12819, resp[1], 1e-4);
            Assert.AreEqual(0.0115, resp[2], 1e-6);
        }
예제 #5
0
        public static AnalysisResults AnalyzeSurroundingHouses(List <House> houses, BovetaSearch search)
        {
            var results = new AnalysisResults();

            // Should always be the case. Extra check just to make sure.
            houses = houses.Where(house => house.livingArea > 0).ToList();

            // Should we use listing price or sold price? Better if possible.
            bool useSoldPrice = false;

            if (houses.Where(house => house.soldPrice > 0).Count() >=
                houses.Where(house => house.listPrice > 0).Count())
            {
                useSoldPrice = true;
                houses       = houses.Where(house => house.soldPrice > 0).ToList();
            }
            else
            {
                houses = houses.Where(house => house.listPrice > 0).ToList();
            }

            // For convenience
            int numHouses = houses.Count();

            // At least MIN_RESULTS houses in big initial radius
            if (numHouses < MIN_RESULTS)
            {
                return(results);
            }

            // Optimize the number of houses/search radius
            houses = houses.OrderBy(w => w.distanceToReferencePoint).ToList();

            double bestRadius = 0;
            double bestScore  = Double.MinValue;

            for (double radius = 100; radius < 10000; radius = radius * 2)
            {
                int    s     = houses.Where(w => w.distanceToReferencePoint <= radius).Count();
                double order = Math.Log(s, LOG_BASE);
                double score = order - radius / RADIUS_W;
                Console.WriteLine(" Radius: " + radius + "Score: " + score);
                if (score > bestScore & s > MIN_RESULTS)
                {
                    bestRadius = radius;
                    bestScore  = score;
                }
            }
            results.SearchRadius = bestRadius;

            houses = houses.Where(w => w.distanceToReferencePoint < bestRadius).ToList();

            if (houses.Count < MIN_RESULTS)
            {
                return(results);
            }

            List <double> xdata   = new List <double>();
            List <double> ydata   = new List <double>();
            List <double> weights = new List <double>();

            foreach (var house in houses)
            {
                int housePrice = house.listPrice;
                if (useSoldPrice)
                {
                    housePrice = house.soldPrice;
                }

                weights.Add(1 + POL_WEIGHT_NUM / (POL_WEIGHT_DENOM + house.distanceToReferencePoint));
                xdata.Add(house.livingArea);
                ydata.Add(housePrice);
            }

            var    p          = Fit.PolynomialWeighted(xdata.ToArray(), ydata.ToArray(), weights.ToArray(), 1);
            double estimation = p[0] + p[1] * search.Size;

            if (search.Condition != HouseCondition.Average)
            {
                // Adjust weights to accomodate for condition

                List <double> modelerr = new List <double>();

                // 1. Find error in current model. Use this as measure for over/under valuation
                for (int i = 0; i < ydata.Count; ++i)
                {
                    double modelError = ydata[i] - (p[0] + p[1] * xdata[i]);
                    modelerr.Add(modelError);
                }

                // 2. Adjust weights so that overvalued houses are worth more.
                for (int i = 0; i < modelerr.Count; i++)
                {
                    if (modelerr[i] < 0) // Model price > real price. Probably bad condition
                    {
                        if (search.Condition == HouseCondition.AboveAverage)
                        {
                            weights[i] = weights[i] * 0.5; // Less representive of true house price
                        }
                        else if (search.Condition == HouseCondition.BelowAverage)
                        {
                            weights[i] = weights[i] * 2; // More representive of true house price
                        }
                    }
                    else  // Model price < real price. Probably good condition
                    {
                        if (search.Condition == HouseCondition.AboveAverage)
                        {
                            weights[i] = weights[i] * 2; // More representive of true house price
                        }
                        else if (search.Condition == HouseCondition.BelowAverage)
                        {
                            weights[i] = weights[i] * 0.5; // Less representive of true house price
                        }
                    }
                }

                // Recalculate polynomial
                p = Fit.PolynomialWeighted(xdata.ToArray(), ydata.ToArray(), weights.ToArray(), 1);
            }



            results.Intercept = p[0];
            results.BetaSize  = p[1];

            results.NumDatapointsUsed = houses.Count();
            results.EstimatedValue    = (int)(results.Intercept + results.BetaSize * search.Size);

            if (search.Condition == HouseCondition.BelowAverage & results.EstimatedValue > estimation)
            {
                // Oops. Our advanced searched failed. Reduce cost by 10% for now.....
                results.EstimatedValue = results.EstimatedValue * 0.9;
            }

            if (search.Condition == HouseCondition.AboveAverage & results.EstimatedValue < estimation)
            {
                // Oops. Our advanced searched failed. Increase cost by 10% for now.....
                results.EstimatedValue = results.EstimatedValue * 1.1;
            }

            results.ConfidenceScore = 0.6;

            return(results);
        }