<jupyter_start><jupyter_text>Version 1.1.0  Mean encodings In this programming assignment you will be working with `1C` dataset from the final competition. You are asked to encode `item_id` in 4 different ways:    1) Via KFold scheme;      2) Via Leave-one-out scheme;    3) Via smoothing scheme;    4) Via expanding mean scheme.**You will need to submit** the correlation coefficient between resulting encoding and target variable up to 4 decimal places. General tips* Fill NANs in the encoding with `0.3343`.* Some encoding schemes depend on sorting order, so in order to avoid confusion, please use the following code snippet to construct the data frame. This snippet also implements mean encoding without regularization.<jupyter_code>NAN_VALUE = 0.3343
import warnings
warnings.filterwarnings("ignore", message="numpy.dtype size changed")
warnings.filterwarnings("ignore", message="numpy.ufunc size changed")
# python standard library
from itertools import product

from sklearn.model_selection import KFold
import pandas
import numpy
# this course (github)
# from grader import Grader<jupyter_output><empty_output><jupyter_text>Read data<jupyter_code>sales = pandas.read_csv('../readonly/final_project_data/sales_train.csv.gz')<jupyter_output><empty_output><jupyter_text>Aggregate data Since the competition task is to make a monthly prediction, we need to aggregate the data to montly level before doing any encodings. The following code-cell serves just that purpose.<jupyter_code>group_by_columns = ['shop_id', 'item_id', 'date_block_num']
grid = [] 
for block_num in sales['date_block_num'].unique():
    block = sales[sales['date_block_num']==block_num]
    cur_shops = block['shop_id'].unique()
    cur_items = block['item_id'].unique()
    grid.append(numpy.array(list(product(*[cur_shops, cur_items, [block_num]])), dtype='int32'))
grid = pandas.DataFrame(numpy.vstack(grid), columns=group_by_columns, dtype=numpy.int32)
grouped = sales.groupby(group_by_columns, as_index=False)
grouped = grouped["item_cnt_day"].sum()
grouped = grouped.rename(dict(item_cnt_day="target"), axis="columns")
all_data = pandas.merge(grid, grouped, how='left', on=group_by_columns).fillna(0)
all_data.sort_values(['date_block_num','shop_id','item_id'], inplace=True)<jupyter_output><empty_output><jupyter_text>Mean encodings without regularization After we did the techinical work, we are ready to actually *mean encode* the desired `item_id` variable. Here are two ways to implement mean encoding features *without* any regularization. You can use this code as a starting point to implement regularized techniques.   Method 1<jupyter_code>item_id_target_mean = all_data.groupby('item_id').target.mean()
all_data['item_target_enc'] = all_data['item_id'].map(item_id_target_mean)
all_data['item_target_enc'].fillna(NAN_VALUE, inplace=True) 
encoded_feature = all_data['item_target_enc'].values
first_correlation = numpy.corrcoef(all_data['target'].values, encoded_feature)[0][1]
print(first_correlation)<jupyter_output>0.48303869886216977<jupyter_text>Method 2<jupyter_code>all_data['item_target_enc'] = all_data.groupby('item_id')['target'].transform('mean')
all_data['item_target_enc'].fillna(NAN_VALUE, inplace=True) 
encoded_feature = all_data['item_target_enc'].values
second_correlation = numpy.corrcoef(all_data['target'].values, encoded_feature)[0][1]
print(second_correlation)
print(abs(first_correlation - second_correlation))<jupyter_output>0.48303869886216977
0.0<jupyter_text>See the printed value? It is the correlation coefficient between the target variable and your new encoded feature. You need to **compute correlation coefficient** between the encodings, that you will implement and **submit those to coursera**.<jupyter_code># grader = Grader()<jupyter_output><empty_output><jupyter_text>1. KFold scheme Explained starting at 41 sec of [Regularization video](https://www.coursera.org/learn/competitive-data-science/lecture/LGYQ2/regularization). **Now it's your turn to write the code!** You may use 'Regularization' video as a reference for all further tasks.First, implement KFold scheme with five folds. Use KFold(5) from sklearn.model_selection. 1. Split your data in 5 folds with `sklearn.model_selection.KFold` with `shuffle=False` argument.2. Iterate through folds: use all but the current fold to calculate mean target for each level `item_id`, and  fill the current fold.    *  See the **Method 1** from the example implementation. In particular learn what `map` and pd.Series.map functions do. They are pretty handy in many situations.<jupyter_code>folder = KFold(n_splits=5, shuffle=False)
column = "item_id"
encoded_column = column + "_mean_target"
train_new = pandas.DataFrame(index=all_data.index, columns=all_data.columns)
train_new[encoded_column] = numpy.nan
for training_index, validation_index in folder.split(all_data):
    x_train = all_data.iloc[training_index].copy()
    x_validation = all_data.iloc[validation_index].copy()
    means = x_validation[column].map(x_train.groupby(column).target.mean())
    x_validation[encoded_column] = means
    # train_new is a dataframe copy we made of the training data
    train_new.iloc[validation_index] = x_validation
train_new.fillna(NAN_VALUE, inplace=True)
# YOUR CODE GOES HERE

# You will need to compute correlation like that
corr = np.corrcoef(all_data['target'].values, encoded_feature)[0][1]
print(corr)
grader.submit_tag('KFold_scheme', corr)<jupyter_output><empty_output><jupyter_text>2. Leave-one-out scheme Now, implement leave-one-out scheme. Note that if you just simply set the number of folds to the number of samples and run the code from the **KFold scheme**, you will probably wait for a very long time. To implement a faster version, note, that to calculate mean target value using all the objects but one *given object*, you can:1. Calculate sum of the target values using all the objects.2. Then subtract the target of the *given object* and divide the resulting value by `n_objects - 1`. Note that you do not need to perform `1.` for every object. And `2.` can be implemented without any `for` loop.It is the most convenient to use `.transform` function as in **Method 2**.<jupyter_code># YOUR CODE GOES HERE

corr = np.corrcoef(all_data['target'].values, encoded_feature)[0][1]
print(corr)
grader.submit_tag('Leave-one-out_scheme', corr)<jupyter_output><empty_output><jupyter_text>3. Smoothing Explained starting at 4:03 of [Regularization video](https://www.coursera.org/learn/competitive-data-science/lecture/LGYQ2/regularization). Next, implement smoothing scheme with $\alpha = 100$. Use the formula from the first slide in the video and $0.3343$ as `globalmean`. Note that `nrows` is the number of objects that belong to a certain category (not the number of rows in the dataset).<jupyter_code># YOUR CODE GOES HERE

corr = np.corrcoef(all_data['target'].values, encoded_feature)[0][1]
print(corr)
grader.submit_tag('Smoothing_scheme', corr)<jupyter_output><empty_output><jupyter_text>4. Expanding mean scheme Explained starting at 5:50 of [Regularization video](https://www.coursera.org/learn/competitive-data-science/lecture/LGYQ2/regularization). Finally, implement the *expanding mean* scheme. It is basically already implemented for you in the video, but you can challenge yourself and try to implement it yourself. You will need [`cumsum`](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.core.groupby.DataFrameGroupBy.cumsum.html) and [`cumcount`](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.core.groupby.GroupBy.cumcount.html) functions from pandas.<jupyter_code># YOUR CODE GOES HERE

corr = np.corrcoef(all_data['target'].values, encoded_feature)[0][1]
print(corr)
grader.submit_tag('Expanding_mean_scheme', corr)<jupyter_output><empty_output><jupyter_text>Authorization & SubmissionTo submit assignment parts to Cousera platform, please, enter your e-mail and token into variables below. You can generate token on this programming assignment page. Note: Token expires 30 minutes after generation.<jupyter_code>STUDENT_EMAIL = # EMAIL HERE
STUDENT_TOKEN = # TOKEN HERE
grader.status()
grader.submit(STUDENT_EMAIL, STUDENT_TOKEN)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10138922739458932, 'fraction_numerical': 0.01389227394589325, 'mean_word_length': 6.5431985294117645, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 43, 'https://': 5, 'lorem ipsum': 0, 'www.': 3, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '11', 'dir': 'jupyter-structured-clean-dedup', 'id': '435898', 'license': 'MIT', 'n_tokens_mistral': 2616, 'n_tokens_neox': 2482, 'n_words': 759, 'path': 'source/mean_encoding/programming_assignment_week_3.ipynb', 'repo_name': 'necromuralist/auspicium-ex-tripudiis', 'size': '8206'}