{ "cells": [ { "cell_type": "code", "execution_count": 113, "id": "49b206fc-a5ec-4206-8ca4-c71f5e1f1bea", "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAQkAAAD4CAYAAAD/0RNsAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/MnkTPAAAACXBIWXMAAAsTAAALEwEAmpwYAAAiaklEQVR4nO3deXhU5d3/8fd3ZjKEsO8IQgKyg2wJIanWal3qjisQwr4Et1bbarXlUfu01Va0WrVaCQFZZam12mrdd32SQILs+77KKmuALHP//pjhV4iZkMx2zsx8X9eVK2HmzJyPJ84nZ86cc99ijEEppfxxWB1AKWVvWhJKqWppSSilqqUloZSqlpaEUqparkiurHnz5iYlJSWSq1RKAcXFxQeMMS0CeWxESyIlJYWioqJIrlIpBYjItkAfq283lFLV0pJQSlVLS0IpVS0tCaVUtbQklFLV0pJQSlVLS0IpVS3blcRXGw4wpyDgj3SVUiEW0ZOpamJB0Q7+vWw3p8s9jLu0g9VxlIp7tiuJP9/Zh/IKD79/ezWl5R7uvvwiqyMpFdds93bD7XLwYlY/burThqfeW8sLH2+wOpJScc12exIALqeDvwzpS4JTePbD9ZRVePjF1V0QEaujKRV3zrsnISLTRWSfiKysdPtPRWSdiKwSkcmhDuZ0CM/c0YehA9rx4icb+dO7a9HxOJWKvJrsScwA/grMOnODiFwBDAJ6G2NOi0jLcIRzOIQnb72YBKeDKV9sprTCw2M39tA9CqUi6LwlYYz5QkRSKt18N/AnY8xp3zL7wpAN8BbF7wb1JMHpYPrXWygt9/D7Qb1wOLQolIqEQI9JdAF+KCJPAKeAB40xi0MX61wiwqM3dsftcvDK55soq/Dwx9t649SiUCrsAi0JF9AEyAAGAAtFpKOp4qCBiOQAOQDt27cPNCciwsPXdsXtcvDCxxsorzBMvqM3LqftPqBRKqYEWhI7gTd8pbBIRDxAc2B/5QWNMblALkBaWlpQRx5FhF9c3QW3U3jmg/WUVnh4bkhfErQolAqbQEviTeDHwGci0gVwAwdCFep87vtxZxKcDv747lrKKjy8mNUft0uLQqlwqMlHoPOAfKCriOwUkXHAdKCj72PR+cCoqt5qhNPEH13EYzf24P1Ve7l7TjGnyysiuXql4kZNPt3I8nPX8BBnqbWxl3bA7XLwP2+uZMKsYnJHpJKY4LQ6llIxJer30YdnJDP59t58uWE/Y2cspqS03OpISsWUqC8JgMED2vHs4D4UbD7I6OmLOX5ai0KpUImJkgC4td+FPD+0H8Xbv2PktEKOniqzOpJSMSFmSgLgpj5teGlYP1bsOsLwvEKOlGhRKBWsmCoJgGt7XcArw1NZu+cYWVMLOHSi1OpIKpbMnQspKeBweL/PnWt1orCLuZIAuLJ7K6aOSmPT/uNk5Raw/9hpqyMpuwnkxT53LuTkwLZtYIz3e05OzBdFTJYEwI+6tODV0QPYfqiEobn57D16yupIyi4CfbFPmgQlJefeVlLivT2GxWxJAPygU3NmjBnAt0dOMWRKPrsPn7Q6krKDQF/s27fX7vYYEdMlATCwYzNmjRvIweOlDMnNZ8ehkvM/SMW2QF/s/i5QDOLCxWgQ8yUBkJrchDnjB3KkpIyhuQVsO3jC6kjKSoG+2J94ApKSzr0tKcl7ewyLi5IA6NOuMfNyMigpLWfwlHw27T9udSRllUBf7NnZkJsLyckg4v2em+u9PYZJJK/LSktLM0VFRRFbX1XWfXuM7LwCQHhtwkC6tGpgaR5lkblzvccgtm/37kE88URMv9hFpNgYkxbQY+OtJAA27jvGsKmFlHsMc8YNpEebhlZHUiqsgimJuHm7cbZOLRuwYGImdVwOhuUVsHLXEasjKWVbcVkSAB2a12PhxEzquV1kTS3gm+3fWR1JKVuK25IAaNc0iYV3ZdIkyc2IaYtYvPWQ1ZGUsp2AJ+fx3fegiBgRaR6eeOHXtnFdFk7MpGWDOoyavoj8TQetjqSUrdRkT2IGcG3lG0WkHXA1EPWnm7VulMj8iRm0bVyXMTMW8eWG743nq1TcOm9JGGO+AKraD38O+BUQE3PvtWyQyPycDFKa1WPczCI+XRu2+YaUiioBHZMQkZuBXcaYZTVYNkdEikSkaP9+e/+Fbla/DvMmZNClVX1yZhfxwapvrY6klOVqXRIikgRMAh6ryfLGmFxjTJoxJq1Fixa1XV3ENannZu74DHq2acQ9c5fwzvI9VkdSylKB7ElcBHQAlonIVuBCYImItA5lMCs1qpvA7HHp9G3XmJ/OW8JbS3dZHUkpy9S6JIwxK4wxLY0xKcaYFLyzefU3xsTUvnmDxARmjk0nvUNTHliwlNeLd1odSdlFnI1OFejkPHGhXh0Xr45O59JOzXno9WXMWxT1H+SoYMXh6FRxee1GbZ0qq+DuOcV8um4/vxvUk5GZKVZHUlZJSfEWQ2XJybB1a6TT1JheuxFmiQlOXhmRytU9WvHYW6vI+3Kz1ZGUVeJwdCotiRqq43LycnZ/rr+4NX94Zw0vf7bR6kjKCnE4OpWWRC0kOB28MLQfg/q2YfJ763j+ow1EeJ5kZbU4HJ3qvBMGq3O5nA6eHdyXBKeD5z5aT2lFBQ9e0xURsTqaioQzA9PE0YA1WhIBcDqEybf3JsEpvPTpJkrLPfzm+u5aFPEiOzumS6EyfbsRIIdDeOKWixmZmczUL7fwv/9erW89VPBseA6G7kkEweEQ/vfmnridDvK+2kJphYc/DOqFw6F7FCoAZ87BODMnyJlzMMDSPRfdkwiSiDDphu7cc/lFvFa4nYf/sZwKj+5RfI8N/0Lajk1nCNOSCAER4aGfdOWBqzrz9+Kd/HLhUsorPFbHso9wn6UYKwVk03MwtCRCRER44KouPPSTrry5dDf3z19KmRaFVzj/QsbSadI2PQdDSyLE7r2iE5Ou7847K/Zw79wllJZrUYT1L6RNd9EDYtNzMLQkwmDCZR357U09+GD1Xu6aU8ypsgqrI1krnH8hbbqLHhCbzhCmJREmoy/pwJO3Xswna/cxYVYRJ0vjuCjC+RfSprvotXbmuMqIEd5/z57tvWDMX0FE8jiMMSZiX6mpqSbeLFi83aQ88rYZOiXfnDhdZnUc68yZY0xysjEi3u9z5oTueZOSjPEekfB+JSWF7vkjobb/DQH8NwNFJsDXrZZEBLyxZIfp8Mjb5o6/fW2Oniy1Ok7sCVcBRUpy8rkv+DNfycmhWd4EVxLnHU9CRKYDNwL7jDG9fLc9DdwElAKbgDHGmMPn22uJ1vEkQuHt5d5PPHpf2IgZY9JpVDfB6kjKLhwO78u8MhHwVHHgu7bLE/7xJGbw/Xk3PgR6GWN6A+uBXwey8nhyY+82vJzdn5W7jjA8r5DDJaVWR1J2UdvjKhE+DhPQvBvGmA+MMeW+fxbgHQxXncdPerZmyohU1u09RtbUQg4eP211JGUHtT2wG+GPSkPx6cZY4F1/d0bTvBuR8ONurcgbmcbm/cfJmlrAvmOnrI6krFbbjz4j/FFpjca4FJEU4O0zxyTOun0SkAbcZmrwRPF8TKKy/9t4gHEzi7igcSLzJmTQqmGi1ZFUDLNkjEsRGYX3gGZ2TQpCnesHnZozc2w6e4+cYsiUfHYfPml1pOgUK9dt2Fig0/xdCzwM3GyMKTnf8qpq6R2aMnv8QA6eKGXwlHx2HNJNWSuxdN2GjQU678ZfgQbAhyKyVEReCXPOmNW/fRNeG5/BsVPlDJmSz9YDJ6yOFD1i6boNG9N5N2xi9e6jDJ9WiMshvDYhg04t61sdyf4COF8gXum8GzGgR5uGzJuQgcfA0Nx81n17zOpI9hcr123YnJaEjXRt3YD5ORk4RMiaWsDq3UetjmRvNr20OtZoSdhMp5b1WTgxk0SXg6ypBSzfedjqSPZl00urY40ek7CpHYdKyJpawJGSMmaOS6d/+yZWR1JRTI9JxKB2TZNYMDGTpvXdjMgrZNGWQ+d/kFJhoCVhY20b12XhxExaNUpk1PRF/N+mA1ZHUnFIS8LmWjVMZEFOJu2a1mXMq4v5Yr1e/6IiS0siCrRoUId5EzLo2KI+42cW8cnavVZHUnFESyJKNKtfh3kTBtK1dQMmzi7mvZXfWh1JxQktiSjSOMnNnPED6dW2Efe+toS3l++2OpKKA1oSUaZR3QRmjxtI//aN+dm8b3jzm11WR1IxTksiCtWv42Lm2HQGdmjGzxcuZWHRDqsjqRimJRGlktwupo8ewKWdmvOr15czt3Cb1ZGii45DUWNaElGsrtvJ1JFp/LhbSyb9cyUzvt5idaTooONQ1IqWRJRLTHDyyvBUrunRit/+ezVTv9hsdST703EoakVLIga4XQ5eyu7PDb0v4In/rOGlTzdaHcneYmn+0AioychU00Vkn4isPOu2piLyoYhs8H3Xq48sluB08PyQvtzary1Pv7+O5z5cjw496oeOQ1ErgU7O8wjwsTGmM/Cx79/KYi6ng2fu7MOdqRfy/McbmPz+Oi2Kqug4FLUS0OQ8wCBgpu/nmcAtoY2lAuV0CE/d3pthA9vzt8828cQ7a7QoKtNxKGrFFeDjWhlj9gAYY/aISEt/C4pIDpAD0F535yLC4RCeuKUXbqeDvK+2UFbh4fGbeuJwiNXR7CM7W0uhhgItiRozxuQCueAddCbc61NeIsLjN/XA7XKQ+8VmSis8PHHLxVoUqtYCLYm9InKBby/iAmBfKEOp0BARfn1dN9xOB3/9dCOl5YbJd/TGqUWhaiHQkvgXMAr4k+/7WyFLpEJKRHjwJ11JcDp47qP1lHs8/PnOPric+um3qpnzloRvcp7LgeYishN4HG85LPRN1LMduDOcIVXw7r+qMwkuYfJ76yir8PD80H4kaFGoGjhvSRhjsvzcdWWIs6gwu+fyTridDv7wzhrKKpbw12H9qONyWh1L2Zz+KYkz43/Ykd8N6smHq/dy1+xiTpVVWB1J2ZyWRBwamZnCH2+7mM/W72f8zCJOlmpRKP+0JOJUVnp7Jt/em683HWDMjEWcOF1udSRlU1oScezOtHb8ZUhfFm/9jlHTF3HsVJnVkZQNaUnEuUF92/JiVj+W7jjMiGmLOHJSi0KdS0tCcf3FF/Bydn9W7T5Cdl4B350otTqSshEtCQXANT1bkzsijfV7j5M1tYADx09bHUnZhJaE+v+u6NaSaaPS2HrwBFm5Bew7dsrqSMoGtCTUOX7YuQWvjk5n1+GTDJ1SwLdHtCjinZaE+p7Mi5oxa2w6+46dZkhuPrsOn7Q6krKQloQN+Bvd3cpR39NSmjJ7XDqHTpQy+JV8th8sOf+DVEzSkrCYv9Hd77nH+lHf+7VvwrwJGZwoLWdIbj5bDpyI3MqVbUgkhzZLS0szRUVFEVtfNEhJ8RZAZU4nVFRxtnRyMmzdGu5U51q9+yjDpxXicgivTRhIp5YNIhtABU1Eio0xaYE8VvckLOZvFPeqCqK65cOpR5uGzM/JwGNgaG4B6749FvkQyjJaEhbzN+yn088V3FYNE9qlVQMWTMzA6RCG5uazctcRa4KoiAuqJETk5yKySkRWisg8EUkMVbB44W9095wc+436flGL+iycmEmS28WwqQUs23HYujAqYgIuCRFpC/wMSDPG9AKcwNBQBYsX/kZ3f/lle476ntysHvNzMmiUlMDwvEKKt1WebUHFmoAPXPpKogDoAxwF3gReMMZ84O8xeuAyduw+fJLsvEL2HT3F9NEDGNixmdWRVDUsOXBpjNkFPIN3jMs9wJGqCkJEckSkSESK9u/fH+jqlM20aVyXBTkZtG6UyOhXF/P1xgNWR1JhEszbjSZ4Z/LqALQB6onI8MrLGWNyjTFpxpi0Fi1aBJ5U2U7LhonMz8mkfdMkxs5YzOfr9Y9ALArmwOVVwBZjzH5jTBnwBvCD0MRS0aJFgzrMy8ngohb1mTCziI9W77U6kgqxYEpiO5AhIkkiInhHz14TmlgqmjSt5+a1CQPpdkED7ppTzHsr91gdSYVQMMckCoHXgSXACt9z5YYol4oyjZPczBk/kN4XNuLe177h38t2Wx1JhUhQ50kYYx43xnQzxvQyxowwxuhIJXGsYWICs8YNJDW5CffP/4Y3luy0OpIKAT3jUoVU/TouZowZQEbHZvzy78tYuHiH1ZFUkLQkVMgluV1MHz2AH3Zuwa/+sZzZBVVcwaaihpaECovEBCe5I1K5sltLHn1zJdO/2mJ1JBUgLQkVNokJTv42PJVre7bmd2+vZsrnm6yOpAKgJaHCyu1y8OKwftzUpw1/fHctL368wepIqpbOO6u4UsFKcDp4bnAfEhzCnz9cT1mFh59f3QXv6TXK7nRPIoZZOUZmZS6ng6fv7MPgtAt54ZONPPXeOiI5KpoKnO5JxKgzY2eW+MavPTNGJlh3ubnTIfzptt64XQ5e+XwTpeUeHr2xu+5R2JzuScSoSZP+WxBnlJR4b7eSwyH8flAvxlySwvSvt/DYW6vweHSPws50TyJG+RsL04oxMisTER67sQdul4Mpn2+mrMLDk7dejMOhexR2pCURo9q3r3oUbqvGyKxMRHjk2m64nQ5e/GQjpRUenr6jD04tCtvRtxsxyt/YmVaOkVmZiPDLa7ryi6u78MaSXTywYCnlFR6rY6lKbFUSVhyNt9MnAKHkb+xMq8fIrMrPruzMI9d149/LdvPTed9QWq5FYSvGmIh9paamGn/mzDEmKckY73xV3q+kJO/t4WLFOpV/eV9uNskPv23GzVhkTpWVWx0npgBFJsDXrW1m8PI3k1U4Z6yyYp2qerPzt/LoW6v4UZcWTBmRSmKCnwlIVK1YNoOXiDQWkddFZK2IrBGRzECfy4qj8Xb+BCBejchM4U+3XcwXG/YzbuZiSkrLrY4U94I9JvE88J4xphveofUDHr7O31H3cB6Nt2Kd6vyGprfnmTv6kL/pIKNfXczx01oUVgpmtOyGwGXANABjTKkx5nCgz2fF0fho+AQgXt2eeiF/GdqP4m3fMWr6Io6eKrM6UtwKZk+iI7AfeFVEvhGRPBGpF+iTWXE0Ppo+AYhHN/dpw1+z+rFsx2FG5BVypESLwgrBzOCVhncGr0uMMYUi8jxw1BjzaKXlcoAcgPbt26duq+pIoVLV+Gj1Xu6Zu4TOreoze9xAmtZzWx0p6lh14HInsNN4R80G78jZ/SsvZHRyHhWkq3q0IndkKhv2HWfY1AIOHNfxliMpmCH1vwV2iEhX301XAqtDkkqpSi7v2pJXRw9g68ETDM0tYN/RU1ZHihvBfrrxU2CuiCwH+gJPBp1IKT8u6dScGWPS2X34JENyC9hz5KTVkeJCsPNuLPW9lehtjLnFGPNdqIIpe7L6NPaMjs2YPS6dA8dOM2RKATu/Kzn/g1RQbHXthrK3MwPZbNvmPYn9zEA2wRZFbYsnNbkps8cP5HBJKUOmFLDt4IngAqhqaUmoGvM3kM399wf+nIEWT992jXltQgYnSssZMqWAzfuPBx5CVUtLQtWYv9PVDx4MfG8imBG0erVtxPycDMoqPAzJLWDD3mOBhVDV0pJQNVbd6eqBDosX7PUz3Vo3ZH5OBgBDcwtYs+doYEGUX1oSqsaqO1090IviQnH9TOdWDViQk0GC00HW1AJW7joSWBhVJS0JVWPZ2dCsWdX3BXpRXKiun+nYoj4LJmZQz+1i2NQClu44HFgg9T1aEqpWnn8+tBfFhfL6meRm9VgwMYPGSW6G5xVStPVQYKHUObQkVK2E46K47GzvID8ej/d7MM91YZMkFkzMoGWDOoycvoiCzQcDfzIFBHGBVyCqG5lKqVDad/QU2XmF7PiuhLyRA7i0c3OrI1nKspGplLKrlg0TmZeTQUqzeoyduZhP1+2zOlLU0pJQMat5/TrMm5BB55b1mTirmA9X77U6UlTSklAxrUk9N6+Nz6B7m4bcPaeYd1fssTpS1NGSUDGvUVICc8al06ddY+6b9w1vLd1ldaSooiURZ6y+itMqDRITmDU2ndTkJvx8wVJeL95pdaSooSURR8J1FWe0qFfHxYwxA8i8qBkPvb6M+Yt07oSa0JKII8FcTBUrktwupo0awGWdW/DIGyuYnb/V6ki2F3RJiIjTN1r226EIpMJHJyPySkxwkjsylau6t+LRt1Yx7astVkeytVDsSdxPEJPyqMjRyYj+q47LycvZ/bmuV2t+//Zq/vbZJqsj2Vaw0/xdCNwA5IUmjgonnYzoXG6Xgxez+nFznzY89d5aXvh4g9WRbMkV5OP/AvwKaOBvgUrzbgS5OhWMM9dETJrkfYvRvr23IOJ5MiKX08FzQ/ricgrPfriesgoPv7i6CyJidTTbCLgkRORGYJ8xplhELve3nDEmF8gF77Ubga5PhUZ2dnyXQlWcDuGZO/rgdjp48ZONlJZ7eOS6bloUPsHsSVwC3Cwi1wOJQEMRmWOMGR6aaEpFjsMhPHnrxSQ4HUz5YjOlFR4eu7GHFgVBlIQx5tfArwF8exIPakGoaOZwCL8b1BO3y8G0r7ZQWu7h94N64XDEd1EEe0xCqZgiIvzPDd1JcDp45fNNlFV4+ONtvXHGcVGEpCSMMZ8Bn4XiuZSymojw8LVdcbscvPDxBsoqDE/f0RuXMz7PPdQ9CaWqICL84uouuJ3CMx94P/V4bkhfEuKwKLQklKrGfT/ujNvl4Mn/rKWswsOLWf1xu+KrKOLrv1apAORcdhGP39SD91ft5e45xZwqq7A6UkRpSShVA2Mu6cAfbunFx2v3MWFWUVwVhZaEUjU0PCOZybf35quNBxg7YzElpeVWR4oILQmlamHwgHY8O7gPBZsPMnr6Yo6fjv2i0JJQqpZu7Xchzw/tR/H27xg5rZCjp8qsjhRWWhJKBeCmPm14aVh/Vuw6wvC8Qg6XlFodKWy0JJQK0LW9WvPK8FTW7jnGsKmFHDoRm0WhJaFUEK7s3oqpo9LYtP84WbkF7D922upIIacloVSQftSlBa+OHsD2QyUMzc1n79FTVkcKKS0JpULgB52aM3NsOt8eOcWQKfnsPnzS6kghoyWhVIikd2jKrHEDOXi8lCG5+ew4VHL+B0UBLQmlQig1uQlzxg/kSEkZQ6bks+3gCasjBU1LQqkQ69OuMfNyMjhZVsHgKfls2n/c6khBCbgkRKSdiHwqImtEZJWI3B/KYNEmXqfPU1Xr2aYR83MyqfAYhkwpYP3eY1ZHClgwexLlwC+NMd2BDOBeEekRmljRJd6nz1NV69q6AfNzMnEIDM0tYPXuo1ZHCkjAJWGM2WOMWeL7+RjeCXrahipYNNHp85Q/nVrWZ8HETOq4HGRNLWDFziNWR6q1kByTEJEUoB9QWMV9OSJSJCJF+/fvD8XqbEenz1PV6dC8HgsnZlK/jotheQV8s/07qyPVSijmAq0P/AN4wBjzvf0pY0yuMSbNGJPWokWLYFdnSzp9njqfdk2TWHhXJk3ruRkxbRGLtx6yOlKNBTvNXwLegphrjHkjNJGij06fp2qibeO6LMjJpGXDOoyavoj8TQetjlQjwXy6IcA0YI0x5tnQRYo+2dmQmwvJySDi/Z6bqzNlqe9r3SiR+TkZtG1clzEzFvHlBvu/BRdjApt5T0QuBb4EVgAe382/Mcb8x99j0tLSTFFRUUDrUyqWHDx+muy8QjYfOMGU4alc0a1lWNcnIsXGmLRAHhvMpxtfGWPEGNPbGNPX9+W3IJRS/9Wsfh3mTcigS6v65Mwu4oNV31odyS8941IpizSp52bu+Ax6tmnEPXOX8M7yPVZHqpKWhFIWalQ3gdnj0unbrjE/nbeEt5busjrS92hJKGWxBokJzBybTnqHpjywYCl/L9phdaRzaEkoZQP16rh4dXQ6l3ZqzkOvL+e1QvuciacloZRN1HU7mToyjSu6tuA3/1zBrPytVkcCtCSUspXEBCevjEjl6h6teOytVeR9udnqSFoSStlNHZeTl7P7c8PFF/CHd9bw0qcbLc2js4orZUMJTgfPD+2Lyyk8/f46yio83H9lZ7wnOkeWloRSNuVyOnh2cF8SnA7+8tEGyio8PHhN14gXhZaEUjbmdAiTb+9NgtPBS59uorTcw2+u7x7RotCSUMrmHA7hyVt74XYKU7/cQlmF4fGbekSsKLQklIoCIsJvb+5JgtNB3ldbOF3u4YlbeuFwhL8otCSUihIiwqQbuuN2OXj5s02UVXh46vbeOMNcFFoSSkUREeGhn3TF7fIezCyv8PDs4L5h3aPQklAqyogID1zVhQSnA4/HhP0th5aEUlHq3is6RWQ9wY5xea2IrBORjSLySKhCKaXsI5gxLp3AS8B1QA8gK14n51EqlgWzJ5EObDTGbDbGlALzgUGhiaWUsotgSqItcPboGDupYgaveJicR6lYFkxJVHVI9XtDb8fD5DxKxbJgSmIn0O6sf18I7A4ujlLKboIpicVAZxHpICJuYCjwr9DEUkrZRcDnSRhjykXkPuB9wAlMN8asClkypZQtBDyDV0ArE9kPbAvjKpoDB8L4/JohOtZvhwxWr79yhmRjTEAHBSNaEuEmIkWBTmWmGWJn/XbIYPX6Q5lBx7hUSlVLS0IpVa1YK4lcqwOgGeywfrA+g9XrhxBliKljEkqp0Iu1PQmlVIhpSSilqhWVJXG+cSzE6wXf/ctFpH+I199ORD4VkTUiskpE7q9imctF5IiILPV9PRbiDFtFZIXvuYuquD/c26DrWf9tS0XkqIg8UGmZkG8DEZkuIvtEZOVZtzUVkQ9FZIPvexM/jw16/BM/639aRNb6tvM/RaSxn8dW+zsLMsNvRWTXWdv6ej+Prf02MMZE1Rfeszs3AR0BN7AM6FFpmeuBd/FehJYBFIY4wwVAf9/PDYD1VWS4HHg7jNthK9C8mvvDug2q+J18i/eEnbBuA+AyoD+w8qzbJgOP+H5+BHgqkP9vglj/NYDL9/NTVa2/Jr+zIDP8FniwBr+nWm+DaNyTqMk4FoOAWcarAGgsIheEKoAxZo8xZonv52PAGqq4TN5iYd0GlVwJbDLGhPNsWgCMMV8AhyrdPAiY6ft5JnBLFQ8NyfgnVa3fGPOBMabc988CvBc7ho2fbVATAW2DaCyJmoxjUaOxLkJBRFKAfkBhFXdnisgyEXlXRHqGeNUG+EBEikUkp4r7I7YN8F7cN8/PfeHcBme0MsbsAW+BAy2rWCZS22Ms3j24qpzvdxas+3xveab7ecsV0DaIxpKoyTgWNRrrIuggIvWBfwAPGGOOVrp7Cd7d7z7Ai8CbIV79JcaY/niHD7xXRC6rHK+Kx4RjG7iBm4G/V3F3uLdBbYR9e4jIJKAcmOtnkfP9zoLxN+AioC+wB/hzVRGruO282yAaS6Im41iEfawLEUnAWxBzjTFvVL7fGHPUGHPc9/N/gAQRaR6q9Rtjdvu+7wP+iXdX8myRGu/jOmCJMWZvFRnDug3OsvfMWynf931VLBPW7SEio4AbgWzjOwBQWQ1+ZwEzxuw1xlQYYzzAVD/PHdA2iMaSqMk4Fv8CRvqO8GcAR87sjoaCiAgwDVhjjHnWzzKtfcshIul4t/XBEK2/nog0OPMz3gNnKystFtZtcJYs/LzVCOc2qORfwCjfz6OAt6pYJmzjn4jItcDDwM3GmBI/y9TkdxZMhrOPN93q57kD2wbBHmm14gvvkfv1eI/UTvLddhdwl+9nwTuS9yZgBZAW4vVfinc3bTmw1Pd1faUM9wGr8B5BLgB+EML1d/Q97zLfOiK+DXzrSML7om901m1h3QZ4C2kPUIb3L+M4oBnwMbDB972pb9k2wH+q+/8mROvfiPe9/pn/F16pvH5/v7MQZpjt+z0vx/vCvyBU20BPy1ZKVSsa324opSJIS0IpVS0tCaVUtbQklFLV0pJQSlVLS0IpVS0tCaVUtf4f5x75gbLBu+YAAAAASUVORK5CYII=\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "[[0.69314718]]\n" ] } ], "source": [ "import numpy as np \n", "import matplotlib.pyplot as plt\n", "\n", "def draw(x1, x2):\n", " ln = plt.plot(x1, x2)\n", " \n", "def sigmoid(score):\n", " return 1/(1 + np.exp(-score))\n", " \n", "def calculate_error(line_parameters, points, y):\n", " m = points.shape[0]\n", " p = sigmoid(points*line_parameters)\n", " cross_entropy = -(1/m)*(np.log(p).T * y + np.log(1-p).T * (1-y))\n", " \n", " return cross_entropy\n", "\n", "def gradient_descent(line_parameters, points, y, alpha):\n", " m = points.shape[0]\n", "\n", " for i in range(500):\n", " p = sigmoid(points*line_parameters)\n", " gradient = (points.T * (p - y))*(alpha/m)\n", " line_parameters = line_parameters - gradient\n", " w1 = line_parameters.item(0)\n", " w2 = line_parameters.item(1)\n", " b = line_parameters.item(2)\n", " \n", " x1 = np.array([ points[:,0].min(), points[:,0].max()])\n", "#w1x1 + w2x2 + b = 0\n", "\n", " x2 = -b /w2 + x1 * (-w1/w2)\n", " \n", " draw(x1, x2)\n", "\n", "n_pts = 10\n", "\n", "np.random.seed(0)\n", "\n", "bias = np.ones(n_pts)\n", "\n", "random_x1_values = np.random.normal(10, 2, n_pts)\n", "random_x2_values = np.random.normal(12,2,n_pts)\n", "top_region = np.array([random_x1_values, random_x2_values, bias]).T\n", "bottom_region = np.array([np.random.normal(4,2, n_pts), np.random.normal(6,2, n_pts), bias]).T\n", "all_points = np.vstack((top_region, bottom_region))\n", "\n", "line_parameters = np.matrix([np.zeros(3)]).T\n", "#x1 = np.array([ bottom_region[:,0].min(), top_region[:,0].max()])\n", "#w1x1 + w2x2 + b = 0\n", "\n", "#x2 = -b /w2 + x1 * (-w1/w2)\n", "\n", "\n", "linear_combination = all_points * line_parameters\n", "probabilities = sigmoid(linear_combination)\n", "\n", "y = np.array([np.zeros(n_pts), np.ones(n_pts)]).reshape(n_pts*2, 1)\n", "\n", "\n", "\n", "_, ax = plt.subplots(figsize=(4,4))\n", "ax.scatter(top_region[:,0], top_region[:, 1], color='r')\n", "ax.scatter(bottom_region[:,0], bottom_region[:, 1], color='b')\n", "gradient_descent(line_parameters, all_points, y, 0.06)\n", "plt.show()\n", "\n", "print(calculate_error(line_parameters, all_points, y))\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "id": "ca08c3f7-4e08-4585-b6ea-f9637eee7037", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.7" } }, "nbformat": 4, "nbformat_minor": 5 }