{"cells":[{"cell_type":"code","execution_count":null,"metadata":{"collapsed":false},"outputs":[],"source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load in \n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport time\nfrom sklearn.preprocessing import LabelEncoder\nfrom sklearn.neighbors import KNeighborsClassifier\n"},{"cell_type":"code","execution_count":null,"metadata":{"collapsed":false},"outputs":[],"source":"# Input varialbles\nfw = [500., 1000., 4., 3., 2., 8.] #feature weights (black magic here)\nth = 5 #Keeping place_ids with more than th samples."},{"cell_type":"code","execution_count":null,"metadata":{"collapsed":false},"outputs":[],"source":"def process_one_cell(df_train, df_test, x_min, x_max, y_min, y_max):\n    x_border_augment = 0.02\n    y_border_augment = 0.02\n\n    #Working on df_train\n    df_cell_train = df_train[(df_train['x'] >= x_min-x_border_augment) & (df_train['x'] < x_max+x_border_augment) &\n                               (df_train['y'] >= y_min-y_border_augment) & (df_train['y'] < y_max+y_border_augment)]\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    # to be delete: df_cell_test = df_test.loc[df_test.grid_cell == grid_id]\n    df_cell_test = df_test[(df_test['x'] >= x_min) & (df_test['x'] < x_max) &\n                               (df_test['y'] >= y_min) & (df_test['y'] < y_max)]\n    row_ids = df_cell_test.index\n\n    #Feature engineering on x and y\n    df_cell_train.loc[:,'x'] *= fw[0]\n    df_cell_train.loc[:,'y'] *= fw[1]\n    df_cell_test.loc[:,'x'] *= fw[0]\n    df_cell_test.loc[:,'y'] *= fw[1]\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'], axis=1).values.astype(float)\n    X_test = df_cell_test.values.astype(float)\n\n    #Applying the classifier\n    clf = KNeighborsClassifier(n_neighbors=26, weights='distance', \n                               metric='manhattan', n_jobs=2)\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    \n    return pred_labels, row_ids"},{"cell_type":"code","execution_count":null,"metadata":{"collapsed":false},"outputs":[],"source":"def process_grid(df_train, df_test, size, x_step, y_step):\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=np.int64)\n    \n    for i in range((int)(size/x_step)):\n        start_time_row = time.time()\n        x_min = x_step * i\n        x_max = x_step * (i+1)\n        x_min = round(x_min, 4)\n        x_max = round(x_max, 4) \n        if x_max == size:\n            x_max = x_max + 0.001\n\n        for j in range((int)(size/y_step)):\n            y_min = y_step * j\n            y_max = y_step * (j+1)\n            y_min = round(y_min, 4)\n            y_max = round(y_max, 4)   \n            if y_max == size:\n                y_max = y_max + 0.001\n\n            #Applying classifier to one grid cell\n            pred_labels, row_ids = process_one_cell(df_train, df_test, x_min, x_max, y_min, y_max)\n\n            #Updating predictions\n            preds[row_ids] = pred_labels\n\n        print(\"Row %d/%d elapsed time: %.2f seconds\" % (i+1, (int)(size/x_step),(time.time() - start_time_row)))\n\n    print('Generating submission file ...')\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('sub_knn.csv', index=True, header=True, index_label='row_id')  "},{"cell_type":"code","execution_count":null,"metadata":{"collapsed":false},"outputs":[],"source":"# Main\nif __name__ == '__main__':\n    \"\"\"\n    \"\"\"\n    print('Loading data ...')\n    df_train = pd.read_csv('../input/train.csv',\n                           usecols=['row_id','x','y','time','place_id'], \n                           index_col = 0)\n    df_test = pd.read_csv('../input/test.csv',\n                          usecols=['row_id','x','y','time'],\n                          index_col = 0)\n \n    #Defining the size of the grid\n    size = 10.0\n    x_step = 0.5\n    y_step = 0.5\n    \n    print('Preparing train data')\n    #Feature engineering\n    mintue = df_train['time']%60\n    df_train['hour'] = df_train['time']//60\n    df_train['weekday'] = df_train['hour']//24\n    df_train['month'] = df_train['weekday']//30\n    df_train['year'] = (df_train['weekday']//365+1)*fw[5]\n    df_train['hour'] = ((df_train['hour']%24+1)+mintue/60.0)*fw[2]\n    df_train['weekday'] = (df_train['weekday']%7+1)*fw[3]\n    df_train['month'] = (df_train['month']%12+1)*fw[4]\n    df_train.drop(['time'], axis=1, inplace=True)\n    \n    print('Preparing test data')\n    mintue = df_test['time']%60\n    df_test['hour'] = df_test['time']//60\n    df_test['weekday'] = df_test['hour']//24\n    df_test['month'] = df_test['weekday']//30\n    df_test['year'] = (df_test['weekday']//365+1)*fw[5]\n    df_test['hour'] = ((df_test['hour']%24+1)+mintue/60.0)*fw[2]\n    df_test['weekday'] = (df_test['weekday']%7+1)*fw[3]\n    df_test['month'] = (df_test['month']%12+1)*fw[4]\n    df_test.drop(['time'], axis=1, inplace=True)\n    \n    #Solving classification problems inside each grid cell \n    process_grid(df_train, df_test, size, x_step, y_step)"}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"}},"nbformat":4,"nbformat_minor":0}