{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# default_exp datasets.retailrocket"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# RetailRocket Dataset\n",
    "> RetailRocket dataset."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#hide\n",
    "from nbdev.showdoc import *"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "from typing import List, Optional, Callable, Union, Any, Tuple\n",
    "\n",
    "import os\n",
    "import os.path as osp\n",
    "from collections.abc import Sequence\n",
    "import sys\n",
    "\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "from datetime import timezone, datetime, timedelta\n",
    "import time\n",
    "\n",
    "from recohut.utils.common_utils import download_url, extract_zip, makedirs\n",
    "from recohut.datasets.bases import common as base"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### v1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class RetailRocketDataset(base.SessionGraphDataset):\n",
    "    train_url = \"https://github.com/RecoHut-Datasets/retail_rocket/raw/v1/train.txt\"\n",
    "    test_url = \"https://github.com/RecoHut-Datasets/retail_rocket/raw/v1/test.txt\"\n",
    "    all_train_seq_url = \"https://github.com/RecoHut-Datasets/retail_rocket/raw/v1/all_train_seq.txt\"\n",
    "\n",
    "    def __init__(self, root, shuffle=False, n_node=40727, is_train=True):\n",
    "        self.n_node = n_node\n",
    "        self.shuffle = shuffle\n",
    "        self.is_train = is_train\n",
    "        super().__init__(root, shuffle, n_node)\n",
    "\n",
    "    @property\n",
    "    def raw_file_names(self) -> str:\n",
    "        if self.is_train:\n",
    "            return ['train.txt', 'all_train_seq.txt']\n",
    "        return ['test.txt', 'all_train_seq.txt']\n",
    "\n",
    "    def download(self):\n",
    "        download_url(self.all_train_seq_url, self.raw_dir)\n",
    "        if self.is_train:\n",
    "            download_url(self.train_url, self.raw_dir)\n",
    "        else:\n",
    "            download_url(self.test_url, self.raw_dir)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Downloading https://github.com/RecoHut-Datasets/retail_rocket/raw/v1/all_train_seq.txt\n",
      "Downloading https://github.com/RecoHut-Datasets/retail_rocket/raw/v1/train.txt\n",
      "Using existing file all_train_seq.txt\n",
      "Downloading https://github.com/RecoHut-Datasets/retail_rocket/raw/v1/test.txt\n"
     ]
    }
   ],
   "source": [
    "root = '/content/retail_rocket'\n",
    "\n",
    "train_data = RetailRocketDataset(root=root, shuffle=True, is_train=True)\n",
    "test_data = RetailRocketDataset(root=root, shuffle=False, is_train=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### v2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#exporti\n",
    "def to_list(value: Any) -> Sequence:\n",
    "    if isinstance(value, Sequence) and not isinstance(value, str):\n",
    "        return value\n",
    "    else:\n",
    "        return [value]\n",
    "\n",
    "def files_exist(files: List[str]) -> bool:\n",
    "    # NOTE: We return `False` in case `files` is empty, leading to a\n",
    "    # re-processing of files on every instantiation.\n",
    "    return len(files) != 0 and all([osp.exists(f) for f in files])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class RetailRocketDatasetv2(base.Dataset):\n",
    "    r\"\"\"Load and process RetailRocket dataset.\n",
    "\n",
    "    Args:\n",
    "        root (string): Root directory where the dataset should be saved.\n",
    "        process_method (string):\n",
    "            last: last day => test set\n",
    "            last_min_date: last day => test set, but from a minimal date onwards\n",
    "            days_test: last N days => test set\n",
    "            slice: create multiple train-test-combinations with a sliding window approach\n",
    "        min_date (string, optional): Minimum date\n",
    "        session_length (int, optional): Session time length :default = 30 * 60 #30 minutes\n",
    "        min_session_length (int, optional): Minimum number of items for a session to be valid\n",
    "        min_item_support (int, optional): Minimum number of interactions for an item to be valid\n",
    "        num_slices (int, optional): Offset in days from the first date in the data set\n",
    "        days_offset (int, optional): Number of days the training start date is shifted after creating one slice\n",
    "        days_shift (int, optional): Days shift\n",
    "        days_train (int, optional): Days in train set in each slice\n",
    "        days_test (int, optional): Days in test set in each slice\n",
    "    \"\"\"\n",
    "\n",
    "    url = 'https://github.com/RecoHut-Datasets/retail_rocket/raw/v2/retailrocket.zip'\n",
    "\n",
    "    def __init__(self, root, process_method, min_date='2015-09-02',\n",
    "                 session_length=30*60, min_session_length=2, min_item_support=5,\n",
    "                 num_slices=5, days_offset=0, days_shift=27, days_train=25, days_test=2):\n",
    "        super().__init__(root)\n",
    "        self.process_method = process_method\n",
    "        self.min_date = min_date\n",
    "        self.session_length = session_length\n",
    "        self.min_session_length = min_session_length\n",
    "        self.min_item_support = min_item_support\n",
    "        self.num_slices = num_slices\n",
    "        self.days_offset = days_offset\n",
    "        self.days_shift = days_shift\n",
    "        self.days_train = days_train\n",
    "        self.days_test = days_test\n",
    "        self.data = None\n",
    "        self.cart = None\n",
    "\n",
    "        self._process()\n",
    "\n",
    "    @property\n",
    "    def raw_file_names(self) -> str:\n",
    "        return 'events.csv'\n",
    "\n",
    "    @property\n",
    "    def processed_file_names(self) -> str:\n",
    "        return 'data.pkl'\n",
    "\n",
    "    def download(self):\n",
    "        path = download_url(self.url, self.raw_dir)\n",
    "        extract_zip(path, self.raw_dir)\n",
    "        from shutil import move, rmtree\n",
    "        move(osp.join(self.raw_dir, 'retailrocket', 'events.csv'),\n",
    "             osp.join(self.raw_dir, 'events.csv'))\n",
    "        rmtree(osp.join(self.raw_dir, 'retailrocket'))\n",
    "        os.unlink(path)\n",
    "\n",
    "    def load(self):\n",
    "        #load csv\n",
    "        data = pd.read_csv(osp.join(self.raw_dir,self.raw_file_names), sep=',',\n",
    "                           header=0, usecols=[0,1,2,3],\n",
    "                           dtype={0:np.int64, 1:np.int32, 2:str, 3:np.int32})\n",
    "        #specify header names\n",
    "        data.columns = ['Time','UserId','Type','ItemId']\n",
    "        data['Time'] = (data.Time / 1000).astype(int)\n",
    "        data.sort_values(['UserId','Time'], ascending=True, inplace=True)\n",
    "\n",
    "        #sessionize\n",
    "        data['TimeTmp'] = pd.to_datetime(data.Time, unit='s')\n",
    "        data.sort_values(['UserId','TimeTmp'], ascending=True, inplace=True)\n",
    "\n",
    "        data['TimeShift'] = data['TimeTmp'].shift(1)\n",
    "        data['TimeDiff'] = (data['TimeTmp'] - data['TimeShift']).dt.total_seconds().abs()\n",
    "        data['SessionIdTmp'] = (data['TimeDiff'] > self.session_length).astype(int)\n",
    "        data['SessionId'] = data['SessionIdTmp'].cumsum( skipna=False)\n",
    "        del data['SessionIdTmp'], data['TimeShift'], data['TimeDiff']\n",
    "\n",
    "        data.sort_values(['SessionId','Time'], ascending=True, inplace=True)\n",
    "\n",
    "        cart = data[data.Type == 'addtocart']\n",
    "        data = data[data.Type == 'view']\n",
    "        del data['Type']\n",
    "    \n",
    "        # output\n",
    "        print(data.Time.min())\n",
    "        print(data.Time.max())\n",
    "        data_start = datetime.fromtimestamp( data.Time.min(), timezone.utc)\n",
    "        data_end = datetime.fromtimestamp( data.Time.max(), timezone.utc)\n",
    "        del data['TimeTmp']\n",
    "    \n",
    "        print('Loaded data set\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}\\n\\tSpan: {} / {}\\n\\n'.\n",
    "              format(len(data), data.SessionId.nunique(), data.ItemId.nunique(), data_start.date().isoformat(), data_end.date().isoformat()))\n",
    "        \n",
    "        self.data = data\n",
    "        self.cart = cart\n",
    "\n",
    "    def filter_data(self): \n",
    "        data = self.data\n",
    "\n",
    "        #filter session length\n",
    "        session_lengths = data.groupby('SessionId').size()\n",
    "        data = data[np.in1d(data.SessionId, session_lengths[session_lengths>1].index)]\n",
    "        \n",
    "        #filter item support\n",
    "        item_supports = data.groupby('ItemId').size()\n",
    "        data = data[np.in1d(data.ItemId, item_supports[item_supports>= self.min_item_support].index)]\n",
    "        \n",
    "        #filter session length\n",
    "        session_lengths = data.groupby('SessionId').size()\n",
    "        data = data[np.in1d(data.SessionId, session_lengths[session_lengths>= self.min_session_length].index)]\n",
    "        \n",
    "        #output\n",
    "        data_start = datetime.fromtimestamp(data.Time.min(), timezone.utc)\n",
    "        data_end = datetime.fromtimestamp(data.Time.max(), timezone.utc)\n",
    "        \n",
    "        print('Filtered data set\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}\\n\\tSpan: {} / {}\\n\\n'.\n",
    "              format(len(data), data.SessionId.nunique(), data.ItemId.nunique(), data_start.date().isoformat(), data_end.date().isoformat()))\n",
    "    \n",
    "        self.data = data\n",
    "        \n",
    "    def filter_min_date(self):\n",
    "        data = self.data\n",
    "\n",
    "        min_datetime = datetime.strptime(self.min_date + ' 00:00:00', '%Y-%m-%d %H:%M:%S')\n",
    "        \n",
    "        #filter\n",
    "        session_max_times = data.groupby('SessionId').Time.max()\n",
    "        session_keep = session_max_times[session_max_times > min_datetime.timestamp()].index\n",
    "        \n",
    "        data = data[np.in1d(data.SessionId, session_keep)]\n",
    "        \n",
    "        #output\n",
    "        data_start = datetime.fromtimestamp(data.Time.min(), timezone.utc)\n",
    "        data_end = datetime.fromtimestamp(data.Time.max(), timezone.utc)\n",
    "        \n",
    "        print('Filtered data set\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}\\n\\tSpan: {} / {}\\n\\n'.\n",
    "              format(len(data), data.SessionId.nunique(), data.ItemId.nunique(), data_start.date().isoformat(), data_end.date().isoformat()))\n",
    "        \n",
    "        self.data = data\n",
    "\n",
    "    def split_data_org(self):\n",
    "        data = self.data\n",
    "        tmax = data.Time.max()\n",
    "        session_max_times = data.groupby('SessionId').Time.max()\n",
    "        session_train = session_max_times[session_max_times < tmax-86400].index\n",
    "        session_test = session_max_times[session_max_times >= tmax-86400].index\n",
    "        train = data[np.in1d(data.SessionId, session_train)]\n",
    "        test = data[np.in1d(data.SessionId, session_test)]\n",
    "        test = test[np.in1d(test.ItemId, train.ItemId)]\n",
    "        tslength = test.groupby('SessionId').size()\n",
    "        test = test[np.in1d(test.SessionId, tslength[tslength>=2].index)]\n",
    "        print('Full train set\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}'.format(len(train), train.SessionId.nunique(), train.ItemId.nunique()))\n",
    "        train.to_csv(osp.join(self.processed_dir,'events_train_full.txt'), sep='\\t', index=False)\n",
    "        print('Test set\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}'.format(len(test), test.SessionId.nunique(), test.ItemId.nunique()))\n",
    "        test.to_csv(osp.join(self.processed_dir,'events_test.txt'), sep='\\t', index=False)\n",
    "        \n",
    "        tmax = train.Time.max()\n",
    "        session_max_times = train.groupby('SessionId').Time.max()\n",
    "        session_train = session_max_times[session_max_times < tmax-86400].index\n",
    "        session_valid = session_max_times[session_max_times >= tmax-86400].index\n",
    "        train_tr = train[np.in1d(train.SessionId, session_train)]\n",
    "        valid = train[np.in1d(train.SessionId, session_valid)]\n",
    "        valid = valid[np.in1d(valid.ItemId, train_tr.ItemId)]\n",
    "        tslength = valid.groupby('SessionId').size()\n",
    "        valid = valid[np.in1d(valid.SessionId, tslength[tslength>=2].index)]\n",
    "        print('Train set\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}'.format(len(train_tr), train_tr.SessionId.nunique(), train_tr.ItemId.nunique()))\n",
    "        train_tr.to_csv(osp.join(self.processed_dir,'events_train_tr.txt'), sep='\\t', index=False)\n",
    "        print('Validation set\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}'.format(len(valid), valid.SessionId.nunique(), valid.ItemId.nunique()))\n",
    "        valid.to_csv(osp.join(self.processed_dir,'events_train_valid.txt'), sep='\\t', index=False)\n",
    "\n",
    "    def split_data(self):\n",
    "        data = self.data\n",
    "        data_end = datetime.fromtimestamp(data.Time.max(), timezone.utc)\n",
    "        test_from = data_end - timedelta(self.days_test)\n",
    "        \n",
    "        session_max_times = data.groupby('SessionId').Time.max()\n",
    "        session_train = session_max_times[session_max_times < test_from.timestamp()].index\n",
    "        session_test = session_max_times[session_max_times >= test_from.timestamp()].index\n",
    "        train = data[np.in1d(data.SessionId, session_train)]\n",
    "        test = data[np.in1d(data.SessionId, session_test)]\n",
    "        test = test[np.in1d(test.ItemId, train.ItemId)]\n",
    "        tslength = test.groupby('SessionId').size()\n",
    "        test = test[np.in1d(test.SessionId, tslength[tslength>=2].index)]\n",
    "        print('Full train set\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}'.format(len(train), train.SessionId.nunique(), train.ItemId.nunique()))\n",
    "        train.to_csv(osp.join(self.processed_dir,'events_train_full.txt'), sep='\\t', index=False)\n",
    "        print('Test set\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}'.format(len(test), test.SessionId.nunique(), test.ItemId.nunique()))\n",
    "        test.to_csv(osp.join(self.processed_dir,'events_test.txt'), sep='\\t', index=False)\n",
    "\n",
    "    def slice_data(self):\n",
    "        for slice_id in range(0, self.num_slices):\n",
    "            self.split_data_slice(slice_id, self.days_offset+(slice_id*self.days_shift))\n",
    "\n",
    "    def split_data_slice(self, slice_id, days_offset):\n",
    "        data = self.data\n",
    "        data_start = datetime.fromtimestamp(data.Time.min(), timezone.utc)\n",
    "        data_end = datetime.fromtimestamp(data.Time.max(), timezone.utc)\n",
    "        \n",
    "        print('Full data set {}\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}\\n\\tSpan: {} / {}'.\n",
    "            format(slice_id, len(data), data.SessionId.nunique(), data.ItemId.nunique(), data_start.isoformat(), data_end.isoformat()))    \n",
    "        \n",
    "        start = datetime.fromtimestamp(data.Time.min(), timezone.utc ) + timedelta(days_offset) \n",
    "        middle =  start + timedelta(self.days_train)\n",
    "        end =  middle + timedelta(self.days_test)\n",
    "        \n",
    "        #prefilter the timespan\n",
    "        session_max_times = data.groupby('SessionId').Time.max()\n",
    "        greater_start = session_max_times[session_max_times >= start.timestamp()].index\n",
    "        lower_end = session_max_times[session_max_times <= end.timestamp()].index\n",
    "        data_filtered = data[np.in1d(data.SessionId, greater_start.intersection(lower_end))]\n",
    "        \n",
    "        print('Slice data set {}\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}\\n\\tSpan: {} / {} / {}'.\n",
    "            format( slice_id, len(data_filtered), data_filtered.SessionId.nunique(), data_filtered.ItemId.nunique(), start.date().isoformat(), middle.date().isoformat(), end.date().isoformat() ) )\n",
    "        \n",
    "        #split to train and test\n",
    "        session_max_times = data_filtered.groupby('SessionId').Time.max()\n",
    "        sessions_train = session_max_times[session_max_times < middle.timestamp()].index\n",
    "        sessions_test = session_max_times[session_max_times >= middle.timestamp()].index\n",
    "        \n",
    "        train = data[np.in1d(data.SessionId, sessions_train)]\n",
    "        \n",
    "        print('Train set {}\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}\\n\\tSpan: {} / {}'.\n",
    "            format( slice_id, len(train), train.SessionId.nunique(), train.ItemId.nunique(), start.date().isoformat(), middle.date().isoformat() ) )\n",
    "        \n",
    "        train.to_csv(osp.join(self.processed_dir,'events_train_full.'+str(slice_id)+'.txt'), sep='\\t', index=False)\n",
    "        \n",
    "        test = data[np.in1d(data.SessionId, sessions_test)]\n",
    "        test = test[np.in1d(test.ItemId, train.ItemId)]\n",
    "        \n",
    "        tslength = test.groupby('SessionId').size()\n",
    "        test = test[np.in1d(test.SessionId, tslength[tslength>=2].index)]\n",
    "        \n",
    "        print('Test set {}\\n\\tEvents: {}\\n\\tSessions: {}\\n\\tItems: {}\\n\\tSpan: {} / {} \\n\\n'.\n",
    "            format( slice_id, len(test), test.SessionId.nunique(), test.ItemId.nunique(), middle.date().isoformat(), end.date().isoformat() ) )\n",
    "        \n",
    "        test.to_csv(osp.join(self.processed_dir,'events_test.'+str(slice_id)+'.txt'), sep='\\t', index=False)\n",
    "\n",
    "    def store_buys(self):\n",
    "        self.cart.to_csv(osp.join(self.processed_dir,'events_buys.txt'), sep='\\t', index=False)\n",
    "        \n",
    "    def process(self):\n",
    "        self.load()\n",
    "        self.filter_data()\n",
    "        if self.process_method == 'last':\n",
    "            self.split_data_org()\n",
    "        elif self.process_method == 'last_min_date':\n",
    "            self.filter_min_date()\n",
    "            self.split_data_org()\n",
    "        elif self.process_method == 'days_test':\n",
    "            self.split_data()\n",
    "        elif self.process_method == 'slice':\n",
    "            self.slice_data()\n",
    "        self.store_buys()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Processing...\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1430622011\n",
      "1442545187\n",
      "Loaded data set\n",
      "\tEvents: 2664312\n",
      "\tSessions: 1755206\n",
      "\tItems: 234838\n",
      "\tSpan: 2015-05-03 / 2015-09-18\n",
      "\n",
      "\n",
      "Filtered data set\n",
      "\tEvents: 1085763\n",
      "\tSessions: 306919\n",
      "\tItems: 49070\n",
      "\tSpan: 2015-05-03 / 2015-09-18\n",
      "\n",
      "\n",
      "Filtered data set\n",
      "\tEvents: 103032\n",
      "\tSessions: 30705\n",
      "\tItems: 23246\n",
      "\tSpan: 2015-09-01 / 2015-09-18\n",
      "\n",
      "\n",
      "Full train set\n",
      "\tEvents: 99363\n",
      "\tSessions: 29631\n",
      "\tItems: 22866\n",
      "Test set\n",
      "\tEvents: 2925\n",
      "\tSessions: 849\n",
      "\tItems: 1736\n",
      "Train set\n",
      "\tEvents: 95145\n",
      "\tSessions: 28467\n",
      "\tItems: 22325\n",
      "Validation set\n",
      "\tEvents: 3295\n",
      "\tSessions: 925\n",
      "\tItems: 1977\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Done!\n"
     ]
    }
   ],
   "source": [
    "rr = RetailRocketDatasetv2(root='/content/retailrocket', process_method='last_min_date')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Processing...\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1430622011\n",
      "1442545187\n",
      "Loaded data set\n",
      "\tEvents: 2664312\n",
      "\tSessions: 1755206\n",
      "\tItems: 234838\n",
      "\tSpan: 2015-05-03 / 2015-09-18\n",
      "\n",
      "\n",
      "Filtered data set\n",
      "\tEvents: 1085763\n",
      "\tSessions: 306919\n",
      "\tItems: 49070\n",
      "\tSpan: 2015-05-03 / 2015-09-18\n",
      "\n",
      "\n",
      "Full train set\n",
      "\tEvents: 1082094\n",
      "\tSessions: 305845\n",
      "\tItems: 49062\n",
      "Test set\n",
      "\tEvents: 3627\n",
      "\tSessions: 1065\n",
      "\tItems: 2190\n",
      "Train set\n",
      "\tEvents: 1077876\n",
      "\tSessions: 304681\n",
      "\tItems: 49058\n",
      "Validation set\n",
      "\tEvents: 4194\n",
      "\tSessions: 1162\n",
      "\tItems: 2606\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Done!\n"
     ]
    }
   ],
   "source": [
    "rr = RetailRocketDatasetv2(root='/content/retailrocket', process_method='last')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[01;34m/content/retailrocket\u001b[00m\n",
      "├── [104M]  \u001b[01;34mprocessed\u001b[00m\n",
      "│   ├── [4.1M]  events_buys.txt\n",
      "│   ├── [456K]  events_test.0.txt\n",
      "│   ├── [487K]  events_test.1.txt\n",
      "│   ├── [494K]  events_test.2.txt\n",
      "│   ├── [426K]  events_test.3.txt\n",
      "│   ├── [363K]  events_test.4.txt\n",
      "│   ├── [115K]  events_test.txt\n",
      "│   ├── [6.6M]  events_train_full.0.txt\n",
      "│   ├── [6.5M]  events_train_full.1.txt\n",
      "│   ├── [6.4M]  events_train_full.2.txt\n",
      "│   ├── [5.9M]  events_train_full.3.txt\n",
      "│   ├── [5.1M]  events_train_full.4.txt\n",
      "│   ├── [ 33M]  events_train_full.txt\n",
      "│   ├── [ 33M]  events_train_tr.txt\n",
      "│   └── [132K]  events_train_valid.txt\n",
      "└── [ 90M]  \u001b[01;34mraw\u001b[00m\n",
      "    └── [ 90M]  events.csv\n",
      "\n",
      " 194M used in 2 directories, 16 files\n"
     ]
    }
   ],
   "source": [
    "!tree --du -h -C /content/retailrocket"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Author: Sparsh A.\n",
      "\n",
      "Last updated: 2021-12-22 07:09:01\n",
      "\n",
      "recohut: 0.0.5\n",
      "\n",
      "Compiler    : GCC 7.5.0\n",
      "OS          : Linux\n",
      "Release     : 5.4.144+\n",
      "Machine     : x86_64\n",
      "Processor   : x86_64\n",
      "CPU cores   : 2\n",
      "Architecture: 64bit\n",
      "\n",
      "sys    : 3.7.12 (default, Sep 10 2021, 00:21:48) \n",
      "[GCC 7.5.0]\n",
      "pandas : 1.1.5\n",
      "numpy  : 1.19.5\n",
      "IPython: 5.5.0\n",
      "\n"
     ]
    }
   ],
   "source": [
    "#hide\n",
    "%reload_ext watermark\n",
    "%watermark -a \"Sparsh A.\" -m -iv -u -t -d -p recohut"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "name": "python3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
