All Downloads are FREE. Search and download functionalities are using the official Maven repository.

nak.example.PpaExample.scala Maven / Gradle / Ivy

The newest version!
package nak.example

/*
 Copyright 2013 Jason Baldridge
 
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at 
 
 http://www.apache.org/licenses/LICENSE-2.0
 
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License. 
*/


/**
 * An example of using the API to classify the prepositional phrase attachment
 * data, trying to be as simple and self-contained as possible. Includes example
 * of how to serialize (save) and deserialize (load) a classifier.
 *
 * After compiling Nak, you can run it as follows (in the top-level of Nak):
 *
 * $ bin/nak run nak.example.PpaExample data/classify/ppa/training data/classify/ppa/devset ppa-classifier.obj 
 * 
 * @author jasonbaldridge
 */
object PpaExample {

  import nak.NakContext._
  import nak.core._
  import nak.data._
  import nak.liblinear.LiblinearConfig
  import nak.util.ConfusionMatrix

  def main(args: Array[String]) {
    val Array(trainfile, evalfile, fileForSavedClassifier) = args

    // A function (with supporting regex) that reads the format of the PPA
    // files and turns them into Examples. E.g. a line like:
    //   0 join board as director V
    // becames an Example with "V" as the label, and "join board as director"
    // as the features. Normally we'd go ahead and transform this into better
    // features, but this shows what you'd be more likely to do if reading in
    // documents.
    val PpaLineRE = """^(\d+)\s(.*)\s(N|V)$""".r
    def readRaw(filename: String) =
      for (PpaLineRE(id,obs,label) <- io.Source.fromFile(filename).getLines)
      yield Example(label, obs)

    // A featurizer that simply splits the raw inputs and attaches the
    // appropriate attributes to each of the elements.
    val featurizer = new Featurizer[String,String] {
      def apply(input: String) = {
        val attributes = Array("verb","object","prep","prep-obj")
        for ((attr,value) <- attributes.zip(input.split("\\s")))
        yield FeatureObservation(attr+"="+value)
      }
    }

    // Get the training examples in their raw format.
    val rawExamples = readRaw(trainfile).toList
    
    // Configure and train with liblinear. Here we use the (default) L2-Regularized
    // Logistic Regression classifier with a C value of .5. We accept the default
    // eps and verbosity values.
    val config = LiblinearConfig(cost=.5)
    val trainedClassifier = trainClassifier(config, featurizer, rawExamples)
    
    // Save the classifier to disk, then load it. Obviously not necessary here, but this
    // shows how to do it.
    saveClassifier(trainedClassifier, fileForSavedClassifier)
    val classifier = loadClassifier[FeaturizedClassifier[String,String]](fileForSavedClassifier)

    // Make predictions on the evaluation data. Because the classifier knows about
    // featurization, we can apply the classifier directly to each example using evalRaw.
    val comparisons = for (ex <- readRaw(evalfile).toList) yield
      (ex.label, classifier.predict(ex.features), ex.features)

    // Compute and print out the confusion matrix based on the comparisons
    // obtained above.
    val (goldLabels, predictions, inputs) = comparisons.unzip3
    println(ConfusionMatrix(goldLabels, predictions, inputs))
  }

}

object PpaExampleBinomial {

  import nak.NakContext._
  import nak.core._
  import nak.data._
  import nak.liblinear.LiblinearConfig
  import nak.util.ConfusionMatrix

  def main(args: Array[String]) {
    val Array(trainfile, evalfile, fileForSavedClassifier) = args

    // A function (with supporting regex) that reads the format of the PPA
    // files and turns them into Examples. E.g. a line like:
    //   0 join board as director V
    // becames an Example with "V" indicating "success" as its label ("N"
    // is "failure"), and "join board as director"
    // as the features. Normally we'd go ahead and transform this into better
    // features, but this shows what you'd be more likely to do if reading in
    // documents.
    val PpaLineRE = """^(\d+)\s(.*)\s(N|V)$""".r
    def readRaw(filename: String) =
      for (PpaLineRE(id,obs,label) <- io.Source.fromFile(filename).getLines)
      yield {
        val successFail = if (label=="V") (1,0) else (0,1)
        Example(successFail, obs)
      }

    // A featurizer that simply splits the raw inputs and attaches the
    // appropriate attributes to each of the elements.
    val featurizer = new Featurizer[String,String] {
      def apply(input: String) = {
        val attributes = Array("verb","object","prep","prep-obj")
        for ((attr,value) <- attributes.zip(input.split("\\s")))
        yield FeatureObservation(attr+"="+value)
      }
    }

    // Get the training examples in their raw format.
    val rawExamples = readRaw(trainfile).toList
    
    // Configure and train with liblinear. Here we use the (default) L2-Regularized
    // Logistic Regression classifier with a C value of .5. We accept the default
    // eps and verbosity values.
    val config = LiblinearConfig(cost=0.5)
    val trainedClassifier = trainBinomialClassifier(config, featurizer, rawExamples)
    
    // Save the classifier to disk, then load it. Obviously not necessary here, but this
    // shows how to do it.
    saveClassifier(trainedClassifier, fileForSavedClassifier)
    val classifier = loadClassifier[FeaturizedClassifier[String,String]](fileForSavedClassifier)

    // Make predictions on the evaluation data. Because the classifier knows about
    // featurization, we can apply the classifier directly to each example using evalRaw.
    val comparisons = for (ex <- readRaw(evalfile).toList) yield {
      val goldLabel = if (ex.label._1 == 1) "Y" else "N"
      (goldLabel, classifier.predict(ex.features), ex.features)
    }

    // Compute and print out the confusion matrix based on the comparisons
    // obtained above.
    val (goldLabels, predictions, inputs) = comparisons.unzip3
    println(ConfusionMatrix(goldLabels, predictions, inputs))
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy