/// <summary> /// Callback on insert of Watson results - using the transaction submitted but NOT committed /// /// For each action, use the most likely sentiment (highest SentimentScore) /// Use Net Promoter score (promoters - detractors), normalized to [0, 1000] where 500 is neutral /// </summary> /// <param name="transaction">data associated with the watson transaction</param> public static void TicketSentimentStrategy(DataContext db, ActionToAnalyze actionToAnalyze, ActionSentimentScore maxScore) { if (actionToAnalyze.IsAgent) { return; } try { // normalize to [0, 1000] double actionScore = Convert.ToDouble(ToneSentiment.ToneSentiments[maxScore.SentimentID].SentimentMultiplier.Value) * Convert.ToDouble(maxScore.SentimentScore); actionScore = 500 * actionScore + 500; // submit TicketSentiment TicketSentiment score = null; CreateTicketSentiment(db, actionToAnalyze, actionScore, out score); score.TicketSentimentScore = (int)Math.Round(score.AverageActionSentiment); score.SetSentimentID(maxScore.SentimentID); db.SubmitChanges(); } catch (Exception e2) { WatsonEventLog.WriteEntry("Exception caught at select from ACtionsToAnalyze or HttpPOST:", e2); Console.WriteLine(e2.ToString()); } }
static bool CreateTicketSentiment(DataContext db, ActionToAnalyze actionToAnalyze, double actionScore, out TicketSentiment score) { Table <TicketSentiment> table = db.GetTable <TicketSentiment>(); score = table.Where(t => (t.TicketID == actionToAnalyze.TicketID) && (t.IsAgent == actionToAnalyze.IsAgent)).FirstOrDefault(); if (score == null) { score = new TicketSentiment() { TicketID = actionToAnalyze.TicketID, OrganizationID = actionToAnalyze.OrganizationID, IsAgent = actionToAnalyze.IsAgent, TicketDateCreated = actionToAnalyze.DateCreated, TicketSentimentScore = 0, Sad = false, Frustrated = false, Satisfied = false, Excited = false, Polite = false, Impolite = false, Sympathetic = false, AverageActionSentiment = actionScore, ActionSentimentCount = 1 }; table.InsertOnSubmit(score); return(true); } return(false); }
public void DoRebuild() { try { string connectionString = ConfigurationManager.AppSettings.Get("ConnectionString"); using (SqlConnection connection = new SqlConnection(connectionString)) using (DataContext db = new DataContext(connection)) { db.ObjectTrackingEnabled = false; // read-only linq to sql Initialize(db); // load the highest confidence sentiment for each client action MaxActionSentiment[] actionSentiments = LoadActionSentiments(db); Array.Sort(actionSentiments, (lhs, rhs) => lhs.TicketID.CompareTo(rhs.TicketID)); foreach (MaxActionSentiment actionSentiment in actionSentiments) { // new TicketSentiment? double actionScore = ToTicketScore(actionSentiment.SentimentID, actionSentiment.MaxSentimentScore); if (!_ticketSentiments.ContainsKey(actionSentiment.TicketID)) { _ticketSentiments[actionSentiment.TicketID] = CreateTicketSentiment(actionSentiment, db, actionScore); continue; } // update existing TicketSentiment TicketSentiment sentiment = _ticketSentiments[actionSentiment.TicketID]; int count = sentiment.ActionSentimentCount; sentiment.AverageActionSentiment = (count * sentiment.AverageActionSentiment + actionScore) / (count + 1); sentiment.ActionSentimentCount = count + 1; sentiment.TicketSentimentScore = (int)Math.Round(sentiment.AverageActionSentiment); sentiment.SetSentimentID(actionSentiment.SentimentID); } int insertCount = 0; foreach (KeyValuePair <int, TicketSentiment> pair in _ticketSentiments) { pair.Value.Insert(db); if (++insertCount >= 1000) { Console.Write('.'); insertCount = 0; } } } } catch (Exception e) { WatsonEventLog.WriteEntry("Exception in RebuildTicketSentimentsTable", e); Console.WriteLine(e.ToString()); } }
/// <summary> /// first action sentiment creates the ticket sentiment /// </summary> TicketSentiment CreateTicketSentiment(MaxActionSentiment actionSentiment, DataContext db, double actionScore) { TicketSentiment ticketSentiment = new TicketSentiment() { TicketID = actionSentiment.TicketID, OrganizationID = actionSentiment.OrganizationID, IsAgent = actionSentiment.IsAgent, TicketDateCreated = actionSentiment.DateCreated, TicketSentimentScore = (int)Math.Round(actionScore), Sad = false, Frustrated = false, Satisfied = false, Excited = false, Polite = false, Impolite = false, Sympathetic = false, AverageActionSentiment = actionScore, ActionSentimentCount = 1 }; ticketSentiment.SetSentimentID(actionSentiment.SentimentID); return(ticketSentiment); }
public void RecordWatsonResults(ActionToAnalyze actionToAnalyze) { // insert ActionSentiment ActionSentiment sentiment = InsertActionSentiment(_db, actionToAnalyze); _db.SubmitChanges(); // get the DB generated ID int actionSentimentID = sentiment.ActionSentimentID; // insert child records - ActionSentimentScore(s) List <Tones> tones = actionToAnalyze.GetTones(); List <ActionSentimentScore> scores = InsertSentimentScores(tones, _db, actionSentimentID); // update the corresponding ticket sentiment if (!actionToAnalyze.IsAgent) { ActionSentimentScore maxScore = scores.Where(s => s.SentimentScore == scores.Max(a => a.SentimentScore)).First(); TicketSentiment.TicketSentimentStrategy(_db, actionToAnalyze, maxScore); } // Delete ActionToAnalyze actionToAnalyze.DeleteOnSubmit(_db); _db.SubmitChanges(); }