Use np.random.set_seed(42) and random_state=42 make notebook's output constant

main
Aurélien Geron 2017-06-06 23:13:43 +02:00
parent 6ec768b165
commit a331fe6404
1 changed files with 270 additions and 104 deletions

View File

@ -47,11 +47,10 @@
"\n",
"# Common imports\n",
"import numpy as np\n",
"import numpy.random as rnd\n",
"import os\n",
"\n",
"# to make this notebook's output stable across runs\n",
"rnd.seed(42)\n",
"np.random.seed(42)\n",
"\n",
"# To plot pretty figures\n",
"%matplotlib inline\n",
@ -85,7 +84,10 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"The next few code cells generate the first figures in chapter 5. The first actual code sample comes after:"
]
@ -253,7 +255,7 @@
"Xo2 = np.concatenate([X, X_outliers[1:]], axis=0)\n",
"yo2 = np.concatenate([y, y_outliers[1:]], axis=0)\n",
"\n",
"svm_clf2 = SVC(kernel=\"linear\", C=10**9)#float(\"inf\"))\n",
"svm_clf2 = SVC(kernel=\"linear\", C=10**9)\n",
"svm_clf2.fit(Xo2, yo2)\n",
"\n",
"plt.figure(figsize=(12,2.7))\n",
@ -303,7 +305,10 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"This is the first code example in chapter 5:"
]
@ -312,7 +317,9 @@
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": false
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
@ -328,7 +335,7 @@
"\n",
"svm_clf = Pipeline((\n",
" (\"scaler\", StandardScaler()),\n",
" (\"linear_svc\", LinearSVC(C=1, loss=\"hinge\")),\n",
" (\"linear_svc\", LinearSVC(C=1, loss=\"hinge\", random_state=42)),\n",
" ))\n",
"\n",
"svm_clf.fit(X, y)"
@ -338,7 +345,9 @@
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
@ -347,7 +356,10 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"Now let's generate the graph comparing different regularization settings:"
]
@ -363,8 +375,8 @@
"outputs": [],
"source": [
"scaler = StandardScaler()\n",
"svm_clf1 = LinearSVC(C=1, loss=\"hinge\")\n",
"svm_clf2 = LinearSVC(C=100, loss=\"hinge\")\n",
"svm_clf1 = LinearSVC(C=1, loss=\"hinge\", random_state=42)\n",
"svm_clf2 = LinearSVC(C=100, loss=\"hinge\", random_state=42)\n",
"\n",
"scaled_svm_clf1 = Pipeline((\n",
" (\"scaler\", scaler),\n",
@ -535,7 +547,7 @@
"polynomial_svm_clf = Pipeline((\n",
" (\"poly_features\", PolynomialFeatures(degree=3)),\n",
" (\"scaler\", StandardScaler()),\n",
" (\"svm_clf\", LinearSVC(C=10, loss=\"hinge\"))\n",
" (\"svm_clf\", LinearSVC(C=10, loss=\"hinge\", random_state=42))\n",
" ))\n",
"\n",
"polynomial_svm_clf.fit(X, y)"
@ -545,7 +557,9 @@
"cell_type": "code",
"execution_count": 14,
"metadata": {
"collapsed": false
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
@ -570,7 +584,9 @@
"cell_type": "code",
"execution_count": 15,
"metadata": {
"collapsed": false
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
@ -587,7 +603,9 @@
"cell_type": "code",
"execution_count": 16,
"metadata": {
"collapsed": false
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
@ -781,27 +799,31 @@
"cell_type": "code",
"execution_count": 22,
"metadata": {
"collapsed": true
"collapsed": true,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
"rnd.seed(42)\n",
"np.random.seed(42)\n",
"m = 50\n",
"X = 2 * rnd.rand(m, 1)\n",
"y = (4 + 3 * X + rnd.randn(m, 1)).ravel()"
"X = 2 * np.random.rand(m, 1)\n",
"y = (4 + 3 * X + np.random.randn(m, 1)).ravel()"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {
"collapsed": false
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
"from sklearn.svm import LinearSVR\n",
"\n",
"svm_reg = LinearSVR(epsilon=1.5)\n",
"svm_reg = LinearSVR(epsilon=1.5, random_state=42)\n",
"svm_reg.fit(X, y)"
]
},
@ -815,8 +837,8 @@
},
"outputs": [],
"source": [
"svm_reg1 = LinearSVR(epsilon=1.5)\n",
"svm_reg2 = LinearSVR(epsilon=0.5)\n",
"svm_reg1 = LinearSVR(epsilon=1.5, random_state=42)\n",
"svm_reg2 = LinearSVR(epsilon=0.5, random_state=42)\n",
"svm_reg1.fit(X, y)\n",
"svm_reg2.fit(X, y)\n",
"\n",
@ -877,21 +899,25 @@
"cell_type": "code",
"execution_count": 26,
"metadata": {
"collapsed": true
"collapsed": true,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
"rnd.seed(42)\n",
"np.random.seed(42)\n",
"m = 100\n",
"X = 2 * rnd.rand(m, 1) - 1\n",
"y = (0.2 + 0.1 * X + 0.5 * X**2 + rnd.randn(m, 1)/10).ravel()"
"X = 2 * np.random.rand(m, 1) - 1\n",
"y = (0.2 + 0.1 * X + 0.5 * X**2 + np.random.randn(m, 1)/10).ravel()"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {
"collapsed": false
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
@ -1149,7 +1175,7 @@
},
"outputs": [],
"source": [
"X, y = make_moons(n_samples=1000, noise=0.4)\n",
"X, y = make_moons(n_samples=1000, noise=0.4, random_state=42)\n",
"plt.plot(X[:, 0][y==0], X[:, 1][y==0], \"bs\")\n",
"plt.plot(X[:, 0][y==1], X[:, 1][y==1], \"g^\")"
]
@ -1232,8 +1258,8 @@
" def fit(self, X, y):\n",
" # Random initialization\n",
" if self.random_state:\n",
" rnd.seed(self.random_state)\n",
" w = rnd.randn(X.shape[1], 1) # n feature weights\n",
" np.random.seed(self.random_state)\n",
" w = np.random.randn(X.shape[1], 1) # n feature weights\n",
" b = 0\n",
"\n",
" m = len(X)\n",
@ -1416,21 +1442,30 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"# 8."
]
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"_Exercise: train a `LinearSVC` on a linearly separable dataset. Then train an `SVC` and a `SGDClassifier` on the same dataset. See if you can get them to produce roughly the same model._"
]
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"Let's use the Iris dataset: the Iris Setosa and Iris Versicolor classes are linearly separable."
]
@ -1439,7 +1474,9 @@
"cell_type": "code",
"execution_count": 44,
"metadata": {
"collapsed": true
"collapsed": true,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
@ -1471,7 +1508,7 @@
"C = 5\n",
"alpha = 1 / (C * len(X))\n",
"\n",
"lin_clf = LinearSVC(loss=\"hinge\", C=C)\n",
"lin_clf = LinearSVC(loss=\"hinge\", C=C, random_state=42)\n",
"svm_clf = SVC(kernel=\"linear\", C=C)\n",
"sgd_clf = SGDClassifier(loss=\"hinge\", learning_rate=\"constant\", eta0=0.001, alpha=alpha,\n",
" n_iter=100000, random_state=42)\n",
@ -1490,7 +1527,10 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"Let's plot the decision boundaries of these three models:"
]
@ -1499,7 +1539,9 @@
"cell_type": "code",
"execution_count": 46,
"metadata": {
"collapsed": false
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
@ -1533,28 +1575,40 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"Close enough!"
]
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"# 9."
]
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"_Exercise: train an SVM classifier on the MNIST dataset. Since SVM classifiers are binary classifiers, you will need to use one-versus-all to classify all 10 digits. You may want to tune the hyperparameters using small validation sets to speed up the process. What accuracy can you reach?_"
]
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"First, let's load the dataset and split it into a training set and a test set. We could use `train_test_split()` but people usually just take the first 60,000 instances for the training set, and the last 10,000 instances for the test set (this makes it possible to compare your model's performance with others): "
]
@ -1563,7 +1617,9 @@
"cell_type": "code",
"execution_count": 47,
"metadata": {
"collapsed": false
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
@ -1581,7 +1637,10 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"Many training algorithms are sensitive to the order of the training instances, so it's generally good practice to shuffle them first:"
]
@ -1590,7 +1649,9 @@
"cell_type": "code",
"execution_count": 48,
"metadata": {
"collapsed": true
"collapsed": true,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
@ -1602,7 +1663,10 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"Let's start simple, with a linear SVM classifier. It will automatically use the One-vs-All (also called One-vs-the-Rest, OvR) strategy, so there's nothing special we need to do. Easy!"
]
@ -1611,17 +1675,22 @@
"cell_type": "code",
"execution_count": 49,
"metadata": {
"collapsed": false
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
"lin_clf = LinearSVC()\n",
"lin_clf = LinearSVC(random_state=42)\n",
"lin_clf.fit(X_train, y_train)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"Let's make predictions on the training set and measure the accuracy (we don't want to measure it on the test set yet, since we have not selected and trained the final model yet):"
]
@ -1630,7 +1699,9 @@
"cell_type": "code",
"execution_count": 50,
"metadata": {
"collapsed": false
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
@ -1642,16 +1713,21 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"Wow, 85% accuracy on MNIST is a really bad performance. This linear model is certainly too simple for MNIST, but perhaps we just needed to scale the data first:"
"Wow, 82% accuracy on MNIST is a really bad performance. This linear model is certainly too simple for MNIST, but perhaps we just needed to scale the data first:"
]
},
{
"cell_type": "code",
"execution_count": 51,
"metadata": {
"collapsed": false
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
@ -1664,11 +1740,13 @@
"cell_type": "code",
"execution_count": 52,
"metadata": {
"collapsed": false
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
"lin_clf = LinearSVC()\n",
"lin_clf = LinearSVC(random_state=42)\n",
"lin_clf.fit(X_train_scaled, y_train)"
]
},
@ -1676,7 +1754,9 @@
"cell_type": "code",
"execution_count": 53,
"metadata": {
"collapsed": false
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
@ -1686,9 +1766,12 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"That's much better (we almost divided the error rate by half), but still not great at all for MNIST. If we want to use an SVM, we will have to use a kernel. Let's try an `SVC` with an RBF kernel (the default).\n",
"That's much better (we cut the error rate in two), but still not great at all for MNIST. If we want to use an SVM, we will have to use a kernel. Let's try an `SVC` with an RBF kernel (the default).\n",
"\n",
"**Warning**: if you are using Scikit-Learn ≤ 0.19, the `SVC` class will use the One-vs-One (OvO) strategy by default, so you must explicitly set `decision_function_shape=\"ovr\"` if you want to use the OvR strategy instead (OvR is the default since 0.19)."
]
@ -1697,7 +1780,9 @@
"cell_type": "code",
"execution_count": 54,
"metadata": {
"collapsed": false
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
@ -1709,7 +1794,9 @@
"cell_type": "code",
"execution_count": 55,
"metadata": {
"collapsed": false
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
@ -1719,7 +1806,10 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"That's promising, we get better performance even though we trained the model on 6 times less data. Let's tune the hyperparameters by doing a randomized search with cross validation. We will do this on a small dataset just to speed up the process:"
]
@ -1728,7 +1818,9 @@
"cell_type": "code",
"execution_count": 56,
"metadata": {
"collapsed": false
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
@ -1744,7 +1836,9 @@
"cell_type": "code",
"execution_count": 57,
"metadata": {
"collapsed": false
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
@ -1755,7 +1849,9 @@
"cell_type": "code",
"execution_count": 58,
"metadata": {
"collapsed": false
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
@ -1764,7 +1860,10 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"This looks pretty low but remember we only trained the model on 1,000 instances. Let's retrain the best estimator on the whole training set (run this at night, it will take hours):"
]
@ -1773,7 +1872,9 @@
"cell_type": "code",
"execution_count": 59,
"metadata": {
"collapsed": false
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
@ -1784,7 +1885,9 @@
"cell_type": "code",
"execution_count": 60,
"metadata": {
"collapsed": false
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
@ -1794,7 +1897,10 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"Ah, this looks good! Let's select this model. Now we can test it on the test set:"
]
@ -1803,7 +1909,9 @@
"cell_type": "code",
"execution_count": 61,
"metadata": {
"collapsed": false
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
@ -1813,37 +1921,51 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"Not too bad, but apparently the model is overfitting slightly. It's tempting to tweak the hyperparameters a bit more (e.g. decreasing `C` and/or `gamma`), but we would run the risk of overfitting the test set. Other people have found that the hyperparameters `C=5` and `gamma=0.005` yield even better performance (over 98% accuracy). By running the randomized search for longer and on a larger part of the training set, you may be able to find this as well."
]
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"## 10."
]
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"_Exercise: train an SVM regressor on the California housing dataset._"
]
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"Let's load the dataset using Scikit-Learn's `fetch_california_housing()` function:"
]
},
{
"cell_type": "code",
"execution_count": 63,
"execution_count": 62,
"metadata": {
"collapsed": true
"collapsed": true,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
@ -1856,16 +1978,21 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"Split it into a training set and a test set:"
]
},
{
"cell_type": "code",
"execution_count": 65,
"execution_count": 63,
"metadata": {
"collapsed": true
"collapsed": true,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
@ -1876,16 +2003,21 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"Don't forget to scale the data:"
]
},
{
"cell_type": "code",
"execution_count": 83,
"execution_count": 64,
"metadata": {
"collapsed": true
"collapsed": true,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
@ -1898,37 +2030,47 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"Let's train a simple `LinearSVR` first:"
]
},
{
"cell_type": "code",
"execution_count": 84,
"execution_count": 65,
"metadata": {
"collapsed": false
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
"from sklearn.svm import LinearSVR\n",
"\n",
"lin_svr = LinearSVR()\n",
"lin_svr = LinearSVR(random_state=42)\n",
"lin_svr.fit(X_train_scaled, y_train)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"Let's see how it performs on the training set:"
]
},
{
"cell_type": "code",
"execution_count": 92,
"execution_count": 66,
"metadata": {
"collapsed": false
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
@ -1941,16 +2083,21 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"Let's look at the RMSE:"
]
},
{
"cell_type": "code",
"execution_count": 93,
"execution_count": 67,
"metadata": {
"collapsed": false
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
@ -1959,16 +2106,21 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"In this training set, the targets are tens of thousands of dollars. The RMSE gives a rough idea of the kind of error you should expect (with a higher weight for large errors): so with this model we can expect errors somewhere around $10,000. Not great. Let's see if we can do better with an RBF Kernel. We will use randomized search with cross validation to find the appropriate hyperparameter values for `C` and `gamma`:"
]
},
{
"cell_type": "code",
"execution_count": 86,
"execution_count": 68,
"metadata": {
"collapsed": false
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
@ -1977,15 +2129,17 @@
"from scipy.stats import reciprocal, uniform\n",
"\n",
"param_distributions = {\"gamma\": reciprocal(0.001, 0.1), \"C\": uniform(1, 10)}\n",
"rnd_search_cv = RandomizedSearchCV(SVR(), param_distributions, n_iter=10, verbose=2)\n",
"rnd_search_cv = RandomizedSearchCV(SVR(), param_distributions, n_iter=10, verbose=2, random_state=42)\n",
"rnd_search_cv.fit(X_train_scaled, y_train)"
]
},
{
"cell_type": "code",
"execution_count": 90,
"execution_count": 69,
"metadata": {
"collapsed": false
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
@ -1994,16 +2148,21 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"Now let's measure the RMSE on the training set:"
]
},
{
"cell_type": "code",
"execution_count": 91,
"execution_count": 70,
"metadata": {
"collapsed": false
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
@ -2014,16 +2173,21 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"Looks much better than the linear model. Let's select this model and evaluate it on the test set:"
]
},
{
"cell_type": "code",
"execution_count": 94,
"execution_count": 71,
"metadata": {
"collapsed": false
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
@ -2036,7 +2200,9 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
"collapsed": true,
"deletable": true,
"editable": true
},
"outputs": [],
"source": []