Skip to content

Instantly share code, notes, and snippets.

@jaymody
Last active December 9, 2022 18:10
Show Gist options
  • Save jaymody/0ceb427d3f3aa1d9bacbc24e996cb8f7 to your computer and use it in GitHub Desktop.
Save jaymody/0ceb427d3f3aa1d9bacbc24e996cb8f7 to your computer and use it in GitHub Desktop.
Playing around with entropy/information theory (equations from: https://machinelearningmastery.com/cross-entropy-for-machine-learning/)
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Entropy and Information\n",
"Playing around with entropy/information theory (equations from: https://machinelearningmastery.com/cross-entropy-for-machine-learning/)"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import seaborn as sns"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"possible_events = [-2, -1, 0, 1, 2]\n",
"number_of_events = 15"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<seaborn.axisgrid.FacetGrid at 0x10bc9abb0>"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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1+vFF19UaWmpioqK1Lt3b02cOPGiY/j6+iomJsYxEUySY2JYfHx8o9stXrxYCxcuVF5enmJjY53WRUZGKiQkxGnMqqoqbd68+aJjAgBgIpfOqO+//3699dZbsixL99xzjxYvXqzrrrvOsb5jx45asmSJwsLCLjlWenq6UlJSFBsbq2HDhiknJ0fV1dVKTU2VJE2ZMkU9e/ZUdna2JOmZZ55RZmam3nzzTUVERDjed+7UqZM6deokLy8vzZ07V0899ZT69++vyMhIPf744woLC9P48eNd2V0AADzGpaD+8ssv9cILL+iOO+5o9JJxUFBQkz7GlZycrOPHjyszM1MlJSWKjo5WXl6eYzJYcXGxvL2/P/Ffvny5amtrdeeddzqNk5WVpSeeeEKS9PDDD6u6ulozZsxQRUWFbrzxRuXl5bXofWwAADzBpaDOysrS8OHD1a6d8+Znz57Vp59+qhEjRqhdu3YaOXJkk8ZLS0tTWlpag+vy8/OdHh84cOCS43l5eenJJ5/Uk08+2aTnBwDAVC69R33zzTfrm2++uaC9srJSN998c4uLAgAA57gU1JZlycvL64L28vJydezYscVFAQCAc5p16fuOO+6QdO7S8tSpU53en66rq9OOHTs0fPhw91YIAMAVrFlBHRgYKOncGXXnzp3l7+/vWOfr66uf/vSnmj59unsrBADgCtasoF65cqUkKSIiQg899BCXuQEAaGUuz/oGAACtr8lBPXToUNntdnXt2lXXX399g5PJztu6datbigMA4ErX5KAeN26cY/IY3/AFAEDbaHJQ//ByN5e+AQBoGy7flAMAALS+Jp9Rd+3a9aLvS/9QQ99aBgAAmq/JQZ2Tk9OKZQAAgIY0OahTUlJasw4AANCAJgd1VVWVAgICHD9fzPl+AACgZZr1HvXRo0fVo0cPdenSpcH3q8/frKOurs6tRQIAcKVqclB/9NFH6tatmyRpw4YNrVYQAAD4XpODeuTIkQ3+DAAAWo9L3/UtSd9++63+8z//U7t375YkDRw4UKmpqY6zbgAA0HIufeHJxx9/rIiICD3//PP69ttv9e233+r5559XZGSkPv74Y3fXCADAFculM+rZs2crOTlZy5cvl4+PjySprq5Os2bN0uzZs7Vz5063FgkAwJXKpTPqoqIiPfjgg46QliQfHx+lp6erqKjIbcUBAHClcymo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tV1SUpKOHj3qWN56661WqrBhrtRtyq1Q7777bu3atUsffPCB3nvvPX388ceaMWPGJbebPn260zFfvHhxq9bZGrejbSvNrV06981TPzy+X3/9dRtWfE51dbWGDBmiZcuWNan//v37NXbsWN18883avn275s6dq//4j//Q+vXrW7lSZ82t+7y9e/c6HfMePXq0UoUN27hxo2bPnq1Nmzbpgw8+0JkzZzRmzBhVV1c3uk2bvc4ttKrFixdbkZGRja6vqKiw2rdvb7399tuOtt27d1uSrIKCgrYo8QIrV660AgMDm9Q3JSXFGjduXKvW01RNrbu+vt4KCQmxnn32WUdbRUWFZbPZrLfeeqsVK3T25ZdfWpKszz77zNH23//935aXl5d1+PDhRrcbOXKkNWfOnDao8HvDhg2zZs+e7XhcV1dnhYWFWdnZ2Q32/+Uvf2mNHTvWqS0uLs669957W7XOhjS39ua8/tuKJOudd965aJ+HH37Yuvbaa53akpOTrcTExFas7OKaUveGDRssSda3337bJjU11bFjxyxJ1saNGxvt01avc86oW1llZaW6devW6PrCwkKdOXPG6bacUVFR6tWrV6O3+jRNfn6+evTooQEDBmjmzJkqLy/3dEkXdalbobaVgoICdenSRbGxsY62hIQEeXt7a/PmzRfd9o033lBQUJCuu+46ZWRk6OTJk61W5/nb0f7weDXldrQ/7C+dux1tW7+mXaldOncbw969eys8PFzjxo3Trl272qLcFjHlmLsqOjpaoaGhuuWWW/SPf/zD0+U4bnd8sd/fbXXMPf7NZP+XFRUV6YUXXtCSJUsa7VNSUiJfX98L3lu92G05TZKUlKQ77rhDkZGR+uqrr/TYY4/p1ltvVUFBgXx8fDxdXoNcuRVqa9Xx48t77dq1U7du3S5ax1133aXevXsrLCxMO3bs0COPPKK9e/dq7dq1rVJna9yOtq24UvuAAQO0YsUKDR48WJWVlVqyZImGDx+uXbt26eqrr26Lsl3S2DGvqqrSqVOn5O/v76HKLi40NFS5ubmKjY1VTU2NXnnlFY0aNUqbN2/W0KFDPVJTfX295s6dq3/7t39z+tbLH2ur1zln1E3w6KOPNjjZ4YfLj//RHz58WElJSZo4caKmT5/uocpdq705Jk2apF/84hcaNGiQxo8fr/fee0+fffaZ8vPzja67NbV27TNmzFBiYqIGDRqku+++W6tWrdI777yjr776yo17ceWKj4/XlClTFB0drZEjR2rt2rXq3r27/vCHP3i6tP+TBgwYoHvvvVcxMTEaPny4VqxYoeHDh+u5557zWE2zZ8/WF198odWrV3ushh/ijLoJHnzwQU2dOvWiffr06eP4+ciRI7r55ps1fPhwx81CGhMSEqLa2lpVVFQ4nVVf7FafzdHc2luqT58+CgoKUlFRkUaPHu3yOK1Ztyu3Qm2OptYeEhJywYSms2fP6ptvvmnW//u4uDhJ567g9O3bt9n1Xkpr3I62rbhS+4+1b99e119/vYqKilqjRLdp7JgHBAQYezbdmGHDhumTTz7xyHOnpaU5JnZe6gpKW73OCeom6N69u7p3796kvocPH9bNN9+smJgYrVy50umGIg2JiYlR+/btZbfbNWHCBEnnZj8WFxe75baczandHQ4dOqTy8nKnAHRFa9b9w1uhng/m87dCbe6M94Y0tfb4+HhVVFSosLBQMTExkqSPPvpI9fX1jvBtiu3bt0tSi495Y354O9rzd6A7fzvatLS0Brc5fzvauXPnOtp+eDvatuJK7T9WV1ennTt36rbbbmvFSlsuPj7+go8GeeKYu8P27dtb7fXcGMuydP/99+udd95Rfn6+IiMjL7lNm73O3To17Qp36NAhq1+/ftbo0aOtQ4cOWUePHnUsP+wzYMAAa/PmzY62++67z+rVq5f10UcfWZ9//rkVHx9vxcfHt3n9X3/9tbVt2zZrwYIFVqdOnaxt27ZZ27Zts7777jtHnwEDBlhr1661LMuyvvvuO+uhhx6yCgoKrP3791sffvihNXToUKt///7W6dOnja3bsixr0aJFVpcuXax3333X2rFjhzVu3DgrMjLSOnXqVJvVbVmWlZSUZF1//fXW5s2brU8++cTq37+/NXnyZMf6H79eioqKrCeffNL6/PPPrf3791vvvvuu1adPH2vEiBGtWufq1astm81mvfrqq9aXX35pzZgxw+rSpYtVUlJiWZZl3XPPPdajjz7q6P+Pf/zDateunbVkyRJr9+7dVlZWltW+fXtr586drVqnO2pfsGCBtX79euurr76yCgsLrUmTJll+fn7Wrl272rTu7777zvFalmQtXbrU2rZtm/X1119blmVZjz76qHXPPfc4+v/rX/+yOnToYM2bN8/avXu3tWzZMsvHx8fKy8szuu7nnnvOWrdunbVv3z5r586d1pw5cyxvb2/rww8/bNO6Z86caQUGBlr5+flOv7tPnjzp6OOp1zlB7UYrV660JDW4nLd//35LkrVhwwZH26lTp6xZs2ZZXbt2tTp06GDdfvvtTuHeVlJSUhqs/Ye1SrJWrlxpWZZlnTx50hozZozVvXt3q3379lbv3r2t6dOnO34Bmlq3ZZ37iNbjjz9uBQcHWzabzRo9erS1d+/eNq3bsiyrvLzcmjx5stWpUycrICDASk1NdfoD48evl+LiYmvEiBFWt27dLJvNZvXr18+aN2+eVVlZ2eq1vvDCC1avXr0sX19fa9iwYdamTZsc60aOHGmlpKQ49f/zn/9s/eQnP7F8fX2ta6+91vrb3/7W6jU2pjm1z50719E3ODjYuu2226ytW7e2ec3nP7b04+V8rSkpKdbIkSMv2CY6Otry9fW1+vTp4/SaN7XuZ555xurbt6/l5+dndevWzRo1apT10UcftXndjf3u/uEx9NTrnNtcAgBgMGZ9AwBgMIIaAACDEdQAABiMoAYAwGAENQAABiOoAQAwGEENAIDBCGoAAAxGUAMAYDCCGgAAgxHUAAAYjKAGAMBg/x/r++YQTVsVzAAAAABJRU5ErkJggg==",
"text/plain": [
"<Figure size 500x500 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# skewed (normalish) disribution\n",
"skewed_dist = [-2, -2, -1, -1, -1, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2]\n",
"assert set(skewed_dist) == set(possible_events)\n",
"assert len(skewed_dist) == number_of_events\n",
"sns.displot(skewed_dist, stat=\"probability\", bins=5)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<seaborn.axisgrid.FacetGrid at 0x1394c4550>"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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SUmRv7+/OnbsqFmzZikqKkp33323G84CAAD1c2tQT5w4UefOndPChQtVUlKi8PBw5eTkWG8wKy4ulqfn9xf9p0+f1uDBg62vMzIylJGRoVGjRik/P1+S9NVXX2ny5Mm6cOGCunTponvuuUe7du1Sly5drNu9/PLL8vT0VHx8vCorKxUTE6M//vGPLXPQAAA0gVuDWpKSk5OVnJxsd9318L0uNDRUhmHccr7169c3uE8fHx9lZWUpKyur0X0CAOAO/3Z3fQMA8O+EoAYAwMQIagAATIygBgDAxAhqAABMjKAGAMDECGoAAEyMoAYAwMQIagAATIygBgDAxAhqAABMjKAGAMDECGoAAEyMoAYAwMQIagAATIygBgDAxAhqAABMjKAGAMDECGoAAEyMoAYAwMQIagAATIygBgDAxAhqAABMjKAGAMDECGoAAEyMoAYAwMQIagAATIygBgDAxAhqAABMjKAGAMDECGoAAEyMoAYAwMQIagAATIygBgDAxAhqAABMjKAGAMDECGoAAEyMoAYAwMQIagAATIygBgDAxAhqAABMjKAGAMDE3B7UWVlZCg0NlY+PjyIjI7Vnz556aw8cOKD4+HiFhobKw8NDmZmZdWrS09M1bNgwdejQQV27dlVcXJyOHDliUzN69Gh5eHjYLI8//rizDw0AgGZza1Bv2LBBKSkpSktLU1FRkQYNGqSYmBidPXvWbv3ly5fVq1cvLVmyREFBQXZrtm/frpkzZ2rXrl3Kzc1VdXW17r//fl26dMmmLikpSWfOnLEuS5cudfrxAQDQXK3cufPly5crKSlJiYmJkqTs7Gy99957Wr16tebPn1+nftiwYRo2bJgk2V0vSTk5OTav33jjDXXt2lWFhYUaOXKkdbxt27b1hj0AAGbhtivqqqoqFRYWKjo6+vtmPD0VHR2tgoICp+2nvLxckuTv728zvnbtWgUEBKh///5KTU3V5cuXbzlPZWWlKioqbBYAAFzNbVfU58+fV01NjQIDA23GAwMDdfjwYafso7a2Vk8++aR++tOfqn///tbxRx55RD179lRwcLD279+vZ555RkeOHNGmTZvqnSs9PV0vvPCCU/oCAKCx3PrWt6vNnDlTn3/+uT766COb8RkzZlh/HjBggLp166axY8fq2LFj6t27t925UlNTlZKSYn1dUVGhkJAQ1zQOAMD/cVtQ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lClTdODAAeXm5mrLli3asWOHZsyY4bLjBADAEW4P6uXLlyspKUmJiYm66667lJ2drbZt22r16tV261955RXFxsZq3rx5uvPOO7V48WINGTJEK1eutKmzWCwKCgqyLp06dbKuO3TokHJycvSXv/xFkZGRuueee/Tqq69q/fr1On36tN39VlZWqqKiwmYBAMDV3BrUVVVVKiwsVHR0tHXM09NT0dHRKigosLtNQUGBTb0kxcTE1KnPz89X165d1bdvXz3xxBO6cOGCzRx+fn4aOnSodSw6Olqenp7avXu33f2mp6fL19fXuoSEhDT5eAEAaCq3BvX58+dVU1OjwMBAm/HAwECVlJTY3aakpKTB+tjYWL355pvKy8vTiy++qO3bt+uBBx5QTU2NdY6uXbvazNGqVSv5+/vXu9/U1FSVl5dbl5MnTzb5eAEAaKpW7m7AFSZNmmT9ecCAARo4cKB69+6t/Px8jR071qE5LRaLLBaLs1oEAKBR3HpFHRAQIC8vL5WWltqMl5aWKigoyO42QUFBTaqXpF69eikgIEBHjx61znHzzWpXr17VxYsXbzkPAAAtza1B7e3trYiICOXl5VnHamtrlZeXp6ioKLvbREVF2dRLUm5ubr31kvTVV1/pwoUL6tatm3WOsrIyFRYWWmu2bdum2tpaRUZGNueQAABwKrff9Z2SkqI///nP+utf/6pDhw7piSee0KVLl5SYmChJmjp1qlJTU631c+bMUU5Ojl566SUdPnxYzz//vD799FMlJydLkr799lvNmzdPu3bt0pdffqm8vDw9/PDD6tOnj2JiYiRJd955p2JjY5WUlKQ9e/bo448/VnJysiZNmqTg4OCWPwkAANTD7Z9RT5w4UefOndPChQtVUlKi8PBw5eTkWG8YKy4ulqfn9/8/MWLECK1bt04LFizQs88+qzvuuEObN29W//79JUleXl7av3+//vrXv6qsrEzBwcG6//77tXjxYpvPmNeuXavk5GSNHTtWnp6eio+P14oVK1r24AEAaIDbg1qSkpOTrVfEN8vPz68zNmHCBE2YMMFufZs2bfTBBx80uE9/f3+tW7euSX0CANDS3P7WNwAAqB9BDQCAiRHUAACYGEENAICJEdQAAJgYQQ0AgIkR1AAAmBhBDQCAiRHUAACYGEENAICJEdQAAJgYQQ0AgIkR1AAAmBhBDQCA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",
"text/plain": [
"<Figure size 500x500 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# balanced disribution\n",
"balanced_dist = [-2, -2, -2, -1, -1, -1, 0, 0, 0, 1, 1, 1, 2, 2, 2]\n",
"assert set(balanced_dist) == set(possible_events)\n",
"assert len(balanced_dist) == number_of_events\n",
"sns.displot(balanced_dist, stat=\"probability\", bins=5)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<seaborn.axisgrid.FacetGrid at 0x1397ae0d0>"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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jlZOTo6LSwQA4Obl1Bl1bm6uPvnkEwUEBMjT01Oenp66++67lZ6erieeeEI7duxwdZ0AANyUnDqjrqysVMuWLSVJAQEBOnnypKTLE84OHDjguuoAALjJOXVGfccdd+irr75SeHi4YmJitHjxYnl7e+svf/mLIiIiXF0jAAA3LaeCeubMmSorK5MkzZs3T//xH/+he+65R7fccovWrl3r0gIBALiZORXU8fHx9p87d+6s/fv369tvv1Xr1q3tM78BAED91etz1JJ07NgxSVJoaGi9iwEAAI6cmkx26dIlzZo1S/7+/goLC1NYWJj8/f01c+ZMXbx40dU1AgBw03LqjPrxxx/XunXrtHjxYsXGxkq6/JGtOXPmqKioSCtWrHBpkQAA3KycCuo33nhDa9as0eDBg+1tPXv2VGhoqEaPHk1QAwDgIk5d+rbZbAoLC7uqPTw8XN7e3vWtCQAA/B+ngjo5OVnz589XeXm5va28vFzPPvuskpOTXVYcAAA3u1pf+h4+fLjD448//lg/+9nP1KtXL0nSV199pYqKCg0cONC1FQIAcBOrdVD7+/s7PB4xYoTDYz6eBQCA69U6qFetWtWQdQAAgGrU6wtPzpw5Y78JR9euXdW2bVuXFAUAAC5zajJZWVmZfvvb3yo4OFj9+vVTv379FBISokceeUTnzp1zdY0AANy0nArqlJQUbdq0SX/7299UXFys4uJivffee9q0aZOefPJJV9cIAMBNy6lL3//93/+td955RwMGDLC33X///fL19dWvfvUrvvAEAAAXceqM+ty5cwoMDLyqvV27dlz6BgDAhZwK6tjYWKWlpenChQv2tvPnz2vu3Ln27/4GAAD159Sl74yMDCUkJFz1hSc+Pj7asGGDSwsEAOBm5lRQ9+jRQwcPHtTrr7+u/fv3S5JGjx6thx56SL6+vi4tEACAm1mdg/rixYvq1q2b3n//fY0fP74hagIAAP+nzu9RN23a1OG96fpavny5wsLC5OPjo5iYGG3durXGvnv27NGIESMUFhYmDw8PZWRkXNVnzpw58vDwcFi6devmsnoBAGhMTk0mmzx5shYtWqRLly7V68nXrl2rlJQUpaWlafv27erVq5fi4+N1+vTpavufO3dOERERWrhwoYKCgmoc9/bbb9epU6fsy2effVavOgEAcBen3qP+4osvlJ2drQ8//FA9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",
"text/plain": [
"<Figure size 500x500 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# random disribution\n",
"random_dist = np.random.randint(-2, 3, 15)\n",
"assert len(random_dist) == number_of_events\n",
"sns.displot(random_dist, stat=\"probability\", bins=5)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"skewed_dist\n",
"P(-2) = 0.13333333333333333\n",
"P(-1) = 0.2\n",
"P(0) = 0.3333333333333333\n",
"P(1) = 0.2\n",
"P(2) = 0.13333333333333333\n",
"\n",
"balanced_dist\n",
"P(-2) = 0.2\n",
"P(-1) = 0.2\n",
"P(0) = 0.2\n",
"P(1) = 0.2\n",
"P(2) = 0.2\n",
"\n",
"random_dist\n",
"P(-2) = 0.13333333333333333\n",
"P(-1) = 0.3333333333333333\n",
"P(0) = 0.06666666666666667\n",
"P(1) = 0.3333333333333333\n",
"P(2) = 0.13333333333333333\n",
"\n"
]
}
],
"source": [
"def compute_probability_density_function(X):\n",
" values, counts = np.unique(X, return_counts=True)\n",
" d = {v: c / len(X) for v, c in zip(values, counts)}\n",
" return lambda x: d[x] if x in d else 1e-16 # use non-zero probability to avoid division by zero or log(0) errors\n",
"\n",
"dists_dict = {\"skewed_dist\": skewed_dist, \"balanced_dist\": balanced_dist, \"random_dist\": random_dist}\n",
"prob_density_functions_dict = {k: compute_probability_density_function(v) for k, v in dists_dict.items()}\n",
"\n",
"for name, P in prob_density_functions_dict.items():\n",
" print(name)\n",
" for x in possible_events:\n",
" print(f\"P({x}) = {P(x)}\")\n",
" print()"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"skewed_dist\n",
"h(-2) = 2.0149030205422647\n",
"h(-1) = 1.6094379124341003\n",
"h(0) = 1.0986122886681098\n",
"h(1) = 1.6094379124341003\n",
"h(2) = 2.0149030205422647\n",
"\n",
"balanced_dist\n",
"h(-2) = 1.6094379124341003\n",
"h(-1) = 1.6094379124341003\n",
"h(0) = 1.6094379124341003\n",
"h(1) = 1.6094379124341003\n",
"h(2) = 1.6094379124341003\n",
"\n",
"random_dist\n",
"h(-2) = 2.0149030205422647\n",
"h(-1) = 1.0986122886681098\n",
"h(0) = 2.70805020110221\n",
"h(1) = 1.0986122886681098\n",
"h(2) = 2.0149030205422647\n",
"\n"
]
}
],
"source": [
"# information\n",
"# h(x) = -log(P(x))\n",
"\n",
"# Low Probability Event (surprising): More information.\n",
"# Higher Probability Event (unsurprising): Less information.\n",
"\n",
"h = lambda x, P: -np.log(P(x))\n",
"\n",
"for name, P in prob_density_functions_dict.items():\n",
" print(name)\n",
" for x in possible_events:\n",
" print(f\"h({x}) = {h(x, P)}\")\n",
" print()"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"skewed_dist = 1.5472867333409475\n",
"balanced_dist = 1.6094379124341005\n",
"random_dist = 1.4502523446634912\n"
]
}
],
"source": [
"# entropy\n",
"# H(X) = – sum x in X P(x) * log(P(x))\n",
"\n",
"# Skewed Probability Distribution (unsurprising): Low entropy.\n",
"# Balanced Probability Distribution (surprising): High entropy.\n",
"\n",
"H = lambda X: -sum([P(x) * np.log(P(x)) for x in possible_events if P(x) != 0])\n",
"\n",
"for name, P in prob_density_functions_dict.items():\n",
" print(f\"{name} = {H(P)}\")"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"crossH(skewed_dist, skewed_dist) = 1.5472867333409475\n",
"crossH(skewed_dist, balanced_dist) = 1.6094379124341003\n",
"crossH(skewed_dist, random_dist) = 1.8794357879792514\n",
"crossH(balanced_dist, skewed_dist) = 1.669458830924168\n",
"crossH(balanced_dist, balanced_dist) = 1.6094379124341005\n",
"crossH(balanced_dist, random_dist) = 1.787016163904592\n",
"crossH(random_dist, skewed_dist) = 1.6835068996785447\n",
"crossH(random_dist, balanced_dist) = 1.6094379124341003\n",
"crossH(random_dist, random_dist) = 1.4502523446634912\n"
]
}
],
"source": [
"# cross entropy\n",
"# crossH(P, Q) = – sum x in X P(x) * log(Q(x))\n",
"\n",
"# property: the cross entropy of a distribution with itself is the same as just the \n",
"# entropy of the distribution:\n",
"# crossH(X, X) = H(X)\n",
"\n",
"crossH = lambda P, Q: -sum([P(x) * np.log(Q(x)) for x in possible_events])\n",
"\n",
"import itertools\n",
"for (name1, P), (name2, Q) in itertools.product(prob_density_functions_dict.items(), repeat=2):\n",
" print(f\"crossH({name1}, {name2}) = {crossH(P, Q)}\")"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"crossH(skewed_dist, skewed_dist) = 0.0\n",
"crossH(skewed_dist, balanced_dist) = 0.06215117909315299\n",
"crossH(skewed_dist, random_dist) = 0.3321490546383038\n",
"crossH(balanced_dist, skewed_dist) = 0.06002091849006766\n",
"crossH(balanced_dist, balanced_dist) = 0.0\n",
"crossH(balanced_dist, random_dist) = 0.17757825147049155\n",
"crossH(random_dist, skewed_dist) = 0.23325455501505368\n",
"crossH(random_dist, balanced_dist) = 0.1591855677706092\n",
"crossH(random_dist, random_dist) = 0.0\n"
]
}
],
"source": [
"# kl divergence\n",
"# KLD(P, Q) = – sum x in X P(x) * log(P(x)/Q(x)) = crossH(Q(x), P(x)) - H(P(X))\n",
"\n",
"KLD = lambda P, Q: sum([P(x) * np.log(P(x) / Q(x)) for x in possible_events])\n",
"\n",
"import itertools\n",
"for (name1, P), (name2, Q) in itertools.product(prob_density_functions_dict.items(), repeat=2):\n",
" print(f\"crossH({name1}, {name2}) = {KLD(P, Q)}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3.9.10 64-bit ('3.9.10')",
"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.10"
},
"orig_nbformat": 4,
"vscode": {
"interpreter": {
"hash": "fd09b19eb83f586d348350b5c89c7a987a0d039b02a538583d56ff9c88f80cb0"
}
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment