public override void SaveSummary(TextWriter writer, RoleMappedSchema schema) { var names = default(VBuffer <DvText>); MetadataUtils.GetSlotNames(schema, RoleMappedSchema.ColumnRole.Feature, Weight.Length, ref names); writer.WriteLine("Ordinary Least Squares Model Summary"); writer.WriteLine("R-squared: {0:g4}", RSquared); if (HasStatistics) { writer.WriteLine("Adjusted R-squared: {0:g4}", RSquaredAdjusted); writer.WriteLine(); writer.WriteLine("Index\tName\tWeight\tStdErr\tt-Value\tp-Value"); const string format = "{0}\t{1}\t{2}\t{3:g4}\t{4:g4}\t{5:e4}"; writer.WriteLine(format, "", "Bias", Bias, _standardErrors[0], _tValues[0], _pValues[0]); Contracts.Assert(Weight.IsDense); var coeffs = Weight.Values; for (int i = 0; i < coeffs.Length; i++) { var name = names.GetItemOrDefault(i); writer.WriteLine(format, i, DvText.Identical(name, DvText.Empty) ? $"f{i}" : name.ToString(), coeffs[i], _standardErrors[i + 1], _tValues[i + 1], _pValues[i + 1]); } } else { writer.WriteLine(); writer.WriteLine("Index\tName\tWeight"); const string format = "{0}\t{1}\t{2}"; writer.WriteLine(format, "", "Bias", Bias); Contracts.Assert(Weight.IsDense); var coeffs = Weight.Values; for (int i = 0; i < coeffs.Length; i++) { var name = names.GetItemOrDefault(i); writer.WriteLine(format, i, DvText.Identical(name, DvText.Empty) ? $"f{i}" : name.ToString(), coeffs[i]); } } }
public static IEnumerable <KeyValuePair <string, Single> > GetSortedLinearModelFeatureNamesAndWeights(Single bias, ref VBuffer <Single> weights, ref VBuffer <DvText> names) { var orderedWeights = weights.Items() .Where(weight => Math.Abs(weight.Value) >= Epsilon) .OrderByDescending(kv => Math.Abs(kv.Value)); var list = new List <KeyValuePair <string, Single> >() { new KeyValuePair <string, Single>("(Bias)", bias) }; foreach (var weight in orderedWeights) { int index = weight.Key; var name = names.GetItemOrDefault(index); list.Add(new KeyValuePair <string, Single>( DvText.Identical(name, DvText.Empty) ? $"f{index}" : name.ToString(), weight.Value)); } return(list); }
///<inheritdoc/> public IList <KeyValuePair <string, object> > GetSummaryInKeyValuePairs(RoleMappedSchema schema) { Host.CheckValueOrNull(schema); List <KeyValuePair <string, object> > results = new List <KeyValuePair <string, object> >(); var names = default(VBuffer <DvText>); MetadataUtils.GetSlotNames(schema, RoleMappedSchema.ColumnRole.Feature, _numFeatures, ref names); for (int classNumber = 0; classNumber < _biases.Length; classNumber++) { results.Add(new KeyValuePair <string, object>( string.Format("{0}+(Bias)", GetLabelName(classNumber)), _biases[classNumber] )); } for (int classNumber = 0; classNumber < _weights.Length; classNumber++) { var orderedWeights = _weights[classNumber].Items().OrderByDescending(kv => Math.Abs(kv.Value)); foreach (var weight in orderedWeights) { var value = weight.Value; if (value == 0) { break; } int index = weight.Key; var name = names.GetItemOrDefault(index); results.Add(new KeyValuePair <string, object>( string.Format("{0}+{1}", GetLabelName(classNumber), DvText.Identical(name, DvText.Empty) ? $"f{index}" : name.ToString()), value )); } } return(results); }
/// <summary> /// Build a Bing TreeEnsemble .ini representation of the given predictor /// </summary> public static string LinearModelAsIni(ref VBuffer <Float> weights, Float bias, IPredictor predictor = null, RoleMappedSchema schema = null, PlattCalibrator calibrator = null) { // TODO: Might need to consider a max line length for the Weights list, requiring us to split it up into // multiple evaluators StringBuilder inputBuilder = new StringBuilder(); StringBuilder aggregatedNodesBuilder = new StringBuilder("Nodes="); StringBuilder weightsBuilder = new StringBuilder("Weights="); var featureNames = default(VBuffer <DvText>); MetadataUtils.GetSlotNames(schema, RoleMappedSchema.ColumnRole.Feature, weights.Length, ref featureNames); int numNonZeroWeights = 0; const string weightsSep = "\t"; VBufferUtils.ForEachDefined(ref weights, (idx, value) => { if (Math.Abs(value - 0) >= Epsilon) { numNonZeroWeights++; var name = featureNames.GetItemOrDefault(idx); inputBuilder.AppendLine("[Input:" + numNonZeroWeights + "]"); inputBuilder.AppendLine("Name=" + (featureNames.Count == 0 ? "Feature_" + idx : DvText.Identical(name, DvText.Empty) ? $"f{idx}" : name.ToString())); inputBuilder.AppendLine("Transform=linear"); inputBuilder.AppendLine("Slope=1"); inputBuilder.AppendLine("Intercept=0"); inputBuilder.AppendLine(); aggregatedNodesBuilder.Append("I:" + numNonZeroWeights + weightsSep); weightsBuilder.Append(value + weightsSep); } }); StringBuilder builder = new StringBuilder(); builder.AppendLine("[TreeEnsemble]"); builder.AppendLine("Inputs=" + numNonZeroWeights); builder.AppendLine("Evaluators=1"); builder.AppendLine(); builder.AppendLine(inputBuilder.ToString()); builder.AppendLine("[Evaluator:1]"); builder.AppendLine("EvaluatorType=Aggregator"); builder.AppendLine("Type=Linear"); builder.AppendLine("Bias=" + bias); builder.AppendLine("NumNodes=" + numNonZeroWeights); builder.AppendLine(aggregatedNodesBuilder.ToString().Trim()); builder.AppendLine(weightsBuilder.ToString().Trim()); #if false // REVIEW: This should be done by the caller using the actual training args! builder.AppendLine(); builder.AppendLine("[Comments]"); builder.Append("Trained by TLC"); if (predictor != null) { builder.Append(" as /cl " + predictor.GetType().Name); if (predictor is IInitializable) { string settings = string.Join(";", (predictor as IInitializable).GetSettings()); if (!string.IsNullOrEmpty(settings)) { builder.Append(" /cls " + settings); } } } #endif string ini = builder.ToString(); // Add the calibration if the model was trained with calibration if (calibrator != null) { string calibratorEvaluatorIni = IniFileUtils.GetCalibratorEvaluatorIni(ini, calibrator); ini = IniFileUtils.AddEvaluator(ini, calibratorEvaluatorIni); } return(ini); }