// =========================================================================================================== private void BtnBuildAndTrainModel_Click(object sender, EventArgs e) { if (!_modelImplementation.Ready) { return; } PnlBuildPipelineAndModel.BackColor = Color.LightCoral; PnlLoadTestingDataAndEvaluate.Enabled = false; Application.DoEvents(); ClassificationMode classificationMode = (RadioBtnOneVsAll.Checked) ? ClassificationMode.OneVersusAll : (RadioBtnLightGbm.Checked) ? ClassificationMode.LightGbm : ClassificationMode.Error; _modelImplementation.BuildTrainingPipelineAndModel(classificationMode); if (_modelImplementation.ErrorHasOccured) { ShowMessageAlert(_modelImplementation.FailureInformation); } PnlBuildPipelineAndModel.BackColor = Color.LightSeaGreen; PnlLoadTestingDataAndEvaluate.Enabled = !_modelImplementation.ErrorHasOccured; PnlLoadTestingDataAndEvaluate.BackColor = Color.LightBlue; }
private void outerRadioButton_CheckedChanged(object sender, EventArgs e) { if (outerRadioButton.Checked) { Mode = ClassificationMode.OUTER; Classify(); BuildTree(); } }
private bool Classify(ChatLogDataContext db, int MessageID, int CategoryID, ClassificationMode Mode, bool isSecond = false) { try { // Save or update to the classified var mitem = db.LogMessages.SingleOrDefault(l => l.Id == MessageID); var citem = db.Categories.SingleOrDefault(c => c.Id == CategoryID); if (mitem != null && citem != null) { // Check if the item exists var cl = db.ClassifiedMessages.SingleOrDefault(c => c.MessageId == MessageID); if (cl != null) { // Already exists -- set to the new category if (isSecond) { cl.SecondCategoryId = CategoryID; } else { cl.CategoryId = CategoryID; } cl.DateModified = DateTime.Now; } else { // Add a new one db.ClassifiedMessages.InsertOnSubmit(new ClassifiedMessage { CategoryId = citem.Id, MessageId = mitem.Id, DateModified = DateTime.Now }); } //Update the message status mitem.Status = (short)MessageStatus.Done; mitem.DateModified = DateTime.Now; db.SubmitChanges(); } return(true); } catch { return(false); } }
private ClassifyViewModel GetNextUnclassifiedItem(ClassificationMode mode, ChatLogDataContext db, int currentId) { var firstitem = db.LogMessages.OrderBy(m => m.Id).FirstOrDefault(m => m.Status == (short)mode); try { if (firstitem != null) { var newitem = db.LogMessages.OrderBy(m => m.Id).FirstOrDefault(m => m.Status == (short)mode && m.Id > currentId); if (newitem != null) { firstitem = newitem; } } if (firstitem == null) { firstitem = new LogMessage() { Id = 0, Message = string.Empty }; } // Get related messages var related = db.LogMessages.Where(m => m.SessionFileName == firstitem.SessionFileName).OrderBy(m => m.Id).ToList(); return(new ClassifyViewModel() { MessageId = firstitem.Id, Mode = mode, Message = firstitem.Message, Categories = db.Categories.ToList(), RelatedMessages = related, Selectors = CategorySelector.GetCategorySelectors(db.Categories.ToList()), SelectedCategories = string.Empty }); } finally { firstitem = null; } }
public ActionResult Next(string messageId, ClassificationMode mode) { int mid = Convert.ToInt32(messageId); using (var db = new ChatLogDataContext()) { var mitem = db.LogMessages.SingleOrDefault(l => l.Id == mid); //if (mitem != null) //{ // // Update status and move next // mitem.Status = (short)MessageStatus.Skipped; // mitem.DateModified = DateTime.Now; //} //db.SubmitChanges(); return(View("Classify", GetNextUnclassifiedItem(mode, db, mid))); } }
private static void ReplaceNode(TreeNode node1, TreeNode node2, Dictionary <TreeNode, Dictionary <TreeNode, double> > data, ClassificationMode mode) { var row1 = data.GetEquals(node1); var row2 = data.GetEquals(node2); var newNode = new InnerNode(node1, node2); var newRow = new Dictionary <TreeNode, double>(); newRow.Add(newNode, 0.0); //filling new row foreach (TreeNode key in row1.Keys) { if (!key.Equals(node1) && !key.Equals(node2)) { double relation = Math.Sqrt((Math.Pow(row1.GetEquals(key), 2.0) + Math.Pow(row2.GetEquals(key), 2.0)) / 2.0); newRow.Add(key, relation); } } //removing old rows data.Remove(data.First(x => x.Key.Equals(node1)).Key); data.Remove(data.First(x => x.Key.Equals(node2)).Key); //fixing existing rows foreach (Dictionary <TreeNode, double> row in data.Values) { double relation = Math.Sqrt((Math.Pow(row.GetEquals(node1), 2.0) + Math.Pow(row.GetEquals(node2), 2.0)) / 2.0); row.Remove(row.First(x => x.Key.Equals(node1)).Key); row.Remove(row.First(x => x.Key.Equals(node2)).Key); row.Add(newNode, relation); } data.Add(newNode, newRow); }
public static List <List <string> > Classify(Dictionary <string, Dictionary <string, double> > GridData, ClassificationMode mode, int groupsCount) { var treeRelations = convertToNodes(GridData); while (treeRelations.Keys.Count > groupsCount) { FindAndUnite(treeRelations, mode); } return(ExtractGroups(treeRelations)); }
private static void FindAndUnite(Dictionary <TreeNode, Dictionary <TreeNode, double> > treeRelations, ClassificationMode mode) { TreeNode node1 = null; TreeNode node2 = null; double relation = double.MinValue; foreach (TreeNode key1 in treeRelations.Keys) { var row = treeRelations.Get(key1); foreach (TreeNode key2 in row.Keys) { if (!key1.Equals(key2)) { double inner = row.Get(key2); double outer = row.Where(x => !x.Key.Equals(key2)).Sum(x => x.Value) + treeRelations.First(x => x.Key.Equals(key2)).Value .Where(x => !x.Key.Equals(key1)).Sum(x => x.Value); double currentRelation = mode == ClassificationMode.INNER ? -inner : mode == ClassificationMode.OUTER ? outer : outer - inner; if ((node1 == null && node2 == null) || currentRelation > relation) { node1 = key1; node2 = key2; relation = currentRelation; } } } } ReplaceNode(node1, node2, treeRelations, mode); }
public static List <Tuple <string, TreeNode> > ExtractTree(Dictionary <string, Dictionary <string, double> > GridData, ClassificationMode mode, int groupsCount) { var treeRelations = convertToNodes(GridData); var tree = new List <Tuple <string, TreeNode> >(); while (treeRelations.Keys.Count > groupsCount) { FindAndUnite(treeRelations, mode); } //mark root nodes int i = 1; foreach (var node in treeRelations.Keys) { node.GroupRoot = "Група" + i++; } while (treeRelations.Keys.Count > 1) { FindAndUnite(treeRelations, mode); } addToTree(treeRelations.Keys.First(), null, tree); return(tree); }
private bool Classify(ChatLogDataContext db, int MessageID, string CategoryIds, ClassificationMode Mode, bool isSecond = false) { try { // Save or update to the classified var originalMessage = db.LogMessages.SingleOrDefault(l => l.Id == MessageID); if (originalMessage != null) { // Check if the item exists var classified01 = db.ClassifiedMessages.SingleOrDefault(c => c.MessageId == MessageID); if (classified01 != null) { // Already exists -- set to the new category classified01.SelectedCategories = CategoryIds.Replace(',', '|'); classified01.DateModified = DateTime.Now; } else { // Add a new one db.ClassifiedMessages.InsertOnSubmit(new ClassifiedMessage { MessageId = originalMessage.Id, SelectedCategories = CategoryIds.Replace(',', '|'), DateModified = DateTime.Now }); } //Update the message status originalMessage.Status = (short)MessageStatus.Done; originalMessage.DateModified = DateTime.Now; db.SubmitChanges(); } return(true); } catch { return(false); } }
// =========================================================================================================== public void BuildTrainingPipelineAndModel(ClassificationMode classificationMode) { if (ErrorHasOccured) { return; } try { switch (classificationMode) { case ClassificationMode.OneVersusAll: // first time this project was builot // Data process configuration with pipeline data transformations EstimatorChain <NormalizingTransformer> dataProcessPipeline1 = _mlContext.Transforms.Conversion.MapValueToKey("Label", "Label") .Append(_mlContext.Transforms.Concatenate( outputColumnName: "Features", inputColumnNames: FeatureNames.ToArray())) .Append(_mlContext.Transforms.NormalizeMinMax("Features", "Features")) .AppendCacheCheckpoint(_mlContext); // Set the training algorithm EstimatorChain <KeyToValueMappingTransformer> trainer1 = _mlContext.MulticlassClassification.Trainers.OneVersusAll( _mlContext.BinaryClassification.Trainers.AveragedPerceptron(labelColumnName: "Label", numberOfIterations: 10, featureColumnName: "Features"), labelColumnName: "Label") .Append(_mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel", "PredictedLabel")); IEstimator <ITransformer> trainingPipeline1 = dataProcessPipeline1.Append(trainer1); // Train Model _mlModel = trainingPipeline1.Fit(_trainingDataView); break; case ClassificationMode.LightGbm: // Data process configuration with pipeline data transformations EstimatorChain <ColumnConcatenatingTransformer> dataProcessPipeline2 = _mlContext.Transforms.Conversion.MapValueToKey("Label", "Label") .Append(_mlContext.Transforms.Concatenate( outputColumnName: "Features", inputColumnNames: FeatureNames.ToArray())); // Set the training algorithm EstimatorChain <KeyToValueMappingTransformer> trainer2 = _mlContext.MulticlassClassification.Trainers.LightGbm(labelColumnName: "Label", featureColumnName: "Features") .Append(_mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel", "PredictedLabel")); EstimatorChain <TransformerChain <KeyToValueMappingTransformer> > trainingPipeline2 = dataProcessPipeline2.Append(trainer2); // Train Model _mlModel = trainingPipeline2.Fit(_trainingDataView); break; default: throw new ArgumentOutOfRangeException(nameof(classificationMode), classificationMode, null); } // TODO //// Cross-Validate with single dataset (since we don't have two datasets, one for training and for evaluate) //// in order to evaluate and get the model's accuracy metrics //Console.WriteLine("=============== Cross-validating to get model's accuracy metrics ==============="); //var crossValidationResults = mlContext.MulticlassClassification.CrossValidate(trainingDataView, trainingPipeline, numberOfFolds: 5, labelColumnName: "Label"); //PrintMulticlassClassificationFoldsAverageMetrics(crossValidationResults); } catch (Exception ex) { Debug.WriteLine(ex.Message); ErrorHasOccured = true; FailureInformation = ex.Message; return; } }