anchor.diff:  
   === Indexing categorical features
   
  -Usually the first components in our Pipeline will be Transformers and Estimators
  -used to fit the data to the format expected by the algorithm we're using. One
  -such formatting requirement for the algorithm we're going to use is that every
  -feature should be numerical (no strings allowed) and since we have a couple of
  -columns containing strings, namely Sex and Embarked, we will have to transform
  -those into numerical columns.
  +Usually, the first components in our Pipeline will be Transformers and
  +Estimators used to fit the data to the format expected by the algorithm we're
  +using. One such formatting requirements for the algorithm we're going to use is
  +that every feature should be numerical (no strings allowed) and since we have a
  +couple of columns containing strings, namely Sex and Embarked, we will have to
  +transform those into numerical columns.
   
   Fortunately, there exists an Estimator for this use case: StringIndexer.
  -It will simply add a column to an existing Dataset indexing a column
  -containing string values. The most frequent values will get the smallest
  -indices. As an example consider this Dataset which could be a subset of the
  +It simply adds a column to an existing DataFrame indexing a column containing
  +string values. The most frequent values will get the smallest indices. As an
  +example, consider the DataFrame in table 2.4 which could be a subset of the
   Titanic one:
   
  -.Example Dataset containing a single Sex column
  +.Example DataFrame containing a single Sex column
   [options="header"]
   |===
   |Sex
  
positive.code: before assembler since the VectorAssembler assembles the indexed columns and
  decisionTree comes last since it uses the output of the VectorAssembler.
  
  If you remember correctly, a Pipeline is an Estimator and calling the fit method
  on it will actually trigger the indexing, assembling and learning of the
  algorithm that are contained in the Pipeline. This will effectively produces a
  Transformer capable of adding a column to a Dataset with the predictions
  given by the algorithm or, in other words, a machine learning model.
  
  However, there is still a small requirement we're not meeting: every machine
  learning algorithm in Spark ML needs the label column to contain doubles. As is,
  the label column (Survived) contains integers as indicated by the printSchema
  method on imputedTitanicTrain.
  
  .Casting the Survived column to double
  [source,scala]
  
negative.code: 
  === Loading the test data
  
  We load the test data in the same way we loaded the training data, assuming it's
  located at '/data/test.csv' (listing 2.15):
  
  .Loading our test data into a DataFrame using the SparkSession made available in the REPL
  [source,scala]
  ----
  val testFilePath = "/data/test.csv"
  