code: func trainClassifiers() error {
  	for _, pconf := range PluginsGo {
  		ss, err := fetchTrainingSentences(pconf.ID, pconf.Name)
  		if err != nil {
  			return err
  		}
  
  		// Assemble list of Bayesian classes from all trained intents
  		// for this plugin. m is used to keep track of the classes
  		// already taught to each classifier.
  		m := map[string]struct{}{}
  		for _, s := range ss {
  			_, ok := m[s.Intent]
  			if ok {
  				continue
  			}
  			log.Debug("learning intent", s.Intent)
  			m[s.Intent] = struct{}{}
  			pluginIntents[s.PluginID] = append(pluginIntents[s.PluginID],
  				bayesian.Class(s.Intent))
  		}
  
  		// Build classifier from complete sets of intents
  		for _, s := range ss {
  			intents := pluginIntents[s.PluginID]
  			// Calling bayesian.NewClassifier() with 0 or 1
  			// classes causes a panic.
  			if len(intents) == 0 {
  				break
  			}
  			if len(intents) == 1 {
  				intents = append(intents, bayesian.Class("__no_intent"))
  			}
  			c := bayesian.NewClassifier(intents...)
  			bClassifiers[s.PluginID] = c
  		}
  
  		// With classifiers initialized, train each of them on a
  		// sentence's stems.
  		for _, s := range ss {
  			tokens := TokenizeSentence(s.Sentence)
  			stems := StemTokens(tokens)
  			c, exists := bClassifiers[s.PluginID]
  			if exists {
  				c.Learn(stems, bayesian.Class(s.Intent))
  			}
  		}
  	}
  	return nil
  }
docs: // trainClassifiers trains classifiers for each plugin.