What is Random State? And Why is it Always 42?
An inquiry into what the number 42 has to do with machine learning and the universe
If you’re like me and have used or been interested in using artificial intelligence or machine learning to solve various real-world problems, then you have undoubtedly run into the mystical Random State variable and wondered: why is it always 42? Well, turns out the answer is far less mundane than the explanation you typically get on StackOverflow threads about esoteric variable settings.
If you’re just here for the answer to the titular question, then here it is: the number doesn’t really matter; it’s an arbitrary number fed into the program to dictate that the program should use a specific seed of randomness (42). This is so the same set of pseudo-random numbers is generated each time we run the program. This answer isn’t quite satisfactory though as it leads us to another larger question: If it doesn’t matter then why do people always choose 42?
Turns out the answer to this question is equal parts science and fiction. The number 42 is sort of an ongoing inside joke in the scientific and science fiction community and is derived from the legendary Hitchhiker’s Guide to the Galaxy by Douglas Adams wherein an enormous supercomputer named Deep Thought calculates the “Answer to the Ultimate Question of Life…” over the period of 7.5 million years. This was originally intended to be entirely a joke but since its publication in 1979, science fiction junkies and nerds alike have attempted to impute meaning to the number and somewhat verify its claim of answering the “Ultimate Question of Life, the Universe and Everything”. You can check out the many pop culture references to the number 42 on its dedicated Wikipedia page.
The ironic part is that Douglas Adams himself undermines everyone’s obsession with the number:
“It was a joke. It had to be a number, an ordinary, smallish number, and I chose that one. Binary representations, base 13, Tibetan monks are all complete nonsense. I sat on my desk, stared in to the garden and thought 42 will do. I typed it out. End of story.”
Despite Adams’ attempts to quell the world’s feverish fascination with the number, people don’t hesitate to search for and point out the occurrences of the number 42. To name a few:
- The Titanic was traveling at a speed of 42 km/hour when it collided with the iceberg
- On page 42 of Harry Potter and the Philosopher’s Stone, Harry finds out he is a wizard
- In the Book of Revelation, it is prophesied that the beast will hold dominion over the earth for 42 months.
- 42 is the angle rounded to whole degrees for which a rainbow appears (the critical angle).
- Lewis Carrol, a mathematician and writer made use of the number several times in his works. For example, rule Forty-two in Alice’s Adventures in Wonderland (“All persons more than a mile high to leave the court”).
- Alice’s attempts at multiplication (chapter two of Alice in Wonderland) work if one uses base 18 to write the first answer, and increases the base by threes to 21, 24, etc. (the answers working up to 4 × 12 = “19” in base 39), but “breaks” precisely when one attempts the answer to 4 × 13 in base 42, leading Alice to declare “oh dear! I shall never get to twenty at that rate!”
So, why do we set Random State to 42 when running Machine Learning algorithms?
Because, it is simply the answer to life, the universe and everything.
…Or if you’re a bit less romantic about it, it’s because geeks and nerds alike really enjoy science fiction and one of the most famous science fiction books ever written heavily associates the number 42 with advanced machine learning and artificial intelligence.
I, personally, love running into little easter eggs like this in my life, and get a kick out of the fact that people around the world unquestioningly set 42 as their random state variable, unaware of its hilarious history and pop culture relevance.
If you liked this article and would like to read more stuff like this in the future, consider giving me a follow on Medium. Thanks for reading.
10. Common pitfalls and recommended practices¶
The purpose of this chapter is to illustrate some common pitfalls and anti-patterns that occur when using scikit-learn. It provides examples of what not to do, along with a corresponding correct example.
10.1. Inconsistent preprocessing¶
scikit-learn provides a library of Dataset transformations , which may clean (see Preprocessing data ), reduce (see Unsupervised dimensionality reduction ), expand (see Kernel Approximation ) or generate (see Feature extraction ) feature representations. If these data transforms are used when training a model, they also must be used on subsequent datasets, whether it’s test data or data in a production system. Otherwise, the feature space will change, and the model will not be able to perform effectively.
For the following example, let’s create a synthetic dataset with a single feature:
Wrong
The train dataset is scaled, but not the test dataset, so model performance on the test dataset is worse than expected:
Right
Instead of passing the non-transformed X_test to predict , we should transform the test data, the same way we transformed the training data:
Alternatively, we recommend using a Pipeline , which makes it easier to chain transformations with estimators, and reduces the possibility of forgetting a transformation:
Pipelines also help avoiding another common pitfall: leaking the test data into the training data.
10.2. Data leakage¶
Data leakage occurs when information that would not be available at prediction time is used when building the model. This results in overly optimistic performance estimates, for example from cross-validation , and thus poorer performance when the model is used on actually novel data, for example during production.
A common cause is not keeping the test and train data subsets separate. Test data should never be used to make choices about the model. The general rule is to never call fit on the test data. While this may sound obvious, this is easy to miss in some cases, for example when applying certain pre-processing steps.
Although both train and test data subsets should receive the same preprocessing transformation (as described in the previous section), it is important that these transformations are only learnt from the training data. For example, if you have a normalization step where you divide by the average value, the average should be the average of the train subset, not the average of all the data. If the test subset is included in the average calculation, information from the test subset is influencing the model.
An example of data leakage during preprocessing is detailed below.
10.2.1. Data leakage during pre-processing¶
We here choose to illustrate data leakage with a feature selection step. This risk of leakage is however relevant with almost all transformations in scikit-learn, including (but not limited to) StandardScaler , SimpleImputer , and PCA .
A number of Feature selection functions are available in scikit-learn. They can help remove irrelevant, redundant and noisy features as well as improve your model build time and performance. As with any other type of preprocessing, feature selection should only use the training data. Including the test data in feature selection will optimistically bias your model.
To demonstrate we will create this binary classification problem with 10,000 randomly generated features:
Wrong
Using all the data to perform feature selection results in an accuracy score much higher than chance, even though our targets are completely random. This randomness means that our X and y are independent and we thus expect the accuracy to be around 0.5. However, since the feature selection step ‘sees’ the test data, the model has an unfair advantage. In the incorrect example below we first use all the data for feature selection and then split the data into training and test subsets for model fitting. The result is a much higher than expected accuracy score:
Right
To prevent data leakage, it is good practice to split your data into train and test subsets first. Feature selection can then be formed using just the train dataset. Notice that whenever we use fit or fit_transform , we only use the train dataset. The score is now what we would expect for the data, close to chance:
Here again, we recommend using a Pipeline to chain together the feature selection and model estimators. The pipeline ensures that only the training data is used when performing fit and the test data is used only for calculating the accuracy score:
The pipeline can also be fed into a cross-validation function such as cross_val_score . Again, the pipeline ensures that the correct data subset and estimator method is used during fitting and predicting:
10.2.2. How to avoid data leakage¶
Below are some tips on avoiding data leakage:
Always split the data into train and test subsets first, particularly before any preprocessing steps.
Never include test data when using the fit and fit_transform methods. Using all the data, e.g., fit(X) , can result in overly optimistic scores.
Conversely, the transform method should be used on both train and test subsets as the same preprocessing should be applied to all the data. This can be achieved by using fit_transform on the train subset and transform on the test subset.
The scikit-learn pipeline is a great way to prevent data leakage as it ensures that the appropriate method is performed on the correct data subset. The pipeline is ideal for use in cross-validation and hyper-parameter tuning functions.
10.3. Controlling randomness¶
Some scikit-learn objects are inherently random. These are usually estimators (e.g. RandomForestClassifier ) and cross-validation splitters (e.g. KFold ). The randomness of these objects is controlled via their random_state parameter, as described in the Glossary . This section expands on the glossary entry, and describes good practices and common pitfalls w.r.t. this subtle parameter.
For an optimal robustness of cross-validation (CV) results, pass RandomState instances when creating estimators, or leave random_state to None . Passing integers to CV splitters is usually the safest option and is preferable; passing RandomState instances to splitters may sometimes be useful to achieve very specific use-cases. For both estimators and splitters, passing an integer vs passing an instance (or None ) leads to subtle but significant differences, especially for CV procedures. These differences are important to understand when reporting results.
For reproducible results across executions, remove any use of random_state=None .
10.3.1. Using None or RandomState instances, and repeated calls to fit and split ¶
The random_state parameter determines whether multiple calls to fit (for estimators) or to split (for CV splitters) will produce the same results, according to these rules:
If an integer is passed, calling fit or split multiple times always yields the same results.
If None or a RandomState instance is passed: fit and split will yield different results each time they are called, and the succession of calls explores all sources of entropy. None is the default value for all random_state parameters.
We here illustrate these rules for both estimators and CV splitters.
Since passing random_state=None is equivalent to passing the global RandomState instance from numpy ( random_state=np.random.mtrand._rand ), we will not explicitly mention None here. Everything that applies to instances also applies to using None .
10.3.1.1. Estimators¶
Passing instances means that calling fit multiple times will not yield the same results, even if the estimator is fitted on the same data and with the same hyper-parameters:
We can see from the snippet above that repeatedly calling sgd.fit has produced different models, even if the data was the same. This is because the Random Number Generator (RNG) of the estimator is consumed (i.e. mutated) when fit is called, and this mutated RNG will be used in the subsequent calls to fit . In addition, the rng object is shared across all objects that use it, and as a consequence, these objects become somewhat inter-dependent. For example, two estimators that share the same RandomState instance will influence each other, as we will see later when we discuss cloning. This point is important to keep in mind when debugging.
If we had passed an integer to the random_state parameter of the SGDClassifier , we would have obtained the same models, and thus the same scores each time. When we pass an integer, the same RNG is used across all calls to fit . What internally happens is that even though the RNG is consumed when fit is called, it is always reset to its original state at the beginning of fit .
10.3.1.2. CV splitters¶
Randomized CV splitters have a similar behavior when a RandomState instance is passed; calling split multiple times yields different data splits:
We can see that the splits are different from the second time split is called. This may lead to unexpected results if you compare the performance of multiple estimators by calling split many times, as we will see in the next section.
10.3.2. Common pitfalls and subtleties¶
While the rules that govern the random_state parameter are seemingly simple, they do however have some subtle implications. In some cases, this can even lead to wrong conclusions.
10.3.2.1. Estimators¶
Different `random_state` types lead to different cross-validation procedures
Depending on the type of the random_state parameter, estimators will behave differently, especially in cross-validation procedures. Consider the following snippet:
We see that the cross-validated scores of rf_123 and rf_inst are different, as should be expected since we didn’t pass the same random_state parameter. However, the difference between these scores is more subtle than it looks, and the cross-validation procedures that were performed by cross_val_score significantly differ in each case:
Since rf_123 was passed an integer, every call to fit uses the same RNG: this means that all random characteristics of the random forest estimator will be the same for each of the 5 folds of the CV procedure. In particular, the (randomly chosen) subset of features of the estimator will be the same across all folds.
Since rf_inst was passed a RandomState instance, each call to fit starts from a different RNG. As a result, the random subset of features will be different for each folds.
While having a constant estimator RNG across folds isn’t inherently wrong, we usually want CV results that are robust w.r.t. the estimator’s randomness. As a result, passing an instance instead of an integer may be preferable, since it will allow the estimator RNG to vary for each fold.
Here, cross_val_score will use a non-randomized CV splitter (as is the default), so both estimators will be evaluated on the same splits. This section is not about variability in the splits. Also, whether we pass an integer or an instance to make_classification isn’t relevant for our illustration purpose: what matters is what we pass to the RandomForestClassifier estimator.
Cloning
Another subtle side effect of passing RandomState instances is how clone will work:
Since a RandomState instance was passed to a , a and b are not clones in the strict sense, but rather clones in the statistical sense: a and b will still be different models, even when calling fit(X, y) on the same data. Moreover, a and b will influence each-other since they share the same internal RNG: calling a.fit will consume b ’s RNG, and calling b.fit will consume a ’s RNG, since they are the same. This bit is true for any estimators that share a random_state parameter; it is not specific to clones.
If an integer were passed, a and b would be exact clones and they would not influence each other.
Even though clone is rarely used in user code, it is called pervasively throughout scikit-learn codebase: in particular, most meta-estimators that accept non-fitted estimators call clone internally ( GridSearchCV , StackingClassifier , CalibratedClassifierCV , etc.).
10.3.2.2. CV splitters¶
When passed a RandomState instance, CV splitters yield different splits each time split is called. When comparing different estimators, this can lead to overestimating the variance of the difference in performance between the estimators:
Directly comparing the performance of the LinearDiscriminantAnalysis estimator vs the GaussianNB estimator on each fold would be a mistake: the splits on which the estimators are evaluated are different. Indeed, cross_val_score will internally call cv.split on the same KFold instance, but the splits will be different each time. This is also true for any tool that performs model selection via cross-validation, e.g. GridSearchCV and RandomizedSearchCV : scores are not comparable fold-to-fold across different calls to search.fit , since cv.split would have been called multiple times. Within a single call to search.fit , however, fold-to-fold comparison is possible since the search estimator only calls cv.split once.
For comparable fold-to-fold results in all scenarios, one should pass an integer to the CV splitter: cv = KFold(shuffle=True, random_state=0) .
While fold-to-fold comparison is not advisable with RandomState instances, one can however expect that average scores allow to conclude whether one estimator is better than another, as long as enough folds and data are used.
What matters in this example is what was passed to KFold . Whether we pass a RandomState instance or an integer to make_classification is not relevant for our illustration purpose. Also, neither LinearDiscriminantAnalysis nor GaussianNB are randomized estimators.
10.3.3. General recommendations¶
10.3.3.1. Getting reproducible results across multiple executions¶
In order to obtain reproducible (i.e. constant) results across multiple program executions, we need to remove all uses of random_state=None , which is the default. The recommended way is to declare a rng variable at the top of the program, and pass it down to any object that accepts a random_state parameter:
We are now guaranteed that the result of this script will always be 0.84, no matter how many times we run it. Changing the global rng variable to a different value should affect the results, as expected.
It is also possible to declare the rng variable as an integer. This may however lead to less robust cross-validation results, as we will see in the next section.
We do not recommend setting the global numpy seed by calling np.random.seed(0) . See here for a discussion.
10.3.3.2. Robustness of cross-validation results¶
When we evaluate a randomized estimator performance by cross-validation, we want to make sure that the estimator can yield accurate predictions for new data, but we also want to make sure that the estimator is robust w.r.t. its random initialization. For example, we would like the random weights initialization of a SGDCLassifier to be consistently good across all folds: otherwise, when we train that estimator on new data, we might get unlucky and the random initialization may lead to bad performance. Similarly, we want a random forest to be robust w.r.t the set of randomly selected features that each tree will be using.
For these reasons, it is preferable to evaluate the cross-validation performance by letting the estimator use a different RNG on each fold. This is done by passing a RandomState instance (or None ) to the estimator initialization.
When we pass an integer, the estimator will use the same RNG on each fold: if the estimator performs well (or bad), as evaluated by CV, it might just be because we got lucky (or unlucky) with that specific seed. Passing instances leads to more robust CV results, and makes the comparison between various algorithms fairer. It also helps limiting the temptation to treat the estimator’s RNG as a hyper-parameter that can be tuned.
Whether we pass RandomState instances or integers to CV splitters has no impact on robustness, as long as split is only called once. When split is called multiple times, fold-to-fold comparison isn’t possible anymore. As a result, passing integer to CV splitters is usually safer and covers most use-cases.
Random state (Pseudo-random number) in Scikit learn
I want to implement a machine learning algorithm in scikit learn, but I don’t understand what this parameter random_state does? Why should I use it?
I also could not understand what is a Pseudo-random number.
![]()
8 Answers 8
train_test_split splits arrays or matrices into random train and test subsets. That means that everytime you run it without specifying random_state , you will get a different result, this is expected behavior. For example:
Run 1:
Run 2
It changes. On the other hand if you use random_state=some_number , then you can guarantee that the output of Run 1 will be equal to the output of Run 2, i.e. your split will be always the same. It doesn’t matter what the actual random_state number is 42, 0, 21, . The important thing is that everytime you use 42, you will always get the same output the first time you make the split. This is useful if you want reproducible results, for example in the documentation, so that everybody can consistently see the same numbers when they run the examples. In practice I would say, you should set the random_state to some fixed number while you test stuff, but then remove it in production if you really need a random (and not a fixed) split.
Regarding your second question, a pseudo-random number generator is a number generator that generates almost truly random numbers. Why they are not truly random is out of the scope of this question and probably won’t matter in your case, you can take a look here form more details.
If you don’t specify the random_state in your code, then every time you run(execute) your code a new random value is generated and the train and test datasets would have different values each time.
However, if a fixed value is assigned like random_state = 42 then no matter how many times you execute your code the result would be the same .i.e, same values in train and test datasets.
![]()
Well the question what is "random state" and why is it used, has been answered above nicely by people above. I will try and answer the question "Why do we choose random state as 42 very often during training a machine learning model? why we dont choose 12 or 32 or 5? " Is there a scientific explanation?
Many students and practitioners use this number(42) as random state is because it is used by many instructors in online courses. They often set the random state or numpy seed to number 42 and learners follow the same practice without giving it much thought.
To be specific, 42 has nothing to do with AI or ML. It is actually a generic number, In Machine Learning, it doesn’t matter what the actual random number is, as mentioned in scikit API doc, any INTEGER is sufficient enough for the task at hand.
42 is a reference from Hitchhikers guide to galaxy book. The answer to life universe and everything and is meant as a joke. It has no other significance.
References:

![]()
![]()
If you don’t mention the random_state in the code, then whenever you execute your code a new random value is generated and the train and test datasets would have different values each time.
However, if you use a particular value for random_state(random_state = 1 or any other value) everytime the result will be same,i.e, same values in train and test datasets. Refer below code:
Doesn’t matter how many times you run the code, the output will be 70.
Try to remove the random_state and run the code.
Now here output will be different each time you execute the code.
random_state number splits the test and training datasets with a random manner. In addition to what is explained here, it is important to remember that random_state value can have significant effect on the quality of your model (by quality I essentially mean accuracy to predict). For instance, If you take a certain dataset and train a regression model with it, without specifying the random_state value, there is the potential that everytime, you will get a different accuracy result for your trained model on the test data. So it is important to find the best random_state value to provide you with the most accurate model. And then, that number will be used to reproduce your model in another occasion such as another research experiment. To do so, it is possible to split and train the model in a for-loop by assigning random numbers to random_state parameter:
![]()
If there is no randomstate provided the system will use a randomstate that is generated internally. So, when you run the program multiple times you might see different train/test data points and the behavior will be unpredictable. In case, you have an issue with your model you will not be able to recreate it as you do not know the random number that was generated when you ran the program.
If you see the Tree Classifiers — either DT or RF, they try to build a try using an optimal plan. Though most of the times this plan might be the same there could be instances where the tree might be different and so the predictions. When you try to debug your model you may not be able to recreate the same instance for which a Tree was built. So, to avoid all this hassle we use a random_state while building a DecisionTreeClassifier or RandomForestClassifier.
PS: You can go a bit in depth on how the Tree is built in DecisionTree to understand this better.
randomstate is basically used for reproducing your problem the same every time it is run. If you do not use a randomstate in traintestsplit, every time you make the split you might get a different set of train and test data points and will not help you in debugging in case you get an issue.
Why Random_state=42 in Machine Learning?
You will often see people setting random_state=42. Usually, this number has no special properties, but in this article, I’ll explain why random_state=42 in Machine Learning.
What is Random_state in Machine Learning?
Scikit-Learn provides some functions for dividing datasets into multiple subsets in different ways. The simplest function is train_test_split(), which divides data into training and testing sets. There is a random_state parameter which allows you to set the seed of the random generator.
Then you can pass it multiple datasets with the same number of rows, and it will split them on the same indices. For example, just look at the code below:
Why Random_state=42?
If you don’t set random_state to 42, every time you run your code again, it will generate a different test set. Over time, you (or your machine learning algorithm) will be able to see the dataset, which you want to avoid.
One solution is to save the test set on the first run, and then load it on subsequent runs. Another option is to set the start value of the random number generator (for example, with np.random.seed(42)) so that it always generates the same clues mixed up.
Summary
If there is no random_state provided, the system will use a random_state which is generated internally. So whenever you will run your machine learning code multiple times, you may see different data points of training and test sets and which may result in unpredictable behaviour.
If you have a problem with your model, you will not be able to recreate it because you do not know the random number generated when running the program.
I hope you liked this article on why random_state=42 in machine learning. Feel free to ask your valuable questions in the comments section below.