{
  "id": 362692,
  "title": "📌 Advanced Feature Engineering 2 - Ball Touch Positions",
  "url": "/competitions/tabular-playground-series-oct-2022/discussion/362692",
  "author_name": "Hasan Basri Akçay",
  "post_date": "2022-10-28T15:07:33.101000",
  "votes": 4,
  "comment_count": 0,
  "views": 0,
  "content": "<p>Hi all,</p>\n<p>I created four new features which are goal angle, ball touch positions, car number inside the triangle, and goal direction. The ball touch positions represent ball and player touch coordinates.</p>\n<p>Feature 1, goal angle <a href=\"https://www.kaggle.com/competitions/tabular-playground-series-oct-2022/discussion/362691\" target=\"_blank\">link</a>.<br>\nFeature 2 is the ball touch position.<br>\nFeature 3, the car number in the triangle <a href=\"https://www.kaggle.com/competitions/tabular-playground-series-oct-2022/discussion/362839\" target=\"_blank\">link</a>.<br>\nFeature 4, goal direction <a href=\"https://www.kaggle.com/competitions/tabular-playground-series-oct-2022/discussion/362852\" target=\"_blank\">link</a>.</p>\n<p>Feature 1 <a href=\"https://www.kaggle.com/competitions/tabular-playground-series-oct-2022/discussion/362691\" target=\"_blank\">link</a>.</p>\n<h2>Ball Touch Positions</h2>\n<pre><code>def get_line_equation(vec):\n    from numpy import ones,vstack\n    from numpy.linalg import lstsq\n\n    try:\n        points = vec\n        x_coords, y_coords = zip(*points)\n        A = vstack([x_coords,ones(len(x_coords))]).T\n        m, c = lstsq(A, y_coords)[0]\n        return m, c\n    except:\n        return None, None\n\ndef get_cross_point(vec1, vec2):\n    vec1_m, vec1_c = get_line_equation(vec1)\n    vec2_m, vec2_c = get_line_equation(vec2)\n    cross_c = vec2_c - vec1_c\n    cross_x = cross_c / (vec1_m - vec2_m) \n    cross_y = cross_x * vec1_m + vec1_c\n    return cross_x, cross_y\n\ndef add_touch_features(df):\n    touch_groups = {\n        f\"{el}_touch\": [f'{el}_pos_x', f'{el}_pos_y', f'{el}_vel_x', f'{el}_vel_y']\n        for el in [f'p{i}' for i in range(6)]\n    }\n\n    # Touch Time of The Ball Per Player\n    ball_point1_tpls = [tuple(x) for x in df[['ball_pos_x', 'ball_pos_y']].to_numpy()]\n    ball_point2_tpls = [tuple([x[0]+x[2], x[1]+x[3]]) for x in df[['ball_pos_x', 'ball_pos_y', 'ball_vel_x', 'ball_vel_y']].to_numpy()]\n    for col, vec in touch_groups.items():\n        p_point1_tpls = [tuple(x) for x in df[vec[:2]].to_numpy()]\n        p_point2_tpls = [tuple([x[0]+x[2], x[1]+x[3]]) for x in df[vec].to_numpy()]\n        touch_x, touch_y = [], []\n        for vec1, vec2 in zip(zip(ball_point1_tpls, ball_point2_tpls), zip(p_point1_tpls, p_point2_tpls)):\n            cross_point = get_cross_point(list(vec1), list(vec2))\n            if (cross_point[0] &gt;= 81 or cross_point[0] &lt;= -81) or (cross_point[1] &gt;= 105 or cross_point[1] &lt;= -105):\n                touch_time = -1\n                cross_point_x = -120 if cross_point[0] &lt;= -81 else 120\n                cross_point_y = -155 if cross_point[1] &lt;= -105 else 155\n                touch_time_list.append(touch_time)\n                touch_x.append(cross_point_x)\n                touch_y.append(cross_point_y)\n                continue\n\n            cross_point_dist = np.sqrt((cross_point[0] - vec2[0][0])**2+(cross_point[1] - vec2[0][1])**2)\n            touch_x.append(cross_point[0])\n            touch_y.append(cross_point[1])\n        df[col+\"_x\"] = touch_x\n        df[col+\"_y\"] = touch_y\n</code></pre>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F3381067%2F49dc00bee30b59d1d9a4b8c7dabf23e6%2F__results___7_0.png?generation=1666969544689976&amp;alt=media\" alt=\"\"></p>\n<p>Thank you for the great visualization <a href=\"https://www.kaggle.com/sergiosaharovskiy\" target=\"_blank\">@sergiosaharovskiy</a> ✔️</p>",
  "messages": [
    {
      "id": 2007892,
      "postDate": "2022-10-28T15:07:33.103Z",
      "content": "<p>Hi all,</p>\n<p>I created four new features which are goal angle, ball touch positions, car number inside the triangle, and goal direction. The ball touch positions represent ball and player touch coordinates.</p>\n<p>Feature 1, goal angle <a href=\"https://www.kaggle.com/competitions/tabular-playground-series-oct-2022/discussion/362691\" target=\"_blank\">link</a>.<br>\nFeature 2 is the ball touch position.<br>\nFeature 3, the car number in the triangle <a href=\"https://www.kaggle.com/competitions/tabular-playground-series-oct-2022/discussion/362839\" target=\"_blank\">link</a>.<br>\nFeature 4, goal direction <a href=\"https://www.kaggle.com/competitions/tabular-playground-series-oct-2022/discussion/362852\" target=\"_blank\">link</a>.</p>\n<p>Feature 1 <a href=\"https://www.kaggle.com/competitions/tabular-playground-series-oct-2022/discussion/362691\" target=\"_blank\">link</a>.</p>\n<h2>Ball Touch Positions</h2>\n<pre><code>def get_line_equation(vec):\n    from numpy import ones,vstack\n    from numpy.linalg import lstsq\n\n    try:\n        points = vec\n        x_coords, y_coords = zip(*points)\n        A = vstack([x_coords,ones(len(x_coords))]).T\n        m, c = lstsq(A, y_coords)[0]\n        return m, c\n    except:\n        return None, None\n\ndef get_cross_point(vec1, vec2):\n    vec1_m, vec1_c = get_line_equation(vec1)\n    vec2_m, vec2_c = get_line_equation(vec2)\n    cross_c = vec2_c - vec1_c\n    cross_x = cross_c / (vec1_m - vec2_m) \n    cross_y = cross_x * vec1_m + vec1_c\n    return cross_x, cross_y\n\ndef add_touch_features(df):\n    touch_groups = {\n        f\"{el}_touch\": [f'{el}_pos_x', f'{el}_pos_y', f'{el}_vel_x', f'{el}_vel_y']\n        for el in [f'p{i}' for i in range(6)]\n    }\n\n    # Touch Time of The Ball Per Player\n    ball_point1_tpls = [tuple(x) for x in df[['ball_pos_x', 'ball_pos_y']].to_numpy()]\n    ball_point2_tpls = [tuple([x[0]+x[2], x[1]+x[3]]) for x in df[['ball_pos_x', 'ball_pos_y', 'ball_vel_x', 'ball_vel_y']].to_numpy()]\n    for col, vec in touch_groups.items():\n        p_point1_tpls = [tuple(x) for x in df[vec[:2]].to_numpy()]\n        p_point2_tpls = [tuple([x[0]+x[2], x[1]+x[3]]) for x in df[vec].to_numpy()]\n        touch_x, touch_y = [], []\n        for vec1, vec2 in zip(zip(ball_point1_tpls, ball_point2_tpls), zip(p_point1_tpls, p_point2_tpls)):\n            cross_point = get_cross_point(list(vec1), list(vec2))\n            if (cross_point[0] &gt;= 81 or cross_point[0] &lt;= -81) or (cross_point[1] &gt;= 105 or cross_point[1] &lt;= -105):\n                touch_time = -1\n                cross_point_x = -120 if cross_point[0] &lt;= -81 else 120\n                cross_point_y = -155 if cross_point[1] &lt;= -105 else 155\n                touch_time_list.append(touch_time)\n                touch_x.append(cross_point_x)\n                touch_y.append(cross_point_y)\n                continue\n\n            cross_point_dist = np.sqrt((cross_point[0] - vec2[0][0])**2+(cross_point[1] - vec2[0][1])**2)\n            touch_x.append(cross_point[0])\n            touch_y.append(cross_point[1])\n        df[col+\"_x\"] = touch_x\n        df[col+\"_y\"] = touch_y\n</code></pre>\n<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F3381067%2F49dc00bee30b59d1d9a4b8c7dabf23e6%2F__results___7_0.png?generation=1666969544689976&amp;alt=media\" alt=\"\"></p>\n<p>Thank you for the great visualization <a href=\"https://www.kaggle.com/sergiosaharovskiy\" target=\"_blank\">@sergiosaharovskiy</a> ✔️</p>",
      "rawMarkdown": "Hi all,\n\nI created four new features which are goal angle, ball touch positions, car number inside the triangle, and goal direction. The ball touch positions represent ball and player touch coordinates.\n\nFeature 1, goal angle [link](https://www.kaggle.com/competitions/tabular-playground-series-oct-2022/discussion/362691).\nFeature 2 is the ball touch position.\nFeature 3, the car number in the triangle [link](https://www.kaggle.com/competitions/tabular-playground-series-oct-2022/discussion/362839).\nFeature 4, goal direction [link](https://www.kaggle.com/competitions/tabular-playground-series-oct-2022/discussion/362852).\n\nFeature 1 [link](https://www.kaggle.com/competitions/tabular-playground-series-oct-2022/discussion/362691).\n\n## Ball Touch Positions\n```\ndef get_line_equation(vec):\n    from numpy import ones,vstack\n    from numpy.linalg import lstsq\n\n    try:\n        points = vec\n        x_coords, y_coords = zip(*points)\n        A = vstack([x_coords,ones(len(x_coords))]).T\n        m, c = lstsq(A, y_coords)[0]\n        return m, c\n    except:\n        return None, None\n\ndef get_cross_point(vec1, vec2):\n    vec1_m, vec1_c = get_line_equation(vec1)\n    vec2_m, vec2_c = get_line_equation(vec2)\n    cross_c = vec2_c - vec1_c\n    cross_x = cross_c / (vec1_m - vec2_m) \n    cross_y = cross_x * vec1_m + vec1_c\n    return cross_x, cross_y\n\ndef add_touch_features(df):\n    touch_groups = {\n        f\"{el}_touch\": [f'{el}_pos_x', f'{el}_pos_y', f'{el}_vel_x', f'{el}_vel_y']\n        for el in [f'p{i}' for i in range(6)]\n    }\n\n    # Touch Time of The Ball Per Player\n    ball_point1_tpls = [tuple(x) for x in df[['ball_pos_x', 'ball_pos_y']].to_numpy()]\n    ball_point2_tpls = [tuple([x[0]+x[2], x[1]+x[3]]) for x in df[['ball_pos_x', 'ball_pos_y', 'ball_vel_x', 'ball_vel_y']].to_numpy()]\n    for col, vec in touch_groups.items():\n        p_point1_tpls = [tuple(x) for x in df[vec[:2]].to_numpy()]\n        p_point2_tpls = [tuple([x[0]+x[2], x[1]+x[3]]) for x in df[vec].to_numpy()]\n        touch_x, touch_y = [], []\n        for vec1, vec2 in zip(zip(ball_point1_tpls, ball_point2_tpls), zip(p_point1_tpls, p_point2_tpls)):\n            cross_point = get_cross_point(list(vec1), list(vec2))\n            if (cross_point[0] >= 81 or cross_point[0] <= -81) or (cross_point[1] >= 105 or cross_point[1] <= -105):\n                touch_time = -1\n                cross_point_x = -120 if cross_point[0] <= -81 else 120\n                cross_point_y = -155 if cross_point[1] <= -105 else 155\n                touch_time_list.append(touch_time)\n                touch_x.append(cross_point_x)\n                touch_y.append(cross_point_y)\n                continue\n\n            cross_point_dist = np.sqrt((cross_point[0] - vec2[0][0])**2+(cross_point[1] - vec2[0][1])**2)\n            touch_x.append(cross_point[0])\n            touch_y.append(cross_point[1])\n        df[col+\"_x\"] = touch_x\n        df[col+\"_y\"] = touch_y\n```\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F3381067%2F49dc00bee30b59d1d9a4b8c7dabf23e6%2F__results___7_0.png?generation=1666969544689976&alt=media)\n\nThank you for the great visualization @sergiosaharovskiy ✔️",
      "votes": 4
    }
  ],
  "comments": [],
  "raw_markdown_by_id": {
    "2007892": "Hi all,\n\nI created four new features which are goal angle, ball touch positions, car number inside the triangle, and goal direction. The ball touch positions represent ball and player touch coordinates.\n\nFeature 1, goal angle [link](https://www.kaggle.com/competitions/tabular-playground-series-oct-2022/discussion/362691).\nFeature 2 is the ball touch position.\nFeature 3, the car number in the triangle [link](https://www.kaggle.com/competitions/tabular-playground-series-oct-2022/discussion/362839).\nFeature 4, goal direction [link](https://www.kaggle.com/competitions/tabular-playground-series-oct-2022/discussion/362852).\n\nFeature 1 [link](https://www.kaggle.com/competitions/tabular-playground-series-oct-2022/discussion/362691).\n\n## Ball Touch Positions\n```\ndef get_line_equation(vec):\n    from numpy import ones,vstack\n    from numpy.linalg import lstsq\n\n    try:\n        points = vec\n        x_coords, y_coords = zip(*points)\n        A = vstack([x_coords,ones(len(x_coords))]).T\n        m, c = lstsq(A, y_coords)[0]\n        return m, c\n    except:\n        return None, None\n\ndef get_cross_point(vec1, vec2):\n    vec1_m, vec1_c = get_line_equation(vec1)\n    vec2_m, vec2_c = get_line_equation(vec2)\n    cross_c = vec2_c - vec1_c\n    cross_x = cross_c / (vec1_m - vec2_m) \n    cross_y = cross_x * vec1_m + vec1_c\n    return cross_x, cross_y\n\ndef add_touch_features(df):\n    touch_groups = {\n        f\"{el}_touch\": [f'{el}_pos_x', f'{el}_pos_y', f'{el}_vel_x', f'{el}_vel_y']\n        for el in [f'p{i}' for i in range(6)]\n    }\n\n    # Touch Time of The Ball Per Player\n    ball_point1_tpls = [tuple(x) for x in df[['ball_pos_x', 'ball_pos_y']].to_numpy()]\n    ball_point2_tpls = [tuple([x[0]+x[2], x[1]+x[3]]) for x in df[['ball_pos_x', 'ball_pos_y', 'ball_vel_x', 'ball_vel_y']].to_numpy()]\n    for col, vec in touch_groups.items():\n        p_point1_tpls = [tuple(x) for x in df[vec[:2]].to_numpy()]\n        p_point2_tpls = [tuple([x[0]+x[2], x[1]+x[3]]) for x in df[vec].to_numpy()]\n        touch_x, touch_y = [], []\n        for vec1, vec2 in zip(zip(ball_point1_tpls, ball_point2_tpls), zip(p_point1_tpls, p_point2_tpls)):\n            cross_point = get_cross_point(list(vec1), list(vec2))\n            if (cross_point[0] >= 81 or cross_point[0] <= -81) or (cross_point[1] >= 105 or cross_point[1] <= -105):\n                touch_time = -1\n                cross_point_x = -120 if cross_point[0] <= -81 else 120\n                cross_point_y = -155 if cross_point[1] <= -105 else 155\n                touch_time_list.append(touch_time)\n                touch_x.append(cross_point_x)\n                touch_y.append(cross_point_y)\n                continue\n\n            cross_point_dist = np.sqrt((cross_point[0] - vec2[0][0])**2+(cross_point[1] - vec2[0][1])**2)\n            touch_x.append(cross_point[0])\n            touch_y.append(cross_point[1])\n        df[col+\"_x\"] = touch_x\n        df[col+\"_y\"] = touch_y\n```\n![](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F3381067%2F49dc00bee30b59d1d9a4b8c7dabf23e6%2F__results___7_0.png?generation=1666969544689976&alt=media)\n\nThank you for the great visualization @sergiosaharovskiy ✔️"
  }
}