{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":22559,"databundleVersionId":1923081,"sourceType":"competition"},{"sourceId":1979353,"sourceType":"datasetVersion","datasetId":1182086},{"sourceId":1979363,"sourceType":"datasetVersion","datasetId":1182157}],"dockerImageVersionId":30066,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","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\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"_kg_hide-output":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Prepare paths:\nimport glob\nfrom pathlib import Path\ninpath = '/kaggle/input/indoor-location-navigation/'\nmetapath = inpath + 'metadata/'\ntrainpath = inpath + 'train/'\ntestpath = inpath + 'test/'\n\n# Extract testing files, buildings and sites:\nos.system(f'grep SiteID {testpath}/* > test_buildings.txt')\ntest_buildings = pd.read_csv('test_buildings.txt',sep='\\t',header=None,names=['file','building','site'])\ntest_buildings['file'] = test_buildings['file'].apply(lambda x: x[:-2])\ntest_buildings['building'] = test_buildings['building'].apply(lambda x: x[7:])\n\n# How many buildings in the testing set?\nbuildings = np.unique(test_buildings['building'])\nprint('There are',len(buildings),'buildings in the testing set.')\n\ntest_buildings.head()","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Compile C++ pre-processing code:\ner=os.system(\"g++ /kaggle/input/indoor-cpp/1_preprocess.cpp -std=c++11 -o preprocess\")\nif(er): print(\"Error\")\n\n# Reformat the testing set:\nos.system('mkdir test')\nfor i,(path_filename,building) in enumerate(zip(test_buildings['file'],test_buildings['building'])):\n    er=os.system(f'./preprocess {path_filename} test {building} {0}') #since we do not know the floor, we use 0.\n    if(er): print(\"Error:\",path_filename)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Wifi testing data:\nos.system('mkdir test_wifi')\nos.system(\"g++ /kaggle/input/indoor-cpp/2_preprocess_wifi.cpp -std=c++11 -o preprocess_wifi\")\nfor building in buildings:\n    os.system(f'./preprocess_wifi {building}')","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.cluster import KMeans\n\nimport lightgbm as lgb\nlgb_params = {'objective': 'multiclass',\n              'boosting_type': 'gbdt',\n              'n_estimators': 50000,\n              'learning_rate': 0.1,\n              'num_leaves': 90,\n              'colsample_bytree': 0.4,\n              'subsample': 0.6,\n              'subsample_freq': 2,\n              'bagging_seed': 42,\n              'reg_alpha': 10,\n              'reg_lambda': 2,\n              'random_state': 42,\n              'n_jobs': -1,\n#               'device':'gpu'\n}","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.model_selection import StratifiedKFold\n\nresult = pd.DataFrame(columns=['floor','proba'])\n\nfor building in buildings:\n    \n    # Training set:\n    xyw = pd.DataFrame()\n    for floor in np.arange(-3,10):\n        file = f'/kaggle/input/indoor-xy-floor/{building}_{floor}.csv'\n        if Path(file).is_file():\n            xyi = pd.read_csv(file,index_col=0)\n            bcols = [c for c in xyi.columns if len(c.split('_'))==3] #beacon cols\n            wcols = [c for c in xyi.columns if c not in ['x','y','count','magn']+bcols] #wifi cols\n            xyi = xyi.loc[~np.isnan(xyi['count']),['x','y','count','magn']+wcols]\n            xyi.insert(0,'floor',floor)\n            if(len(xyw)):\n                xyw = xyw.merge(xyi,how='outer')\n            else: xyw = xyi\n    xyw.replace(np.nan,-99.0,inplace=True)\n\n    # XY clustering:\n    kmeans = KMeans(n_clusters=4,random_state=0).fit(xyw[['x','y']])\n    xyw.insert(0,'cluster',kmeans.labels_)\n\n    # Testing set:\n    tfw = pd.read_csv(f'test_wifi/{building}.txt')\n    tfw = tfw.pivot_table(index=['path_id','t1_wifi'],columns='bssid_wifi',values='rssid_wifi')\n    tfw = tfw.reindex(columns=xyw.columns[6:],fill_value=np.nan)\n    tfw.fillna(-99.0,inplace=True)\n\n    # Arrays:\n    dfmat = np.array(xyw.iloc[:,6:])\n    mtest = np.array(tfw)\n    labs = np.array([str(f)+'_'+str(c) for (f,c) in zip(xyw['floor'],xyw['cluster'])])\n    features = list(np.unique(labs))\n    yvalid = pd.DataFrame(np.zeros([len(labs),len(features)]),index=xyw.index,columns=features)\n    ytest = pd.DataFrame(np.zeros([len(tfw),len(features)]),index=tfw.index,columns=features)\n\n    # K-fold CV of coordinates:\n    seeds, folds = 1, 10\n    skf = StratifiedKFold(n_splits=folds,random_state=42,shuffle=True)\n    for fold, (idt,idv) in enumerate(skf.split(dfmat,labs)):\n        print('\\r',f'{fold}',end='\\t')\n        mtrain, mvalid = dfmat[idt], dfmat[idv]\n        ltrain, lvalid = labs[idt], labs[idv]\n        modelf = lgb.LGBMClassifier(**lgb_params)\n        modelf.fit(mtrain,ltrain,eval_set=[(mvalid,lvalid)],\n            eval_metric='softmax',early_stopping_rounds=10,verbose=False)\n        yvalid.loc[xyw.index[idv],modelf.classes_] = modelf.predict_proba(mvalid)\n        ytest[modelf.classes_] += modelf.predict_proba(mtest) / folds\n\n    # Performance:\n    yvalid['truth'] = xyw['floor']\n    yvalid = yvalid.melt(id_vars='truth')\n    yvalid['pred'] = [int(x.split('_')[0]) for x in yvalid.variable]\n    frmse = np.mean(np.sqrt((yvalid['pred']-yvalid['truth'])**2))\n    print(building,f'floor rmse = {frmse}')\n\n    # Prediction:\n    ytest = ytest.groupby('path_id').mean().melt(ignore_index=False,value_name='proba')\n    ytest['floor'] = [x.split('_')[0] for x in ytest.variable]\n    ytest = ytest.groupby(['path_id','floor'])['proba'].sum().reset_index()\n    ytest = ytest.loc[ytest.groupby('path_id')['proba'].transform(max) == ytest['proba']]\n    ytest.index = [building+'_'+x for x in ytest.path_id]\n    result = pd.concat([result,ytest[['floor','proba']]])\n    result.to_csv('result_floor.csv')\n    \nresult.head()","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Example:\nimport matplotlib.pyplot as plt\nplt.figure(figsize=(15,15))\nplt.scatter(xyw.x,xyw.y,c=xyw.cluster)\nplt.show()","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}