{"cells":[{"metadata":{},"cell_type":"markdown","source":"Here are some local CV functions I made for validation. Sharing them to get some feed back on whether they are accurate or not.  \nDistance functions and thresholds based on this competition's official evaluation."},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nfrom math import sqrt, acos, pi\nfrom scipy.spatial.transform import Rotation as R","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"thres_rot = [50, 45, 40, 35, 30, 25, 20, 15, 10, 5]\nthres_pos = [0.1, 0.09, 0.08, 0.07, 0.06, 0.05, 0.04, 0.03, 0.02, 0.01]","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"def trans_dist(p1, p2):\n    dx = p1[0] - p2[0]\n    dy = p1[1] - p2[1]\n    dz = p1[2] - p2[2]\n    return sqrt(dx * dx + dy * dy + dz * dz)\n\ndef rot_dist(true, pred):\n    x, y, z = true\n    true = [z, x, y]\n    x, y, z = pred\n    pred = [z, x, y]\n    q1 = R.from_euler('zyx', true)\n    q2 = R.from_euler('zyx', pred)\n    diff = R.inv(q2) * q1\n    W = np.clip(diff.as_quat()[-1], -1., 1.)\n    W = (acos(W) * 360) / pi\n    if W > 180:\n        W = 360 - W\n    return W\n\ndef get_acc(true, pred):\n    pred_rot = pred[:-3]\n    true_rot = true[:-3]\n    pred_pos = pred[3:]\n    true_pos = true[3:]\n  \n    rot_d = rot_dist(true_rot, pred_rot)\n    tran_d = trans_dist(true_pos, pred_pos)\n    print(rot_d, tran_d)\n\n    thres = []\n    for t in thres_rot:\n        if rot_d < t:\n            thres.append(1)\n        else:\n            thres.append(0)\n    for t in thres_pos:\n        if tran_d < t:\n            thres.append(1)\n        else:\n            thres.append(0)\n    print(thres)\n    true_thres = np.ones((20))\n\n    return apk(true_thres, thres, k=20)\n\n'''Ref: https://github.com/benhamner/Metrics/blob/master/Python/ml_metrics/average_precision.py'''\ndef apk(actual, predicted, k=10):\n    if len(predicted)>k:\n        predicted = predicted[:k]\n\n    score = 0.0\n    num_hits = 0.0\n\n    for i,p in enumerate(predicted):\n        # if p in actual and p not in predicted[:i]:\n        if p == actual[i]:\n            num_hits += 1.0\n#             score += 1 / (i+1.0)\n            score += num_hits / (i+1.0)\n\n    if len(actual) == 0:\n        return 0.0\n\n    return score / min(len(actual), k)\n\ndef mapk(actual, predicted, k=10):\n    return np.mean([apk(a,p,k) for a,p in zip(actual, predicted)])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pred = [0.15, -3.1, -3.1, 8.09433326, 5.27078698, 21.43466666]\ntrue = [0.169198, -3.11164, -3.08562, 7.42949, 4.99111, 20.2823]\n\nprint(get_acc(true, pred))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Its tricky making a CV that works like the PB leaderboard, the less cars given the higher the score..."},{"metadata":{"trusted":true},"cell_type":"code","source":"'''Ref: https://www.kaggle.com/pestipeti/explanation-of-map5-scoring-metric'''\ndef map_per_set(labels, predictions, k=1):\n    scores = []\n    for idx,l in enumerate(labels):\n        try:\n            scores.append(1 / (predictions[:k].index(l) + 1.))\n        except ValueError:\n            scores.append(0)\n    return np.mean(scores)","execution_count":null,"outputs":[]}],"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"}},"nbformat":4,"nbformat_minor":1}