Source code
The Scala programming language is used to implement and evaluate the machine learning techniques covered in Scala for machine learning. The source code presented in the book has been reduced to the minimum essential to the understanding of machine learning algorithms. The formal implementation of these algorithms is available on the website of Packt Publishing, http://www.packtpub.com.
Convention
The source code presented throughout the book follows a simple style guide and set of conventions.
Context bounds
Most of the Scala classes discussed in the book are parameterized with a type associated to the discrete/categorical value (Int
) or continuous value (Double
) [1:10]. For this book, context bounds are used instead of view bounds, as follows:
class A[T: ToInt](param: Param//implicit conversion to Int class C[T: ToDouble](param: Param)//implicit conversion to Double
Note
View bound deprecation
The notation for the view bound, T <% Double
, is being deprecated in Scala 2.11 and higher. The declaration class A[T <% Float]
is the short notation for class A[T](implicit f: T => Float)
.
Presentation
For the sake of readability of the implementation of algorithms, code non-essential to the understanding of a concept or algorithm, such as error checking, comments, exception, or import, is omitted. The following code elements are shown in the code snippets presented in the book:
- Code documentation:
// ….. /* … */
- Validation of
class
parameters and method arguments:require( Math.abs(x) < EPS, " …")
- Class qualifiers and scope declaration:
final protected class SVM { … } private[this] val lsError = …
- Method qualifiers:
final protected def dot: = …
- Exceptions:
try { correlate … } catch { case e: MathException => …. } Try { .. } match { case Success(res) => case Failure(e => .. }
- Logging and debugging code:
private val logger = Logger.getLogger("..") logger.info( … )
- Non-essential annotation:
@inline def main = …. @throw(classOf[IllegalStateException])
- Non-essential methods
The complete list of Scala code elements omitted in the code snippets in the book can be found in the Code snippets format section in the Appendix.
Primitives and implicits
The algorithms presented in this book share the same primitive types, generic operators, and implicit conversions. For the sake of the readability of the code, the following primitive types will be used:
type DblPair = (Double, Double) type DblArray = Array[Double] type DblMatrix = Array[DblArray] type DblVec = Vector[Double] type XSeries[T] = Vector[T] // One dimensional vector type XVSeries[T] = Vector[Array[T]] // multi-dimensional vector
Time series, introduced in the Time series section in Chapter 3, Data Preprocessing, are implemented as XSeries[T]
or XVSeries[T]
of the parameterized type T.
Make a note of these six types; they are used across the entire book.
The conversion between the primitive types listed above and types introduced in the particular library (that is, the Apache Commons Math library) is described in the relevant chapters.
Immutability
It is usually a good idea to reduce the number of states of an object. A method invocation transitions an object from one state to another. The larger the number of methods or states, the more cumbersome the testing process becomes.
For example, there is no point in creating a model that is not defined (trained). Therefore, making the training of a model as part of the constructor of the class it implements makes a lot of sense. Therefore, the only public methods of a machine learning algorithm are the following:
- Classification or prediction
- Validation
- Retrieval of model parameters (weights, latent variables, hidden states, and so on) if needed
Tip
Performance of Scala iterators
The evaluation of the performance of Scala high-order iterative methods is beyond the scope of this book. However, it is important to be aware of the trade-off of each method. For instance, the monadic for expression is to be avoided as a counting iterator. The source code presented in this book uses the higher-order method foreach
for iterative counting.