I am working on the file "Learning Pandas.ipynb".
The first task is:
Apply
How to change values in the columns:
Can you write Python code for it?

# take the real part or abs of the columns (save as a different dataframes)
df4real = df4.apply(np.real)
df4abs = df4.apply(np.abs)

# the diagonal will be the kernel density estimate (kde)
scatter_matrix(df4abs, figsize=(8, 8), diagonal='kde')

# Format the notebook using style by Lorena Barba (http://lorenabarba.com/)
# run this cell first to use the nice format.
from IPython.core.display import HTML
def css_styling():
    styles = open("./styles/custom.css", "r").read()
    return HTML(styles)
css_styling()


I am working on the file "Learning Pandas.ipynb".
The first task is:
Our data is currently represented as a stack of 2D arrays (so a 3D "array"). In that implementation the third index is essentially a shot number and the first two are pixel row and pixel column. We'd like to make a dataframe of this data and then work with it in pandas instead of in an array. Another data type we have is the $K_p$ values (essentially the FFT output). In this case, it is a 1D array for each shot of data. The pandas version would be a dataframe with each element being a 1D array of $K_p$ values.
To test this, let's create a random dummy set that is 20 shots of 400 $K_p$ values:
Can you write Python code for it?

# create an example dataframe:
df = pd.DataFrame(np.random.randn(20,400), index=np.arange(20), columns=1.23*np.arange(400))

df


I am working on the file "Learning Pandas.ipynb".
The first task is:
Select a few columns:
Can you write Python code for it?


I am working on the file "Learning Pandas.ipynb".
The first task is:
So we see a few nice features:
 - we can label the columns with useful things, this could be the actual mode index $p$ for the columns
 - we can also label rows, this could be shot number, or even a alphanumeric code for shot/run (can it be alphanumeric?)
To show this, we'll create a list of the row labels using a list comprehension. Note, this could also be done with a generator, but that is a more advanced pythonism
Can you write Python code for it?

# nested string list comprehension:
rows = ["r{}s{}".format(i,j) for i in np.arange(4) for j in np.arange(5)]

# could also be a generator:
row_gen = ("r{}s{}".format(i,j) for i in np.arange(4) for j in np.arange(5))

for i in row_gen:
    print(i)

df2 = pd.DataFrame(np.random.randn(20,400), index=rows, columns=1.23*np.arange(400))

df2


I am working on the file "Learning Tensorflow/Working_of_TensorFlow.ipynb".
The first task is:

Building a Graph
As we said before, TensorFlow works as a graph computational model. Let's create our first graph.
To create two source operations which will output numbers we will define two constants:
Can you write Python code for it?

a = tf.constant([2])
b = tf.constant([3])


I am working on the file "Learning Tensorflow/Working_of_TensorFlow.ipynb".
The first task is:

Why Tensors?
The Tensor structure helps us by giving the freedom to shape the dataset the way we want.
And it is particularly helpful when dealing with images, due to the nature of how information in images are encoded,
Thinking about images, its easy to understand that it has a height and width, so it would make sense to represent the information contained in it with a two dimensional strucutre (a matrix)... until you remember that images have colors, and to add information about the colors, we need another dimension, and thats when Tensors become particulary helpful.
Images are encoded into color channels, the image data is represented into each color intensity in a color channel at a given point, the most common one being RGB, which means Red, Blue and Green. The information contained into an image is the intensity of each channel color into the width and height of the image, just like this:

So the intensity of the red channel at each point with width and height can be represented into a matrix, the same goes for the blue and green channels, so we end up having three matrices, and when these are combined they form a tensor.

Variables
Now that we are more familiar with the structure of data, we will take a look at how TensorFlow handles variables.
To define variables we use the command tf.variable().
To be able to use variables in a computation graph it is necessary to initialize them before running the graph in a session. This is done by running tf.global_variables_initializer().
To update the value of a variable, we simply run an assign operation that assigns a value to the variable:
Can you write Python code for it?


I am working on the file "Learning Tensorflow/Working_of_TensorFlow.ipynb".
The first task is:

Placeholders
Now we know how to manipulate variables inside TensorFlow, but what about feeding data outside of a TensorFlow model?
If you want to feed data to a TensorFlow model from outside a model, you will need to use placeholders.
So what are these placeholders and what do they do?
Placeholders can be seen as "holes" in your model, "holes" which you will pass the data to, you can create them using
 tf.placeholder(datatype), where datatype specifies the type of data (integers, floating points, strings, booleans) along with its precision (8, 16, 32, 64) bits.
The definition of each data type with the respective python sintax is defined as:
|Data type  |Python type|Description|
| --------- | --------- | --------- |
|DT_FLOAT   |tf.float32 |32 bits floating point.|
|DT_DOUBLE  |tf.float64 |64 bits floating point.|
|DT_INT8    |tf.int8    |8 bits signed integer.|
|DT_INT16   |tf.int16   |16 bits signed integer.|
|DT_INT32   |tf.int32   |32 bits signed integer.|
|DT_INT64   |tf.int64   |64 bits signed integer.|
|DT_UINT8   |tf.uint8   |8 bits unsigned integer.|
|DT_STRING  |tf.string  |Variable length byte arrays. Each element of a Tensor is a byte array.|
|DT_BOOL    |tf.bool    |Boolean.|
|DT_COMPLEX64   |tf.complex64   |Complex number made of two 32 bits floating points: real and imaginary parts.|
|DT_COMPLEX128  |tf.complex128  |Complex number made of two 64 bits floating points: real and imaginary parts.|
|DT_QINT8   |tf.qint8   |8 bits signed integer used in quantized Ops.|
|DT_QINT32  |tf.qint32  |32 bits signed integer used in quantized Ops.|
|DT_QUINT8  |tf.quint8  |8 bits unsigned integer used in quantized Ops.|

[[Table Source]](https://www.tensorflow.org/versions/r0.9/resources/dims_types.html)

So we create a placeholder:
Can you write Python code for it?


I am working on the file "Learning Tensorflow/Working_of_TensorFlow.ipynb".
The first task is:

Operations
Operations are nodes that represent the mathematical operations over the tensors on a graph. These operations can be any kind of functions, like add and subtract tensor or maybe an activation function.
tf.matmul, tf.add, tf.nn.sigmoid are some of the operations in TensorFlow. These are like functions in python but operate directly over tensors and each one does a specific thing.

Other operations can be easily found in: https://www.tensorflow.org/versions/r0.9/api_docs/python/index.html

Can you write Python code for it?

a = tf.constant([5])
b = tf.constant([2])
c = tf.add(a,b)
d = tf.subtract(a,b)

with tf.Session() as session:
    result = session.run(c)
    print ('c =: %s' % result)
    result = session.run(d)
    print ('d =: %s' % result)


I am working on the file "Learning Tensorflow/Working_of_TensorFlow.ipynb".
The first task is:

Tensorboard
TensorBoard is a suite of web applications for inspecting and understanding your TensorFlow runs and graphs. TensorBoard currently supports five visualizations: scalars, images, audio, histograms, and graphs. The computations you will use in TensorFlow for things such as training a massive deep neural network, can be fairly complex and confusing, TensorBoard will make this a lot easier to understand, debug, and optimize your TensorFlow programs.
This is what a tensorboard looks like:

Can you write Python code for it?

import tensorflow as tf

with tf.name_scope("Operations"):
    with tf.name_scope("Scope_a"):
        a = tf.add(1, 2, name="a")
        b = tf.multiply(a, 3, name="b")
    with tf.name_scope("Scope_b"):
        c = tf.add(4, 5, name="c")
        d = tf.multiply(c, 6, name="d")

with tf.name_scope("Scope_c"):
    e = tf.multiply(4, 5, name="e")
    f = tf.div(c, 6, name="f")
g = tf.add(b, d,  name="g")
h = tf.multiply(g, f, name="h")

with tf.Session() as sess:
    print(sess.run(h))

with tf.Session() as sess:
    writer = tf.summary.FileWriter("/home/raghav/TECH/output4", sess.graph)
    print(sess.run(h))
    writer.close()


I am working on the file "Learning Tensorflow/Working_of_TensorFlow.ipynb".
The first task is:
And define a simple multiplication operation:
Can you write Python code for it?


I am working on the file "Learning Tensorflow/Working_of_TensorFlow.ipynb".
The first task is:
Close the session to release resources:
Can you write Python code for it?


I am working on the file "Learning Tensorflow/Working_of_TensorFlow.ipynb".
The first task is:
Let's first create a simple counter, a variable that increases one unit at a time:
Can you write Python code for it?

one = tf.constant(1)
new_value = tf.add(state, one)
update = tf.assign(state, new_value)


I am working on the file "Learning Tensorflow/Working_of_TensorFlow.ipynb".
The first task is:
Since data in TensorFlow is passed in form of multidimensional arrays we can pass any kind of tensor through the placeholders to get the answer to the simple multiplication operation:
Can you write Python code for it?


I am working on the file "Learning Tensorflow/Working_of_TensorFlow.ipynb".
The first task is:
To avoid having to close sessions every time, we can define them in a with block, so after running the with block the session will close automatically:
Can you write Python code for it?

with tf.Session() as session:
    result = session.run(c)
    print(result)


I am working on the file "Learning Tensorflow/Working_of_TensorFlow.ipynb".
The first task is:
Variables must be initialized by running an initialization operation after having launched the graph.  We first have to add the initialization operation to the graph:
Can you write Python code for it?


I am working on the file "Learning Tensorflow/Working_of_TensorFlow.ipynb".
The first task is:
We then start a session to run the graph, first initialize the variables, then print the initial value of the state variable, and then run the operation of updating the state variable and printing the result after each update:
Can you write Python code for it?

with tf.Session() as session:
  session.run(init)
  print(session.run(state))
  for i in range(3):
    session.run(update)
    print(session.run(state))


I am working on the file "Learning and Adjusting Tuning Curves.ipynb".
The first task is:
Finally, we mark particular data to be recorded during the model run.
Can you write Python code for it?

with model:
    p_out = nengo.Probe(bci)            # the output from the BCI
    p_stim = nengo.Probe(stim[:2])      # the desired target location
    p_spikes = nengo.Probe(m1.neurons)  # the spike data in m1


I am working on the file "Learning and Adjusting Tuning Curves.ipynb".
The first task is:
Getting better.
What happens after 500 seconds of learning?
Can you write Python code for it?

pylab.plot(sim.trange(), sim.data[p_out], label='BCI output')
pylab.gca().set_color_cycle(None)
pylab.plot(sim.trange(), sim.data[p_stim], linestyle='--', label='desired')
pylab.xlim(499, 500)
pylab.legend(loc='best')
pylab.show()


I am working on the file "Learning and Adjusting Tuning Curves.ipynb".
The first task is:
Here is the tuning curve for neuron #2, with the initial tuning curve in red (using data from t=0 to t=100) and the final tuning curve in blue (using data from t=400 to t=500).
Can you write Python code for it?

index = 2
pylab.figure(figsize=(6,6))
plot_tuning(index, t_start=0, t_end=100, cmap='Reds')
plot_tuning(index, t_start=400, t_end=500, cmap='Blues')


I am working on the file "Learning and Adjusting Tuning Curves.ipynb".
The first task is:
If we left it like this, then the way we're decoding the spikes in the BCI is exactly what the neural model is already doing, so it would give perfect behaviour instantly and there'd be nothing to learn.
Let's give it something to learn by swapping the 2 dimensions being decoded.  That is, we're staying in manifold, but swapping dimension 1 and dimension 2
Can you write Python code for it?

bci.decoder = np.vstack([bci.decoder[1], bci.decoder[0]])


I am working on the file "Learning and Adjusting Tuning Curves.ipynb".
The first task is:
Let's see what it's doing at a behavioural level.  First, we plot behaviour in the first second
Can you write Python code for it?

pylab.plot(sim.trange(), sim.data[p_out], label='BCI output')
pylab.gca().set_color_cycle(None)
pylab.plot(sim.trange(), sim.data[p_stim], linestyle='--', label='desired')
pylab.xlim(0,1)
pylab.legend(loc='best')
pylab.show()


I am working on the file "Learning and Adjusting Tuning Curves.ipynb".
The first task is:
M1 is gets its inputs from earlier motor areas, so let's add that in.  We'll call it PMC (or maybe SMA), and we'll assume that it's doing a few different things, so let's arbitarily pick that it's a 6-dimensional manifold.
We then connect it to M1.  When we do this, we can specify the relationship that we want between these manifolds and Nengo will find the synaptic connection weights that best approximate that mapping.  This mapping can be a non-linear function (although the more non-linear it is, the less accurately it'll approximate that function).  Here, we just do a linear function that grabs the first 3 dimensions from pmc and sends it to m1.
This is the connection that will actually end up being adjusted during learning, so we also define a learning rule.  This is the PES rule, which is really just standard delta rule (i.e. a supervised learning rule on just that one set of connections, which ends up being backprop without backpropagation).
Can you write Python code for it?

with model:
    pmc = nengo.Ensemble(n_neurons=500, dimensions=6)

    # function to approximate
    def starting_map(x):
        return x[0], x[1], x[2]

    c = nengo.Connection(pmc, m1, function=starting_map,
                         learning_rule_type=nengo.PES(learning_rate=1e-5))


I am working on the file "Learning and Adjusting Tuning Curves.ipynb".
The first task is:
Now we need to give the system a learning signal.  The solution provided here is cheating a fair bit, in that it already knows which direction to change things to improve the results.  A more complete solution would require learning to characterize the relationship between the observed change in cursor position and the desired change.  This is exactly the sort of learning we've done elsewhere in the adaptive Jacobian kinematics learning models (such as http://rspb.royalsocietypublishing.org/content/283/1843/20162134) but for this demonstration I'm cheating and skipping that part.
Can you write Python code for it?

with model:
    # population representing the error signal
    error = nengo.Ensemble(n_neurons=500, dimensions=3)

    # feedback from the BCI as to where the cursor actually went to
    nengo.Connection(bci, error[:2], transform=1)

    # minus the actual desired location
    nengo.Connection(pmc[:2], error[:2], transform=-1)

    # use this difference to drive the learning from pmc to m1
    nengo.Connection(error, c.learning_rule, transform=[[0,1,0],[1,0,0],[0,0,1]])


I am working on the file "Learning curves and bias-variance tradeoff.ipynb".
The first task is:
Here we show the learning curve for $d = 20$. From the above
discussion, we know that $d = 20$ is a high-variance estimator
which over-fits the data. This is indicated by the fact that the
training error is much less than the cross-validation error. As
we add more samples to this training set, the training error will
continue to climb, while the cross-validation error will continue
to decrease, until they meet in the middle. In this case, our
intrinsic error was set to 1.0, and we can infer that adding more
data will allow the estimator to very closely match the best
possible cross-validation error.
Can you write Python code for it?


I am working on the file "Learning curves and bias-variance tradeoff.ipynb".
The first task is:
In order to quantify the effects of bias and variance and construct
the best possible estimator, we will split our training data into
three parts: a training set, a cross-validation set, and a
test set. As a general rule, the training set should be about
60% of the samples, and the cross-validation and test sets should
be about 20% each.
The general idea is as follows. The model parameters (in our case,
the coefficients of the polynomials) are learned using the training
set as above. The error is evaluated on the cross-validation set,
and the meta-parameters (in our case, the degree of the polynomial)
are adjusted so that this cross-validation error is minimized.
Finally, the labels are predicted for the test set. These labels
are used to evaluate how well the algorithm can be expected to
perform on unlabeled data.
Why do we need both a cross-validation set and a test set? Many
machine learning practitioners use the same set of data as both
a cross-validation set and a test set. This is not the best approach,
for the same reasons we outlined above. Just as the parameters can
be over-fit to the training data, the meta-parameters can be over-fit
to the cross-validation data. For this reason, the minimal
cross-validation error tends to under-estimate the error expected
on a new set of data.
The cross-validation error of our polynomial classifier can be visualized by plotting the error as a function of the polynomial degree d. We can do this as follows.  This will spit out warnings about "poorly conditioned" polynomials: that is OK for now.
Can you write Python code for it?

degrees = np.arange(1, 21)
train_err = np.zeros(len(degrees))
crossval_err = np.zeros(len(degrees))
test_err = np.zeros(len(degrees))

for i, d in enumerate(degrees):
    p = np.polyfit(xtrain, ytrain, d)

    train_err[i] = compute_error(xtrain, ytrain, p)
    crossval_err[i] = compute_error(xcrossval, ycrossval, p)

pl.figure()
pl.title('Error for 100 Training Points')
pl.plot(degrees, crossval_err, lw=2, label = 'cross-validation error')
pl.plot(degrees, train_err, lw=2, label = 'training error')
pl.plot([0, 20], [error, error], '--k', label='intrinsic error')

pl.legend()
pl.xlabel('degree of fit')
pl.ylabel('rms error')


I am working on the file "Learning curves and bias-variance tradeoff.ipynb".
The first task is:
In the above figure, we see fits for three different values of $d$.
For $d = 1$, the data is under-fit. This means that the model is too
simplistic: no straight line will ever be a good fit to this data. In
this case, we say that the model suffers from high bias. The model
itself is biased, and this will be reflected in the fact that the data
is poorly fit. At the other extreme, for $d = 6$ the data is over-fit.
This means that the model has too many free parameters (6 in this case)
which can be adjusted to perfectly fit the training data. If we add a
new point to this plot, though, chances are it will be very far from
the curve representing the degree-6 fit. In this case, we say that the
model suffers from high variance. The reason for this label is that if
any of the input points are varied slightly, it could result in an
extremely different model.
In the middle, for $d = 2$, we have found a good mid-point. It fits
the data fairly well, and does not suffer from the bias and variance
problems seen in the figures on either side. What we would like is a
way to quantitatively identify bias and variance, and optimize the
metaparameters (in this case, the polynomial degree d) in order to
determine the best algorithm. This can be done through a process
called cross-validation.
Cross-validation and Testing
Let's start by defining a new dataset which we can use to explore
cross-validation.  We will use a simple x vs. y regression estimator
for ease of visualization, but the concepts also readily apply to
more complicated datasets and models.
Can you write Python code for it?

Ntrain = 100
Ncrossval = 100
Ntest = 50
error = 1.0

# randomly sample the data
np.random.seed(0)
x = np.random.random(Ntrain + Ncrossval + Ntest)
y = test_func(x, error)

# select training set
# data is already random, so we can just choose a slice.
xtrain = x[:Ntrain]
ytrain = y[:Ntrain]

# select cross-validation set
xcrossval = x[Ntrain:Ntrain + Ncrossval]
ycrossval = y[Ntrain:Ntrain + Ncrossval]

# select test set
xtest = x[Ntrain:-Ntest]
ytest = y[Ntrain:-Ntest]

pl.scatter(xtrain, ytrain, color='red')
pl.scatter(xcrossval, ycrossval, color='blue')


I am working on the file "Learning curves and bias-variance tradeoff.ipynb".
The first task is:
Polynomial regression can be done with the functions polyfit
and polyval, available in numpy. For example:
Can you write Python code for it?

import numpy as np
np.random.seed(42)
x = np.random.random(20)
y = np.sin(2 * x)
p = np.polyfit(x, y, 1)  # fit a 1st-degree polynomial (i.e. a line) to the data
print p  # slope and intercept

x_new = np.random.random(3)
y_new = np.polyval(p, x_new)  # evaluate the polynomial at x_new
print abs(np.sin(x_new) - y_new)


I am working on the file "Learning curves and bias-variance tradeoff.ipynb".
The first task is:
Run the following code to produce an example plot:
Can you write Python code for it?

N = 8
np.random.seed(42)
x = 10 ** np.linspace(-2, 0, N)
y = test_func(x)

xfit = np.linspace(-0.2, 1.2, 1000)

titles = ['d = 1 (under-fit)', 'd = 2', 'd = 6 (over-fit)']
degrees = [1, 2, 6]

pl.figure(figsize = (9, 3.5))
pl.subplots_adjust(left = 0.06, right=0.98,
                   bottom=0.15, top=0.85,
                   wspace=0.05)
for i, d in enumerate(degrees):
    pl.subplot(131 + i, xticks=[], yticks=[])
    pl.scatter(x, y, marker='x', c='k', s=50)

    p = np.polyfit(x, y, d)
    yfit = np.polyval(p, xfit)
    pl.plot(xfit, yfit, '-b')

    pl.xlim(-0.2, 1.2)
    pl.ylim(0, 12)
    pl.xlabel('house size')
    if i == 0:
        pl.ylabel('price')

    pl.title(titles[i])


I am working on the file "Learning curves and bias-variance tradeoff.ipynb".
The first task is:
When the error of predicted results is larger than desired,
there are a few courses of action that can be taken:

Increase the number of training points N. This might give us a
   training set with more coverage, and lead to greater accuracy.
Increase the degree d of the polynomial. This might allow us to
   more closely fit the training data, and lead to a better result
Add more features. If we were to, for example, perform a linear
   regression using $x$, $\sqrt{x}$, $x^{-1}$, or other functions, we might
   hit on a functional form which can better be mapped to the value of y.

The best course to take will vary from situation to situation, and from
problem to problem. In this situation, number 2 and 3 may be useful, but
number 1 will certainly not help: our model does not intrinsically fit the
data very well. In machine learning terms, we say that it has high bias
and that the data is under-fit. The ability to quickly figure out how
to tune and improve your model is what separates good machine learning
practitioners from the bad ones. In this section we’ll discuss some tools
that can help determine which course is most likely to lead to good results.
Bias, Variance, Overfitting, and Underfitting
We’ll work with a simple example. Imagine that you would like to build
an algorithm which will predict the price of a house given its size.
Naively, we’d expect that the cost of a house grows as the size increases,
but there are many other factors which can contribute. Imagine we approach
this problem with the polynomial regression discussed above. We can tune
the degree $d$ to try to get the best fit.
First let's define some utility functions:
Can you write Python code for it?

def test_func(x, err=0.5):
    return np.random.normal(10 - 1. / (x + 0.1), err)

def compute_error(x, y, p):
    yfit = np.polyval(p, x)
    return np.sqrt(np.mean((y - yfit) ** 2))


I am working on the file "Learning on marked data/Week 1/PA_linreg_stochastic_grad_descent.ipynb".
The first task is:
1. Загрузите данные из файла advertising.csv в объект pandas DataFrame. Источник данных.
Can you write Python code for it?

import pandas as pd
adver_data = pd.read_csv('advertising.csv')


I am working on the file "Learning on marked data/Week 1/PA_linreg_stochastic_grad_descent.ipynb".
The first task is:
2. Реализуйте функцию mserror - среднеквадратичную ошибку прогноза. Она принимает два аргумента - объекты Series y (значения целевого признака) и y_pred (предсказанные значения). Не используйте в этой функции циклы - тогда она будет вычислительно неэффективной.
Can you write Python code for it?

def mserror(y, y_pred):
    # Ваш код здесь
    # sum(iter, start=0) - Сумма членов последовательности.
    return sum((y - y_pred)**2,0)/y.shape[0]


I am working on the file "Learning on marked data/Week 1/PA_linreg_stochastic_grad_descent.ipynb".
The first task is:
3. Реализуйте функцию normal_equation, которая по заданным матрицам (массивам NumPy) X и y вычисляет вектор весов $w$ согласно нормальному уравнению линейной регрессии.
Can you write Python code for it?

def normal_equation(X, y):
    ans = np.dot(np.dot(np.linalg.pinv(np.dot(X.T,X)),X.T),y)
    return ans

norm_eq_weights = normal_equation(X, y)
print(norm_eq_weights)


I am working on the file "Learning on marked data/Week 1/PA_linreg_stochastic_grad_descent.ipynb".
The first task is:
4. Напишите функцию linear_prediction, которая принимает на вход матрицу X и вектор весов линейной модели w, а возвращает вектор прогнозов в виде линейной комбинации столбцов матрицы X с весами w.
Can you write Python code for it?

def linear_prediction(X, w):
    return np.dot(X,w)


I am working on the file "Learning on marked data/Week 1/PA_linreg_stochastic_grad_descent.ipynb".
The first task is:
5. Напишите функцию stochastic_gradient_step, реализующую шаг стохастического градиентного спуска для линейной регрессии. Функция должна принимать матрицу X, вектора y и w, число train_ind - индекс объекта обучающей выборки (строки матрицы X), по которому считается изменение весов, а также число $\eta$ (eta) - шаг градиентного спуска (по умолчанию eta=0.01). Результатом будет вектор обновленных весов. Наша реализация функции будет явно написана для данных с 3 признаками, но несложно модифицировать для любого числа признаков, можете это сделать.
Can you write Python code for it?

def stochastic_gradient_step(X, y, w, train_ind, eta=0.01):
    grad0 = w[0]-(2.0*eta)/X.shape[0]*X[train_ind,0]*((w[0]*X[train_ind,0]+w[1]*X[train_ind,1]+w[2]*X[train_ind,2]+w[3]*X[train_ind,3])-y[train_ind])
    grad1 = w[1]-(2.0*eta)/X.shape[0]*X[train_ind,1]*((w[0]*X[train_ind,0]+w[1]*X[train_ind,1]+w[2]*X[train_ind,2]+w[3]*X[train_ind,3])-y[train_ind])
    grad2 = w[2]-(2.0*eta)/X.shape[0]*X[train_ind,2]*((w[0]*X[train_ind,0]+w[1]*X[train_ind,1]+w[2]*X[train_ind,2]+w[3]*X[train_ind,3])-y[train_ind])
    grad3 = w[3]-(2.0*eta)/X.shape[0]*X[train_ind,3]*((w[0]*X[train_ind,0]+w[1]*X[train_ind,1]+w[2]*X[train_ind,2]+w[3]*X[train_ind,3])-y[train_ind])
    return  np.array([grad0, grad1, grad2, grad3])


I am working on the file "Learning on marked data/Week 1/PA_linreg_stochastic_grad_descent.ipynb".
The first task is:
6. Напишите функцию stochastic_gradient_descent, реализующую стохастический градиентный спуск для линейной регрессии. Функция принимает на вход следующие аргументы:
- X - матрица, соответствующая обучающей выборке
- y - вектор значений целевого признака
- w_init - вектор начальных весов модели
- eta - шаг градиентного спуска (по умолчанию 0.01)
- max_iter - максимальное число итераций градиентного спуска (по умолчанию 10000)
- max_weight_dist - максимальное евклидово расстояние между векторами весов на соседних итерациях градиентного спуска,
при котором алгоритм прекращает работу (по умолчанию 1e-8)
- seed - число, используемое для воспроизводимости сгенерированных псевдослучайных чисел (по умолчанию 42)
- verbose - флаг печати информации (например, для отладки, по умолчанию False)
На каждой итерации в вектор (список) должно записываться текущее значение среднеквадратичной ошибки. Функция должна возвращать вектор весов $w$, а также вектор (список) ошибок.
Can you write Python code for it?

def stochastic_gradient_descent(X, y, w_init, eta=1e-2, max_iter=1e4,
                                min_weight_dist=1e-8, seed=42, verbose=False):
    # Инициализируем расстояние между векторами весов на соседних
    # итерациях большим числом.
    weight_dist = np.inf
    # Инициализируем вектор весов
    w = w_init
    # Сюда будем записывать ошибки на каждой итерации
    errors = []
    # Счетчик итераций
    iter_num = 0
    # Будем порождать псевдослучайные числа
    # (номер объекта, который будет менять веса), а для воспроизводимости
    # этой последовательности псевдослучайных чисел используем seed.
    np.random.seed(seed)

    # Основной цикл
    while weight_dist > min_weight_dist and iter_num < max_iter:
        # порождаем псевдослучайный
        # индекс объекта обучающей выборки
        random_ind = np.random.randint(X.shape[0])

        # Ваш код здесь
        old_w = w
        w = stochastic_gradient_step(X, y, w, random_ind, eta=0.01)
        weight_dist = np.linalg.norm(w - old_w)
        errors.append(mserror(y,np.dot(X,w)))
        iter_num += 1

    return w, errors


I am working on the file "Learning on marked data/Week 1/PA_linreg_stochastic_grad_descent.ipynb".
The first task is:
Запустите $10^5$ итераций стохастического градиентного спуска. Укажите вектор начальных весов w_init, состоящий из нулей. Оставьте параметры  eta и seed равными их значениям по умолчанию (eta=0.01, seed=42 - это важно для проверки ответов).
Can you write Python code for it?

%%time
stoch_grad_desc_weights, stoch_errors_by_iter = stochastic_gradient_descent(X,
y, [0,0,0,0], 0.01, 100000, 1e-8, 42, False)


I am working on the file "Learning on marked data/Week 1/PA_linreg_stochastic_grad_descent.ipynb".
The first task is:
Какова среднеквадратичная ошибка прогноза значений Sales в виде линейной модели с весами, найденными с помощью градиентного спуска? Запишите ответ в файл '4.txt'.
Can you write Python code for it?

answer4 = mserror(y, linear_prediction(X, stoch_grad_desc_weights))
print(answer4)
write_answer_to_file(answer4, '4.txt')


I am working on the file "Learning on marked data/Week 1/PA_linreg_stochastic_grad_descent.ipynb".
The first task is:
Отмасштабируйте столбцы матрицы X, вычтя из каждого значения среднее по соответствующему столбцу и поделив результат на стандартное отклонение. Для определенности, используйте методы mean и std векторов NumPy (реализация std в Pandas может отличаться). Обратите внимание, что в numpy вызов функции .mean() без параметров возвращает среднее по всем элементам массива, а не по столбцам, как в pandas. Чтобы произвести вычисление по столбцам, необходимо указать параметр axis.
Can you write Python code for it?

import numpy as np
# mean - среднее
# std - стандартное отклонение
means, stds = np.mean(X,axis=0),np.std(X,axis=0)

X = (X - means)/stds


I am working on the file "Learning on marked data/Week 1/PA_linreg_stochastic_grad_descent.ipynb".
The first task is:
Посмотрим на вектор весов, к которому сошелся метод.
Can you write Python code for it?


I am working on the file "Learning on marked data/Week 1/PA_linreg_stochastic_grad_descent.ipynb".
The first task is:
Посмотрим на среднеквадратичную ошибку на последней итерации.
Can you write Python code for it?


I am working on the file "Learning on marked data/Week 1/PA_linreg_stochastic_grad_descent.ipynb".
The first task is:
Посмотрите на первые 5 записей и на статистику признаков в этом наборе данных.
Can you write Python code for it?

# Ваш код здесь
adver_data.head(5)

# Ваш код здесь
# Создает различные сводные статистические данные, исключая значения NaN.
print adver_data.describe ()


I am working on the file "Learning on marked data/Week 1/PA_linreg_stochastic_grad_descent.ipynb".
The first task is:
Создайте массивы NumPy X из столбцов TV, Radio и Newspaper и y - из столбца Sales. Используйте атрибут values объекта pandas DataFrame.
Can you write Python code for it?

X = adver_data[['TV','Radio','Newspaper']].values
y = adver_data[['Sales']].values
print X[0]
print y[0]


I am working on the file "Learning on marked data/Week 1/PA_linreg_stochastic_grad_descent.ipynb".
The first task is:
Теперь посмотрим на зависимость ошибки от номера итерации для $10^5$ итераций стохастического градиентного спуска. Видим, что алгоритм сходится.
Can you write Python code for it?

%pylab inline
plot(range(len(stoch_errors_by_iter)), stoch_errors_by_iter)
xlabel('Iteration number')
ylabel('MSE')


I am working on the file "Learning on marked data/Week 1/peer_review_linreg_height_weight.ipynb".
The first task is:
[10]. Постройте 3D-график зависимости функции ошибки, посчитанной в п.6 от параметров $w_0$ и $w_1$. Подпишите ось $x$ меткой «Intercept», ось $y$ – меткой «Slope», a ось $z$ – меткой «Error».
Can you write Python code for it?

fig = plt.figure()
ax = fig.gca(projection='3d') # get current axis

# Создаем массивы NumPy с координатами точек по осям X и У.
# Используем метод meshgrid, при котором по векторам координат
# создается матрица координат. Задаем нужную функцию Z(x, y).
X = np.arange(-10,10,1)#w0
Y = np.arange(-10,10,1)#w1
X, Y = np.meshgrid(X, Y)
Z = error(X,Y,data)

# Наконец, используем метод *plot_surface* объекта
# типа Axes3DSubplot. Также подписываем оси.
surf = ax.plot_surface(X, Y, Z)
ax.set_xlabel('Intercept')
ax.set_ylabel('Slope')
ax.set_zlabel('Error')
ax.set_title('Error in 3D')
plt.show()

# Ваш код здесь

# Ваш код здесь


I am working on the file "Learning on marked data/Week 1/peer_review_linreg_height_weight.ipynb".
The first task is:
[3]. Постройте картинку, на которой будут отображены попарные зависимости признаков , 'Height', 'Weight' и 'BMI' друг от друга. Используйте метод pairplot библиотеки Seaborn.
Can you write Python code for it?

# Ваш код здесь
g = sns.pairplot(data)#,diag_kind="hist",kind="reg"


I am working on the file "Learning on marked data/Week 1/peer_review_linreg_height_weight.ipynb".
The first task is:
Аргументы:

y='Height' - тот признак, распределение которого мы строим
kind='hist' - означает, что строится гистограмма
color='red' - цвет

[2]. Посмотрите на первые 5 записей с помощью метода head Pandas DataFrame. Нарисуйте гистограмму распределения веса с помощью метода plot Pandas DataFrame. Сделайте гистограмму зеленой, подпишите картинку.
Can you write Python code for it?

# Ваш код здесь
# Первые 5 записей из данных
data.head(5)

# Ваш код здесь
# Диаграмма расределения веса
data.plot(y='Weight', kind='hist',
           color='green',  title='Weight (inch.) distribution')


I am working on the file "Learning on marked data/Week 1/peer_review_linreg_height_weight.ipynb".
The first task is:
Итак, мы решаем задачу: как через облако точек, соответсвующих наблюдениям в нашем наборе данных, в пространстве признаков "Рост" и "Вес" провести прямую линию так, чтобы минимизировать функционал из п. 6. Для начала давайте отобразим хоть какие-то прямые и убедимся, что они плохо передают зависимость роста от веса.
[7]. Проведите на графике из п. 5 Задания 1 две прямые, соответствующие значениям параметров ($w_0, w_1) = (60, 0.05)$ и ($w_0, w_1) = (50, 0.16)$. Используйте метод plot из matplotlib.pyplot, а также метод linspace библиотеки NumPy. Подпишите оси и график.
Can you write Python code for it?

# Ваш код здесь
x = np.linspace(70,180)

def y(w0,w1,x):
    return w0 + w1 * x

data.plot(x='Weight',y='Height', kind='scatter')
plt.title('Correlation Weight and Height')
plt.plot(x,y(60,0.05,x),color='r')
plt.plot(x,y(50,0.16,x),color='g')
plt.legend( ('w0 = 60, w1 = 0.05', 'w0 = 50, w1 = 0.16') )


I am working on the file "Learning on marked data/Week 1/peer_review_linreg_height_weight.ipynb".
The first task is:
Минимизация квадратичной функции ошибки - относительная простая задача, поскольку функция выпуклая. Для такой задачи существует много методов оптимизации. Посмотрим, как функция ошибки зависит от одного параметра (наклон прямой), если второй параметр (свободный член) зафиксировать.
[8]. Постройте график зависимости функции ошибки, посчитанной в п. 6, от параметра $w_1$ при $w_0$ = 50. Подпишите оси и график.
Can you write Python code for it?

# Ваш код здесь
# ошибка от параметра w1
w0 = 50
err_graph = []
for w1 in range(-10,10,1):
    err_graph.append(error(w1,w0,data))
    plt.plot(err_graph)


I am working on the file "Learning on marked data/Week 1/peer_review_linreg_height_weight.ipynb".
The first task is:
Один из эффективных методов первичного анализа данных - отображение попарных зависимостей признаков. Создается $m \times m$ графиков (m - число признаков), где по диагонали рисуются гистограммы распределения признаков, а вне диагонали - scatter plots зависимости двух признаков. Это можно делать с помощью метода $scatter_matrix$ Pandas Data Frame или pairplot библиотеки Seaborn.
Чтобы проиллюстрировать этот метод, интересней добавить третий признак. Создадим признак Индекс массы тела (BMI). Для этого воспользуемся удобной связкой метода apply Pandas DataFrame и lambda-функций Python.
Can you write Python code for it?

def make_bmi(height_inch, weight_pound):
    METER_TO_INCH, KILO_TO_POUND = 39.37, 2.20462
    return (weight_pound / KILO_TO_POUND) / \
           (height_inch / METER_TO_INCH) ** 2

data['BMI'] = data.apply(lambda row: make_bmi(row['Height'],
                                              row['Weight']), axis=1)


I am working on the file "Learning on marked data/Week 1/peer_review_linreg_height_weight.ipynb".
The first task is:
При анализе многомерных данных человек часто хочет получить интуитивное представление о природе данных с помощью визуализации. Увы, при числе признаков больше 3 такие картинки нарисовать невозможно. На практике для визуализации данных в 2D и 3D в данных выделаяют 2 или, соответственно, 3 главные компоненты (как именно это делается - мы увидим далее в курсе) и отображают данные на плоскости или в объеме.
Посмотрим, как в Python рисовать 3D картинки, на примере отображения функции $z(x,y) = sin(\sqrt{x^2+y^2})$ для значений $x$ и $y$ из интервала [-5,5] c шагом 0.25.
Can you write Python code for it?


I am working on the file "Learning on marked data/Week 1/peer_review_linreg_height_weight.ipynb".
The first task is:
Считаем данные по росту и весу (weights_heights.csv, приложенный в задании) в объект Pandas DataFrame:
Can you write Python code for it?

data = pd.read_csv('weights_heights.csv', index_col='Index')


I am working on the file "Learning on marked data/Week 1/peer_review_linreg_height_weight.ipynb".
The first task is:
Часто при первичном анализе данных надо исследовать зависимость какого-то количественного признака от категориального (скажем, зарплаты от пола сотрудника). В этом помогут "ящики с усами" - boxplots библиотеки Seaborn. Box plot - это компактный способ показать статистики вещественного признака (среднее и квартили) по разным значениям категориального признака. Также помогает отслеживать "выбросы" - наблюдения, в которых значение данного вещественного признака сильно отличается от других.
[4]. Создайте в DataFrame data новый признак weight_category, который будет иметь 3 значения: 1 – если вес меньше 120 фунтов. (~ 54 кг.), 3 - если вес  больше или равен 150 фунтов (~68 кг.), 2 – в остальных случаях. Постройте «ящик с усами» (boxplot), демонстрирующий зависимость роста от весовой категории. Используйте метод boxplot библиотеки Seaborn и метод apply Pandas DataFrame. Подпишите ось y меткой «Рост», ось x – меткой «Весовая категория».
Can you write Python code for it?

# определение значения для признака weight_category
def weight_category(weight):
    if weight<120:
        return 1
    elif weight>=150:
        return 3
    else:
        return 2

data['weight_cat'] = data['Weight'].apply(weight_category)
# Ваш код здесь
sns.boxplot(x=data["weight_cat"], y=data["Height"])
data.head(5)


I am working on the file "Learning on marked data/Week 1/peer_review_linreg_height_weight.ipynb".
The first task is:
Чаще всего первое, что надо надо сделать после считывания данных - это посмотреть на первые несколько записей. Так можно отловить ошибки чтения данных (например, если вместо 10 столбцов получился один, в названии которого 9 точек с запятой). Также это позволяет познакомиться с данными, как минимум, посмотреть на признаки и их природу (количественный, категориальный и т.д.).
После этого стоит построить гистограммы распределения признаков - это опять-таки позволяет понять природу признака (степенное у него распределение, или нормальное, или какое-то еще). Также благодаря гистограмме можно найти какие-то значения, сильно не похожие на другие - "выбросы" в данных.
Гистограммы удобно строить методом plot Pandas DataFrame с аргументом kind='hist'.
Пример. Построим гистограмму распределения роста подростков из выборки data. Используем метод plot для DataFrame data c аргументами y='Height' (это тот признак, распределение которого мы строим)
Can you write Python code for it?

data.plot(y='Height', kind='hist',
           color='red',  title='Height (inch.) distribution')


I am working on the file "Learning on marked data/Week 2/MetricsPA.ipynb".
The first task is:
F1-score
Очевидный недостаток пары метрик precision-recall - в том, что их две: непонятно, как ранжировать алгоритмы. Чтобы этого избежать, используют F1-метрику, которая равна среднему гармоническому precision и recall.
F1-метрика будет равна 1, если и только если precision = 1 и recall = 1 (идеальный алгоритм).
(: Обмануть F1 сложно: если одна из величин маленькая, а другая близка к 1 (по графикам видно, что такое соотношение иногда легко получить), F1 будет далека от 1. F1-метрику сложно оптимизировать, потому что для этого нужно добиваться высокой полноты и точности одновременно.
Например, посчитаем F1 для того же набора векторов, для которого мы строили графики (мы помним, что там одна из кривых быстро выходит в единицу).
Can you write Python code for it?

from sklearn.metrics import f1_score

T = 0.5
print "Разные склонности алгоритмов к ошибкам FP и FN:"
for actual, predicted, descr in zip([actual_1, actual_10, actual_11],
                                    [predicted_1 > T, predicted_10 > T, predicted_11 > T],
                                    ["Typical:", "Avoids FP:", "Avoids FN:"]):
    print descr, "f1 =", f1_score(actual, predicted)


I am working on the file "Learning on marked data/Week 2/MetricsPA.ipynb".
The first task is:
F1-метрика в двух последних случаях, когда одна из парных метрик равна 1, значительно меньше, чем в первом, сбалансированном случае.
<font color="green" size=5>Programming assignment: problem 2. </font> На precision и recall влияют и характер вектора вероятностей, и установленный порог.
Для тех же пар (actual, predicted), что и в предыдущей задаче, найдите оптимальные пороги, максимизирующие F1_score. Будем рассматривать только пороги вида T = 0.1 * k, k - целое; соответственно, нужно найти три значения k. Если f1 максимизируется при нескольких значениях k, укажите наименьшее из них.
Запишите найденные числа k в следующем порядке:
k_1, k_10, k_11
Цифры XXX после пробела соответствуют таким же цифрам в названиях переменных actual_XXX и predicted_XXX.
Передайте ответ в функцию write_answer_2. Загрузите файл в форму.
Если вы запишите список из трех найденных k в том же порядке в переменную ks, то с помощью кода ниже можно визуализировать найденные пороги:
Can you write Python code for it?

############### Programming assignment: problem 2 ###############
k = 1
print "Поиск значений к:"
for i in range(10):
    T = 0.1 * k
    print 'k = ',k,'T =  ',T
    for actual, predicted, descr in zip([actual_1, actual_10, actual_11],
                                        [predicted_1 > T, predicted_10 > T, predicted_11 > T],
                                        ["Typical:", "Avoids FP:", "Avoids FN:"]):
        print descr, "f1 =", f1_score(actual, predicted)
    k += 1
    print

k_1 = 5
k_10 = 3
k_11 =6
ks = [k_1, k_10, k_11]

many_scatters([actual_1, actual_10, actual_11], [predicted_1, predicted_10, predicted_11],
              np.array(ks)*0.1, ["Typical", "Avoids FP", "Avoids FN"], (1, 3))

def write_answer_2(k_1, k_10, k_11):
    answers = [k_1, k_10, k_11]
    with open("pa_metrics_problem2.txt", "w") as fout:
        fout.write(" ".join([str(num) for num in answers]))
write_answer_2(k_1, k_10, k_11)


I am working on the file "Learning on marked data/Week 2/MetricsPA.ipynb".
The first task is:
Идеальная ситуация: существует порог T, верно разделяющий вероятности, соответствующие двум классам. Пример такой ситуации:
Can you write Python code for it?


I am working on the file "Learning on marked data/Week 2/MetricsPA.ipynb".
The first task is:
Интервалы вероятностей для двух классов прекрасно разделяются порогом T = 0.5.
Чаще всего интервалы накладываются - тогда нужно аккуратно подбирать порог.
Самый неправильный алгоритм делает все наоборот: поднимает вероятности класса 0 выше вероятностей класса 1. Если так произошло, стоит посмотреть, не перепутались ли метки 0 и 1 при создании целевого вектора из сырых данных.
Примеры:
Can you write Python code for it?


I am working on the file "Learning on marked data/Week 2/MetricsPA.ipynb".
The first task is:
Как и предыдущие метрики, log_loss хорошо различает идеальный, типичный и плохой случаи. Но обратите внимание, что интерпретировать величину достаточно сложно: метрика не достигает нуля никогда и не имеет верхней границы. Поэтому даже для идеального алгоритма, если смотреть только на одно значение log_loss, невозможно понять, что он идеальный.
Но зато эта метрика различает осторожный и рискующий алгоритмы. Как мы видели выше, в случаях Typical careful и Typical risky количество ошибок при бинаризации по T = 0.5 примерно одинаковое, в случаях Ideal ошибок вообще нет. Однако за неудачно угаданные классы в Typical рискующему алгоритму приходится платить большим увеличением log_loss, чем осторожному алгоритму. С другой стороны, за удачно угаданные классы рискованный идеальный алгоритм получает меньший log_loss, чем осторожный идеальный алгоритм.
Таким образом, log_loss чувствителен и к вероятностям, близким к 0 и 1, и к вероятностям, близким к 0.5.
Ошибки FP и FN обычный Log_loss различать не умеет.
Однако нетрудно сделать обобщение log_loss на случай, когда нужно больше штрафовать FP или FN: для этого достаточно добавить выпуклую (то есть неотрицательную и суммирующуюся к единице) комбинацию из двух коэффициентов к слагаемым правдоподобия. Например, давайте штрафовать false positive:
$weighted_log_loss(actual, predicted) = -\frac 1 n \sum_{i=1}^n (0.3\, \cdot actual_i \cdot \log (predicted_i) + 0.7\,\cdot (1-actual_i)\cdot \log (1-predicted_i))$
$log_loss(actual, predicted) = - \frac 1 n \sum_{i=1}^n (actual_i \cdot \log (predicted_i) + (1-actual_i) \cdot \log (1-predicted_i))$, $n$ - длина векторов.
Если алгоритм неверно предсказывает большую вероятность первому классу, то есть объект на самом деле принадлежит классу 0, то первое слагаемое в скобках равно нулю, а второе учитывается с большим весом.
<font color="green" size=5>Programming assignment: problem 3. </font> Напишите функцию, которая берет на вход векторы actual и predicted и возвращает модифицированный Log-Loss, вычисленный по формуле выше....
Can you write Python code for it?

############### Programming assignment: problem 3 ###############
import math
def weighted_log_loss(actual,predicted):
    sum = 0.
    n = len(actual)
    for i in xrange(0,n):
        sum += 0.3 * actual[i] * math.log(predicted[i]) + 0.7 * (1 - actual[i]) * math.log(1 - predicted[i])
    return round(sum/-n,12)

answer = []
j = 0
print "Вычисление модифицированного Log_loss\n"
print "Алгоритмы, разные по качеству:"
for actual, predicted, descr in zip([actual_0, actual_1, actual_2],
                                    [predicted_0, predicted_1, predicted_2],
                                    ["Perfect:", "Typical:", "Awful:"]):
    answer.append(weighted_log_loss(actual, predicted))
    print descr, answer[j]
    j += 1

print "\nОсторожный и рискующий алгоритмы:"
for actual, predicted, descr in zip([actual_0r, actual_1r],
                                    [ predicted_0r, predicted_1r],
                                    ["Ideal careful", "Ideal risky", "Typical careful:", "Typical risky:"]):
    answer.append(weighted_log_loss(actual, predicted))
    print descr, answer[j]
    j += 1

print "\nРазные склонности алгоритмов к ошибкам FP и FN:"
for actual, predicted, descr in zip([actual_10, actual_11],
                                    [predicted_10, predicted_11],
                                    ["Avoids FP:", "Avoids FN:"]):
    answer.append(weighted_log_loss(actual, predicted))
    print descr, answer[j]
    j += 1

def write_answer_3(wll_0, wll_1, wll_2, wll_0r, wll_1r, wll_10, wll_11):
    answers = [wll_0, wll_1, wll_2, wll_0r, wll_1r, wll_10, wll_11]
    with open("pa_metrics_problem3.txt", "w") as fout:
        fout.write(" ".join([str(num) for num in answers]))
write_answer_3(answer[0], answer[1], answer[2], answer[3], answer[4], answer[5], answer[6])


I am working on the file "Learning on marked data/Week 2/MetricsPA.ipynb".
The first task is:
Мы описали разные характеры векторов вероятностей. Далее мы будем смотреть, как метрики оценивают разные векторы предсказаний, поэтому обязательно выполните ячейки, создающие векторы для визуализации.
Метрики, оценивающие бинарные векторы предсказаний
Есть две типичные ситуации, когда специалисты по машинному обучению начинают изучать характеристики метрик качества:
1. при участии в соревновании или решении прикладной задачи, когда вектор предсказаний оценивается по конкретной метрике, и нужно построить алгоритм, максимизирующий эту метрику.
1. на этапе формализации задачи машинного обучения, когда есть требования прикладной области, и нужно предложить математическую метрику, которая будет соответствовать этим требованиям.
Далее мы вкратце рассмотрим каждую метрику с этих двух позиций.
Precision и recall; accuracy
Для начала разберемся с метриками, оценивающие качество уже после бинаризации по порогу T, то есть сравнивающие два бинарных вектора: actual и predicted.
Две популярные метрики - precision и recall. Первая показывает, как часто алгоритм предсказывает класс 1 и оказывается правым, а вторая - как много объектов класса 1 алгоритм нашел.
Также рассмотрим самую простую и известную метрику - accuracy; она показывает долю правильных ответов.
Выясним преимущества и недостатки этих метрик, попробовав их на разных векторах вероятностей.
Can you write Python code for it?

from sklearn.metrics import precision_score, recall_score, accuracy_score

T = 0.5
print "Алгоритмы, разные по качеству:"
for actual, predicted, descr in zip([actual_0, actual_1, actual_2],
                                    [predicted_0 > T, predicted_1 > T, predicted_2 > T],
                                    ["Perfect:", "Typical:", "Awful:"]):
    print descr, "precision =", precision_score(actual, predicted), "recall =", \
        recall_score(actual, predicted), ";",\
        "accuracy =", accuracy_score(actual, predicted)
print
print "Осторожный и рискующий алгоритмы:"
for actual, predicted, descr in zip([actual_1, actual_1r],
                                    [predicted_1 > T, predicted_1r > T],
                                    ["Typical careful:", "Typical risky:"]):
    print descr, "precision =", precision_score(actual, predicted), "recall =", \
        recall_score(actual, predicted), ";",\
        "accuracy =", accuracy_score(actual, predicted)
print
print "Разные склонности алгоритмов к ошибкам FP и FN:"
for actual, predicted, descr in zip([actual_10, actual_11],
                                    [predicted_10 > T, predicted_11 > T],
                                    ["Avoids FP:", "Avoids FN:"]):
    print descr, "precision =", precision_score(actual, predicted), "recall =", \
        recall_score(actual, predicted), ";",\
        "accuracy =", accuracy_score(actual, predicted)


I am working on the file "Learning on marked data/Week 2/MetricsPA.ipynb".
The first task is:
Обратите внимание на разницу weighted_log_loss между случаями Avoids FP и Avoids FN.
ROC и AUC
При построении ROC-кривой (receiver operating characteristic) происходит варьирование порога бинаризации вектора вероятностей, и  вычисляются величины, зависящие от числа ошибок FP и FN. Эти величины задаются так, чтобы в случае, когда существует порог для идеального разделения классов, ROC-кривая проходила через определенную точку - верхний левый угол квадрата [0, 1] x [0, 1]. Кроме того, она всегда проходит через левый нижний и правый верхний углы. Получается наглядная визуализация качества алгоритма. С целью охарактеризовать эту визуализацию численно, ввели понятие AUC - площадь под ROC-кривой.
Есть несложный и эффективный алгоритм, который за один проход по выборке вычисляет ROC-кривую и AUC, но мы не будем вдаваться в детали.
Построим ROC-кривые для наших задач:
Can you write Python code for it?

from sklearn.metrics import roc_curve, roc_auc_score

plt.figure(figsize=(15, 5))
plt.subplot(1, 3, 1)
aucs = ""
for actual, predicted, descr in zip([actual_0, actual_1, actual_2],
                                    [predicted_0, predicted_1, predicted_2],
                                    ["Perfect", "Typical", "Awful"]):
    fpr, tpr, thr = roc_curve(actual, predicted)
    plt.plot(fpr, tpr, label=descr)
    aucs += descr + ":%3f"%roc_auc_score(actual, predicted) + " "
plt.xlabel("false positive rate")
plt.ylabel("true positive rate")
plt.legend(loc=4)
plt.axis([-0.1, 1.1, -0.1, 1.1])
plt.subplot(1, 3, 2)
for actual, predicted, descr in zip([actual_0, actual_0r, actual_1, actual_1r],
                                    [predicted_0, predicted_0r, predicted_1, predicted_1r],
                                    ["Ideal careful", "Ideal Risky", "Typical careful", "Typical risky"]):
    fpr, tpr, thr = roc_curve(actual, predicted)
    aucs += descr + ":%3f"%roc_auc_score(actual, predicted) + " "
    plt.plot(fpr, tpr, label=descr)
plt.xlabel("false positive rate")
plt.ylabel("true positive rate")
plt.legend(loc=4)
plt.axis([-0.1, 1.1, -0.1, 1.1])
plt.subplot(1, 3, 3)
for actual, predicted, descr in zip([actual_1, actual_10, actual_11],
                                    [predicted_1, predicted_10, predicted_11],
                                    ["Typical", "Avoids FP", "Avoids FN"]):
    fpr, tpr, thr = roc_curve(actual, predicted)
    aucs += descr + ":%3f"%roc_auc_score(actual, predicted) + " "
    plt.plot(fpr, tpr, label=descr)
plt.xlabel("false positive rate")
plt.ylabel("true positive rate")
plt.legend(loc=4)
plt.axis([-0.1, 1.1, -0.1, 1.1])
print aucs


I am working on the file "Learning on marked data/Week 2/MetricsPA.ipynb".
The first task is:
При увеличении порога мы делаем меньше ошибок FP и больше ошибок FN, поэтому одна из кривых растет, а вторая  - падает. По такому графику можно подобрать оптимальное значение порога, при котором precision и recall будут приемлемы. Если такого порога не нашлось, нужно обучать другой алгоритм.
Оговоримся, что приемлемые значения precision и recall определяются предметной областью. Например, в задаче определения, болен ли пациент определенной болезнью (0 - здоров, 1 - болен), ошибок false negative стараются избегать, требуя recall около 0.9. Можно сказать человеку, что он болен, и при дальнейшей диагностике выявить ошибку; гораздо хуже пропустить наличие болезни.
<font color="green" size=5>Programming assignment: problem 1. </font> Фиксируем порог T = 0.65; по графикам можно примерно узнать, чему равны метрики на трех выбранных парах векторов (actual, predicted). Вычислите точные precision и recall для этих трех пар векторов.
6 полученных чисел запишите в текстовый файл в таком порядке:
precision_1 recall_1 precision_10 recall_10 precision_11 recall_11
Цифры XXX после пробела соответствуют таким же цифрам в названиях переменных actual_XXX и predicted_XXX.
Передайте ответ в функцию write_answer_1. Полученный файл загрузите в форму.
Can you write Python code for it?

############### Programming assignment: problem 1 ###############
T = 0.65
ans =[]
print "Метрики на трех выбранных парах векторов:"
for actual, predicted, descr in zip([actual_1, actual_10, actual_11],
                                    [predicted_1 > T, predicted_10 > T, predicted_11 > T],
                                    ["Typical:", "Avoids FP:", "Avoids FN:"]):
    print descr, "precision =", precision_score(actual, predicted), "recall =", \
        recall_score(actual, predicted), ";",\
        "accuracy =", accuracy_score(actual, predicted)
    ans.append(precision_score(actual, predicted))
    ans.append(recall_score(actual, predicted))
print
print ans

def write_answer_1(precision_1, recall_1, precision_10, recall_10, precision_11, recall_11):
    answers = [precision_1, recall_1, precision_10, recall_10, precision_11, recall_11]
    with open("pa_metrics_problem1.txt", "w") as fout:
        fout.write(" ".join([str(num) for num in answers]))
write_answer_1(ans[0],ans[1],ans[2],ans[3],ans[4],ans[5])


I am working on the file "Learning on marked data/Week 2/MetricsPA.ipynb".
The first task is:
Также интервалы могут смещаться. Если алгоритм боится ошибок false positive, то он будет чаще делать предсказания, близкие к нулю.
Аналогично, чтобы избежать ошибок false negative, логично чаще предсказывать большие вероятности.
Can you write Python code for it?


I am working on the file "Learning on marked data/Week 2/MetricsPA.ipynb".
The first task is:
Чем больше объектов в выборке, тем более гладкой выглядит кривая (хотя на самом деле она все равно ступенчатая).
Как и ожидалось, кривые всех идеальных алгоритмов проходят через левый верхний угол. На первом графике также показана типичная ROC-кривая (обычно на практике они не доходят до "идеального" угла).
AUC рискующего алгоритма значительном меньше, чем у осторожного, хотя осторожный и рискущий идеальные алгоритмы не различаются по ROC или AUC. Поэтому стремиться увеличить зазор между интервалами вероятностей классов смысла не имеет.
Наблюдается перекос кривой в случае, когда алгоритму свойственны ошибки FP или FN. Однако по величине AUC это отследить невозможно (кривые могут быть симметричны относительно диагонали (0, 1)-(1, 0)).
После того, как кривая построена, удобно выбирать порог бинаризации, в котором будет достигнут компромисс между FP или FN. Порог соответствует точке на кривой. Если мы хотим избежать ошибок FP, нужно выбирать точку на левой стороне квадрата (как можно выше), если FN - точку на верхней стороне квадрата (как можно левее). Все промежуточные точки будут соответствовать разным пропорциям FP и FN.
<font color="green" size=5>Programming assignment: problem 4. </font> На каждой кривой найдите точку, которая ближе всего к левому верхнему углу (ближе в смысле обычного евклидова расстояния), этой точке соответствует некоторый порог бинаризации. Запишите в выходной файл пороги в следующем порядке:
T_0 T_1 T_2 T_0r T_1r T_10 T_11
Цифры XXX после пробела соответствуют таким же цифрам в названиях переменных actual_XXX и predicted_XXX.
Если порогов, минимизирующих расстояние, несколько, выберите наибольший.
Передайте ответ в функцию write_answer_4. Загрузите файл в форму.
Пояснение: функция roc_curve возвращает три значения: FPR (массив абсции точек ROC-кривой), TPR (массив ординат точек ROC-кривой) и thresholds (массив порогов, соответствующих точкам).
Рекомендуем отрисовывать найденную точку на графике с помощью функции plt.scatter.
Can you write Python code for it?

def Binarization_threshold(fpr,tpr,thr):
    ideal = np.array([0,1])
    mins = np.linalg.norm(ideal - np.array([fpr[0],tpr[0]]))
    ansT = thr[0]#t
    resX = fpr[0]#x
    resY = tpr[0]#y
    for i in xrange(1,len(fpr)):
        result = np.linalg.norm(ideal - np.array([fpr[i],tpr[i]]))
        if result < mins:
            mins = result
            ansT = thr[i]#t
            resX = fpr[i]#x
            resY = tpr[i]#y

    plt.scatter(resX,resY)
    return ansT

############### Programming assignment: problem 4 ###############
plt.figure(figsize=(15, 5))
plt.subplot(1, 3, 1)
aucs = ""
answer4 = []
for actual, predicted, descr in zip([actual_0, actual_1, actual_2],
                                    [predicted_0, predicted_1, predicted_2],
                                    ["Perfect", "Typical", "Awful"]):
    fpr, tpr, thr = roc_curve(actual, predicted)

    answer4.append(Binarization_threshold(fpr,tpr,thr))#search t

    plt.plot(fpr, tpr, label=descr)
    aucs += descr + ":%3f"%roc_auc_score(actual, predicted) + " "
plt.xlabel("false positive rate")
plt.ylabel("true positive rate")
plt.legend(loc=4)
plt.axis([-0.1, 1.1, -0.1, 1.1])
plt.subplot(1, 3, 2)

#-------
for actual, predicted, descr in zip([actual_0r,actual_1r],
                                    [predicted_0r,predicted_1r],
                                    ["Ideal Risky","Typical risky"]):
    fpr, tpr, thr = roc_curve(actual, predicted)

    answer4.append(Binarization_threshold(fpr,tpr,thr))#search t

    aucs += descr + ":%3f"%roc_auc_score(actual, predicted) + " "
    plt.plot(fpr, tpr, label=descr)
plt.xlabel("false positive rate")
plt.ylabel("true positive rate")
plt.legend(loc=4)
plt.axis([-0.1, 1.1, -0.1, 1.1])
plt.subplot(1, 3, 3)

#--------
for actual, predicted, descr in zip([actual_10, actual_11],
                                    [predicted_10, predicted_11],
                                    ["Avoids FP", "Avoids FN"]):
    fpr, tpr, thr = roc_curve(actual, predicted)

   ...


I am working on the file "Learning on marked data/Week 2/MetricsPA.ipynb".
The first task is:
Что предсказывают алгоритмы
Для вычисления метрик качества в обучении с учителем нужно знать только два вектора: вектор правильных ответов и вектор предсказанных величин; будем обозначать их actual и predicted. Вектор actual известен из обучающей выборки, вектор predicted возвращается алгоритмом предсказания. Сегодня мы не будем использовать какие-то алгоритмы классификации, а просто рассмотрим разные векторы предсказаний.
В нашей формулировке actual состоит из нулей и единиц, а predicted - из величин из интервала [0, 1] (вероятности класса 1). Такие векторы удобно показывать на scatter plot.
Чтобы сделать финальное предсказание (уже бинарное), нужно установить порог T: все объекты, имеющие предсказание выше порога, относят к классу 1, остальные - к классу 0.
Can you write Python code for it?

# рисует один scatter plot
# scatterplot- это тип графика,
# который показывает данные как совокупность точек.
def scatter(actual, predicted, T):
    plt.scatter(actual, predicted)
    plt.xlabel("Labels")
    plt.ylabel("Predicted probabilities")
    plt.plot([-0.2, 1.2], [T, T])
    plt.axis([-0.1, 1.1, -0.1, 1.1])#область осей [xmin, xmax, ymin, ymax]

# рисует несколько scatter plot в таблице, имеющей размеры shape
def many_scatters(actuals, predicteds, Ts, titles, shape):
    plt.figure(figsize=(shape[1]*5, shape[0]*5))
    i = 1
    for actual, predicted, T, title in zip(actuals, predicteds, Ts, titles):
        ax = plt.subplot(shape[0], shape[1], i)
        ax.set_title(title)
        i += 1
        scatter(actual, predicted, T)


I am working on the file "Learning on marked data/Week 2/OverfittingTask.ipynb".
The first task is:
Блок 1. Ответьте на вопросы (каждый 0.5 балла):
1. Каков характер зависимости числа прокатов от месяца?
   * ответ: линейная
1. Укажите один или два признака, от которых число прокатов скорее всего зависит линейно
   * ответ: день недели, месяц.
Давайте более строго оценим уровень линейной зависимости между признаками и целевой переменной. Хорошей мерой линейной зависимости между двумя векторами является корреляция Пирсона. В pandas ее можно посчитать с помощью двух методов датафрейма: corr и corrwith. Метод df.corr вычисляет матрицу корреляций всех признаков из датафрейма. Методу df.corrwith нужно подать еще один датафрейм в качестве аргумента, и тогда он посчитает попарные корреляции между признаками из df и этого датафрейма.
Can you write Python code for it?

# Код 1.1 (0.5 балла)
# Посчитайте корреляции всех признаков, кроме последнего, с последним с помощью метода corrwith:
df_new = df.drop('cnt',axis = 1)
print 'Все кроме последнего: \n', df_new.corr()
print '\n Последний признак: \n', df.corrwith(df['cnt'])


I am working on the file "Learning on marked data/Week 2/OverfittingTask.ipynb".
The first task is:
В выборке есть признаки, коррелирующие с целевым, а значит, задачу можно решать линейными методами.
По графикам видно, что некоторые признаки похожи друг на друга. Поэтому давайте также посчитаем корреляции между вещественными признаками.
Can you write Python code for it?

# Код 1.2 (0.5 балла)
# Посчитайте попарные корреляции между признаками temp, atemp, hum, windspeed(mph), windspeed(ms) и cnt
# с помощью метода corr:
df_new = df.drop(['season', 'mnth','yr','holiday','weekday','workingday','weathersit'], axis=1)
df_new.corr()


I am working on the file "Learning on marked data/Week 2/OverfittingTask.ipynb".
The first task is:
Давайте обучим линейную регрессию на наших данных и посмотрим на веса признаков.
Can you write Python code for it?

from sklearn.linear_model import LinearRegression

# Код 2.1 (1 балл)
# Создайте объект линейного регрессора, обучите его на всех данных и выведите веса модели
# (веса хранятся в переменной coef_ класса регрессора).
# Можно выводить пары (название признака, вес), воспользовавшись функцией zip, встроенной в язык python
# Названия признаков хранятся в переменной df.columns
lin_reg = LinearRegression()
lin_reg.fit(X,y)
print zip(df.columns,lin_reg.coef_)


I am working on the file "Learning on marked data/Week 2/OverfittingTask.ipynb".
The first task is:
Для каждого дня проката известны следующие признаки (как они были указаны в источнике данных):
* season: 1 - весна, 2 - лето, 3 - осень, 4 - зима
* yr: 0 - 2011, 1 - 2012
* mnth: от 1 до 12
* holiday: 0 - нет праздника, 1 - есть праздник
* weekday: от 0 до 6
* workingday: 0 - нерабочий день, 1 - рабочий день
* weathersit: оценка благоприятности погоды от 1 (чистый, ясный день) до 4 (ливень, туман)
* temp: температура в Цельсиях
* atemp: температура по ощущениям в Цельсиях
* hum: влажность
* windspeed(mph): скорость ветра в милях в час
* windspeed(ms): скорость ветра в метрах в секунду
* cnt: количество арендованных велосипедов (это целевой признак, его мы будем предсказывать)
Итак, у нас есть вещественные, бинарные и номинальные (порядковые) признаки, и со всеми из них можно работать как с вещественными. С номинальныеми признаками тоже можно работать как с вещественными, потому что на них задан порядок. Давайте посмотрим на графиках, как целевой признак зависит от остальных
Can you write Python code for it?

fig, axes = plt.subplots(nrows=3, ncols=4, figsize=(15, 10))
for idx, feature in enumerate(df.columns[:-1]):
    df.plot(feature, "cnt", subplots=True, kind="scatter", ax=axes[idx / 4, idx % 4])


I am working on the file "Learning on marked data/Week 2/OverfittingTask.ipynb".
The first task is:
Мы видим, что веса при линейно-зависимых признаках по модулю значительно больше, чем при других признаках.
Чтобы понять, почему так произошло, вспомним аналитическую формулу, по которой вычисляются веса линейной модели в методе наименьших квадратов:
$w = (X^TX)^{-1} X^T y$.
Если в X есть коллинеарные (линейно-зависимые) столбцы, матрица $X^TX$ становится вырожденной, и формула перестает быть корректной. Чем более зависимы признаки, тем меньше определитель этой матрицы и тем хуже аппроксимация $Xw \approx y$. Такая ситуацию называют проблемой мультиколлинеарности, вы обсуждали ее на лекции.
С парой temp-atemp чуть менее коррелирующих переменных такого не произошло, однако на практике всегда стоит внимательно следить за коэффициентами при похожих признаках.
Решение проблемы мультиколлинеарности состоит в регуляризации линейной модели. К оптимизируемому функционалу прибавляют L1 или L2 норму весов, умноженную на коэффициент регуляризации $\alpha$. В первом случае метод называется Lasso, а во втором --- Ridge. Подробнее об этом также рассказано в лекции.
Обучите регрессоры Ridge и Lasso с параметрами по умолчанию и убедитесь, что проблема с весами решилась.
Can you write Python code for it?

from sklearn.linear_model import Lasso, Ridge

# Код 2.2 (0.5 балла)
# Обучите линейную модель с L1-регуляризацией и выведите веса
lass = Lasso()
lass.fit(X,y)
print zip(df.columns,lass.coef_)

# Код 2.3 (0.5 балла)
# Обучите линейную модель с L2-регуляризацией и выведите веса
rid = Ridge()
rid.fit(X,y)
print zip(df.columns,rid.coef_)


I am working on the file "Learning on marked data/Week 2/OverfittingTask.ipynb".
The first task is:
Ответы на следующие вопросы можно давать, глядя на графики или выводя коэффициенты на печать.
Блок 2. Ответьте на вопросы (каждый 0.25 балла):
1. Какой регуляризатор (Ridge или Lasso) агрессивнее уменьшает веса при одном и том же alpha?
    * Ответ: Lass
1. Что произойдет с весами Lasso, если alpha сделать очень большим? Поясните, почему так происходит.
    * Ответ: При большом alpha коэффициенты обнулятся из-за низкой предсказательной способности.
1. Можно ли утверждать, что Lasso исключает один из признаков windspeed при любом значении alpha > 0? А Ridge? Ситается, что регуляризатор исключает признак, если коэффициент при нем < 1e-3.
    * Ответ:  Да. Нет.
1. Какой из регуляризаторов подойдет для отбора неинформативных признаков?
    * Ответ: Lasso
Далее будем работать с Lasso.
Итак, мы видим, что при изменении alpha модель по-разному подбирает коэффициенты признаков. Нам нужно выбрать наилучшее alpha.
Для этого, во-первых, нам нужна метрика качества. Будем использовать в качестве метрики сам оптимизируемый функционал метода наименьших квадратов, то есть Mean Square Error.
Во-вторых, нужно понять, на каких данных эту метрику считать. Нельзя выбирать alpha по значению MSE на обучающей выборке, потому что тогда мы не сможем оценить, как модель будет делать предсказания на новых для нее данных. Если мы выберем одно разбиение выборки на обучающую и тестовую (это называется holdout), то настроимся на конкретные "новые" данные, и вновь можем переобучиться. Поэтому будем делать несколько разбиений выборки, на каждом пробовать разные значения alpha, а затем усреднять MSE. Удобнее всего делать такие разбиения кросс-валидацией, то есть разделить выборку на K частей, или блоков, и каждый раз брать одну из них как тестовую, а из оставшихся блоков составлять обучающую выборку.
Делать кросс-валидацию для регрессии в sklearn совсем просто: для этого есть специальный регрессор, LassoCV, который берет на вход список из alpha и для каждого из них вычисляет MSE на кросс-валидации. После обучения (если оставить параметр cv=3...
Can you write Python code for it?

from sklearn.linear_model import LassoCV

# Код 3.2 (1 балл)
# Обучите регрессор LassoCV на всех параметрах регуляризации из alpha
# Постройте график _усредненного_ по строкам MSE в зависимости от alpha.
# Выведите выбранное alpha, а также пары "признак-коэффициент" для обученного вектора коэффициентов
alphas = np.arange(1, 100, 5)
lass_cv=LassoCV(alphas=alphas)
lass_cv.fit(X,y)

print 'Выбранное alp = ',lass_cv.alpha_
print '\n Признак-коэфф: \n', zip(df.columns,lass_cv.coef_)

average = map(lambda elem: sum(elem) / 3, lass_cv.mse_path_[:])
plt.plot(lass_cv.alphas_, average)
plt.title('MSE & alphas')
plt.xlabel('alphas')
plt.ylabel('MSE')


I am working on the file "Learning on marked data/Week 2/OverfittingTask.ipynb".
The first task is:
Признаки имеют разный масштаб, значит для дальнейшей работы нам лучше нормировать матрицу объекты-признаки.
Проблема первая: коллинеарные признаки
Итак, в наших данных один признак дублирует другой, и есть еще два очень похожих. Конечно, мы могли бы сразу удалить дубликаты, но давайте посмотрим, как бы происходило обучение модели, если бы мы не заметили эту проблему.
Для начала проведем масштабирование, или стандартизацию признаков: из каждого признака вычтем его среднее и поделим на стандартное отклонение. Это можно сделать с помощью метода scale.
Кроме того, нужно перемешать выборку, это потребуется для кросс-валидации.
Can you write Python code for it?

from sklearn.preprocessing import scale
from sklearn.utils import shuffle

df_shuffled = shuffle(df, random_state=123)
X = scale(df_shuffled[df_shuffled.columns[:-1]])
y = df_shuffled["cnt"]


I am working on the file "Learning on marked data/Week 3/Preprocessing_LR.ipynb".
The first task is:
Балансировка классов.
Алгоритмы классификации могут быть очень чувствительны к несбалансированным классам. Рассмотрим пример с выборками, сэмплированными из двух гауссиан. Их мат. ожидания и матрицы ковариации заданы так, что истинная разделяющая поверхность должна проходить параллельно оси x. Поместим в обучающую выборку 20 объектов, сэмплированных из 1-й гауссианы, и 10 объектов из 2-й. После этого обучим на них линейную регрессию, и построим на графиках объекты и области классификации.
Can you write Python code for it?

np.random.seed(0)
"""Сэмплируем данные из первой гауссианы"""
data_0 = np.random.multivariate_normal([0,0], [[0.5,0],[0,0.5]], size=40)
"""И из второй"""
data_1 = np.random.multivariate_normal([0,1], [[0.5,0],[0,0.5]], size=40)
"""На обучение берём 20 объектов из первого класса и 10 из второго"""
example_data_train = np.vstack([data_0[:20,:], data_1[:10,:]])
example_labels_train = np.concatenate([np.zeros((20)), np.ones((10))])
"""На тест - 20 из первого и 30 из второго"""
example_data_test = np.vstack([data_0[20:,:], data_1[10:,:]])
example_labels_test = np.concatenate([np.zeros((20)), np.ones((30))])
"""Задаём координатную сетку, на которой будем вычислять область классификации"""
xx, yy = np.meshgrid(np.arange(-3, 3, 0.02), np.arange(-3, 3, 0.02))
"""Обучаем регрессию без балансировки по классам"""
optimizer = GridSearchCV(LogisticRegression(), param_grid, cv=cv, n_jobs=-1)
optimizer.fit(example_data_train, example_labels_train)
"""Строим предсказания регрессии для сетки"""
Z = optimizer.predict(np.c_[xx.ravel(), yy.ravel()]).reshape(xx.shape)
plt.pcolormesh(xx, yy, Z, cmap=plt.cm.Pastel2)
plt.scatter(data_0[:,0], data_0[:,1], color='red')
plt.scatter(data_1[:,0], data_1[:,1], color='blue')
"""Считаем AUC"""
auc_wo_class_weights = roc_auc_score(example_labels_test, optimizer.predict_proba(example_data_test)[:,1])
plt.title('Without class weights')
plt.show()
print('AUC: %f'%auc_wo_class_weights)
"""Для второй регрессии в LogisticRegression передаём параметр class_weight='balanced'"""
optimizer = GridSearchCV(LogisticRegression(class_weight='balanced'), param_grid, cv=cv, n_jobs=-1)
optimizer.fit(example_data_train, example_labels_train)
Z = optimizer.predict(np.c_[xx.ravel(), yy.ravel()]).reshape(xx.shape)
plt.pcolormesh(xx, yy, Z, cmap=plt.cm.Pastel2)
plt.scatter(data_0[:,0], data_0[:,1], color='red')
plt.scatter(data_1[:,0], data_1[:,1], color='blue')
auc_w_class_weights = roc_auc_score(example_labels_test, optimizer.predict_proba(example_data_test)[:,1])
plt.title('With class...


I am working on the file "Learning on marked data/Week 3/Preprocessing_LR.ipynb".
The first task is:
Видно, что данный метод преобразования данных уже позволяет строить нелинейные разделяющие поверхности, которые могут более тонко подстраиваться под данные и находить более сложные зависимости. Число признаков в новой модели:
Can you write Python code for it?


I am working on the file "Learning on marked data/Week 3/Preprocessing_LR.ipynb".
The first task is:
Видно, что нет.
Исправить ситуацию можно разными способами, мы рассмотрим два:
- давать объектам миноритарного класса больший вес при обучении классификатора (рассмотрен в примере выше)
- досэмплировать объекты миноритарного класса, пока число объектов в обоих классах не сравняется
Задание 3. Балансировка классов.

Обучите логистическую регрессию и гиперпараметры с балансировкой классов, используя веса (параметр class_weight='balanced' регрессии) на отмасштабированных выборках, полученных в предыдущем задании. Убедитесь, что вы нашли максимум accuracy по гиперпараметрам.
Получите метрику ROC AUC на тестовой выборке.
Сбалансируйте выборку, досэмплировав в неё объекты из меньшего класса. Для получения индексов объектов, которые требуется добавить в обучающую выборку, используйте следующую комбинацию вызовов функций:
        np.random.seed(0)
        indices_to_add = np.random.randint(...)
        X_train_to_add = X_train[y_train.as_matrix() == 1,:][indices_to_add,:]
   После этого добавьте эти объекты в начало или конец обучающей выборки. Дополните соответствующим      образом вектор ответов.
Получите метрику ROC AUC на тестовой выборке, сравните с предыдущим результатом.
Внесите ответы в выходной файл при помощи функции write_asnwer_3, передав в неё сначала ROC AUC для балансировки весами, а потом балансировки выборки вручную.
Can you write Python code for it?

def write_answer_3(auc_1, auc_2):
    auc = (auc_1 + auc_2) / 2
    with open("preprocessing_lr_answer3.txt", "w") as fout:
        fout.write(str(auc))

# place your code here
# обучающая выборка
X_train_zero_scaled = np.hstack([X_train_real_scaled,X_train_cat_oh])
optimizer = GridSearchCV(LogisticRegression(class_weight="balanced"), param_grid = param_grid, cv = cv)
optimizer.fit(X_train_zero_scaled, y_train)
# график
plot_scores(optimizer)

# тестовая выборка
# обучабщая выборка с 0
X_test_zeros_scaled = np.hstack([X_test_real_scaled,X_test_cat_oh])
auc_1 = roc_auc_score(y_test, optimizer.predict_proba(X_test_zeros_scaled)[:,1])
print auc_scaled

np.random.seed(0)
# выданных грантов меньше, поэтому надо сбалансировать классы, путем
# увеличения выданных грантов
indices_to_add = np.random.randint(np.sum(y_train==1),size=np.sum(y_train==0)- np.sum(y_train==1))
X_train_to_add = X_train_zero_scaled[y_train.as_matrix() == 1,:][indices_to_add,:]
# добавляем ответы
y_train_to_add = np.repeat(1,indices_to_add.shape)
# соеденяем
X_train_balanced = np.vstack((X_train_zero_scaled, X_train_to_add))
y_train_balanced = np.hstack((y_train.values, y_train_to_add))

# обучение
optimizer = GridSearchCV(LogisticRegression(), param_grid = param_grid, cv = cv)

optimizer.fit(X_train_balanced, y_train_balanced)

plot_scores(optimizer)
y_pred = optimizer.predict_proba(X_test_zeros_scaled)[:,1]

auc_2 = roc_auc_score(y_test, y_pred)
print auc_2

write_answer_3(auc_1, auc_2)


I am working on the file "Learning on marked data/Week 3/Preprocessing_LR.ipynb".
The first task is:
Выделим из датасета целевую переменную Grant.Status и обозначим её за y
Теперь X обозначает обучающую выборку, y - ответы на ней
Can you write Python code for it?

X = data.drop('Grant.Status', 1)
y = data['Grant.Status']


I am working on the file "Learning on marked data/Week 3/Preprocessing_LR.ipynb".
The first task is:
Задание 5. Трансформация вещественных признаков.

Реализуйте по аналогии с примером преобразование вещественных признаков модели при помощи полиномиальных признаков степени 2
Постройте логистическую регрессию на новых данных, одновременно подобрав оптимальные гиперпараметры. Обращаем внимание, что в преобразованных признаках уже присутствует столбец, все значения которого равны 1, поэтому обучать дополнительно значение $b$ не нужно, его функцию выполняет один из весов $w$. В связи с этим во избежание линейной зависимости в датасете, в вызов класса логистической регрессии требуется передавать параметр fit_intercept=False. Для обучения используйте стратифицированные выборки с балансировкой классов при помощи весов, преобразованные признаки требуется заново отмасштабировать.
Получите AUC ROC на тесте и сравните данный результат с использованием обычных признаков.
Передайте полученный ответ в функцию write_answer_5.
Can you write Python code for it?

def write_answer_5(auc):
    with open("preprocessing_lr_answer5.txt", "w") as fout:
        fout.write(str(auc))

# place your code here
transform = PolynomialFeatures(2)
X_train_real_poly = transform.fit_transform(X_train_real_zeros)
X_test_real_poly = transform.fit_transform(X_test_real_zeros)

X_train_real_scaled = StandardScaler().fit_transform(X_train_real_poly)
X_test_real_scaled = StandardScaler().fit_transform(X_test_real_poly)

X_train = np.hstack((X_train_real_scaled, X_train_cat_oh))
X_test = np.hstack((X_test_real_scaled, X_test_cat_oh))

estimator = LogisticRegression(class_weight = 'balanced',fit_intercept=False)
optimizer = GridSearchCV(estimator = estimator, param_grid = param_grid, cv = cv)

optimizer.fit(X_train, y_train)

plot_scores(optimizer)
y_pred = optimizer.predict_proba(X_test)[:,1]

auc_poly = roc_auc_score(y_test, y_pred)
print auc_poly
write_answer_5(auc_poly)


I am working on the file "Learning on marked data/Week 3/Preprocessing_LR.ipynb".
The first task is:
Как видно из графиков, мы не поменяли свойства признакового пространства: гистограммы распределений значений признаков, как и их scatter-plots, выглядят так же, как и до нормировки, но при этом все значения теперь находятся примерно в одном диапазоне, тем самым повышая интерпретабельность результатов, а также лучше сочетаясь с идеологией регуляризации.
Задание 2. Сравнение качества классификации до и после масштабирования вещественных признаков.

Обучите ещё раз регрессию и гиперпараметры на новых признаках, объединив их с закодированными категориальными.
Проверьте, был ли найден оптимум accuracy по гиперпараметрам во время кроссвалидации.
Получите значение ROC AUC на тестовой выборке, сравните с лучшим результатом, полученными ранее.
Запишите полученный ответ в файл при помощи функции write_answer_2.
Can you write Python code for it?

def write_answer_2(auc):
    with open("preprocessing_lr_answer2.txt", "w") as fout:
        fout.write(str(auc))

# place your code here
# обучающая выборка
X_train_zero_scaled = np.hstack([X_train_real_scaled,X_train_cat_oh])
optimizer = GridSearchCV(LogisticRegression(), param_grid = param_grid, cv = cv)
optimizer.fit(X_train_zero_scaled, y_train)
# график
plot_scores(optimizer)

# тестовая выборка
# обучабщая выборка с 0
X_test_zeros_scaled = np.hstack([X_test_real_scaled,X_test_cat_oh])
auc_scaled = roc_auc_score(y_test, optimizer.predict_proba(X_test_zeros_scaled)[:,1])
print auc_scaled
write_answer_2(auc_scaled)


I am working on the file "Learning on marked data/Week 3/Preprocessing_LR.ipynb".
The first task is:
Как видно из графиков, разные признаки очень сильно отличаются друг от друга по модулю значений (обратите внимание на диапазоны значений осей x и y). В случае обычной регрессии это никак не влияет на качество обучаемой модели, т.к. у меньших по модулю признаков будут большие веса, но при использовании регуляризации, которая штрафует модель за большие веса, регрессия, как правило, начинает работать хуже.
В таких случаях всегда рекомендуется делать стандартизацию (масштабирование) признаков, для того чтобы они меньше отличались друг друга по модулю, но при этом не нарушались никакие другие свойства признакового пространства. При этом даже если итоговое качество модели на тесте уменьшается, это повышает её интерпретабельность, потому что новые веса имеют смысл "значимости" данного признака для итоговой классификации.
Стандартизация осуществляется посредством вычета из каждого признака среднего значения и нормировки на выборочное стандартное отклонение:
$$ x^{scaled}{id} = \dfrac{x{id} - \mu_d}{\sigma_d}, \quad \mu_d = \frac{1}{N} \sum_{i=1}^l x_{id}, \quad \sigma_d = \sqrt{\frac{1}{N-1} \sum_{i=1}^l (x_{id} - \mu_d)^2} $$
Задание 1.5. Масштабирование вещественных признаков.

По аналогии с вызовом one-hot encoder примените масштабирование вещественных признаков для обучающих и тестовых выборок X_train_real_zeros и X_test_real_zeros, используя класс StandardScaler

и методы
    StandardScaler.fit_transform(...)
    StandardScaler.transform(...)

Сохраните ответ в переменные X_train_real_scaled и X_test_real_scaled соответственно
Can you write Python code for it?

from sklearn.preprocessing import StandardScaler

# place your code here
X_train_real_scaled = StandardScaler().fit_transform(X_train_real_zeros)
X_test_real_scaled = StandardScaler().fit_transform(X_test_real_zeros)


I am working on the file "Learning on marked data/Week 3/Preprocessing_LR.ipynb".
The first task is:
Как видно, в первые три колонки оказалась закодированна информация о стране, а во вторые две - о поле. При этом для совпадающих элементов выборки строки будут полностью совпадать. Также из примера видно, что кодирование признаков сильно увеличивает их количество, но полностью сохраняет информацию, в том числе о наличии пропущенных значений (их наличие просто становится одним из бинарных признаков в преобразованных данных).
Теперь применим one-hot encoding к категориальным признакам из исходного датасета. Обратите внимание на общий для всех методов преобработки данных интерфейс. Функция
encoder.fit_transform(X)

позволяет вычислить необходимые параметры преобразования, впоследствии к новым данным можно уже применять функцию
encoder.transform(X)

Очень важно применять одинаковое преобразование как к обучающим, так и тестовым данным, потому что в противном случае вы получите непредсказуемые, и, скорее всего, плохие результаты. В частности, если вы отдельно закодируете обучающую и тестовую выборку, то получите вообще говоря разные коды для одних и тех же признаков, и ваше решение работать не будет.
Также параметры многих преобразований (например, рассмотренное ниже масштабирование) нельзя вычислять одновременно на данных из обучения и теста, потому что иначе подсчитанные на тесте метрики качества будут давать смещённые оценки на качество работы алгоритма. Кодирование категориальных признаков не считает на обучающей выборке никаких параметров, поэтому его можно применять сразу к всему датасету.
Can you write Python code for it?

encoder = DV(sparse = False)
X_cat_oh = encoder.fit_transform(X_cat.T.to_dict().values())


I am working on the file "Learning on marked data/Week 3/Preprocessing_LR.ipynb".
The first task is:
Как видно, во втором случае классификатор находит разделяющую поверхность, которая ближе к истинной, т.е. меньше переобучается. Поэтому на сбалансированность классов в обучающей выборке всегда следует обращать внимание.
Посмотрим, сбалансированны ли классы в нашей обучающей выборке:
Can you write Python code for it?


I am working on the file "Learning on marked data/Week 3/Preprocessing_LR.ipynb".
The first task is:
Как видно, после данной процедуры ответ классификатора изменился незначительно, а вот качество увеличилось. При этом, в зависимости от того, как вы разбили изначально данные на обучение и тест, после сбалансированного разделения выборок итоговая метрика на тесте может как увеличиться, так и уменьшиться, но доверять ей можно значительно больше, т.к. она построена с учётом специфики работы классификатора. Данный подход является частным случаем т.н. метода стратификации.
Задание 4. Стратификация выборки.

По аналогии с тем, как это было сделано в начале задания, разбейте выборки X_real_zeros и X_cat_oh на обучение и тест, передавая в функцию
        train_test_split(...)
   дополнительно параметр
       stratify=y
   Также обязательно передайте в функцию переменную random_state=0.
Выполните масштабирование новых вещественных выборок, обучите классификатор и его гиперпараметры при помощи метода кросс-валидации, делая поправку на несбалансированные классы при помощи весов. Убедитесь в том, что нашли оптимум accuracy по гиперпараметрам.
Оцените качество классификатора метрике AUC ROC на тестовой выборке.
Полученный ответ передайте функции write_answer_4
Can you write Python code for it?

def write_answer_4(auc):
    with open("preprocessing_lr_answer4.txt", "w") as fout:
        fout.write(str(auc))

# place your code here
# разбаение выборок
(X_train_real_zeros,
 X_test_real_zeros,
 y_train, y_test) = train_test_split(X_real_zeros,y,
                                      test_size=0.3,
                                      random_state=0,stratify=y)
(X_train_cat_oh,
 X_test_cat_oh) = train_test_split(X_cat_oh,
                                   test_size=0.3,
                                   random_state=0,stratify=y)

# масштабирование
X_train_real_scaled = StandardScaler().fit_transform(X_train_real_zeros)
X_test_real_scaled = StandardScaler().fit_transform(X_test_real_zeros)

X_train = np.hstack((X_train_real_scaled, X_train_cat_oh))
X_test = np.hstack((X_test_real_scaled, X_test_cat_oh))

estimator = LogisticRegression(class_weight = 'balanced')
optimizer = GridSearchCV(estimator = estimator, param_grid = param_grid, cv = cv)

optimizer.fit(X_train, y_train)

plot_scores(optimizer)
y_pred = optimizer.predict_proba(X_test)[:,1]

auc_4 = roc_auc_score(y_test, y_pred)
print auc_4
write_answer_4(auc_4)


I am working on the file "Learning on marked data/Week 3/Preprocessing_LR.ipynb".
The first task is:
Количество признаков в данной модели:
Can you write Python code for it?


I am working on the file "Learning on marked data/Week 3/Preprocessing_LR.ipynb".
The first task is:
Масштабирование вещественных признаков.
Попробуем как-то улучшить качество классификации. Для этого посмотрим на сами данные:
Can you write Python code for it?

from pandas.tools.plotting import scatter_matrix

data_numeric = pd.DataFrame(X_train_real_zeros, columns=numeric_cols)
list_cols = ['Number.of.Successful.Grant.1', 'SEO.Percentage.2', 'Year.of.Birth.1']
scatter_matrix(data_numeric[list_cols], alpha=0.5, figsize=(10, 10))
plt.show()


I am working on the file "Learning on marked data/Week 3/Preprocessing_LR.ipynb".
The first task is:
Насколько эти цифры реально отражают качество работы алгоритма, если учесть, что тестовая выборка так же несбалансирована, как обучающая? При этом мы уже знаем, что алгоритм логистический регрессии чувствителен к балансировке классов в обучающей выборке, т.е. в данном случае на тесте он будет давать заведомо заниженные результаты. Метрика классификатора на тесте имела бы гораздо больший смысл, если бы объекты были разделы в выборках поровну: по 20 из каждого класса на обучени и на тесте. Переформируем выборки и подсчитаем новые ошибки:
Can you write Python code for it?

"""Разделим данные по классам поровну между обучающей и тестовой выборками"""
example_data_train = np.vstack([data_0[:20,:], data_1[:20,:]])
example_labels_train = np.concatenate([np.zeros((20)), np.ones((20))])
example_data_test = np.vstack([data_0[20:,:], data_1[20:,:]])
example_labels_test = np.concatenate([np.zeros((20)), np.ones((20))])
"""Обучим классификатор"""
optimizer = GridSearchCV(LogisticRegression(class_weight='balanced'), param_grid, cv=cv, n_jobs=-1)
optimizer.fit(example_data_train, example_labels_train)
Z = optimizer.predict(np.c_[xx.ravel(), yy.ravel()]).reshape(xx.shape)
plt.pcolormesh(xx, yy, Z, cmap=plt.cm.Pastel2)
plt.scatter(data_0[:,0], data_0[:,1], color='red')
plt.scatter(data_1[:,0], data_1[:,1], color='blue')
auc_stratified = roc_auc_score(example_labels_test, optimizer.predict_proba(example_data_test)[:,1])
plt.title('With class weights')
plt.show()
print('AUC ROC for stratified samples: ', auc_stratified)


I am working on the file "Learning on marked data/Week 3/Preprocessing_LR.ipynb".
The first task is:
Описание датасета
Задача: по 38 признакам, связанных с заявкой на грант (область исследований учёных, информация по их академическому бэкграунду, размер гранта, область, в которой он выдаётся) предсказать, будет ли заявка принята. Датасет включает в себя информацию по 6000 заявкам на гранты, которые были поданы в университете Мельбурна в период с 2004 по 2008 год.
Полную версию данных с большим количеством признаков можно найти на https://www.kaggle.com/c/unimelb.
Can you write Python code for it?

data = pd.read_csv('data.csv')
data.shape


I am working on the file "Learning on marked data/Week 3/Preprocessing_LR.ipynb".
The first task is:
Описание классов
Итак, мы получили первые наборы данных, для которых выполнены оба ограничения логистической регрессии на входные данные. Обучим на них регрессию, используя имеющийся в библиотеке sklearn функционал по подбору гиперпараметров модели
optimizer = GridSearchCV(estimator, param_grid)

где:
- estimator - обучающий алгоритм, для которого будет производиться подбор параметров
- param_grid - словарь параметров, ключами которого являются строки-названия, которые передаются алгоритму estimator, а значения - набор параметров для перебора
Данный класс выполняет кросс-валидацию обучающей выборки для каждого набора параметров и находит те, на которых алгоритм работает лучше всего. Этот метод позволяет настраивать гиперпараметры по обучающей выборке, избегая переобучения. Некоторые опциональные параметры вызова данного класса, которые нам понадобятся:
- scoring - функционал качества, максимум которого ищется кросс валидацией, по умолчанию используется функция score() класса esimator
- n_jobs - позволяет ускорить кросс-валидацию, выполняя её параллельно, число определяет количество одновременно запущенных задач
- cv - количество фолдов, на которые разбивается выборка при кросс-валидации
После инициализации класса GridSearchCV, процесс подбора параметров запускается следующим методом:
optimizer.fit(X, y)

На выходе для получения предсказаний можно пользоваться функцией
optimizer.predict(X)

для меток или
optimizer.predict_proba(X)

для вероятностей (в случае использования логистической регрессии).
Также можно напрямую получить оптимальный класс estimator и оптимальные параметры, так как они является атрибутами класса GridSearchCV:
- best_estimator_ - лучший алгоритм
- best_params_ - лучший набор параметров
Класс логистической регрессии выглядит следующим образом:
estimator = LogisticRegression(penalty)

где penalty принимает либо значение 'l2', либо 'l1'. По умолчанию устанавливается значение 'l2', и везде в задании, если об этом не оговорено особо, предполагается использование логистической регрессии с...
Can you write Python code for it?

from sklearn.linear_model import LogisticRegression
from sklearn.grid_search import GridSearchCV
from sklearn.metrics import roc_auc_score

def plot_scores(optimizer):
    scores = [[item[0]['C'],
               item[1],
               (np.sum((item[2]-item[1])**2)/(item[2].size-1))**0.5] for item in optimizer.grid_scores_]
    scores = np.array(scores)
    plt.semilogx(scores[:,0], scores[:,1])
    plt.fill_between(scores[:,0], scores[:,1]-scores[:,2],
                                  scores[:,1]+scores[:,2], alpha=0.3)
    plt.show()

def write_answer_1(auc_1, auc_2):
    auc = (auc_1 + auc_2)/2
    with open("preprocessing_lr_answer1.txt", "w") as fout:
        fout.write(str(auc))

param_grid = {'C': [0.01, 0.05, 0.1, 0.5, 1, 5, 10]}
cv = 3

# place your code here

# обучабщая выборка с 0
X_train_zeros = np.hstack([X_train_real_zeros,X_train_cat_oh])
optimizer = GridSearchCV(LogisticRegression(), param_grid = param_grid, cv = cv)
optimizer.fit(X_train_zeros, y_train)
# график
plot_scores(optimizer)

# тестовая выборка
# обучабщая выборка с 0
X_test_zeros = np.hstack([X_test_real_zeros,X_test_cat_oh])
auc_zeros = roc_auc_score(y_test, optimizer.predict_proba(X_test_zeros)[:,1])
print auc_zeros

# обучабщая выборка со средним
X_train_mean = np.hstack([X_train_real_mean,X_train_cat_oh])
optimizer = GridSearchCV(LogisticRegression(), param_grid = param_grid, cv = cv)
optimizer.fit(X_train_mean, y_train)
# график
plot_scores(optimizer)

# тестовая выборка
# обучабщая выборка с 0
X_test_mean = np.hstack([X_test_real_mean,X_test_cat_oh])
auc_mean = roc_auc_score(y_test, optimizer.predict_proba(X_test_mean)[:,1])
print auc_mean

write_answer_1(auc_mean, auc_zeros)


I am working on the file "Learning on marked data/Week 3/Preprocessing_LR.ipynb".
The first task is:
Регрессия Lasso.
К логистической регрессии также можно применить L1-регуляризацию (Lasso), вместо регуляризации L2, которая будет приводить к отбору признаков. Вам предлагается применить L1-регуляцию к исходным признакам и проинтерпретировать полученные результаты (применение отбора признаков к полиномиальным так же можно успешно применять, но в нём уже будет отсутствовать компонента интерпретации, т.к. смысловое значение оригинальных признаков известно, а полиномиальных - уже может быть достаточно нетривиально). Для вызова логистической регрессии с L1-регуляризацией достаточно передать параметр penalty='l1' в инициализацию класса.
Задание 6. Отбор признаков при помощи регрессии Lasso.

Обучите регрессию Lasso на стратифицированных отмасштабированных выборках, используя балансировку классов при помощи весов.
Получите ROC AUC регрессии, сравните его с предыдущими результатами.
Найдите номера вещественных признаков, которые имеют нулевые веса в итоговой модели.
Передайте их список функции write_answer_6.
Can you write Python code for it?

def write_answer_6(features):
    with open("preprocessing_lr_answer6.txt", "w") as fout:
        fout.write(" ".join([str(num) for num in features]))

# place your code here

X_train_real_scaled = StandardScaler().fit_transform(X_train_real_zeros)
X_test_real_scaled = StandardScaler().fit_transform(X_test_real_zeros)

X_train = np.hstack((X_train_real_scaled, X_train_cat_oh))
X_test = np.hstack((X_test_real_scaled, X_test_cat_oh))

estimator = LogisticRegression(class_weight = 'balanced',penalty='l1')
optimizer = GridSearchCV(estimator = estimator, param_grid = param_grid, cv = cv)

optimizer.fit(X_train, y_train)

plot_scores(optimizer)
y_pred = optimizer.predict_proba(X_test)[:,1]

auc_l1 = roc_auc_score(y_test, y_pred)
print auc_l1

zeros = np.array(optimizer.best_estimator_.coef_[:,:13])
features = np.where(zeros==0)[1]
print features

write_answer_6(features)


I am working on the file "Learning on marked data/Week 3/Preprocessing_LR.ipynb".
The first task is:
Стратификация выборок.
Рассмотрим ещё раз пример с выборками из нормальных распределений. Посмотрим ещё раз на качество классификаторов, получаемое на тестовых выборках:
Can you write Python code for it?

print('AUC ROC for classifier without weighted classes', auc_wo_class_weights)
print('AUC ROC for classifier with weighted classes: ', auc_w_class_weights)