cyberosa commited on
Commit
17e1ac3
·
1 Parent(s): 3ed8c7a

updating KL-div formula

Browse files
data/closed_markets_div.parquet CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:8d2583a54d7d4b38e51c2bf1e808a710e6a4b232009b5ae8917ce0534b045d94
3
- size 48882
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:abdc271bdfd214e6497de73c32adeada50b680d847b1ad9b0bdf2c2fc442394b
3
+ size 48595
notebooks/closed_markets.ipynb CHANGED
@@ -1468,7 +1468,7 @@
1468
  },
1469
  {
1470
  "cell_type": "code",
1471
- "execution_count": 2,
1472
  "metadata": {},
1473
  "outputs": [],
1474
  "source": [
@@ -1487,6 +1487,7 @@
1487
  " # Avoid division by zero\n",
1488
  " epsilon = 1e-10\n",
1489
  " q = np.clip(q, epsilon, 1 - epsilon)\n",
 
1490
  "\n",
1491
  " # Compute KL divergence\n",
1492
  " kl_div = np.sum(p * np.log(p / q))\n",
@@ -1494,6 +1495,72 @@
1494
  " return kl_div"
1495
  ]
1496
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1497
  {
1498
  "cell_type": "code",
1499
  "execution_count": 3,
@@ -1518,7 +1585,7 @@
1518
  },
1519
  {
1520
  "cell_type": "code",
1521
- "execution_count": 6,
1522
  "metadata": {},
1523
  "outputs": [
1524
  {
@@ -1527,7 +1594,7 @@
1527
  "0.16397451204513597"
1528
  ]
1529
  },
1530
- "execution_count": 6,
1531
  "metadata": {},
1532
  "output_type": "execute_result"
1533
  }
@@ -1561,6 +1628,347 @@
1561
  "kl = np.sum(kl_div(p, q))\n",
1562
  "print(f\"KL divergence: {kl}\")"
1563
  ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1564
  }
1565
  ],
1566
  "metadata": {
 
1468
  },
1469
  {
1470
  "cell_type": "code",
1471
+ "execution_count": 31,
1472
  "metadata": {},
1473
  "outputs": [],
1474
  "source": [
 
1487
  " # Avoid division by zero\n",
1488
  " epsilon = 1e-10\n",
1489
  " q = np.clip(q, epsilon, 1 - epsilon)\n",
1490
+ " print(q)\n",
1491
  "\n",
1492
  " # Compute KL divergence\n",
1493
  " kl_div = np.sum(p * np.log(p / q))\n",
 
1495
  " return kl_div"
1496
  ]
1497
  },
1498
+ {
1499
+ "cell_type": "code",
1500
+ "execution_count": 17,
1501
+ "metadata": {},
1502
+ "outputs": [
1503
+ {
1504
+ "data": {
1505
+ "text/plain": [
1506
+ "array([-22.82067008, 1.6847004 ])"
1507
+ ]
1508
+ },
1509
+ "execution_count": 17,
1510
+ "metadata": {},
1511
+ "output_type": "execute_result"
1512
+ }
1513
+ ],
1514
+ "source": [
1515
+ "p= 0\n",
1516
+ "q = 0.8145\n",
1517
+ "p = np.array([p, 1 - p])\n",
1518
+ "q = np.array([q, 1 - q])\n",
1519
+ "epsilon = 1e-10\n",
1520
+ "p = np.clip(p, epsilon, 1 - epsilon)\n",
1521
+ "np.log(p/q)"
1522
+ ]
1523
+ },
1524
+ {
1525
+ "cell_type": "code",
1526
+ "execution_count": 18,
1527
+ "metadata": {},
1528
+ "outputs": [
1529
+ {
1530
+ "data": {
1531
+ "text/plain": [
1532
+ "array([-2.28206701e-09, 1.68470040e+00])"
1533
+ ]
1534
+ },
1535
+ "execution_count": 18,
1536
+ "metadata": {},
1537
+ "output_type": "execute_result"
1538
+ }
1539
+ ],
1540
+ "source": [
1541
+ "p*np.log(p/q)"
1542
+ ]
1543
+ },
1544
+ {
1545
+ "cell_type": "code",
1546
+ "execution_count": 19,
1547
+ "metadata": {},
1548
+ "outputs": [
1549
+ {
1550
+ "data": {
1551
+ "text/plain": [
1552
+ "1.6847003943841101"
1553
+ ]
1554
+ },
1555
+ "execution_count": 19,
1556
+ "metadata": {},
1557
+ "output_type": "execute_result"
1558
+ }
1559
+ ],
1560
+ "source": [
1561
+ "np.sum(p * np.log(p / q))"
1562
+ ]
1563
+ },
1564
  {
1565
  "cell_type": "code",
1566
  "execution_count": 3,
 
1585
  },
1586
  {
1587
  "cell_type": "code",
1588
+ "execution_count": 12,
1589
  "metadata": {},
1590
  "outputs": [
1591
  {
 
1594
  "0.16397451204513597"
1595
  ]
1596
  },
1597
+ "execution_count": 12,
1598
  "metadata": {},
1599
  "output_type": "execute_result"
1600
  }
 
1628
  "kl = np.sum(kl_div(p, q))\n",
1629
  "print(f\"KL divergence: {kl}\")"
1630
  ]
1631
+ },
1632
+ {
1633
+ "cell_type": "code",
1634
+ "execution_count": 13,
1635
+ "metadata": {},
1636
+ "outputs": [
1637
+ {
1638
+ "data": {
1639
+ "text/plain": [
1640
+ "0.2051808486854041"
1641
+ ]
1642
+ },
1643
+ "execution_count": 13,
1644
+ "metadata": {},
1645
+ "output_type": "execute_result"
1646
+ }
1647
+ ],
1648
+ "source": [
1649
+ "p= 1\n",
1650
+ "q = 0.8145\n",
1651
+ "kl_divergence(p, q)"
1652
+ ]
1653
+ },
1654
+ {
1655
+ "cell_type": "code",
1656
+ "execution_count": 14,
1657
+ "metadata": {},
1658
+ "outputs": [
1659
+ {
1660
+ "name": "stdout",
1661
+ "output_type": "stream",
1662
+ "text": [
1663
+ "KL divergence: 0.20518085094003724\n"
1664
+ ]
1665
+ }
1666
+ ],
1667
+ "source": [
1668
+ "# For multiple probabilities\n",
1669
+ "p = np.array([1.0, 0.0])\n",
1670
+ "q = np.array([0.8145, 0.1855])\n",
1671
+ "\n",
1672
+ "kl = np.sum(kl_div(p, q))\n",
1673
+ "print(f\"KL divergence: {kl}\")"
1674
+ ]
1675
+ },
1676
+ {
1677
+ "cell_type": "code",
1678
+ "execution_count": 32,
1679
+ "metadata": {},
1680
+ "outputs": [
1681
+ {
1682
+ "name": "stdout",
1683
+ "output_type": "stream",
1684
+ "text": [
1685
+ "[1.e+00 1.e-10]\n"
1686
+ ]
1687
+ },
1688
+ {
1689
+ "name": "stderr",
1690
+ "output_type": "stream",
1691
+ "text": [
1692
+ "/var/folders/gp/02mb1d514ng739czlxw1lhh00000gn/T/ipykernel_28964/3714966623.py:19: RuntimeWarning: divide by zero encountered in log\n",
1693
+ " kl_div = np.sum(p * np.log(p / q))\n",
1694
+ "/var/folders/gp/02mb1d514ng739czlxw1lhh00000gn/T/ipykernel_28964/3714966623.py:19: RuntimeWarning: invalid value encountered in multiply\n",
1695
+ " kl_div = np.sum(p * np.log(p / q))\n"
1696
+ ]
1697
+ },
1698
+ {
1699
+ "data": {
1700
+ "text/plain": [
1701
+ "nan"
1702
+ ]
1703
+ },
1704
+ "execution_count": 32,
1705
+ "metadata": {},
1706
+ "output_type": "execute_result"
1707
+ }
1708
+ ],
1709
+ "source": [
1710
+ "p = 0\n",
1711
+ "q = 1\n",
1712
+ "kl_divergence(p, q)"
1713
+ ]
1714
+ },
1715
+ {
1716
+ "cell_type": "code",
1717
+ "execution_count": 28,
1718
+ "metadata": {},
1719
+ "outputs": [
1720
+ {
1721
+ "name": "stdout",
1722
+ "output_type": "stream",
1723
+ "text": [
1724
+ "KL divergence: 0.010050335853501449\n"
1725
+ ]
1726
+ }
1727
+ ],
1728
+ "source": [
1729
+ "p = np.array([0.0, 1.0])\n",
1730
+ "q = np.array([0.01, 0.99])\n",
1731
+ "\n",
1732
+ "kl = np.sum(kl_div(p, q))\n",
1733
+ "print(f\"KL divergence: {kl}\")"
1734
+ ]
1735
+ },
1736
+ {
1737
+ "cell_type": "code",
1738
+ "execution_count": 23,
1739
+ "metadata": {},
1740
+ "outputs": [
1741
+ {
1742
+ "data": {
1743
+ "text/plain": [
1744
+ "0.17425697504355725"
1745
+ ]
1746
+ },
1747
+ "execution_count": 23,
1748
+ "metadata": {},
1749
+ "output_type": "execute_result"
1750
+ }
1751
+ ],
1752
+ "source": [
1753
+ "p = 0.01\n",
1754
+ "q = 0\n",
1755
+ "kl_divergence(p, q)"
1756
+ ]
1757
+ },
1758
+ {
1759
+ "cell_type": "code",
1760
+ "execution_count": 24,
1761
+ "metadata": {},
1762
+ "outputs": [
1763
+ {
1764
+ "name": "stdout",
1765
+ "output_type": "stream",
1766
+ "text": [
1767
+ "KL divergence: inf\n"
1768
+ ]
1769
+ }
1770
+ ],
1771
+ "source": [
1772
+ "p = np.array([0.01, 0.99])\n",
1773
+ "q = np.array([0.0, 1.0])\n",
1774
+ "\n",
1775
+ "kl = np.sum(kl_div(p, q))\n",
1776
+ "print(f\"KL divergence: {kl}\")"
1777
+ ]
1778
+ },
1779
+ {
1780
+ "cell_type": "code",
1781
+ "execution_count": 25,
1782
+ "metadata": {},
1783
+ "outputs": [
1784
+ {
1785
+ "data": {
1786
+ "text/plain": [
1787
+ "array([0.01, 0.99])"
1788
+ ]
1789
+ },
1790
+ "execution_count": 25,
1791
+ "metadata": {},
1792
+ "output_type": "execute_result"
1793
+ }
1794
+ ],
1795
+ "source": [
1796
+ "epsilon = 1e-10\n",
1797
+ "q = 0\n",
1798
+ "q = np.clip(p, epsilon, 1 - epsilon)\n",
1799
+ "q"
1800
+ ]
1801
+ },
1802
+ {
1803
+ "cell_type": "markdown",
1804
+ "metadata": {},
1805
+ "source": [
1806
+ "# New function"
1807
+ ]
1808
+ },
1809
+ {
1810
+ "cell_type": "code",
1811
+ "execution_count": 47,
1812
+ "metadata": {},
1813
+ "outputs": [],
1814
+ "source": [
1815
+ "def kl_divergence(P, Q):\n",
1816
+ " \"\"\"\n",
1817
+ " Compute KL divergence for a single sample with two prob distributions.\n",
1818
+ "\n",
1819
+ " :param P: True distribution)\n",
1820
+ " :param Q: Approximating distribution)\n",
1821
+ " :return: KL divergence value\n",
1822
+ " \"\"\"\n",
1823
+ " # Review edge cases\n",
1824
+ " if P[0] == Q[0]:\n",
1825
+ " return 0.0\n",
1826
+ " # If P is complete opposite of Q, divergence is some max value.\n",
1827
+ " # Here set to 20--allows for Q [\\mu, 1-\\mu] or Q[1-\\mu, \\mu] where \\mu = 10^-8\n",
1828
+ " if P[0] == Q[1]:\n",
1829
+ " return 20\n",
1830
+ "\n",
1831
+ " nonzero = P > 0.0\n",
1832
+ " # Compute KL divergence\n",
1833
+ " kl_div = np.sum(P[nonzero] * np.log(P[nonzero] / Q[nonzero]))\n",
1834
+ "\n",
1835
+ " return kl_div"
1836
+ ]
1837
+ },
1838
+ {
1839
+ "cell_type": "code",
1840
+ "execution_count": 45,
1841
+ "metadata": {},
1842
+ "outputs": [
1843
+ {
1844
+ "name": "stdout",
1845
+ "output_type": "stream",
1846
+ "text": [
1847
+ "0.0\n"
1848
+ ]
1849
+ }
1850
+ ],
1851
+ "source": [
1852
+ "P = np.array([0.0, 1.0])\n",
1853
+ "Q = np.array([0.0, 1.0])\n",
1854
+ "print(kl_divergence(P,Q))"
1855
+ ]
1856
+ },
1857
+ {
1858
+ "cell_type": "code",
1859
+ "execution_count": 46,
1860
+ "metadata": {},
1861
+ "outputs": [
1862
+ {
1863
+ "name": "stdout",
1864
+ "output_type": "stream",
1865
+ "text": [
1866
+ "20\n"
1867
+ ]
1868
+ }
1869
+ ],
1870
+ "source": [
1871
+ "P = np.array([0.0, 1.0])\n",
1872
+ "Q = np.array([1.0, 0.0])\n",
1873
+ "print(kl_divergence(P,Q))"
1874
+ ]
1875
+ },
1876
+ {
1877
+ "cell_type": "code",
1878
+ "execution_count": 37,
1879
+ "metadata": {},
1880
+ "outputs": [
1881
+ {
1882
+ "name": "stdout",
1883
+ "output_type": "stream",
1884
+ "text": [
1885
+ "20\n"
1886
+ ]
1887
+ }
1888
+ ],
1889
+ "source": [
1890
+ "P = np.array([1.0, 0.0])\n",
1891
+ "Q = np.array([0.0, 1.0])\n",
1892
+ "print(kl_divergence(P,Q))"
1893
+ ]
1894
+ },
1895
+ {
1896
+ "cell_type": "code",
1897
+ "execution_count": 49,
1898
+ "metadata": {},
1899
+ "outputs": [
1900
+ {
1901
+ "name": "stdout",
1902
+ "output_type": "stream",
1903
+ "text": [
1904
+ "0.010050335853501506\n"
1905
+ ]
1906
+ }
1907
+ ],
1908
+ "source": [
1909
+ "P = np.array([0.0, 1.0])\n",
1910
+ "Q = np.array([0.01, 0.99])\n",
1911
+ "print(kl_divergence(P,Q))"
1912
+ ]
1913
+ },
1914
+ {
1915
+ "cell_type": "code",
1916
+ "execution_count": 43,
1917
+ "metadata": {},
1918
+ "outputs": [
1919
+ {
1920
+ "data": {
1921
+ "text/plain": [
1922
+ "0.010050335853501506"
1923
+ ]
1924
+ },
1925
+ "execution_count": 43,
1926
+ "metadata": {},
1927
+ "output_type": "execute_result"
1928
+ }
1929
+ ],
1930
+ "source": [
1931
+ "1 * np.log(1 / 0.99)"
1932
+ ]
1933
+ },
1934
+ {
1935
+ "cell_type": "code",
1936
+ "execution_count": 48,
1937
+ "metadata": {},
1938
+ "outputs": [
1939
+ {
1940
+ "name": "stdout",
1941
+ "output_type": "stream",
1942
+ "text": [
1943
+ "4.605170185988092\n"
1944
+ ]
1945
+ }
1946
+ ],
1947
+ "source": [
1948
+ "P = np.array([1.0, 0.0])\n",
1949
+ "Q = np.array([0.01, 0.99])\n",
1950
+ "print(kl_divergence(P,Q))"
1951
+ ]
1952
+ },
1953
+ {
1954
+ "cell_type": "code",
1955
+ "execution_count": 44,
1956
+ "metadata": {},
1957
+ "outputs": [
1958
+ {
1959
+ "data": {
1960
+ "text/plain": [
1961
+ "4.605170185988092"
1962
+ ]
1963
+ },
1964
+ "execution_count": 44,
1965
+ "metadata": {},
1966
+ "output_type": "execute_result"
1967
+ }
1968
+ ],
1969
+ "source": [
1970
+ "np.log(1/0.01)"
1971
+ ]
1972
  }
1973
  ],
1974
  "metadata": {
scripts/closed_markets_divergence.py CHANGED
@@ -138,24 +138,25 @@ def get_closed_markets():
138
  return markets
139
 
140
 
141
- def kl_divergence(p, q):
142
  """
143
- Compute KL divergence for a single sample with two probabilities.
144
 
145
- :param p: First probability (true distribution)
146
- :param q: Second probability (approximating distribution)
147
  :return: KL divergence value
148
  """
149
- # Ensure probabilities sum to 1
150
- p = np.array([p, 1 - p])
151
- q = np.array([q, 1 - q])
152
-
153
- # Avoid division by zero
154
- epsilon = 1e-10
155
- q = np.clip(q, epsilon, 1 - epsilon)
156
 
 
157
  # Compute KL divergence
158
- kl_div = np.sum(p * np.log(p / q))
159
 
160
  return kl_div
161
 
@@ -165,12 +166,15 @@ def market_KL_divergence(market_row: pd.DataFrame) -> float:
165
  Formula in https://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence"""
166
  current_answer = market_row.currentAnswer # "yes", "no"
167
  approx_prob = market_row.first_outcome_prob
168
- true_prob = 0.99 # for yes outcome (99% is the max we can specify to avoid nan)
169
  if current_answer == "no":
170
- true_prob = 0.01 # = 0.1% for yes outcome and 99% for no
171
 
172
  # we have only one sample, the final probability based on tokens
173
- return kl_divergence(true_prob, approx_prob)
 
 
 
174
 
175
 
176
  def compute_tokens_prob(token_amounts: list) -> list:
 
138
  return markets
139
 
140
 
141
+ def kl_divergence(P, Q):
142
  """
143
+ Compute KL divergence for a single sample with two prob distributions.
144
 
145
+ :param P: True distribution)
146
+ :param Q: Approximating distribution)
147
  :return: KL divergence value
148
  """
149
+ # Review edge cases
150
+ if P[0] == Q[0]:
151
+ return 0.0
152
+ # If P is complete opposite of Q, divergence is some max value.
153
+ # Here set to 20--allows for Q [\mu, 1-\mu] or Q[1-\mu, \mu] where \mu = 10^-8
154
+ if P[0] == Q[1]:
155
+ return 20
156
 
157
+ nonzero = P > 0.0
158
  # Compute KL divergence
159
+ kl_div = np.sum(P[nonzero] * np.log(P[nonzero] / Q[nonzero]))
160
 
161
  return kl_div
162
 
 
166
  Formula in https://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence"""
167
  current_answer = market_row.currentAnswer # "yes", "no"
168
  approx_prob = market_row.first_outcome_prob
169
+ true_prob = 1.0 # for yes outcome
170
  if current_answer == "no":
171
+ true_prob = 0.0 # = 0% for yes outcome and 100% for no
172
 
173
  # we have only one sample, the final probability based on tokens
174
+ # Ensure probabilities sum to 1
175
+ P = np.array([true_prob, 1 - true_prob])
176
+ Q = np.array([approx_prob, 1 - approx_prob])
177
+ return kl_divergence(P, Q)
178
 
179
 
180
  def compute_tokens_prob(token_amounts: list) -> list: