<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Bootstrapping
What is bootstrapping?
Bootstrapping is the practice of estimating properties of an estimator (such as its variance) by measuring those properties when sampling from an approximating distribution. One standard choice for an approximating distribution is the empirical distribution function of the observed data. In the case where a set of observations can be assumed to be from an independent and identically distributed population, this can be implemented by constructing a number of resamples with replacement, of the observed dataset (and of equal size to the observed datasert [population]). -- Wikipedia
What is it used for?
Bootstrapping allows assigning measures of accuracy (defined in terms of bias, variance, confidence intervals, prediction error or some other such measure) to sample estimates. -- Effron & Tibshirani, (1993)
Usage
The BootstrapSplit class is a modified version of the Bootstrap iterator from the cross_validation module in scikit-learn. Provided with the number of observations in the population the iterator returns a tuple containing two lists of index references to the population, representing the two split subsets resampled from the population. The size of the samples and the number of iterations can be controlled with keyword parameters.
Step1:  Contrary to other resampling strategies, bootstrapping will allow some observations to occur several times in each sample. However, an observation that occurs in the train sample will never occur in the test sample and vice-versa.
What is weight-limited bootstrapping?
In classic bootstrapping, observations are sampled uniformly with replacement until the sample is equal in size to the population. But in some cases we want to use a different limiting criterion. For example, in the well-known knapsack problem items (observations) are selected until their combined weight reaches a threshold. Weight-limited bootstrapping is similar in that each observation is assigned a weight and the total weight of the sample must not exceed a threshold. For example, sentences are made up of different number of words. Suppose we wanted to fill a page with a random sample of sentences from a long document (population). However, in this case if we simply sampled sentences (observations), we may run out of space as sentences are of different length and a page can contain no more than t words. The solution is to weigh each sentence (observation) by its word count, and to limit the sample to a maximum weight of t.
Step2:  The WeightLimitedBootstrapSplit class re-implements the BootstrapSplit accounting for individual sample weight. In contrast to WeightLimitedBootstrapSplit though it only sets a maximum weight for each sample split, which means that the returned sample is of the closest lower weight given a random resampling with replacement. This introduces a small degree of inaccuracy that needs to be kept in mind when working with very small samples. If the weight of a sample split is smaller than that of the first token in the resampled sequence, an empty list is returned.
In the following example we set the weight limit of the test sample to 1 while the lowest word weight is 2.
Step3:  Bootstrapping without splitting
The module also contains classes for bootstrapping and weight-limited bootstrapping without splitting the sample. The first is just plain sampling with replacement,
Step4:  the latter offers the option to set the maximum sample weight the same way WeightLimitedBootstrapSplit does.
<ASSISTANT_TASK:>
Python Code:
import numpy as np
from __future__ import print_function
from bootstrapsplit import BootstrapSplit
# population
pop = np.array(list('ABDEFGHIJKLMN'))
bs = BootstrapSplit(len(pop), random_state=0)
print(bs)
print('POPULATION:', pop)
for tr_idx, te_idx in bs:
    print("TRAIN:", pop[tr_idx], "TEST:", pop[te_idx])
Explanation: Bootstrapping
What is bootstrapping?
Bootstrapping is the practice of estimating properties of an estimator (such as its variance) by measuring those properties when sampling from an approximating distribution. One standard choice for an approximating distribution is the empirical distribution function of the observed data. In the case where a set of observations can be assumed to be from an independent and identically distributed population, this can be implemented by constructing a number of resamples with replacement, of the observed dataset (and of equal size to the observed datasert [population]). -- Wikipedia
What is it used for?
Bootstrapping allows assigning measures of accuracy (defined in terms of bias, variance, confidence intervals, prediction error or some other such measure) to sample estimates. -- Effron & Tibshirani, (1993)
Usage
The BootstrapSplit class is a modified version of the Bootstrap iterator from the cross_validation module in scikit-learn. Provided with the number of observations in the population the iterator returns a tuple containing two lists of index references to the population, representing the two split subsets resampled from the population. The size of the samples and the number of iterations can be controlled with keyword parameters.
End of explanation
from bootstrapsplit import WeightLimitedBootstrapSplit
w = np.random.randint(low=1, high=3, size=len(pop))
wb = WeightLimitedBootstrapSplit(w, n_iter=3, train_size=9, test_size=4)
print(wb)
print("POPULATION:", pop, "(weight=%s)" % w.sum())
for tr, te in wb:
    print("TRAIN:", pop[tr], "(weight=%s)" % w[tr].sum(), "TEST:", pop[te], "(weight=%s)" % w[te].sum())
Explanation: Contrary to other resampling strategies, bootstrapping will allow some observations to occur several times in each sample. However, an observation that occurs in the train sample will never occur in the test sample and vice-versa.
What is weight-limited bootstrapping?
In classic bootstrapping, observations are sampled uniformly with replacement until the sample is equal in size to the population. But in some cases we want to use a different limiting criterion. For example, in the well-known knapsack problem items (observations) are selected until their combined weight reaches a threshold. Weight-limited bootstrapping is similar in that each observation is assigned a weight and the total weight of the sample must not exceed a threshold. For example, sentences are made up of different number of words. Suppose we wanted to fill a page with a random sample of sentences from a long document (population). However, in this case if we simply sampled sentences (observations), we may run out of space as sentences are of different length and a page can contain no more than t words. The solution is to weigh each sentence (observation) by its word count, and to limit the sample to a maximum weight of t.
End of explanation
w = np.random.randint(low=2, high=5, size=len(pop))
wb = WeightLimitedBootstrapSplit(w, n_iter=3, train_size=0.8, test_size=1)
print(wb)
for tr_idx, te_idx in wb:
    print("TRAIN:", tr_idx, "(%s)" % w[tr_idx].sum(), "TEST:", te_idx, "(%s)" % w[te_idx].sum())
Explanation: The WeightLimitedBootstrapSplit class re-implements the BootstrapSplit accounting for individual sample weight. In contrast to WeightLimitedBootstrapSplit though it only sets a maximum weight for each sample split, which means that the returned sample is of the closest lower weight given a random resampling with replacement. This introduces a small degree of inaccuracy that needs to be kept in mind when working with very small samples. If the weight of a sample split is smaller than that of the first token in the resampled sequence, an empty list is returned.
In the following example we set the weight limit of the test sample to 1 while the lowest word weight is 2.
End of explanation
from bootstrapsplit import Bootstrap
b = Bootstrap(len(pop), n_iter=3)
print(b)
print("POPULATION:", pop)
for s in b:
    print("BOOTSTRAP:", pop[s])
Explanation: Bootstrapping without splitting
The module also contains classes for bootstrapping and weight-limited bootstrapping without splitting the sample. The first is just plain sampling with replacement,
End of explanation
from bootstrapsplit import WeightLimitedBootstrap
w = np.random.randint(low=1, high=5, size=len(pop))
wb = WeightLimitedBootstrap(w, n_iter=3, max_weight=len(pop))
print(wb)
print("POPULATION:", pop, "(weight=%s)" % w.sum())
for s in wb:
    print("BOOTSTRAP:", pop[s], "(weight=%s)" % w[tr].sum())
Explanation: the latter offers the option to set the maximum sample weight the same way WeightLimitedBootstrapSplit does.
End of explanation
<END_TASK>