{"cells":[
 {
  "cell_type": "code",
  "execution_count": null,
  "metadata": {
   "collapsed": false
  },
  "outputs": [],
  "source": "import numpy as np\nimport pandas as pd\nfrom sklearn import preprocessing\nfrom sklearn.preprocessing import LabelEncoder\nfrom sklearn.neighbors import KNeighborsClassifier"
 },
 {
  "cell_type": "code",
  "execution_count": null,
  "metadata": {
   "collapsed": false
  },
  "outputs": [],
  "source": "df_train = pd.read_csv('../input/train.csv',\n                       usecols=['row_id','x','y','time','place_id', 'accuracy'], \n                       index_col = 0)\ndf_test = pd.read_csv('../input/test.csv',\n                      usecols=['row_id','x','y','time', 'accuracy'],\n                      index_col = 0)\nprint('Data loaded.')"
 },
 {
  "cell_type": "code",
  "execution_count": null,
  "metadata": {
   "collapsed": false
  },
  "outputs": [],
  "source": "h_round_base = 0.5 #We round hours to nearest h_round_base\n\ndef prepare_data(df, n_cell_x, n_cell_y):\n    \"\"\"\n    Feature engineering and computation of the grid.\n    \"\"\"\n    #Creating the grid\n    size_x = 10. / n_cell_x\n    size_y = 10. / n_cell_y\n    eps = 0.00001  \n    xs = np.where(df.x.values < eps, 0, df.x.values - eps)\n    ys = np.where(df.y.values < eps, 0, df.y.values - eps)\n    pos_x = (xs / size_x).astype(np.int)\n    pos_y = (ys / size_y).astype(np.int)\n    df['grid_cell'] = pos_y * n_cell_x + pos_x\n    \n    #Feature engineering\n    fw = [500, 1350, 3, 2, 1./40., 2, 10, 1./27.] #feature weights (black magic here)\n    min_max_scaler = preprocessing.MinMaxScaler()\n\n    df.x = df.x.values * fw[0]\n    df.y = df.y.values * fw[1]\n\n    initial_date = np.datetime64('2016-02-01T01:01', dtype='datetime64[m]') \n    d_times = pd.DatetimeIndex(initial_date + np.timedelta64(int(mn), 'm') \n                               for mn in df.time.values)  \n    d_hour = d_times.hour + (d_times.minute / 60.)\n    df['hour'] = ( (d_hour / h_round_base).round() * h_round_base) * fw[2]\n    df['weekday'] = d_times.weekday * fw[3]\n    df['day'] = (d_times.day * fw[4])\n    df['month'] = d_times.month * fw[5]\n    df['year'] = (d_times.year - 2013) * fw[6]\n    \n    df.accuracy = df.accuracy.values * fw[7]\n    \n    df = df.drop(['time'], axis=1) \n    return df"
 },
 {
  "cell_type": "code",
  "execution_count": null,
  "metadata": {
   "collapsed": false
  },
  "outputs": [],
  "source": "def process_one_cell(df_train, df_test, grid_id, th):\n    \"\"\"   \n    Classification inside one grid cell.\n    \"\"\"   \n    #Working on df_train\n    df_cell_train = df_train.loc[df_train.grid_cell == grid_id]\n    place_counts = df_cell_train.place_id.value_counts()\n    mask = (place_counts[df_cell_train.place_id.values] >= th).values\n    df_cell_train = df_cell_train.loc[mask]\n\n    #Working on df_test\n    df_cell_test = df_test.loc[df_test.grid_cell == grid_id]\n    row_ids = df_cell_test.index\n    \n    #Preparing data\n    le = LabelEncoder()\n    y = le.fit_transform(df_cell_train.place_id.values)\n    X = df_cell_train.drop(['place_id', 'grid_cell'], axis=1).values.astype(int)\n    X_test = df_cell_test.drop(['grid_cell'], axis = 1).values.astype(int)\n    \n    #Applying the classifier\n    clf = KNeighborsClassifier(n_neighbors=20, weights='distance', \n                               metric='manhattan')\n\n    clf.fit(X, y)\n    y_pred = clf.predict_proba(X_test)\n    pred_labels = le.inverse_transform(np.argsort(y_pred, axis=1)[:,::-1][:,:3])    \n    return pred_labels, row_ids"
 },
 {
  "cell_type": "code",
  "execution_count": null,
  "metadata": {
   "collapsed": false
  },
  "outputs": [],
  "source": "def process_grid(df_train, df_test, th, n_cells):\n    \"\"\"\n    Iterates over all grid cells, aggregates the results and makes the\n    submission.\n    \"\"\" \n    preds = np.zeros((df_test.shape[0], 3), dtype=int)\n    \n    for g_id in range(n_cells):\n        #Applying classifier to one grid cell\n        pred_labels, row_ids = process_one_cell(df_train, df_test, g_id, th)\n\n        #Updating predictions\n        preds[row_ids] = pred_labels\n        \n        print('\\rProcessed ' + str(g_id + 1) + ' / ' + str(n_cells) + ' cells.', end='')\n\n    return preds"
 },
 {
  "cell_type": "code",
  "execution_count": null,
  "metadata": {
   "collapsed": false
  },
  "outputs": [],
  "source": "#Defining the size of the grid\n#n_cell_x = 10\n#n_cell_y = 10\n\n#print('Preparing train data')\n#df_train = df_train[df_train.accuracy < 1000]\n\n#df_train = prepare_data(df_train, n_cell_x, n_cell_y)\n\n#print('Preparing test data')\n#df_test = prepare_data(df_test, n_cell_x, n_cell_y)\n\n#Solving classification problems inside each grid cell\n#th = 1 #Keeping place_ids with more than th samples. \n#preds = process_grid(df_train, df_test, th, n_cell_x*n_cell_y)\n\n#Auxiliary dataframe with the 3 best predictions for each sample\n#df_aux = pd.DataFrame(preds, dtype=str, columns=['l1', 'l2', 'l3'])  \n    \n#Concatenating the 3 predictions for each sample\n#ds_sub = df_aux.l1.str.cat([df_aux.l2, df_aux.l3], sep=' ')\n    \n#Writting to csv\n#ds_sub.name = 'place_id'\n#ds_sub.to_csv('fb_kaggle_submission.csv', index=True, header=True, index_label='row_id') "
 }
],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"}}, "nbformat": 4, "nbformat_minor": 0}