public void Load_LinearRegression() { string xml = @"<?xml version=""1.0""?> <LinearRegressionModel> <Descriptor Type=""None"" Name=""""> <Features Length=""2""> <Property Name=""LeftOperand"" Type=""Double"" Discrete=""False"" Start=""0"" /> <Property Name=""RightOperand"" Type=""Double"" Discrete=""False"" Start=""1"" /> </Features> <Label> <Property Name=""Result"" Type=""Double"" Discrete=""False"" Start=""-1"" /> </Label> </Descriptor> <v size=""3""> <e>73299.802339155649</e> <e>13929.858323609986</e> <e>28235.048808708329</e> </v> <v size=""2""> <e>22155.108339050836</e> <e>25812.304093938921</e> </v> <v size=""2""> <e>14120.242563388447</e> <e>14302.3670376599</e> </v> </LinearRegressionModel>"; LinearRegressionModel model = new LinearRegressionModel(); model.LoadXml(xml); }
private static void TestLinearRegression(FeatureVector training, FeatureVector test) { LinearRegression lr = new LinearRegression(); LinearRegressionModel lrModel = (LinearRegressionModel)lr.Fit(training); FeatureVector predictions = lrModel.transform(test); PrintPredictionsAndEvaluate(predictions); }
private static void TestMSELinearRegression() { var x = np.array(new double[, ] { { 1, 1, 1, 1 }, { 2, 2, 2, 2 } }); var weights = np.array(new double[] { 2, 2, 2, 2, 2 }); var y = np.array(new double[] { 3, 3 }); var resultat = LinearRegressionModel.MSELinearRegression(weights, x, y); Console.WriteLine(resultat.ToString()); }
private static void TestCostDerivative() { var x = np.array(new double[, ] { { 1.95223362, 0.19171514, 0.00512253, 0.80421507 }, { 2.33011483, 0.07497046, 2.37159478, 0.77167166 } }); var weights = np.array(new double[] { 0.93176825, 1.25294411, 1.08222077, 1.04574184, 1.54479269 }); var y = np.array(new double[] { 2, 1 }); var resultat = LinearRegressionModel.CostDerivative(weights, x, y); Console.WriteLine(resultat.ToString()); }
private static void TestLinearRegression() { var lrm = new LinearRegressionModel { Weights = np.array(new double[] { 2, 4, 6, 2, 2 }) }; var x = np.array(new double[][] { new double[] { 1, 1, 1, 1 } }); var list = LinearRegressionModel.MatrixToDataSet(x); var resultat = lrm.Predict(list); Console.WriteLine(resultat.ToString()); }
private static void TestGradientDescent() { var x = np.array(new double[, ] { { 1.95223362, 0.19171514, 0.00512253, 0.80421507 }, { 2.33011483, 0.07497046, 2.37159478, 0.77167166 } }); var y = np.array(new double[] { 2, 1 }); var weight = np.array(np.random.rand(x.shape[1] + 1)).reshape(x.shape[1] + 1, 1); var progress = LinearRegressionModel.GradientDescent(ref weight, x, y, 500, 0.1); //Console.WriteLine(np.array(progress.ToArray()).ToString()); foreach (var d in progress) { Console.WriteLine(d); } }
public void TestLinearEquationCalculation() { List <UMCLight> observedUmcList = null; List <UMCLight> targetUmcList = null; CreateObservedAndTargetUmcLists(ref observedUmcList, ref targetUmcList); var xyDataList = observedUmcList.Select((t, i) => new XYData(t.DriftTime, targetUmcList[i].DriftTime)).ToList(); var regression = new LinearRegressionModel(); var linearEquation = regression.CalculateRegression(xyDataList); Assert.AreEqual(Math.Round(linearEquation.Slope, 4), 0.7142); Assert.AreEqual(Math.Round(linearEquation.Intercept, 4), 1.1324); }
private static void TestFit() { var lrm = new LinearRegressionModel { Weights = np.array(new double[] { 2, 4, 6, 2, 2 }) }; var x = np.array(new double[, ] { { 1, 1, 1, 1 }, { 2, 5, 2, 2 }, { 2, 3, 2, 2 }, { 5, 2, 2, 2 }, { 2, 2, 3, 2 }, { 7, 2, 2, 2 }, { 2, 6, 2, 2 }, { 2, 4, 2, 2 }, { 2, 3, 3, 2 }, { 2, 2, 2, 8 } }); var list = LinearRegressionModel.MatrixToDataSet(x); var yList = lrm.Predict(list); var y = np.array(yList.Cast <double>().ToArray()); Console.WriteLine($"Weights {lrm.Weights.ToString()}"); Console.WriteLine($"X {x.ToString()}"); Console.WriteLine($"Y { y.ToString()}"); lrm.Fit(list, yList); Console.WriteLine($"Weights after fit {lrm.Weights.ToString()}"); }
/// <summary> /// Aligns features to the baseline correcting for drift time. /// </summary> /// <param name="fullObservedEnumerable">All features.</param> /// <param name="observedEnumerable">Filtered features to use for drift time correction.</param> /// <param name="targetEnumerable">Expected features that should be filtered.</param> /// <param name="massTolerance">PPM Mass Tolerance.</param> /// <param name="netTolerance">Normalized Elution Time Tolerance.</param> public static DriftTimeAlignmentResults <TTarget, TObserved> AlignObservedEnumerable(IEnumerable <UMCLight> fullObservedEnumerable, IEnumerable <TTarget> observedEnumerable, IEnumerable <TObserved> targetEnumerable, double massTolerance, double netTolerance) { // Setup Tolerance for Feature Matching var featureMatcherParameters = new FeatureMatcherParameters(); featureMatcherParameters.SetTolerances(massTolerance, netTolerance, DRIFT_TIME_TOLERANCE); featureMatcherParameters.UseDriftTime = true; // Find all matches based on defined tolerances var featureMatcher = new FeatureMatcher <TTarget, TObserved>(observedEnumerable.ToList(), targetEnumerable.ToList(), featureMatcherParameters); var matchList = featureMatcher.FindMatches(observedEnumerable.ToList(), targetEnumerable.ToList(), featureMatcherParameters.UserTolerances, 0); // Create <ObservedDriftTime, TargetDriftTime> XYData List var xyDataList = new List <XYData>(); foreach (var featureMatch in matchList) { var xyData = new XYData(featureMatch.ObservedFeature.DriftTime, featureMatch.TargetFeature.DriftTime); xyDataList.Add(xyData); } var linearRegression = new LinearRegressionModel(); // Find the Linear Equation for the <ObservedDriftTime, TargetDriftTime> XYData List var linearEquation = linearRegression.CalculateRegression(xyDataList); // Set the Aligned Drift Time value for each of the observed Features, even if they were not found in matching foreach (var observedT in fullObservedEnumerable) { observedT.DriftTimeAligned = linearRegression.Transform(linearEquation, observedT.DriftTime); } var results = new DriftTimeAlignmentResults <TTarget, TObserved>(matchList, linearEquation); return(results); }
public ActionResult PredictionCalculate(CropYieldRequest mvcModel) { // Multiple linear regression can be performed using // the LinearRegressionModel class. // // // This QuickStart sample uses data test scores of 200 high school // students, including science, math, and reading. // First, read the data from a file into a data frame. var data = DataFrame.ReadCsv(@"C:\SF.Code\Extreme\Extreme\test3.csv"); //// Now create the regression model. Parameters are the data frame, //// the name of the dependent variable, and a string array containing //// the names of the independent variables. //var model = new LinearRegressionModel(data, "science", new string[] {"math", "female", "socst", "read"}); // Alternatively, we can use a formula to describe the variables // in the model. The dependent variable goes on the left, the // independent variables on the right of the ~: //var model2 = new LinearRegressionModel(data, // "science ~ math + female + socst + read"); var model = new LinearRegressionModel(data, "Yield ~ Temperature + NDVI + Rainfall"); // We can set model options now, such as whether to exclude // the constant term: // model.NoIntercept = false; // The Compute method performs the actual regression analysis. model.Compute(); // The Parameters collection contains information about the regression // parameters. //Console.WriteLine("Variable\t Value Std.Error t-stat p-Value"); double[] ValuesToSend = new double[10]; int count = 0; foreach (Parameter parameter in model.Parameters) { // Parameter objects have the following properties: Console.WriteLine("{0,-20}\t {1,10:F2}\t {2,10:F6} {3,8:F2}\t {4,7:F5}", // Name, usually the name of the variable: parameter.Name, // Estimated value of the parameter: parameter.Value, // Standard error: parameter.StandardError, // The value of the t statistic for the hypothesis that the parameter // is zero. parameter.Statistic, // Probability corresponding to the t statistic. parameter.PValue); ValuesToSend[count] = parameter.Value; count++; } //Console.WriteLine(); // In addition to these properties, Parameter objects have // a GetConfidenceInterval method that returns // a confidence interval at a specified confidence level. // Notice that individual parameters can be accessed // using their numeric index. Parameter 0 is the intercept, // if it was included. //Interval confidenceInterval = model.Parameters[0].GetConfidenceInterval(0.95); //Console.WriteLine(" for intercept: {0:F4} - {1:F4}", // confidenceInterval.LowerBound, confidenceInterval.UpperBound); // Parameters can also be accessed by name: //confidenceInterval = model.Parameters.Get("NDVI").GetConfidenceInterval(0.95); //Console.WriteLine("95% confidence interval for 'NDVI': {0:F4} - {1:F4}", // confidenceInterval.LowerBound, confidenceInterval.UpperBound); //Console.WriteLine(); // There is also a wealth of information about the analysis available // through various properties of the LinearRegressionModel object: //Console.WriteLine("Residual standard error: {0:F3}", model.StandardError); //Console.WriteLine("R-Squared:\t {0:F4}", model.RSquared); //Console.WriteLine("Adjusted R-Squared:\t {0:F4}", model.AdjustedRSquared); //Console.WriteLine("F-statistic: {0:F4}", model.FStatistic); //Console.WriteLine("Corresponding p-value: {0:F5}", model.PValue); //Console.WriteLine(); // Much of this data can be summarized in the form of an ANOVA table: //Console.WriteLine(model.AnovaTable.ToString()); // All this information can be printed using the Summarize method. // You will also see summaries using the library in C# interactive. //Console.WriteLine(model.Summarize()); LanguageVm eng = new LanguageVm { Home = "Home", Graph = "Graphs", Chart = "Charts", About = "About", Contact = "Contact", MapSrc = "https://ryoeun0.carto.com/builder/3237491e-11e9-11e7-89c3-0e05a8b3e3d7/embed" }; ViewBag.CropYield = (ValuesToSend[0] + ValuesToSend[1] * mvcModel.Temperature + ValuesToSend[2] * mvcModel.NDVI + ValuesToSend[3] * mvcModel.Rainfall).ToString("f2"); ViewBag.RSquared = model.RSquared.ToString("f4"); return(View("Prediction", eng)); }
public async Task <ActionResult <IEnumerable <LinearRegressionModel> > > GenerateLinearCostForecast() { Forecast forecast = new Forecast(); //get the cost data and dates Procedures proc = new Procedures(_db, _config); var results = (await proc.SummaryPeriodCostsAsync(Procedures.Period.Daily)).FirstOrDefault(); LinearRegressionModel data = new LinearRegressionModel(); if (results.dataPoints.Count == 0) { var _day = DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month); var _date = new DateTime(DateTime.Now.Year, DateTime.Now.Month, _day); data.rSquared = 0; data.yIntercept = 0; data.slope = 0; data.start = new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds(); data.end = new DateTimeOffset(_date).ToUnixTimeSeconds(); data.numOfElements = 0; return(new List <LinearRegressionModel> { data }); } if (results.dataPoints.Count == 1) { var _day = DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month); var _date = new DateTime(DateTime.Now.Year, DateTime.Now.Month, _day); data.rSquared = 0; data.yIntercept = results.dataPoints.FirstOrDefault().y; data.slope = 0; data.start = new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds(); data.end = new DateTimeOffset(_date).ToUnixTimeSeconds(); data.numOfElements = 1; return(new List <LinearRegressionModel> { data }); } var x = results.dataPoints.Select(row => row.x); //datetime data var y = results.dataPoints.Select(row => row.y); //cost data <double> DateTime start = x.ElementAt(0); DateTime second = x.ElementAt(1); DateTime end = x.Last(); var epochDates = forecast.generateUnixEpochFromDatetime(start, end, x.Count()); double rSquared, yIntercept, slope; forecast.LinearRegression(epochDates.ToArray(), y.ToArray(), out rSquared, out yIntercept, out slope); data.rSquared = rSquared; data.yIntercept = yIntercept; data.slope = slope; data.start = epochDates.First(); data.end = epochDates.Last(); data.numOfElements = epochDates.Count(); return(new List <LinearRegressionModel> { data }); }
private void buttonForDataSplitNext_Click(object sender, EventArgs e) { trainingSetPercentage = (double)numericUpDownForTrainingSetPercent.Value / 100.0; numFolds = (int)numericUpDownForNumFolds.Value; double[] smaOut = null; double[] wmaOut = null; double[] emaOut = null; double[] macdOut = null; double[] stochasticsOut = null; double[] williamsROut = null; double[] rsiOut = null; double[] closesOut = null; var data = IndicatorService.GetData(code, targetDate, new string[] { "Tarih", "Kapanis" }, numberOfData + 1); if (isSMAChecked) { smaOut = IndicatorDataPreprocessor.GetSMAOut(MovingAverage.Simple(code, targetDate, smaPeriod, numberOfData)); } if (isWMAChecked) { wmaOut = IndicatorDataPreprocessor.GetWMAOut(MovingAverage.Weighted(code, targetDate, wmaPeriod, numberOfData)); } if (isEMAChecked) { emaOut = IndicatorDataPreprocessor.GetEMAOut(MovingAverage.Exponential(code, targetDate, emaPeriod, numberOfData)); } if (isMACDChecked) { macdOut = IndicatorDataPreprocessor.GetMACDOut(new MovingAverageConvergenceDivergence(code, targetDate, firstPeriod, secondPeriod, triggerPeriod, numberOfData)); } if (isStochasticsChecked) { stochasticsOut = IndicatorDataPreprocessor.GetStochasticsOut(new Stochastics(code, targetDate, fastKPeriod, fastDPeriod, slowDPeriod, numberOfData)); } if (isWilliamsRChecked) { williamsROut = IndicatorDataPreprocessor.GetWilliamsROut(WilliamsR.Wsr(code, targetDate, williamsRPeriod, numberOfData)); } if (isRSIChecked) { rsiOut = IndicatorDataPreprocessor.GetRSIOut(RelativeStrengthIndex.Rsi(code, targetDate, rsiPeriod, numberOfData)); } closesOut = IndicatorDataPreprocessor.GetClosesOut(numberOfData, data); int minRowCount = 1000000; if (smaOut != null) { minRowCount = smaOut.Length; } if (wmaOut != null) { minRowCount = minRowCount < wmaOut.Length ? minRowCount : wmaOut.Length; } if (emaOut != null) { minRowCount = minRowCount < emaOut.Length ? minRowCount : emaOut.Length; } if (macdOut != null) { minRowCount = minRowCount < macdOut.Length ? minRowCount : macdOut.Length; } if (rsiOut != null) { minRowCount = minRowCount < rsiOut.Length ? minRowCount : rsiOut.Length; } if (williamsROut != null) { minRowCount = minRowCount < williamsROut.Length ? minRowCount : williamsROut.Length; } if (stochasticsOut != null) { minRowCount = minRowCount < stochasticsOut.Length ? minRowCount : stochasticsOut.Length; } if (closesOut != null) { minRowCount = minRowCount < closesOut.Length ? minRowCount : closesOut.Length; } var fv = new FeatureVector(); if (isSMAChecked) { fv.AddColumn("SMA", smaOut.Select(p => (object)p.ToString(CultureInfo.InvariantCulture)).Take(minRowCount).ToArray()); } if (isWMAChecked) { fv.AddColumn("WMA", wmaOut.Select(p => (object)p.ToString(CultureInfo.InvariantCulture)).Take(minRowCount).ToArray()); } if (isEMAChecked) { fv.AddColumn("EMA", emaOut.Select(p => (object)p.ToString(CultureInfo.InvariantCulture)).Take(minRowCount).ToArray()); } if (isMACDChecked) { fv.AddColumn("MACD", macdOut.Select(p => (object)p.ToString(CultureInfo.InvariantCulture)).Take(minRowCount).ToArray()); } if (isRSIChecked) { fv.AddColumn("RSI", rsiOut.Select(p => (object)p.ToString(CultureInfo.InvariantCulture)).Take(minRowCount).ToArray()); } if (isWilliamsRChecked) { fv.AddColumn("WilliamsR", williamsROut.Select(p => (object)p.ToString(CultureInfo.InvariantCulture)).Take(minRowCount).ToArray()); } if (isStochasticsChecked) { fv.AddColumn("Stochastics", stochasticsOut.Select(p => (object)p.ToString(CultureInfo.InvariantCulture)).Take(minRowCount).ToArray()); } fv.AddColumn("label", closesOut.Select(p => (object)string.Format("{0:0.0}", p).ToString(CultureInfo.InvariantCulture)).Take(minRowCount).ToArray()); var training = new FeatureVector(); var test = new FeatureVector(); int count = fv.Values[0].Length; for (int i = 0; i < fv.ColumnName.Count; i++) { training.AddColumn(fv.ColumnName[i], fv.Values[i].Take((int)(count * trainingSetPercentage)).ToArray()); } for (int i = 0; i < fv.ColumnName.Count; i++) { test.AddColumn(fv.ColumnName[i], fv.Values[i].Skip((int)(count * trainingSetPercentage)).Take(count).ToArray()); // Take(count) means take the rest of all elements, number of the rest of the elements is smaller than count. } if (numFolds > 0) { BinaryClassificationEvaluator bce1 = new BinaryClassificationEvaluator(); LinearRegression linearRegression = new LinearRegression(); CrossValidator cvLinReg = new CrossValidator(linearRegression, bce1, numFolds); CrossValidatorModel cvLinRegModel = (CrossValidatorModel)cvLinReg.Fit(training); FeatureVector linRegPredictions = cvLinRegModel.transform(test); bce1.evaluate(linRegPredictions); linRegAcc = bce1.Accuracy; BinaryClassificationEvaluator bce2 = new BinaryClassificationEvaluator(); LogisticRegression logisticRegression = new LogisticRegression(); CrossValidator cvLogReg = new CrossValidator(logisticRegression, bce2, numFolds); CrossValidatorModel cvLogRegModel = (CrossValidatorModel)cvLogReg.Fit(training); FeatureVector logRegPredictions = cvLogRegModel.transform(test); bce2.evaluate(logRegPredictions); logRegAcc = bce2.Accuracy; BinaryClassificationEvaluator bce3 = new BinaryClassificationEvaluator(); NaiveBayes naiveBayes = new NaiveBayes(); CrossValidator cvNaiBay = new CrossValidator(naiveBayes, bce3, numFolds); CrossValidatorModel cvNaiBayModel = (CrossValidatorModel)cvNaiBay.Fit(training); FeatureVector naiBayPredictions = cvNaiBayModel.transform(test); bce3.evaluate(naiBayPredictions); naiBayAcc = bce3.Accuracy; } else { BinaryClassificationEvaluator bce1 = new BinaryClassificationEvaluator(); LinearRegression linearRegression = new LinearRegression(); LinearRegressionModel linearRegressionModel = (LinearRegressionModel)linearRegression.Fit(training); FeatureVector linRegPredictions = linearRegressionModel.transform(test); bce1.evaluate(linRegPredictions); linRegAcc = bce1.Accuracy; BinaryClassificationEvaluator bce2 = new BinaryClassificationEvaluator(); LogisticRegression logicticRegression = new LogisticRegression(); LogisticRegressionModel logisticRegressionModel = (LogisticRegressionModel)logicticRegression.Fit(training); FeatureVector logRegPredictions = logisticRegressionModel.transform(test); bce2.evaluate(logRegPredictions); logRegAcc = bce2.Accuracy; BinaryClassificationEvaluator bce3 = new BinaryClassificationEvaluator(); NaiveBayes naiveBayes = new NaiveBayes(); NaiveBayesModel naiveBayesModel = (NaiveBayesModel)naiveBayes.Fit(training); FeatureVector naiBayPredictions = naiveBayesModel.transform(test); bce3.evaluate(naiBayPredictions); naiBayAcc = bce3.Accuracy; } labelForLinRegAcc.Text = linRegAcc.ToString(); labelForLogRegAcc.Text = logRegAcc.ToString(); labelForNaiBayAcc.Text = naiBayAcc.ToString(); panelForResults.BringToFront(); }
private void buttonAnalyze_Click(object sender, EventArgs e) { Model newModel = new Model(); string formula = "SalePrice ~ " + string.Join(" + ", typeof(Flat).GetProperties() .Where(o => o.Name != "Id" && o.Name != "SalePrice").Select(o => o.Name).ToArray()); string[] stats = null; Extreme.DataAnalysis.Models.RegressionModel regression = null; switch (comboBoxModels.Text) { case "Linear regression": newModel.Name = "Linear regression"; LinearRegressionModel model1 = new LinearRegressionModel(DataFrame.FromDataTable(flatsRepos.GetDataFrame()), formula); model1.Fit(); newModel.ResidualStandardError = model1.StandardError; newModel.RSquared = model1.RSquared; newModel.AdjustedRSquared = model1.AdjustedRSquared; newModel.FStatistic = model1.FStatistic; newModel.CorrespondingPValue = model1.PValue; stats = new string[] { $"Residual standard error: {model1.StandardError:f2}", $"R-Squared: {model1.RSquared:f2}", $"Adjusted R-Squared: {model1.AdjustedRSquared:f2}", $"F-statistic: {model1.FStatistic:f2}", $"Corresponding p-value: {model1.PValue:f2}" }; regression = model1; break; /* case "Logistic regression": * LogisticRegressionModel model2 = new LogisticRegressionModel(DataFrame.FromDataTable(flatsRepos.GetDataFrame()), formula); * model2.Compute(); * * Extreme.Statistics.Tests.SimpleHypothesisTest lrt = model2.GetLikelihoodRatioTest(); * newModel.LogLikehood = model2.LogLikelihood; * newModel.ChiSquared = lrt.Statistic; * newModel.CorrespondingPValue = lrt.PValue; * * stats = new string[] * { * $"Log-likelihood: {model2.LogLikelihood:f2}", * $"Chi-Squared: {lrt.Statistic:f2}", * $"P-Value: {lrt.PValue:f2}" * }; * //regression = model2; * break;*/ case "Generalized linear regression": newModel.Name = "Generalized linear regression: " + comboBoxGeneralizedType.Text; GeneralizedLinearModel model3 = new GeneralizedLinearModel(DataFrame.FromDataTable(flatsRepos.GetDataFrame()), formula); switch (comboBoxGeneralizedType.Text) { case "Binomial": model3.ModelFamily = ModelFamily.Binomial; break; case "InverseGaussian": model3.ModelFamily = ModelFamily.InverseGaussian; break; case "Normal": model3.ModelFamily = ModelFamily.Normal; break; case "Poisson": model3.ModelFamily = ModelFamily.Poisson; break; default: break; } model3.Fit(); if (comboBoxGeneralizedType.Text == "Normal" || comboBoxGeneralizedType.Text == "Poisson") { newModel.LogLikehood = model3.LogLikelihood; newModel.KernelLogLikehood = model3.GetKernelLogLikelihood(); newModel.Akaike = model3.GetAkaikeInformationCriterion(); newModel.CorrectedAIC = model3.GetCorrectedAkaikeInformationCriterion(); newModel.Bayesian = model3.GetBayesianInformationCriterion(); newModel.ChiSquared = model3.GetChiSquare(); stats = new string[] { $"Log likelihood {model3.LogLikelihood:f2}", $"Kernel log likelihood: {model3.GetKernelLogLikelihood():f2}", $"Akaike (AIC): {model3.GetAkaikeInformationCriterion():f2}", $"Corrected AIC: {model3.GetCorrectedAkaikeInformationCriterion():f2}", $"Bayesian (BIC): { model3.GetBayesianInformationCriterion():f2}", $"Chi Square: { model3.GetChiSquare():f2}" }; } regression = model3; break; } foreach (Parameter parameter in regression.Parameters) { typeof(Model).GetProperty(parameter.Name).SetValue(newModel, parameter.Value); } dataGridViewParams.DataSource = regression.Parameters.ToArray(); dataGridViewParams.Columns[dataGridViewParams.Columns.Count - 1].Visible = false; listBoxStats.Items.Clear(); if (stats != null) { listBoxStats.Items.AddRange(stats); } modelsRepos.Add(newModel); }