{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 3.1 Machine Learning - Introduction\n", "\n", "This notebook demonstrates the basics of using SparkML for Machine Learning. We will build a few different regression models, tune their parameters and evaluate their performance.\n", "\n", "We will be using the wine quality dataset from: https://archive.ics.uci.edu/ml/datasets/Wine+Quality, which captures various physical properties of wines (alcohol content, acidity etc) and their quality as apprised by wine experts (`data/winequality-white.csv`)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's preview the data first:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\"fixed acidity\";\"volatile acidity\";\"citric acid\";\"residual sugar\";\"chlorides\";\"free sulfur dioxide\";\"total sulfur dioxide\";\"density\";\"pH\";\"sulphates\";\"alcohol\";\"quality\"\n", "7;0.27;0.36;20.7;0.045;45;170;1.001;3;0.45;8.8;6\n", "6.3;0.3;0.34;1.6;0.049;14;132;0.994;3.3;0.49;9.5;6\n", "8.1;0.28;0.4;6.9;0.05;30;97;0.9951;3.26;0.44;10.1;6\n", "7.2;0.23;0.32;8.5;0.058;47;186;0.9956;3.19;0.4;9.9;6\n" ] } ], "source": [ "%%sh\n", "\n", "# preview the data file\n", "\n", "head -n 5 data/winequality-white.csv" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It's a semi-colon delimited text file with the header.\n", "\n", "SparkML operates on DataFrames so we need to create one with our data:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# load contents of winequality-white.csv to spark DataFrma\n", "# we need to specify the custom separator `;`\n", "inputDF = spark.read.csv('data/winequality-white.csv',header='true', inferSchema='true', sep=';')" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "root\n", " |-- fixed acidity: double (nullable = true)\n", " |-- volatile acidity: double (nullable = true)\n", " |-- citric acid: double (nullable = true)\n", " |-- residual sugar: double (nullable = true)\n", " |-- chlorides: double (nullable = true)\n", " |-- free sulfur dioxide: double (nullable = true)\n", " |-- total sulfur dioxide: double (nullable = true)\n", " |-- density: double (nullable = true)\n", " |-- pH: double (nullable = true)\n", " |-- sulphates: double (nullable = true)\n", " |-- alcohol: double (nullable = true)\n", " |-- quality: integer (nullable = true)\n", "\n", "Rows: 4898\n" ] } ], "source": [ "# let's see the schema and the number of rows\n", "inputDF.printSchema()\n", "print(\"Rows: %s\" % inputDF.count())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Our dataframe is relatively small. In fact it is so small that we could easily analyse using standard `python` tools. However the code below, which is currenlty running on a sigle computer can be easily run on large spark clusters to analyse dataframes with billions of rows.\n", "\n", "Let's see as sample of the data:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/html": [ "<div>\n", "<table border=\"1\" class=\"dataframe\">\n", " <thead>\n", " <tr style=\"text-align: right;\">\n", " <th></th>\n", " <th>fixed acidity</th>\n", " <th>volatile acidity</th>\n", " <th>citric acid</th>\n", " <th>residual sugar</th>\n", " <th>chlorides</th>\n", " <th>free sulfur dioxide</th>\n", " <th>total sulfur dioxide</th>\n", " <th>density</th>\n", " <th>pH</th>\n", " <th>sulphates</th>\n", " <th>alcohol</th>\n", " <th>quality</th>\n", " </tr>\n", " </thead>\n", " <tbody>\n", " <tr>\n", " <th>0</th>\n", " <td>7.0</td>\n", " <td>0.27</td>\n", " <td>0.36</td>\n", " <td>20.7</td>\n", " <td>0.045</td>\n", " <td>45.0</td>\n", " <td>170.0</td>\n", " <td>1.0010</td>\n", " <td>3.00</td>\n", " <td>0.45</td>\n", " <td>8.8</td>\n", " <td>6</td>\n", " </tr>\n", " <tr>\n", " <th>1</th>\n", " <td>6.3</td>\n", " <td>0.30</td>\n", " <td>0.34</td>\n", " <td>1.6</td>\n", " <td>0.049</td>\n", " <td>14.0</td>\n", " <td>132.0</td>\n", " <td>0.9940</td>\n", " <td>3.30</td>\n", " <td>0.49</td>\n", " <td>9.5</td>\n", " <td>6</td>\n", " </tr>\n", " <tr>\n", " <th>2</th>\n", " <td>8.1</td>\n", " <td>0.28</td>\n", " <td>0.40</td>\n", " <td>6.9</td>\n", " <td>0.050</td>\n", " <td>30.0</td>\n", " <td>97.0</td>\n", " <td>0.9951</td>\n", " <td>3.26</td>\n", " <td>0.44</td>\n", " <td>10.1</td>\n", " <td>6</td>\n", " </tr>\n", " <tr>\n", " <th>3</th>\n", " <td>7.2</td>\n", " <td>0.23</td>\n", " <td>0.32</td>\n", " <td>8.5</td>\n", " <td>0.058</td>\n", " <td>47.0</td>\n", " <td>186.0</td>\n", " <td>0.9956</td>\n", " <td>3.19</td>\n", " <td>0.40</td>\n", " <td>9.9</td>\n", " <td>6</td>\n", " </tr>\n", " <tr>\n", " <th>4</th>\n", " <td>7.2</td>\n", " <td>0.23</td>\n", " <td>0.32</td>\n", " <td>8.5</td>\n", " <td>0.058</td>\n", " <td>47.0</td>\n", " <td>186.0</td>\n", " <td>0.9956</td>\n", " <td>3.19</td>\n", " <td>0.40</td>\n", " <td>9.9</td>\n", " <td>6</td>\n", " </tr>\n", " </tbody>\n", "</table>\n", "</div>" ], "text/plain": [ "DataFrame[fixed acidity: double, volatile acidity: double, citric acid: double, residual sugar: double, chlorides: double, free sulfur dioxide: double, total sulfur dioxide: double, density: double, pH: double, sulphates: double, alcohol: double, quality: int]" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(inputDF.limit(5))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here we will show a few example of using Spark ML to build regression models that **predict the quality of wine based on its properties**." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We have called the new dataframe `dataDF` and applied caching to it. This will tell Spark to try to cache the data in memory for faster access." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### The Basics of Model Building\n", "\n", "\n", "We will now build a simple linear *regression model*.\n", "\n", "Spark requires that all the predictors (features) are combined into a single feature vector.\n", "\n", "We can use `VectorAssembler` to build it from selected columns of our `DataFrame` (we will use all properties):" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "root\n", " |-- fixed acidity: double (nullable = true)\n", " |-- volatile acidity: double (nullable = true)\n", " |-- citric acid: double (nullable = true)\n", " |-- residual sugar: double (nullable = true)\n", " |-- chlorides: double (nullable = true)\n", " |-- free sulfur dioxide: double (nullable = true)\n", " |-- total sulfur dioxide: double (nullable = true)\n", " |-- density: double (nullable = true)\n", " |-- pH: double (nullable = true)\n", " |-- sulphates: double (nullable = true)\n", " |-- alcohol: double (nullable = true)\n", " |-- quality: integer (nullable = true)\n", " |-- features: vector (nullable = true)\n", "\n" ] } ], "source": [ "from pyspark.mllib.linalg import Vectors\n", "from pyspark.ml.feature import VectorAssembler\n", "\n", "# select the columns to be used as the features (all except `quality`)\n", "featureColumns = [c for c in inputDF.columns if c != 'quality']\n", "\n", "# create and configure the assembler\n", "assembler = VectorAssembler(inputCols=featureColumns, \n", " outputCol=\"features\")\n", "\n", "# transform the original data\n", "dataDF = assembler.transform(inputDF)\n", "dataDF.printSchema()" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/html": [ "<div>\n", "<table border=\"1\" class=\"dataframe\">\n", " <thead>\n", " <tr style=\"text-align: right;\">\n", " <th></th>\n", " <th>fixed acidity</th>\n", " <th>volatile acidity</th>\n", " <th>citric acid</th>\n", " <th>residual sugar</th>\n", " <th>chlorides</th>\n", " <th>free sulfur dioxide</th>\n", " <th>total sulfur dioxide</th>\n", " <th>density</th>\n", " <th>pH</th>\n", " <th>sulphates</th>\n", " <th>alcohol</th>\n", " <th>quality</th>\n", " <th>features</th>\n", " </tr>\n", " </thead>\n", " <tbody>\n", " <tr>\n", " <th>0</th>\n", " <td>7.0</td>\n", " <td>0.27</td>\n", " <td>0.36</td>\n", " <td>20.7</td>\n", " <td>0.045</td>\n", " <td>45.0</td>\n", " <td>170.0</td>\n", " <td>1.0010</td>\n", " <td>3.00</td>\n", " <td>0.45</td>\n", " <td>8.8</td>\n", " <td>6</td>\n", " <td>[7.0, 0.27, 0.36, 20.7, 0.045, 45.0, 170.0, 1....</td>\n", " </tr>\n", " <tr>\n", " <th>1</th>\n", " <td>6.3</td>\n", " <td>0.30</td>\n", " <td>0.34</td>\n", " <td>1.6</td>\n", " <td>0.049</td>\n", " <td>14.0</td>\n", " <td>132.0</td>\n", " <td>0.9940</td>\n", " <td>3.30</td>\n", " <td>0.49</td>\n", " <td>9.5</td>\n", " <td>6</td>\n", " <td>[6.3, 0.3, 0.34, 1.6, 0.049, 14.0, 132.0, 0.99...</td>\n", " </tr>\n", " <tr>\n", " <th>2</th>\n", " <td>8.1</td>\n", " <td>0.28</td>\n", " <td>0.40</td>\n", " <td>6.9</td>\n", " <td>0.050</td>\n", " <td>30.0</td>\n", " <td>97.0</td>\n", " <td>0.9951</td>\n", " <td>3.26</td>\n", " <td>0.44</td>\n", " <td>10.1</td>\n", " <td>6</td>\n", " <td>[8.1, 0.28, 0.4, 6.9, 0.05, 30.0, 97.0, 0.9951...</td>\n", " </tr>\n", " </tbody>\n", "</table>\n", "</div>" ], "text/plain": [ "DataFrame[fixed acidity: double, volatile acidity: double, citric acid: double, residual sugar: double, chlorides: double, free sulfur dioxide: double, total sulfur dioxide: double, density: double, pH: double, sulphates: double, alcohol: double, quality: int, features: vector]" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(dataDF.limit(3))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can use the assembler to `transform` our input dataframe into one that includes the feature vector (`features`) shown above.\n", "\n", "Now we are ready to train a simple regession model:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from pyspark.ml.regression import LinearRegression\n", "\n", "# fit a `LinearRegression` model using features in colum `features` and label in column `quality`\n", "lr = LinearRegression(maxIter=30, regParam=0.3, elasticNetParam=0.3, featuresCol=\"features\", labelCol=\"quality\")\n", "lrModel = lr.fit(dataDF)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can now look at the linear regression the coefficients: " ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "('fixed acidity', 0.0)\n", "('volatile acidity', -0.79168917102449954)\n", "('citric acid', 0.0)\n", "('residual sugar', 0.0)\n", "('chlorides', -0.10550323778501457)\n", "('free sulfur dioxide', 0.0)\n", "('total sulfur dioxide', 0.0)\n", "('density', 0.0)\n", "('pH', 0.0)\n", "('sulphates', 0.0)\n", "('alcohol', 0.19726471378350921)\n" ] } ], "source": [ "for t in zip(featureColumns, lrModel.coefficients):\n", " print t" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You may notice that for most properties the coefficients are zero, which means that they do not contribute (according to this specific model) to wine quality. \n", "\n", "This model is using elastic net regularizations which naturally 'selects' the most important variables (as it in turns uses LASSO)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can now use the model to make predictions:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/html": [ "<div>\n", "<table border=\"1\" class=\"dataframe\">\n", " <thead>\n", " <tr style=\"text-align: right;\">\n", " <th></th>\n", " <th>fixed acidity</th>\n", " <th>volatile acidity</th>\n", " <th>citric acid</th>\n", " <th>residual sugar</th>\n", " <th>chlorides</th>\n", " <th>free sulfur dioxide</th>\n", " <th>total sulfur dioxide</th>\n", " <th>density</th>\n", " <th>pH</th>\n", " <th>sulphates</th>\n", " <th>alcohol</th>\n", " <th>quality</th>\n", " <th>features</th>\n", " <th>prediction</th>\n", " </tr>\n", " </thead>\n", " <tbody>\n", " <tr>\n", " <th>0</th>\n", " <td>7.0</td>\n", " <td>0.27</td>\n", " <td>0.36</td>\n", " <td>20.7</td>\n", " <td>0.045</td>\n", " <td>45.0</td>\n", " <td>170.0</td>\n", " <td>1.0010</td>\n", " <td>3.00</td>\n", " <td>0.45</td>\n", " <td>8.8</td>\n", " <td>6</td>\n", " <td>[7.0, 0.27, 0.36, 20.7, 0.045, 45.0, 170.0, 1....</td>\n", " <td>5.546351</td>\n", " </tr>\n", " <tr>\n", " <th>1</th>\n", " <td>6.3</td>\n", " <td>0.30</td>\n", " <td>0.34</td>\n", " <td>1.6</td>\n", " <td>0.049</td>\n", " <td>14.0</td>\n", " <td>132.0</td>\n", " <td>0.9940</td>\n", " <td>3.30</td>\n", " <td>0.49</td>\n", " <td>9.5</td>\n", " <td>6</td>\n", " <td>[6.3, 0.3, 0.34, 1.6, 0.049, 14.0, 132.0, 0.99...</td>\n", " <td>5.660263</td>\n", " </tr>\n", " <tr>\n", " <th>2</th>\n", " <td>8.1</td>\n", " <td>0.28</td>\n", " <td>0.40</td>\n", " <td>6.9</td>\n", " <td>0.050</td>\n", " <td>30.0</td>\n", " <td>97.0</td>\n", " <td>0.9951</td>\n", " <td>3.26</td>\n", " <td>0.44</td>\n", " <td>10.1</td>\n", " <td>6</td>\n", " <td>[8.1, 0.28, 0.4, 6.9, 0.05, 30.0, 97.0, 0.9951...</td>\n", " <td>5.794351</td>\n", " </tr>\n", " </tbody>\n", "</table>\n", "</div>" ], "text/plain": [ "DataFrame[fixed acidity: double, volatile acidity: double, citric acid: double, residual sugar: double, chlorides: double, free sulfur dioxide: double, total sulfur dioxide: double, density: double, pH: double, sulphates: double, alcohol: double, quality: int, features: vector, prediction: double]" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# predict the quality, the predicted quality will be saved in `prediction` column\n", "predictionsDF = lrModel.transform(dataDF)\n", "display(predictionsDF.limit(3))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we can evaluate the performance of our model with Root Mean Squared Error:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Root Mean Squared Error (RMSE) = 0.794772\n" ] } ], "source": [ "from pyspark.ml.evaluation import RegressionEvaluator\n", "\n", "# create a regression evaluator with RMSE metrics\n", "\n", "evaluator = RegressionEvaluator(\n", " labelCol='quality', predictionCol=\"prediction\", metricName=\"rmse\")\n", "rmse = evaluator.evaluate(predictionsDF)\n", "print(\"Root Mean Squared Error (RMSE) = %g\" % rmse)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To get some idea of how good the model is we can try to compare it to the 'zero' model that always predicts the average `quality`." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "5.87790935076\n", "RMSE of 'zero model' = 0.885548\n" ] } ], "source": [ "from pyspark.sql.functions import *\n", "\n", "# calculate the average wine quality\n", "avgQuality = inputDF.groupBy().avg('quality').first()[0]\n", "print(avgQuality)\n", "\n", "# compute the 'zero' model predictions\n", "# `lit` function creates a 'literal' column that is column with the provided value in all rows\n", "zeroModelPredictionsDF = dataDF.select(col('quality'), lit(avgQuality).alias('prediction'))\n", "\n", "# evaluate the 'zero' model\n", "zeroModelRmse = evaluator.evaluate(zeroModelPredictionsDF)\n", "print(\"RMSE of 'zero model' = %g\" % zeroModelRmse)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So we did a little bit better. But this is actually a very biased 'best case' estimate of the RMSE. \n", "\n", "**Why?**" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Traning Evaluating Models with Pipelines\n", "\n", "We will first split our data into traning and testing set and then train a regression model only on the traning set and use the test set for evaluation. \n", "\n", "Rather then using our transformed `dataDF` we will chaing the preprocessing (vector assembling) and model traning into a simple `Pipeline`.\n", "\n", "In general pipelines may include may steps dealing with feature preprocessing, extraction etc." ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# split the input data into traning and test dataframes with 70% to 30% weights\n", "(trainingDF, testDF) = inputDF.randomSplit([0.7, 0.3])" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "RMSE on traning data = 0.795078\n", "RMSE on test data = 0.796021\n" ] } ], "source": [ "from pyspark.ml import Pipeline\n", "\n", "# construct the `Pipeline` that with two stages: the `vector assembler` and `regresion model estimator`\n", "pipeline = Pipeline(stages=[assembler, lr])\n", "\n", "# train the pipleline on the traning data\n", "lrPipelineModel = pipeline.fit(trainingDF)\n", "\n", "# make predictions\n", "traningPredictionsDF = lrPipelineModel.transform(trainingDF)\n", "testPredictionsDF = lrPipelineModel.transform(testDF)\n", "\n", "# evaluate the model on test and traning data\n", "print(\"RMSE on traning data = %g\" % evaluator.evaluate(traningPredictionsDF))\n", "\n", "print(\"RMSE on test data = %g\" % evaluator.evaluate(testPredictionsDF))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As we can see the the RMSE on test data is slighly worse than on the traning data. The difference is not significant though.\n", "\n", "** Why? **\n", "\n", "### Model Tuning\n", "\n", "For many models their perfomance signficanly depends on the model parameters. They need to be chosen for each data set differnly and the process of finding the best parameters is called 'model tuning'.\n", "\n", "In our previous example we used to parameters for `LinearRegression`: `regParam=0.3, elasticNetParam=0.3` with ad hoc values.\n", "\n", "Perhaps we can get a better model if we can tune these parameters. \n", "\n", "Spark ML comes with a ready to use parameter optimiser that uses *cross-validation* to select the best set of parameter from the provided *search grid*." ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from pyspark.ml.tuning import ParamGridBuilder\n", "from pyspark.ml.tuning import CrossValidator\n", "\n", "# create a search grid with the cross-product of the parameter values (9 pairs)\n", "search_grid = ParamGridBuilder() \\\n", " .addGrid(lr.regParam, [0.0, 0.3, 0.6]) \\\n", " .addGrid(lr.elasticNetParam, [0.4, 0.6, 0.8]).build()\n", "\n", "# use `CrossValidator` to tune the model\n", "cv = CrossValidator(estimator = pipeline, estimatorParamMaps = search_grid, evaluator = evaluator, numFolds = 3)\n", "cvModel = cv.fit(trainingDF)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "RMSE on test data with CV = 0.744801\n" ] } ], "source": [ "# evaluate the tuned model\n", "cvTestPredictionsDF = cvModel.transform(testDF)\n", "print(\"RMSE on test data with CV = %g\" % evaluator.evaluate(cvTestPredictionsDF))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This model is slightly better than the guessed model. \n", "\n", "We can also check the cross-validation estimates of RMSE for each of the tested models:" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0.7603682284613418, 0.8033308183021621, 0.8457340595931081, 0.7603682284613418, 0.8223707428602518, 0.8771370047191096, 0.7603682284613418, 0.8355346846704595, 0.8848078566281203]\n" ] } ], "source": [ "print(cvModel.avgMetrics)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Traning Random Forest\n", "\n", "Linear regression is a very simple model. Perhaps we can do better with a more complex one? Let's try to use RandomForest." ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from pyspark.ml.regression import RandomForestRegressor\n", "\n", "# define the random forest estimator\n", "rf = RandomForestRegressor(featuresCol=\"features\", labelCol=\"quality\", numTrees=100, maxBins=128, maxDepth=20, \\\n", " minInstancesPerNode=5, seed=33)\n", "rfPipeline = Pipeline(stages=[assembler, rf])\n", "\n", "# train the random forest model\n", "rfPipelineModel = rfPipeline.fit(trainingDF)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's evaluate the model:" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Random Forest RMSE on traning data = 0.405166\n", "Random Forest RMSE on test data = 0.635806\n" ] } ], "source": [ "rfTrainingPredictions = rfPipelineModel.transform(trainingDF)\n", "rfTestPredictions = rfPipelineModel.transform(testDF)\n", "print(\"Random Forest RMSE on traning data = %g\" % evaluator.evaluate(rfTrainingPredictions))\n", "print(\"Random Forest RMSE on test data = %g\" % evaluator.evaluate(rfTestPredictions))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Random forest does indeed better than linear regression. Please also notice the difference bewteen the peformance on the traning ang testing sets.\n", "\n", "\n", "We can 'extract' the actual random forest model from the `Pipeline` stage. We can use it for example to look at variable importance measure: " ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "SparseVector(11, {0: 0.0621, 1: 0.1159, 2: 0.0693, 3: 0.0722, 4: 0.0793, 5: 0.0979, 6: 0.0718, 7: 0.1122, 8: 0.0678, 9: 0.0535, 10: 0.198})" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rfModel = rfPipelineModel.stages[1]\n", "rfModel.featureImportances" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The model as well as the entire pipelines can be saved to disk and then loaded when needed." ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# save the random forest pipeline to the disk\n", "rfPipelineModel.write().overwrite().save('output/rf.model')" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# load the andom forest pipeline from the dist\n", "from pyspark.ml import PipelineModel\n", "loadedModel = PipelineModel.load('output/rf.model')\n", "loadedPredictionsDF = loadedModel.transform(testDF)" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Loaded model RMSE = 0.635806\n" ] } ], "source": [ "# evaluate the model again to see if we get the same performance\n", "print(\"Loaded model RMSE = %g\" % evaluator.evaluate(loadedPredictionsDF))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Data visualisation (bonus)\n", "\n", "Here we will use Principal Component Analysis to reduce the data dimesionalit so that we can plot the in 2D space.\n", "\n", "As before we will create a multi step pipeline that will:\n", "\n", "* assemble the feature vector from all predictors\n", "* normalise the features (to 0 mean and 1 stddev) \n", "* extract two most significant PCA components\n" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/html": [ "<div>\n", "<table border=\"1\" class=\"dataframe\">\n", " <thead>\n", " <tr style=\"text-align: right;\">\n", " <th></th>\n", " <th>features</th>\n", " <th>norm_features</th>\n", " <th>pca_features</th>\n", " </tr>\n", " </thead>\n", " <tbody>\n", " <tr>\n", " <th>0</th>\n", " <td>[7.0, 0.27, 0.36, 20.7, 0.045, 45.0, 170.0, 1....</td>\n", " <td>[0.0394465814369, 0.00152151099828, 0.00202868...</td>\n", " <td>[0.00738132933449, -0.167246598583]</td>\n", " </tr>\n", " <tr>\n", " <th>1</th>\n", " <td>[6.3, 0.3, 0.34, 1.6, 0.049, 14.0, 132.0, 0.99...</td>\n", " <td>[0.0472672209264, 0.00225082004412, 0.00255092...</td>\n", " <td>[-0.146221111792, -0.153299522903]</td>\n", " </tr>\n", " <tr>\n", " <th>2</th>\n", " <td>[8.1, 0.28, 0.4, 6.9, 0.05, 30.0, 97.0, 0.9951...</td>\n", " <td>[0.0789116854197, 0.00272781134784, 0.00389687...</td>\n", " <td>[0.0445900247096, -0.104780780881]</td>\n", " </tr>\n", " </tbody>\n", "</table>\n", "</div>" ], "text/plain": [ "DataFrame[features: vector, norm_features: vector, pca_features: vector]" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from pyspark.mllib.linalg import Vectors\n", "from pyspark.ml.feature import PCA\n", "from pyspark.ml.feature import Normalizer\n", "from pyspark.ml.feature import VectorAssembler\n", "from pyspark.ml import Pipeline\n", "\n", "all_assembler = VectorAssembler(\n", " inputCols=featureColumns,\n", " outputCol=\"features\")\n", "normalizer = Normalizer(inputCol=\"features\", outputCol=\"norm_features\")\n", "pca = PCA(k=2, inputCol=\"norm_features\", outputCol=\"pca_features\")\n", "\n", "pca_pipeline = Pipeline(stages=[all_assembler, normalizer, pca])\n", "\n", "pca_model = pca_pipeline.fit(inputDF)\n", "\n", "display(pca_model.transform(inputDF).select('features', 'norm_features', 'pca_features').limit(3))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `pca_features` column now contains the reduced 2D representation of all other features.\n", "\n", "We can now use it to visualise a 30% sample of the data. The color represents quality of wine.\n" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "scrolled": false }, "outputs": [ { "data": { "image/png": "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\nQmCC\n", "text/plain": [ "<matplotlib.figure.Figure at 0x1124ef050>" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "plt.rcParams[\"figure.figsize\"] = (10,7)\n", "pca_data = pca_model.transform(inputDF)\n", "\n", "sampling_fraction = 0.5\n", "\n", "pca_xy = np.matrix(map(lambda r:r.pca_features.array, pca_data.sample(False, sampling_fraction, 13).collect()))\n", "pca_colors = map(lambda r: float(r.quality),inputDF.select('quality').sample(False, sampling_fraction, 13).collect())\n", "plt.close()\n", "plt.scatter(pca_xy[:,0], pca_xy[:,1], c=pca_colors, alpha=0.4, cmap=plt.get_cmap('RdYlGn'), edgecolors='none', s=50)\n", "plt.grid(True)\n", "plt.show()\n", "display()" ] } ], "metadata": { "kernelspec": { "display_name": "PySpark", "language": "python", "name": "pyspark" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.11" } }, "nbformat": 4, "nbformat_minor": 1 }