Commit 1f324723
Changed files (17)
examples
embeddings
openai
examples/embeddings/Classification.ipynb
@@ -0,0 +1,130 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Classification using the embeddings\n",
+ "\n",
+ "In the classification task we predict one of the predefined categories given an input. We will predict the score based on the embedding of the review's text, where the algorithm is correct only if it guesses the exact number of stars. We split the dataset into a training and a testing set for all the following tasks, so we can realistically evaluate performance on unseen data. The dataset is created in the [Obtain_dataset Notebook](Obtain_dataset.ipynb).\n",
+ "\n",
+ "In the following example we're predicting the number of stars in a review, from 1 to 5."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ " precision recall f1-score support\n",
+ "\n",
+ " 1 0.82 0.67 0.74 21\n",
+ " 2 0.50 0.50 0.50 6\n",
+ " 3 1.00 0.46 0.63 13\n",
+ " 4 0.75 0.35 0.48 17\n",
+ " 5 0.88 1.00 0.93 143\n",
+ "\n",
+ " accuracy 0.86 200\n",
+ " macro avg 0.79 0.60 0.66 200\n",
+ "weighted avg 0.86 0.86 0.84 200\n",
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "\n",
+ "from sklearn.ensemble import RandomForestClassifier\n",
+ "from sklearn.model_selection import train_test_split\n",
+ "from sklearn.metrics import classification_report, accuracy_score\n",
+ "\n",
+ "df = pd.read_csv('output/embedded_1k_reviews.csv')\n",
+ "df['babbage_similarity'] = df.babbage_similarity.apply(eval).apply(np.array)\n",
+ "\n",
+ "X_train, X_test, y_train, y_test = train_test_split(list(df.babbage_similarity.values), df.Score, test_size = 0.2, random_state=42)\n",
+ "\n",
+ "clf = RandomForestClassifier(n_estimators=100)\n",
+ "clf.fit(X_train, y_train)\n",
+ "preds = clf.predict(X_test)\n",
+ "probas = clf.predict_proba(X_test)\n",
+ "\n",
+ "report = classification_report(y_test, preds)\n",
+ "print(report)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We can see that the model has learnt to distinguish between the categories decently. 5-star reviews show the best performance overall, and this is not too surprising, since they are the most common in the dataset."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "RandomForestClassifier() - Average precision score over all classes: 0.93\n"
+ ]
+ },
+ {
+ "data": {
+ "image/png": "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I+9ynph431RPPvlk1qxZw1tvvcXixYv55S9/2ahNn3/+Oddccw0Ad911F/Pnt1+SKYPBELvohsNh/P5jgVc2m61W24ULF7Jq1Sq+++47LrzwQkATTL/5zW9i9tXkiy++4O233+a3v/0ts2bN4rbbbms3uzsDIQTUESQyECDw3VFCrnKtjcmEsXdv9JFhOEX3xGQykZGRQWlpKWVlZWSoOCiFIqFQnph2Zv/+/fTo0YOrr76aq666ii+++ILJkyfzn//8h+LiYkKhEM899xwzZsxgypQpbN68mc2bN7dawJxyyim8+OKLlETylUSHkwYMGMCmTZsAbZiqqQDFCy+8kOeff55Vq1axcOFCAObMmcOTTz6J2+0G4PDhwzGPTUpKCj/60Y9YsmQJX3yRnMXjavpigiUl+PLzNQEjBIacHMxDhigBowDAbDaTlpaGz+ejvLxcTTtWKBKILueJiTeffPIJ999/P0ajEbvdztNPP02vXr247777+MEPfoCUknnz5nH22Wcft68NGzawYMECysrKePPNN/n973/PN998U6tNXl4et956KzNmzECv13PiiSeyfPlyrr76as4++2zGjh3L3Llz63lf6vZRWVlJbm4uvXr1AuC0005j+/btTJs2DdACg//1r3+xa9culixZgk6nw2g08uijj7Zhb8UPodNETLi6mnB1NQD61FQMvXqhM5niaZoiAbFarYRCISoqKtDpdHH3+CoUCo0uUTtp+/btjBgxIk4WdTzRVPnRKsyKthOqqsK/Zw8AwmjE2KsXutTUDh8qUGUHmknh9kjZgeGxsgNR4nm+V1RU4Ha7SUlJwdlEeYlkZ8N3G7jivSuY2GMiT819Kt7mKBKdfZPBuwH6f96qwN5uXztJoWgpOosFXWoqmEyYcnJUtl1Fs3A4HAghqKysREpJmiozoVDEFSViFN0SodNh7NuXYDCIbGK2kkJRl9SIx66iogIpJenp6UrIKBRxQo1NKLot7VEMUtE9sdvtOJ1OvF4vpaWl6hhSKOKEEjGKbosQAp1Op/J/KFqFzWYjPT0dv99PSUmJOo4UijigREwSoDwGHYcQAiml2reKVmG1WklPTycQCCgho1DEASViuil6vT5W32nhwoVUVVW1uc/bbruN1atXN7p+2bJlPP30023eTnsSne0VvflEa0zt27ePUaNGNfiZgoICzjzzzM4xsB3x+XxceOGFDBkyhClTprBv374G2z300EOMGjWKvLw8Hnzwwdj7v/vd7xgzZgzjxo3jtNNO48iRIwC8+eabSZfwsD2xWCxkZGQQDAZjuaAUCkXnoERMAtORF0Or1crmzZvZunUrJpOJZcuW1VrfmvpTd911F6eeemqj66+99louu+yyFvd7PNpSK0sIEfPGNJe//OUvXH311a3eZnPoiKKD//znP0lPT2fXrl384he/aLAQ6datW3niiSdYv349X331FW+++Sa7du0CYMmSJWzZsoXNmzdz5plnctdddwEwb9483njjjXYRwsmK2WwmMzOTcDhMSUlJtywaqVDEgw4VMUKIuUKIb4UQu4QQSxtpc4EQYpsQ4hshxL870p6O5JxzzmHChAnk5eXx+OOPA5rnYcmSJbE2y5cv5/rrrwfgX//6F5MnT2bcuHFcc801McFit9v51a9+xdixY1m3bh133XUXkydP5sQTT+Taa6+N3Ww3bNgQ+1e8ZMmSmNcgFAqxZMmSWPXpxx577Li2T58+nV27dtWrcN1UX3/84x8ZPXo0Y8eOZelS7aetWTl76dKljBw5kjFjxnDTTTcBtStkb968malTpzJmzJhYQj+AmTNncvPNNzN58mSGDRsWqwJel5kzZ3LjjTcyceJEHnroITZt2sSMGTOYMGECc+bMoaCgAIBdu3Zx6qmnMnbsWMaPH8/u3btxu93MmjWL8ePHM3r0aN58803C4XCzhcxLL73E3LlzAc1jM336dMaPH8/48eP59NNPAS3pYU1vzfXXX8/y5csBGD5nDjffdhujR49m8uTJMZGwePFirr32WqZMmcKvf/3rBm1vC6+99hqLFi0C4Pzzz+fDDz+s9523b9/OlClTSElJwWAwMGPGDF5++WVAm14cxePxxIY5hRDMnDmTN998s032JTvREgVKyCgUnUg0HqC9H4Ae2A0MAkzAV8DIOm2GAl8C6ZHXOcfrd8KECbIu27Ztq/deZ1NSUiKllLKqqkrm5eXJ4uJiWVhYKAcPHhxrM3fuXLl27Vq5bds2eeaZZ0q/3y+llPK6666TK1askFJKCciVK1fW69fn88lLLrlEvv7661JKKfPy8uSnn34qpZTy5ptvlnl5eVJKKR977DH5+9//XkoppdfrlRMmTJB79uypZ6/NZpNSShkIBOT8+fPl3//+d/nxxx/LlJSUWPvG+nr77bfltGnTpMfjqWXjokWL5IsvviiLi4vlsGHDZDgcllJKWVZWJqWU8vbbb5f333+/lFLK0aNHy08++URKKeXvfvc7+fOf/1xKKeWMGTPkL3/5SymllG+99ZacNWtWg/t7xowZ8rrrrpNSSun3++W0adNkYWGhlFLK559/Xl5++eVSSiknT54sX375ZSmllNXV1dLj8chAICBdLpeUUsqioiI5ePBg6fV6ZSgUiu2XvXv3xvZpTfbs2SPHjx8fe+3xeGR1dbWUUsqdO3fK6PH58ccfy3nz5sXa/fSnP5VPPfWU9O3fL/v17i3v+u1vpZRSrlixItZu0aJFct68eTIYDDZqe12+//3vy7Fjx9Z7fPDBB/Xa5uXlyYMHD8ZeDxo0SBYVFdVqs23bNjl06FBZXFwsPR6PnDp1qrz++utj62+55RbZp08fmZeXF9vfUkr5r3/9q1a7NnN0m5SHv5DSX1VvVSKc703h9/vld999JwsKCqTP54u3Oa1ifcF6OWr5KLn4ncXxNkWRDOydJOV2pKz6vFUfBzbKVmqNjswTMxnYJaXcAyCEeB44G9hWo83VwN+klGURQVXY5q3u6KB8DcOb/pf+17/+lVdeeQWAgwcPkp+fz9SpUxk0aBCfffYZQ4cOZceOHZx00kn87W9/Y9OmTUyaNAmA6upqcnJyAC1W5bzzzov1+/HHH/OnP/0Jj8dDWVkZo0aNYvr06VRWVsZKAlx88cWxf8Hvv/8+W7ZsiXlEXC4X+fn5sarVUaqrqxk3bhygeWKuvPJKPv3001oVrhvra/Xq1Vx++eWkpKQA9StnO51OLBYLV155JWeeeWa9+BGXy0V5eTkzZswAYNGiRbGaTQDnnnsuABMmTGg0bgOIFav89ttv2bp1K7NnzwY0b1SvXr2orKzk8OHDLFiwANBiFwACgQC33HILa9asQafTxepCRUsuNEVBQQHZ2dmx14FAgOuvv57Nmzej1+vZuXPncfsAuOj88wH44Q9/yC9+8YvY+wsXLkSv1zdqe10a81S1lhEjRnDzzTdz2mmnYbPZGDduHPoaiQDvuece7rnnHv7whz/wyCOPcOeddwKQk5MTi5Hp7hiNRjIzMyktLaWkpASn0xk7VxQKRfvSkSImFzhY4/UhYEqdNsMAhBD/Q/Pc3CGlfLcDbeoQPvnkE1avXs26detISUlh5syZeL1eAC666CJeeOEFhg8fzoIFC2LxF4sWLeIPf/hDvb4sFkvspuH1evnJT37Cxo0b6dmzJ7///e9j/TaGlJKHH36YOXPmNNkuGhNTl5o1lhrr67333muyb4PBwPr16/nwww9ZtWoVjzzyCB999FGTn6mJ2WwGNEEXdclffvnlfPnll/Tu3Zu33367lq1SSvLy8li3bl2tfiorKxvs/9lnn6WoqIhNmzZhNBoZMGAAPp+vWcNJVqu11m/wf//3f/To0YOvvvqKcDgcExs1q4gD9X63mlK7ZqK0pmpcNURU0NblgQceqBeflJuby8GDB+nTpw/BYBCXy0VmZma9z1555ZVceeWVANxyyy306dOnXptLLrmEM844IyZivF4vVqu1XrvuisFgICsri7KyMsrLywkGg7EkeQqFov2Id2CvAW1IaSbwQ+AJIURa3UZCiB8LITYKITYWFRU13eNw2TGPJnC5XKSnp5OSksKOHTv47LPPYusWLFjAa6+9xnPPPcdFF10EwKxZs1i1ahWFhZrjqbS0lP3799frN3rjy8rKwu12x2IT0tLSSE1N5fPPPwfg+eefj31mzpw5PProo7Gq1Tt37sTj8TS9zxqhsb5mz57NU089FQvkjFbOjuJ2u3G5XJxxxhn83//9H1999VWt9U6nk/T09JgX4Zlnnol5ZRrjqaeeYvPmzTEBU5MTTjiBoqKimIgJBAJ88803pKam0qdPH1599VVAm51TVVWFy+UiJycHo9HIxx9/zP79+9HpdM0SMcOGDavlHXK5XPTq1QudTsczzzwTi23q378/27Zti1U+/vDDD2v180LEa7dy5cqYR60mjdlel7Vr18Yqodd8NBRgPX/+fFasWAHAqlWrOOWUUxq8qUaPywMHDvDyyy9z8cUXA5Cfnx9r89prrzF8+PDY6507dzY6m6u7otPpyMjIwGaz4Xa7KS0tVVOwFV2czj++O9ITcxjoW+N1n8h7NTkEfC6lDAB7hRA70UTNhpqNpJSPA4+DVgCywyxuJXPnzmXZsmWMGDGCE044galTp8bWpaenM2LECLZt28bkyVphrJEjR3L33Xdz2mmnEQ6HMRqN/O1vf6N///61+k1LS+Pqq69m1KhR9OjRgwkTJsTW/fOf/+Tqq69Gp9MxY8aMWFXdq666in379jF+/HiklGRnZ8duhC2l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bBEREcbtN954Q997771648aN+mc/+5meOHGi7tGjh3a5XPqRRx7Rqampunfv3nrZsmXGYxYtWqR79eqlU1JS9OOPP6611nrGjBn6ww8/1Fpr/fjjj+urrrpK9+rVSz/00ENaa62ffvpp/eKLL2qttf7+++/14MGDde/evfWUKVN0Tk6O1lrrkSNH6scee0wPHDhQ9+jRQ3/99ddVln/kyJH6gQce0AMGDNBLlizRO3fu1CNGjND9+/fX1157rT516pTWWuuDBw/qsWPH6pSUFN2vXz996NAhXVBQoMeMGaP79eune/XqpdesWVPpuBw9elQnJydXet6JEydqk8mk+/Tpo99//3199OhRPXr0aN27d289ZswYfezYMeNY3HPPPXrQoEHG3+/jcrn0ww8/rJOTk3Xv3r31q6++avxNO3bs0FprPXfuXD1gwADds2dPvWDBAuOxvuPau3dv/fDDD2uttV61apVOTk7WKSkpevjw4dW95JW4XC5tt9v12bNndefOnfXJkycDetwTTzyh33nnHeN+dWW99NJLdWZmptZa6x07duiRI0dqrb3vg9tuu00PGTJEd+/eXS9fvlxrrY3334033KC7X3qpLty7t8rjVFd//vOf9d13323cv/vuu/Wf//znarf3eDy6U6dO+sCBA1rr6t8TWmudk5NT7brm8P8eVHLStX46WuuXegX8kO2nt+teK3rpmetmNmDBqldaWqpzcnL0qVOn9MmTJ3VGRobOz8/XTqezScoj6knpD1r/GKn1PrTO/l9jMbBT1zETBPpz9nFgDvBv4B7gM+D3Fx+hWh6Xy8W6deu4/vrrAfjuu+/Ys2cPXbt2Zfny5cTExLBjxw7sdjvDhg3j2muvZf/+/axdu5Zt27YZE/P5y87OZvXq1ezbtw+Xy1XlbNJ33HEHS5cuZeTIkSxYsICFCxfy8ssvG2Xavn07n332GQsXLmTDhg1Vlt3hcLBz506cTicjR45k7dq1JCQk8MEHH/DUU0/xdtnkgfPmzWPq1KnGXE42m43Vq1cTHR1NVlYWQ4YMYdKkSQFVBX/yySdERkYav8YnTpzIjBkzmDFjBm+//Tb3338/a9asAbyzJG/ZsqVSjc3y5ctJT09n165dxgSQFT333HO0adMGt9vN2LFj2b17Nx07dmT16tXs378fpRS5ubmAtwZs/fr1dOzY0VgWiFOnTjFhwgQOHz7MCy+8QIcOHQJ63ObNm/n5z39eY1lrGwhv9+7dfPvttxQVFdGvXz9jbqXvvvuO3WlpdHC5eOuDD2o9Ti+++GK5GiafESNG8Oqrr5ZbdvLkSTp37mzc79SpEydPnqy2jN988w1JSUn06NHDWHb06FH69etHdHQ0v/71r40JP+Pi4rDb7WRnZ5ebfFO0Dr65mjweD6WlpZSUlFBQUEBBQQFWq9WooZGzm4JMSE9o9w6cmgZnH4HQ/hA+4qJ2WWuIUUqZgR+01lcCb13UszWC3it7N8h+/z3j3zWuLykpMSb7Gz58OLNnz2bLli0MGjSIrl27AvD3v/+d3bt3GzMQ5+XlcfDgQTZs2MCdd95p9KGpOLNwTEwMoaGhzJ49m/HjxzNxYvn5OPPy8sjNzTUm0ZsxYwbTpk0z1t90k3cS8gEDBlSaFNDfrbfeCsCPP/7Inj17GDduHOCds6l9+/YUFBRw8uRJpk6dCnjnSwFwOp08+eSTfP3115hMJk6ePElGRkadJu/bunUrH3/snVf09ttv57HHHjPWTZs2rcoPrQ0bNjB37lyjiani8QNYtWoVy5cvx+Vycfr0afbu3UvPnj2N43rjjTdy443eYe6HDRvGzJkzueWWW4xjF4jOnTvzr3/9i+PHjzNt2jSmTZtGUlLtHdhOnz5NQkJCjWWtLcRMnjzZ+GAfPXo027dvJzY21nj/2Q8e5KutW/nlI4/UeJweffRRHn300YD/5gvxl7/8pVxYa9++PcePH6dt27akpaUxZcoUfvjhB6KjowFITEzk1KlTEmJaMZPJRHh4OOHh4bjdbiPQ5Ofnk5+fT0hICGFhYYSGhsqZgcEi+mYofQRylkD28w0fYrTWbqXUj0qpS7TWMrlLNfz7xPiLiDjfeUlrzdKlS7nuuuvKbbN+fc1D7lgsFrZv386XX37JqlWreOONN9i4cWPAZQsJ8Z6R4DsVGODOO+/k+++/p0OHDnz22Wflyqq1Jjk5ma1bt5bbT1U1QADvvfcemZmZpKWlYbVa6dKlC6WlpQGXL1D+x/JCHD16lCVLlrBjxw7i4uKYOXMmpaWl5Y7rRx99xGuvvcZXX33FsmXL2LZtG59++ikDBgwgLS0t4C9Sk8lEp06dSE5O5h//+Ae33FJ7B9SwsDDjeFVXVvC+D3zDuFc8vhVrvXz3L/SYXUhNTMeOHdm0aZNx/8SJE4waNarK/bpcLj7++GPS0tKMZb5f2+AN2JdddhkHDhwwOmKXlpYSFhZW5f5E6+MbXyYiIgKXy0VJSQklJSXk5uailCIkJMToXyOBppmLnOwNMZ7Ci95VoM1JccAPSqntQJFvodZ60kWXoJ7VVmPSlK677jreeOMNxowZg9Vq5cCBA3Ts2JFx48bx7LPPMn36dKM5yf9XcmFhIcXFxUyYMIFBgwYZZ3P4xMTEEBcXxzfffMPw4cN59913jVqZ6rzzTuWZaX2uuOIKMjMz2bp1K1dffTVOp5MDBw6QnJxMp06dWLNmDVOmTMFut+N2u8nLyyMxMRGr1crGjRs5dqyKM0oCNHToUN5//31uv/123nvvPaN5oSbjxo3jzTffZPTo0UYzif/xy8/PJyIigpiYGDIyMli3bh2jRo0qd1yHDRtmdKw9fPgwgwcPZvDgwaxbt46ffvqp1hBz4sQJ2rZtS1hYGPn5+WzevJkHHnggoL/5qquu4tChQ3Tp0qXasgJ06dKFtLQ0xo8fz1//+tdy+1i7di1PPPEERUVFbNq0iUWLFnHgwIFy24wdOrTG4wQXVhNz3XXX8eSTT3Lu3DnAW9P4m9/8psptN2zYwJVXXkmnTp2MZZmZmbRp0waz2cyRI0c4ePCg8RporTlz5gxdunQJqCyidbFYLERFRREVFYXT6TQCTWlpKUopbDab1NC0EoGGmPkNWopWYs6cOaSnp9O/f3+01iQkJLBmzRquv/56du3aRWpqKjabjQkTJvD8888bjysoKGDy5MlGH5SqTkNeuXIlc+fOpbi4mG7dutUYUmpjs9n46KOPuP/++415Tx588EGSk5N59913ueeee1iwYAFWq5UPP/yQ6dOnM3HiRHr37k1qaipXXnllnZ976dKl3Hnnnbz44oskJCQE9HfMmTOHAwcOkJKSgtVq5a677uK+++4z1vfp04d+/fpx5ZVX0rlzZ4YN804L739ctda89NJLgPeL/ODBg2itGTt2LH361H4mzL59+3j44YdRSqG15uGHHyY5OTmgAfBuuOEGNm3axDXXXFNtWQGefvppZs+ezfz58yvVeKSkpDB69GiysrKYP38+HTp0qBRi7pw2jaN5edUepwvVpk0b5s+fz8CB3lE4FyxYYISiOXPmMHfuXKNW5f333y/XlATw9ddfG+8jk8nEsmXLjMenpaUxZMiQJj8LTTR/VqsVq9VKdHQ0DoeD0tJSSktLjf5s/jU00oem5VG6honrlFKhwFygO95OvX/QWjfpTF6pqal6586d5Zbt27ePq666qolK1LicTidKKflwb+a01kbTncViqbGTc0lJCaNHj2bz5s11+pB95plniIyM5JFHHqlyvcdux37wIMpmI/Tyyy94/03hgQceYNKkSYwdW3k8zdb0/14vzh2DV1Ig5hJ4KLCa6h1ndjBr/SxSk1J55/q6/yBqSk6n0+hD4/tftNlsRqBpKZ+hr776Km+88QY9e/bk1KlTfPfddzz33HPVfh5UJScnh1tvvZX09HS6dOnCqlWrKg2VAHD8+HHmzJnDTz/9hFKKzz77rG61pcX/hOPDIWwYXPpPlFJpWus6DehV26u4EnAC3wDjgZ5AYHXkQrRiSqly0xHUFE7CwsJYuHAhJ0+e5JJLLmnEUjZfvXr1qjLACBEoXw1NVFSU0YemtLTU6BRssViMWhqbzRa0A+u9/vrrbNiwAZvNxrFjx4yzOS/EokWLGDt2LPPmzWPRokUsWrSIxYsXV9rujjvu4KmnnmLcuHEUFhY2i6a62kJMT611bwCl1B+A7Q1fJCFaBpPJhMlkwu12GxNFVqdiZ+8L8cwzz9T5sc3VXXfd1dRFEC2Ifx8a31lOvpGCi4qKMJlMRqAJCQlpFl/OgZg7dy5Hjhxh/PjxzJo1i4ceeohPP/30gvezdu1ao5P+jBkzGDVqVKUQs3fvXlwul3HWamRk5EWXvz7UFmKcvhtaa1ewJtWWxNfnQgQHs9mM1hq3291iqq+FCGb+ZzlprbHb7UaoKSkpAc43O4WEhGC1Wpu4xNVbtmwZn3/+ORs3biQ+Pr7a7YYPH17l2aVLlizhmmuuISMjg/bt2wPQrl07MjIyKm174MABYmNjuemmmzh69CjXXHMNixYtavJ+RrV9qvZRSuWX3VZAWNl9BWitdXSDlk6IIKeUMmpjZJZrIZoX/2kPwDvgpy/U5Od7v/rMZrMxHEAw1dL4++abbwLe1jehbUUul4tvvvmG77//nksuuYRbb72VFStWMHv27Pos6gWrMcRoraUrtxAXyWQy4fF4cLvd1X5ACCGans1mw2azGc1OdrvdCDXFxcWAt6+NL9AES1+a2mpikpKSOH36NO3bt+f06dMkJlae37lTp0707dvXGAZhypQpfPvtt807xAghLt6FdPIVQjQPZrPZGC1Yl81O7ws1RUVFFBYWGoPs+QJNc216qq0mZtKkSaxcuZJ58+axcuVKJk+eXGmbgQMHkpubS2ZmJgkJCXz11VfGEApNKfjqxYRoYvn5+QwfPrzKduOq3HbbbXz11VdGs5L0aRIiuPgG0IuKiiI+Pp6kpCTatGlDeHg4LpeLvLw8MjMzOXPmDOfOnaOoqMg4rbuxnDlzhk6dOvHSSy/x61//mk6dOhlNYrWZN28eX3zxBT169GDDhg3MmzcPgJ07dzJnzhzAG+qWLFnC2LFj6d27N1rrZtEBX0JMPTGbzfTt25devXoxbdo0o+rxYixYsKDSZI3+HXuXLVvGH//4x4t+nobk68Genp5Or169qtzm0UcfJTk5ud7n7Bk1ahQVxxSqD9HR0bz11lv86le/qrQuPz+fTp06lRtEbvny5bzyyitGda7b7a70uJtvvpkjR47Ue1kb2sqVK+nRowc9evRg5cqVVW7zzDPP0LFjR/r27Uvfvn2NaS58jh8/TmRkJEuWLAG8/RJGjBjR6F8CQgTKZDIRGhpKTEwMiYmJJCUlERsbS2hoKA6Hg7y8PM6ePUtGRga5ubkUFxdX+X9fH9LT04mPj6ddu3acOHGC/Px8cnNzOXHihDEPWW3atm3Ll19+aczl5xt0MjU1ld///vxcz+PGjWP37t38+9//ZsWKFdhstgb5my6ENCfVE/+5k6ZPn86yZcvKfcm5XK4LPjvl2WefrXad1pq5c+fWqay1qUtZL8by5cvJyckJuJmlsctXlSuvvLLKOYbmz5/PiBHlJzQLDw/n//7v/wBvgKnYyfeHH37A7XYbbc0NweVyYa3nD5ycnBwWLlzIzp07UUoxYMAAJk2aVOUgWQ899FC1g2/96le/Yvz48cZ9m83G2LFj+eCDD5g+fXq9llmIhuDf9ATe/ze73W6MIOz7UWs2m41+NyEhIU3+OdYSSE1MAxg+fDiHDh1i06ZNDB8+nEmTJtGzZ0/cbjePPvooAwcOJCUlhTfffNN4zOLFi+nduzd9+vQxqvJmzpxpzHg9b948evbsSb9+/Xj88ccB7y9c36/XXbt2MWTIEFJSUpg6daoxn82oUaN4/PHHGTRoEJdffnm1baOjRo3iwQcfJDU1lVdeeYW0tDRGjhzJgAEDuO666zh9+jQAhw4dMobH79+/P4cPH6awsJCxY8fSv39/evfuzdq1awM+VpMmTaKwsJABAwbwwQcfkJ6ezpgxY0hJSWHs2LEcP37cOBZz585l8ODB5Wa2Bm8weOSRR+jVqxcpKSksXbq00vPce++9pKamkpyczNNPP20s9x3XlJQU40v2ww8/pFevXvTp06dSIKlJWloaGRkZXHvttdVu4xsvxr9Z6b333ivXBl1dWbt06UJWVhbgreb1TT3wzDPPcPvtt3P11VfTo0cP3nrLO9m87/03+T/+g/5TpgR0nC7E+vXrGTduHG3atCEuLo5x48bx+eefX9A+1qxZQ9euXUlOTi63fMqUKVWGRCGCgcViISIigri4ONq1a0dCQgIxMTHYbLZyNTVnzpwhJyeHwsJCnE6nNDXXgcTAeuZyuVi3bh3XX389AN999x179uyha9euLF++nJiYGHbs2IHdbmfYsGFce+217N+/n7Vr17Jt2zZjAkh/2dnZrF69mv379+PxeMjOzq70vHfccQdLly5l5MiRLFiwgIULF/Lyyy8bZdq+fTufffYZCxcurNRE5eNwONi5cydOp5ORI0eydu1aEhIS+OCDD3jqqad4++23mT59OvPmzWPq1KnGXE42m43Vq1cTHR1NVlYWQ4YMYdKkSQH12v/kk0+IjIw0arEmTpzIjBkzmDFjBm+//Tb333+/MQLliRMn2LJlS6Uam+XLl5Oens6uXbuMiQ0reu6552jTpg1ut5uxY8eye/duOnbsaBxXpZQx18qzzz7L+vXr6dixo7GsNh6Ph4cffpg//elP1R5fwJgywuVyGTVKmzdvLjevUFVlTUlJqfH5d+/ezbfffktRURH9+vXjhhtuALzvv91paXRwuXirLCTWdJwuZBbrkydP0rlzZ+N+p06dOHnyZJXle+211/jjH/9Iamoqv/3tb4mLi6OwsJDFixfzxRdfGGHcp1evXuzYsaPGv1mIYOEbPdg3q7zL5cLhcBgX36z0vr43votvXjFRvRYXYvZd2TBzqly1f1+N60tKSujbty/grYmZPXs2W7ZsYdCgQXTt2hXwzvK7e/duo3YlLy/PaIO88847jarIijMLx8TEEBoayuzZs5kwYYIRkHzy8vLIzc01Zq6eMWMG06ZNM9bfdNNNAAwYMID09PRq/4Zbb70VgB9//JE9e/YYIzO63W7at29PQUEBJ0+eZOrUqQDG2ApOp5Mnn3ySr7/+GpPJxMmTJ8nIyKBdu3Y1HrOqbN26lY8//hiA22+/vVyty7Rp06psctqwYQNz5841qmYrHj+AVatWsXz5clwuF6dPn2bv3r307NnTOK433ngjN954IwDDhg1j5syZ3HLLLcaxq83rr7/OhAkTys3SXB3/s5XcbjenT58mISGhxrLWFmImT55MWFgYYWFhjB49mu3btxMbG2u8/+wHD/LV1q388pFHajxOFzKLdaDuvfde5s+fj1KK+fPn8/DDD/P222/zzDPP8NBDD1U58qev2r2goICoqKh6LY8QTc1isWCxWIzPfLfbXS7U+J8ObbFYygUbaYIqT45GPfHvE+PPl7zB249l6dKllYaYX79+fY37tlgsbN++nS+//JIPP/yQ3/3ud3z55ZcBly0kJATA+OIEuPPOO/n+++/p0KGD0dHSV1atNcnJyWzdurXcfqoaZwC8zSGZmZmkpaVhtVrp0qWL8cuiPvkfywtx9OhRlixZwo4dO4iLi2PmzJmUlpaWO64fffQRr732Gl999RXLli1j27ZtfPrppwwYMIC0tDTatm1b43Ns3bqVb775htdff53CwkIcDgeRkZEsWrSoyu1NJhNmsxm3201YWJhxvKorK3jfBx6PB6DS8a1Y6+W7f6HH7EJqYjp27GgMVQ7emrKKs2sDJCUlGbfvuusuIyxu27aNjz76iMcee4zc3Fyjs6SvU7TdbjeCsmgaGcUZbDi2ge6x3ekc1RmzSYYHaAhms9n4EQLeml2n04nD4TAmsvT1qzGZTFitVqmtKdPiQkxtNSZN6brrruONN95gzJgxWK1WDhw4QMeOHRk3bhzPPvss06dPN5qT/H8lFxYWUlxczIQJE7j66qvp3r17uf3GxMQQFxfHN998w/Dhw3n33XeNWpnqvPNO9TPTXnHFFWRmZrJ161auvvpqnE4nBw4cIDk5mU6dOrFmzRqmTJmC3W7H7XaTl5dHYmIiVquVjRs3cuzYsTofo6FDh/L+++9z++2389577zF8+PBaHzNu3DjefPNNRo8ebTST+B+//Px8IiIiiImJISMjg3Xr1jFq1Khyx3XYsGFGx9rDhw8zePBgBg8ezLp16/jpp59qDTH+X/wrVqxg586d1QYYH9+UBFdccQUHDhygS5cu1ZYVvH1i0tLSGD9+PH/961/L7Wvt2rU88cQTFBUVsWnTJhYtWsSBAwfKbTN26NAajxNcWE3Mddddx5NPPmn0v/r73//Ob37zm0rb+QbRAli9erVxlpp//yzfTNy+AJOdnU18fHyzHXejpYuyeWu/fir4iYc2PQSAzWSjW2w3Lou9jO6x3ekR24PLYi+jQ2QHTKr1fok2BN9cTr4foFC+CcrpdFaqrfE1WfmCTTAMwlcfWlyIac7mzJlDeno6/fv3R2tNQkICa9as4frrr2fXrl2kpqZis9mYMGECzz//vPG4goICJk+eTGlpKVprXnjhhUr7XrlyJXPnzqW4uJhu3brVGFJqY7PZ+Oijj7j//vvJy8vD5XLx4IMPkpyczLvvvss999zDggULsFqtfPjhh0yfPp2JEyfSu3dvUlNTufLKK+v83EuXLuXOO+/kxRdfJCEhIaC/Y86cORw4cICUlBSsVit33XVXuVOc+/TpQ79+/bjyyivp3Lkzw4YNAyof15deegnwfpEfPHgQrTVjx46lT58+df57amM2mxk/fjwbN25k3Lhx1ZYV4Omnn2b27NnMnz+/Uo1HSkoKo0ePJisri/nz59OhQ4dKIebOadM4mpdX7XG6UG3atGH+/PkMHDgQ8A4J4AtFc+bMYe7cuaSmpvLYY4+xa9culFJ06dKlXIf26mzcuNHo1yMa3xVxV/Dq6Ff57ux3HMo9xKHcQ5wpOsP+nP3sz9lfbtswSxiXxVxG97judI/1Xi6LvYyk8KRW80XaGCo2Qflqa3wXh8NhzP0E5/vh+IKNxWJpka+HCrbe0Kmpqbri2B/79u3jqqsapi9Mc+PxeIwOoa25CrElKSoqYsyYMXz99dflfnkFyleLUd0pzB67HfvBgyibjdDLL7/Y4jaKm266iUWLFnF5FeVtTf/v9eLcMXglBWIugYf+XefdFDgKOJx7mMO5hzmUe4iDuQc5nHuYrJKsKrePskbRPa67UXPju7QNq7lWU9Sd2+0uF2qcTqfRBO07qcA/3DRZjU3xP+H4cAgbBpf+E6VUmta6TsP/Sk2MEE0sIiKCp59+mp9++omuXbu2+mkJHA4HU6ZMqTLAiKYTZYuib2Jf+ib2Lbc8tzTXqK3xv+TZ8/j+7Pd8f/b7ctvHhcSVq7Xx1dzEhMQ04l/TMpnNZsxmc7m+ZC6Xq1yNjX//GjjfcdhqtRohJ5h+IEuICTK+1BxsNWiiZhMmTDDOVvLNfB2oZ555puEK1gRsNht33HFHUxdDBCg2NJbUdqmktjv/Q1prTXZptjfQnCsfbs7Zz7HjzA52nCl/Cn1iWKK31ibufH+by2IvI8Jatw79wsvXDOXrNAzla2x8c0L5Bxuz2WzU1PiCjdlsbpbNURJihGgmfB19ZbZrEeyUUsSHxRMfFs+Q9kOM5VprMoozOHjO2xTla5I6nHuYsyVnOVtylq2ny58V2SGig9Es1SO2B91ju9M1piuhFjlzra6qqrFxu93lam18ow77fjArpcqFmuZSayMhRohmoqqB8CTIiJZEKUW7iHa0i2jH8E7nzzz0aA8nC09WqrU5mneUU0WnOFV0iq9PfG1sH24JZ8X1K7iqrfSNqi++YOPfL09rXSnYVGyOMpvN5YKN73ZjfXZJiBGiGak4EJ4MbCVaA5My0TmqM52jOjP6ktHGcpfHxfGC497OxGUBZ8eZHZyzn2N/zn4JMQ3MV/tScagD/1ob33VRUVG5bg6+QFPxUt81N/IJGWTkl3nL5z8QntvtbvUdfUXrZTFZ6BbTjW4x3Rh3qXcE8fmb57Pm0JqmLVgrV12tTcVwU7FJyvfYUJ1HDOD2eHA7HBdVluDpgiwMSinp2NuE8vPzGT58OBkZGQFt/+STT5abzj4QJpMJk8lkBBkhhGjOfM3hoaGhREVFERcXR0JCAu3atSMxMZE2bdoQHR2NzWYzTvt2uVzGpLZ1JSGmnpjNZvr27UuvXr2YNm1auTbDulqwYEGNkwkuW7aMP/7xjxf9PA3JNy9Oenq6MVJrRY8++ijJycn1PmfPqFGjqDimUH2Ijo7mrbfe4le/+lW55b73QN++fZk0aZKx/Ne//jV///vfOXr0aLX7fPDBB/n66/Nt/r5mJV+Q8f3TNzeff/45V1xxBd27d692hOJjx44xduxYUlJSGDVqFCdOnDDWPfbYYyQnJ3PVVVdx//33G+H8mmuuMUYCFkIEL/9wExkZSVxcHHGxcQDYrNYq53C7IFrroLoMGDBAV7R3795KyxpbRESEcfsXv/iF/u1vf1tuvdPprLfncjgc9bq/iupz377jcvToUZ2cnFzlNtHR0drlcgW8z0DLN3LkSL1jx46A93ux/N8DFyIrK0sPHjy4ynUej0c7nU5tt9u12+2u0/7dpaW6aPduXbRvX50eXx2Xy6W7deumDx8+rO12u05JSdE//PBDpe1uvvlmvWLFCq211l9++aW+7bbbtNZab968WQ8dOlS7XC7tcrn0kCFD9MaNG7XWWq9YsUL/+te/rvJ5m8P/e1DJSdf66WitX+rV1CWpF//vn/9P91rRS3984OOmLoqoq6JvtN6H1unDtNZaAzt1HTOB1MQ0gOHDh3Po0CE2bdrE8OHDmTRpEj179sTtdvPoo48ycOBAUlJSyg2/vnjxYnr37k2fPn2YN28eADNnzjRmvJ43bx49e/YkJSWFxx9/HPCOD7JkyRIAdu3axZAhQ0hJSWHq1KnGr9hRo0bx+OOPM2jQIC6//PJy89X4GzVqFA8++CCpqam88sorpKWlMXLkSAYMGMB1113H6dOnATh06BDXXHMNffr0oX///hw+fJjCwkLGjh1L//796d27N2vXrg34WE2aNInCwkIGDBjABx98QHp6OmPGjCElJYWxY8dy/Phx41jMnTuXwYMHl5vZGrydzB555BF69epFSkoKS5curfQ89957L6mpqSQnJ/P0008by/2Pq2/E2w8//JBevXrRp08fRowYEfDfUld//etfy81M/uyzzzJw4EB69erFPffcg8lkQillzE4NkJWVRZcuXQDvXE2TJ09m1KhR9OjRg4ULFwLe2q8rrriCGbNmkTp1Kj+dPl3l+6yutm/fTvfu3enWrRs2m43//M//rPK137t3L2PGjAFg9OjRxjZKKUpLS3E4HNjtdpxOpzFZ5KRJk/jLX/5yUeUTQrR80rG3nrlcLtatW2d8KX333Xfs2bOHrl27snz5cmJiYtixYwd2u51hw4Zx7bXXsn//ftauXcu2bduMCSD9ZWdns3r1avbv349SiqysrEp9Yu644w6WLl3KyJEjWbBgAQsXLuTll182yrR9+3Y+++wzFi5cWG0TlcPhYOfOnTidTkaOHMnatWtJSEjggw8+4KmnnuLtt99m+vTpzJs3j6lTp1JaWorH48Fms7F69Wqio6PJyspiyJAhTJo0KaBOyJ988gmRkZHGDOATJ05kxowZzJgxg7fffpv777+fNWvWAN5Zkrds2VKpo+vy5ctJT09n165dxsSGFT333HO0adMGt9vN2LFj2b17Nx07dix3XHNzcwFviFi/fj0dO3Y0lgWitLSU1NRULBYL8+bNY8qUKQE9bvPmzdx8883G/fvuu48FCxYAcPvtt/Ppp58aMz9X17S0fft29uzZQ3h4OAMHDuSGG24gPj6egwcP8s5bb9HviSf4+9atNb7PwDuR5Ysvvlhpeffu3Y1A7XPy5Ek6d+5s3O/UqRPbtm2r9Ng+ffrw8ccf88ADD7B69WoKCgrIzs7m6quvZvTo0bRv3x6tNffdd58xnUBcXBx2u53s7OxaJ98UQrReLS7E/G7uVw2y318uG1Pj+pKSEvr27Qt4a2Jmz57Nli1bGDRoEF27dgW8s/zu3r3b+DLIy8vj4MGDbNiwgTvvvNOY2KtiG2FMTAyhoaHMnj2bG2+8kfHjxxtVab795ObmGjNXz5gxg2nTphmPv+mmmwAYMGAA6enp1f4Nt956KwA//vgje/bsYdw479kAbreb9u3bU1BQwMmTJ5k6dSqAMVCS0+nkySef5Ouvv8ZkMnHy5EkyMjJo165djcesKlu3buXjjz8GvF/g/rUu06ZNq/JMnQ0bNjB37lzjdOSq2lhXrVrF8uXLcblcnD59mr1799KzZ89yx9UXFIYNG8bMmTO55ZZbjGMXiGPHjtGxY0eOHDnCmDFj6N27N5dddlmtjzt9+jQJCQnG/Y0bN/LCCy9QXFxMTk4OycnJTJw40RgAz+VyVQoy48aNM77sb7rpJv75z38yZcoULr30UoYMHoz94EG+2rq1xvcZwPTp05k+fXrAf3MglixZwn333ceKFSsYMWIEHTt2xGw2c+jQIfbt22f0kRk3bpwxEztAYmIip06dkhAjhKhWiwsxTSUsLMyoTfAXEXF+yGytNUuXLuW6664rt8369etr3LfFYmH79u18+eWXfPTRRyxdurTWx/jznQbnG38E4M477+T777+nQ4cOfPbZZ+XKqrUmOTmZrVvLj5zpP/W7v/fee4/MzEzS0tKwWq106dKF0tLSgMsXKP9jeSGOHj3KkiVL2LFjB3FxccycOZPS0tJKx/W1117jq6++YtmyZWzbto1PP/2UAQMGkJaWFtAXaceOHQHo1q0bo0aN4vvvvw8oxISFhRnHq7S0lP/6r/9i586ddO7cmWeeecZY5xv8TilFYWFhuX1UrPXy3b/QY3YhNTEdO3bkp59+Mu6fOHHCOAb+OnToYATTwsJC/vrXvxIbG8tbb73FkCFDjM7f48ePZ+vWrUaIKS0tLTdUuhBCVNTiQkxtNSZN6brrruONN95gzJgxWK1WDhw4QMeOHRk3bhzPPvss06dPN6r5/X8lFxYWUlxczIQJExg2bBjdunUrt9+YmBji4uKMX7HvvvuuUStTnXfeeafadVdccQWZmZls3bqVq6++GqfTyYEDB0hOTqZTp06sWbOGKVOmYLfbcbvd5OXlkZiYiNVqZePGjRw7dqzOx2jo0KG8//773H777bz33nvGF1pNxo0bx5tvvsno0aON5iT/45efn09ERAQxMTFkZGSwbt06Ro0aVe1xPXz4MIMHD2bw4MGsW7eOn376qdYQc+7cOcLDwwkJCSErK4vNmzdX6rtTnauuuopDhw4xatQoI7DEx8dTWFjIRx99ZDQ1denShe+++45BgwaxevVqAKNG5osvviAnJ4ewsDDWrFnD22+/Xel5xg4dyqKyJsGq3mdwYTUxAwcO5ODBgxw9epSOHTvy/vvv8+c//7nSdllZWbRp0waTycRvfvMbZs2aBcAll1zCW2+9xRNPPIHWmn/84x88+OCDgDdInzlzxuj3I4QQVWlxIaY5mzNnDunp6fTv3x+tNQkJCaxZs4brr7+eXbt2kZqais1mY8KECTz//PPG4woKCpg8eTKlpaVorfntb38LlJ8EcuXKlcydO5fi4mK6detWY0ipjc1m46OPPuL+++8nLy8Pl8vFgw8+SHJyMu+++y733HMPCxYswGq18uGHHzJ9+nQmTpxI7969SU1N5corr6zzcy9dupQ777yTF198kYSEhID+jjlz5nDgwAFSUlKwWq3cdddd3Hfffcb6Pn360K9fP6688ko6d+7MsGHDgMrH9aWXXgK8p3wfPHgQrTVjx46lT58+tZZh3759Ridcj8djdBgOxA033MCbb77JnDlziI2N5a677qJXr160a9eOgQMHGts98sgj3HLLLSxfvpwJEyYAGE1LgwYN4j/+4z84ceIEt912G6mpqZWaDq8dMYK9WVnVvs8ulMVi4bXXXuO6667D7XYza9YskpOTAe/wAKmpqUyaNIlNmzbxxBNPoJRixIgR/O53vwPg5ptv5quvvqJ3794opbj++uuZOHEiAGlpaQwZMkRGLBZC1EhV7CBarztX6nrgFcAM/F5rXeVAEkqp/wA+AgZqrWsc2CM1NVVXHPtj3759RofA1sLpdBrn34vg97Of/Yy//e1vxMbGBvwYXTavycqVK/n++++NcFCRx27H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",
+ "text/plain": [
+ "<Figure size 648x720 with 1 Axes>"
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "from utils import plot_multiclass_precision_recall\n",
+ "\n",
+ "plot_multiclass_precision_recall(probas, y_test, [1,2,3,4,5], clf)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Unsurprisingly 5-star and 1-star reviews seem to be easier to predict. Perhaps with more data, the nuances between 2-4 stars could be better predicted, but there's also probably more subjectivity in how people use the inbetween scores."
+ ]
+ }
+ ],
+ "metadata": {
+ "interpreter": {
+ "hash": "be4b5d5b73a21c599de40d6deb1129796d12dc1cc33a738f7bac13269cfcafe8"
+ },
+ "kernelspec": {
+ "display_name": "Python 3.7.3 64-bit ('base': conda)",
+ "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.7.3"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
examples/embeddings/Clustering.ipynb
@@ -0,0 +1,262 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Clustering\n",
+ "\n",
+ "We use a simple k-means algorithm to demonstrate how clustering can be done. Clustering can help discover valuable, hidden groupings within the data. The dataset is created in the [Obtain_dataset Notebook](Obtain_dataset.ipynb)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 31,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(1000, 2048)"
+ ]
+ },
+ "execution_count": 31,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "\n",
+ "\n",
+ "df = pd.read_csv('output/embedded_1k_reviews.csv')\n",
+ "df['babbage_similarity'] = df.babbage_similarity.apply(eval).apply(np.array)\n",
+ "matrix = np.vstack(df.babbage_similarity.values)\n",
+ "matrix.shape"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 1. Find the clusters using K-means"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We show the simplest use of K-means. You can pick the number of clusters that fits your use case best."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 34,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "Cluster\n",
+ "2 2.543478\n",
+ "3 4.374046\n",
+ "0 4.709402\n",
+ "1 4.832099\n",
+ "Name: Score, dtype: float64"
+ ]
+ },
+ "execution_count": 34,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "from sklearn.cluster import KMeans\n",
+ "\n",
+ "n_clusters = 4\n",
+ "\n",
+ "kmeans = KMeans(n_clusters = n_clusters,init='k-means++',random_state=42)\n",
+ "kmeans.fit(matrix)\n",
+ "labels = kmeans.labels_\n",
+ "df['Cluster'] = labels\n",
+ "\n",
+ "df.groupby('Cluster').Score.mean().sort_values()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "It looks like cluster 2 focused on negative reviews, while cluster 0 and 1 focused on positive reviews."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 40,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "Text(0.5, 1.0, 'Clusters identified visualized in language 2d using t-SNE')"
+ ]
+ },
+ "execution_count": 40,
+ "metadata": {},
+ "output_type": "execute_result"
+ },
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXwAAAEICAYAAABcVE8dAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/Z1A+gAAAACXBIWXMAAAsTAAALEwEAmpwYAADNv0lEQVR4nOz9d3ic53XnjX+e6X0GZVAHrADYJVIiRMmSTMmSHUlRIsuR7VTLji1v8m68Tna9693su3Hi9ZuN/dNu1ustiRUndhJnY0e2QlsW5SLJVGMBxSJWEGABMKgzwPRent8fZx7MoAMkKJLifK8L1wxmnnI/z8x873Of8z3nKKqqUkUVVVRRxbsfums9gCqqqKKKKt4ZVAm/iiqqqOImQZXwq6iiiipuElQJv4oqqqjiJkGV8KuooooqbhJUCb+KKqqo4ibBDUH4iqL8saIof3+tx7EcKIqyV1GUJ+d5b42iKKqiKIardO64oijrSs+tiqL8UFGUiKIo/6Qoym8oivKTyzzuxxVFef1Kx3Q1MPOeLnT/r+Ac834PFUW5V1GUnss87mXf15sBV+P+KIqyqvSd1K/kca93XDeEryjKryuKcrj0IYyUfrD3rODxryrJzoSqqg+rqvqtq30eRVF+rijKp2ac26Gq6oXSv08AjUCdqqofVlX126qqfuBqj2smZozpnTjfO3L/K873mqqqG96p893IUBTlTkVRfqooyqSiKIGSIdL8To5BVdWB0neysNLHVhTlm4qifGmRbTyKovy1oiijiqLEFEU5pyjKv694X1UU5YSiKLqK176kKMo3S881PovP+PvoQue9LghfUZR/Dfx34E8RcloF/G/gsWs4rGl4pyaKq4DVwDlVVfPXeiBVVFFCDfB1YA3y/YwBf3MtB3QN8OeAA9gEuIFfBvpmbNMC/Ooix/GUJi7t7zsLbq2q6jX9K11sHPjwAtv8MfD3pef3Af4Z718CHiw9vwM4DESBMeC/lV4fANTSueLAXaXXfxs4A4SAHwOrK46rAv8S6AUuAkrpgxovHf8EsHWeMf8c+FTpuR54GggCF0rHVAFDxT34BjACDAFfAvSl9z4OvF7aP1Qax8Ol9/4/oACkS9f0PyvG3Q78CZAFcqX3P6kdr2KcG4GfApNAD/CRivfqgB+UrvUQ8J8r951xvXuB35vx2nHgQ5VjKj1/BDiN/NCHgM9VXuuMY1Tu94vA0dJ4BoE/rthuzYx7Wnn/j1d87vHSdveV3rsTeBMIl7a7r+KYa4F9pXH+FPiflL6Hc1z/fVR8L5Hv5OeAt4EI8B3AMs++Mz+Tr5auLwq8Bdw747fwXeBvS+M6BeyseP+20j2KAf9UOu+XrvT+lt7/GNAPTAD/iem/Ox3w74Hzpfe/C9QukQNuA2KX+b2bdt+XwQdzfV/+M/BG6d79BKhfyrXPOPenkd9bFvmu/XCecZ8EPrjAPVGBzyPco43xS8A35xr/Uv+uB8J/CMgvNHCWR/j7gd8qPXcAd853g5AVRB8yyxqA/xd4c8ZN/ylQC1iBX0B+gB6E/DcBzfOM+eeUCed3gLNAW+lYr8z4sj0H/CVgBxpKX/J/UfEjzQFPIRPH7wLDgDLzPPP8iKfu3cwffel8g8AnSte/A5mUNpfe/0fkh2sHtiLkPN8P72PAGxX/b0ZI1DzHmEYokRhi7d02c2zzXMt9wDaEXG5BfsAfXOAH/Kk5xvnp0mfhAlqRH/AjpWO+v/S/t+K79N8AM/BehAiWQ/iHECutFjEqfmeefaddN/CbCOkZgH8DjFKaLEqfZ7o0Zj3wX4ADpfdMCCl9FjACH0KIZ6mEv9D93YwQ2D2l8zyNfC+1391ngQOAr3S//hL4v0vkgN/XruEyvnfT7vvl8kHp+3Ie6ER+6z8H/mwp1z7HmL6p3fMFrvmvkMn6E0DHHO+rQAfCNxqPXDHhXw8unTogqK6cyyEHtCuKUq+qalxV1QMLbPs7wH9RVfVM6fx/CmxXFGV1xTb/RVXVSVVVU6VjOxGrWCntN7KEMX0E+O+qqg6qqjqJ/EgBUBSlEfnx/r6qqglVVceRVUTlUq5fVdVnVPE3fgtoRlxfV4pHgUuqqv6Nqqp5VVWPAt8DPlwKZv0K8EelcZ0snXs+PMf0e/cbwPdVVc3MsW0O2KwoiktV1ZCqqkeWMlhVVX+uquoJVVWLqqq+DfxfYPfSLhVKMaEvAb+sqmoUIdYXVFV9oXTMnyLW4COKoqwCuoD/pKpqRlXVV4EfLvVcJfwPVVWHS5/5D4HtS9lJVdW/V1V1ovSZ/FeEQCvjA6+XxlwA/g64tfT6ncgk8T9UVc2pqvp9ZNJZEha5v08g1urrqqpmgT9CCEfD7wD/UVVVf+kz/2PgicVcoYqi3FI61r8t/b/c791iWA4f/I2qqudKv/XvUv68Frv2y8FngG8DvwecVhSlT1GUh2dsoyKrif+kKIppnuMEFUUJV/xtWuik1wPhTwD1K+gj/yQyS59VFKVbUZRHF9h2NfBV7WYhbg0Fsfw0DGpPVFV9GVnW/y9gXFGUryuK4lrCmFoqj4NYYZVjMAIjFeP4S8TS1zBaMYZk6aljCeddDKuBXZVfGISomwAvQh7zjXsaVFWNAT+iPFH9GvKFngu/gkxy/Yqi7FMU5a6lDFZRlF2KorxSCvRFEJKpX+K+bciP+ElVVc+VXl6NTG6V138PMqG2ACFVVRMVh5n3+ufBaMXzJEv8zBRF+ZyiKGdKyqow4vKrvM6Zx7WUfj8twJBaMgFLqPz8FjvvQvd32ne49D2cqNh9NfBcxX08g7gb5zVMFEVpR1yBn1VV9bXSy8v63i0By+GD+T6vxa59QZSUcVpQdW/pGClVVf9UVdXbEaP3u8A/KYpSW7mvqqovAH7gX8xz+HpVVT0Vf2cWGsv1QPj7gQzwwSVunwBs2j8li8Cr/a+qaq+qqr+GEOaXgWcVRbEz94w8iLhOKm+YVVXVNyu2mbafqqr/o/QhbUa+SP92CWMeQdw5GlbNGEOG6R+cS1XVLUs47qzxLRODwL4Z1+9QVfV3gQDiaptv3HPh/wK/ViJwC+K6mj1gVe1WVfUx5DP6Z+TLDrM/26YZu/4D4tttU1XVDfwFMkEvCEVRrKXz/HdVVfdWvDUI/N2M67erqvpnyGdWU/ruaFjs+q8YiqLcC/w7ZFVYo6qqB4kBLHqdyJhbFUWp3Lby87uS+zuCuGu0fa0IUWkYRGJLlffSoqrq0DzXuRr4GfCfVVX9u4q3lvu9u1w+WA4Wu/aZmMkZ31bLQdWZVjyl1eafIi6stXMc7z8Cf0jFdV4urjnhq6oaQZZI/0tRlA8qimJTFMWoKMrDiqJ8ZY5dziEWzS8qimJE/O5m7U1FUX5TURSvqqpFxIcMUES+SEWgUgv+F8B/UBRlS2lft6IoH55vrIqidJWsICPyRUuXjrkYvgv8K0VRfIqi1CDBLe36R5AA0X9VFMWlKIpOUZT1iqIs1VUxNuOaloPngU5FUX6rdM+NpWvcVHIXfB/449Jnshl4cpHjvYBYel8EvlP6DKZBURRTyeJxq6qaQ4Jp2nbHgS2KomxXFMWCuAUq4QQmVVVNK4pyB/DrS7zOvwbOqqo68/v098AvKYryC4qi6BVFsSiKcp+iKD5VVfsR986flMZ8D/BLSzzflcCJEF4AMCiK8kdIvGEp2I9Y1b+nKIpBUZTHkKClhiu5v88i9+o9JffCHzN9EvoL4P/TXHqKonhL558FRVFagZcRkcFfVL53Gd+7y+WD5WCxa5+JRX+TiqL8p9JvzVT6LD5bGt+sXA5VVX+OBHkX+/0timtO+AAlP+W/Rj6sAGIt/B5ilc3cNgL8P0jQYwghXn/FJg8BpxRFiSNqh18tLZ+SiKrljdKy805VVZ9DZv1/VBQlitzUWTNwBVzAM4haRovY//+WcInPIAqg48AR5AtdiY8hwaDTpWM/i7gVloKvIr7SkKIo/2OJ+wBTbpgPIG6YYWRJ+2XKP5jfQ5a1o0gg6m8WOV4GubYHEWtxPvwWcKl0z38HcSNRcrV8EbH8ehF1UiX+H+CLiqLEECPhuywNvwo8rkzXK9+rquogErj/Q8rfu39L+Xfx68AuxNX3BUQZc7XxY+BFhMj6EaNiSW6Zkn/5Q4gbI4zEKJ5HVpBXdH9VVT2F+J3/EbF444haTYvRfBVZHfyktP8B5N7NhU8hhPjHlZ9JxftL/t5dLh/Md7x5zrHYtc/EN5AYVVhRlH+e77DIdQWR3977gV9UVTU+z/b/LxL8n4nwjO/1v17oWjSlRxVVVPEuhKIoB4G/UFV1wcn6Mo7rQCaVDlVVL67ksa933MjXfl1Y+FVUUcXKQFGU3YqiNJVcOk8i8soXV+jYv1Rys9gRaeIJRAL5rse75dqrhF9FFe8ubEBch2FEw/+EujTp8FLwGOJ+GEY04r+q3jwugnfFtVddOlVUUUUVNwmqFn4VVVRRxU2C66ogWH19vbpmzZprPYwqqqiiihsKb731VlBVVe9i211XhL9mzRoOHz58rYdRRRVVVHFDQVGUJWUjV106VVRRRRU3CaqEX0UVVVRxk6BK+FVUUUUVNwmqhF9FFVVUcZOgSvhVVFFFFTcJriuVThVV3BDw+6G7G86dg8lJqKmBDRugqwt8vsX3r6KKa4Qq4Vdxc0Mj70AAvN7FSdvvhz17YGICfvYzeSwW4dZb4fRpePLJKulXcd2i6tKp4uaFRt7JJDQ2yuOePfL6fOjuhkIBXnoJgkFwOMBqhVOn4NgxeHFF6pRVUcVVQZXwq7h50d0NHg+4XKDTyaPHI6/Ph0AARkYgHAanE0wmsNlAr4d0GqqJg1Vcx6i6dKq4edHTA4ODcOECqCq0t8OOHZBIzL+P1wsHDgjBa8jnhfRTKVCW0omwiiquDaqEX8XNCb8f9u8XV0w+L4R/6RJcvAgf/OD8+3V1wd69Yt2HQuV9XS5x9dx22zt1BVVUsWxUCb+KmwtakPb734eTJyEaFbLW68VNc+gQmM1QXz93ANfng6eegj//c4jFxKK3WuW9ri54eKEOmVVUcW1RJfwqbh5oQVqPB8bHIZMRH7yiyPN8HoxGCd5qAdzHHptN+l1d8JWviKV/5IhY+Dt3wkMPVRU6VVzXqBJ+FTcPKoO0igIGg1j2RqP8GQzilgHZRttnLhLXLP0qqriBUCX8Km4eBAIivwQJ0F66BPF4meQLBQm+trfL/w4HjI1dk6G+GxDxRxjuHibYEyQdSmOptVDfWU9LVwtun/taD++mRJXwq1gZLDeB6VrA6xWCd7ng9ttheBjefhtyOXHLmM2webO8B7Ktd9GeElXMAX+3nyPPHCETyZAKpbA32kmFUxitRmLDMTY8tqFK+tcAVcKv4spR6RtvbBSi/OY3oalJslCvlwmgq0vGCVBbC/fdBxZLWWJZKMCdd8p70agEcXfvvlajvWER8Uc4+sxRdAYd6ViaZCBJ6GIIk9XERM8Ezdub6dvbx+1P3X6th3rToUr4VVw5Kn3jwSC89Zb81dXB448vHABdSfj9Ekh99VUJyjY0wHvfK8oZn0/+HntMxjs2Bm1t8KEPlcekrVLGxmSS2r372k9SNyCGu4dJhVNk41nGjo6hM+sopotkohnigTg6g47QxRDtD7dXrfx3GFXCr+LKofnGz52Dn/wEBgbETTI8LCTa3i7EuXfv1Qt0dneLVLKnB7JZmWyGhmQ8Y2Pw8Y+XSX8+El/ovSqWjGBPkHQkTdwfp5ArkAqlKOaL6E16bA02UpMp1IJK34t93P6pqpX/TqJK+FVcObxe6O8Xcs1kIBIpSxvDYSkwZjSK1a1Z2ysJvx+eeUYIfmJC3DGXLoHdLhORyzW/2qaKFUc6lMbkMBEbj0EB1IIKQDFXpJguko1nab69mZHDI/CpazzYmwzVWjpVXDm6uiSJKZ2WZKRUSv5MJvGPx+Nw9KgoYBaqU3O56O6WSWZkpJz9qtPJGEZGZGznzq38eauYE5ZaC9lYFqPViM6sQ9ErKDoFvVFPkSJmpxmzw4yqqNd6qDcdqoRfxZXD54N16yTYOToqenZN214oCPFHo6KCCQRW/vyBgLhxNKLXtPWqKv9nMlK3vop3BPWd9VhrrFjcFnRGHSaXCbPdjMllQm/QY7AaSIfStNzWcq2HetOhSvhVrAw2bID77we3W0oNOByi0FFVsexra8XivhoyR6+3vJpQVTlvNlt+32SSJiVVvCNo6WrB4rbgbHXSsLkBd6sbDKA36jE5TVg9Vmraa2h/uP1aD/WmQ5Xwq1gZdHUJ4W7bVn5Nr4fmZik0Vlcnln9X19U5t9sNLS3yqNOVJ5qGBhnThg1z7+v3w3PPwde/Lo8L1cKvYklw+9zseGqHuHaiWVw+F+seXEdtey31nfVseGwD2z++varQuQaoBm2rWBlokkeTSdwnIyOicQexuFtbRaFzNQKnMwuaOZ1S/Eynk5XFunWzJxq/X5qVvPSSBHa3bVuefPRGSDS7hvB1+fjAVz5A394+ho8Mo6gK6x5YR/tDVSnmtYSiqisTOFEURQ8cBoZUVX1UUZS1wD8CdcBbwG+pqppd6Bg7d+5UD1cbSNz40Mj08GGpWXPbbVdHnTPfefftEyKur5fkqsqiZpVEH4vJCsTlkhr4u3aVG5o8/vjC59ESzRwOCUqHw1c/z6CKKuaBoihvqaq6c9HtVpDw/zWwE3CVCP+7wPdVVf1HRVH+Ajiuqur/WegYVcKv4qpCI+reXrH+T5yQxw0bJMhrNgvpj43Bpz89/3G+/GV47TUh+ro6eM97JKt4sYliuWOtriCqWCKWSvgr4sNXFMUH/CLwV6X/FeB9wLOlTb4FfHAlzlVFFZcNLSM4l5PAsscjhD8yIv9HIovXz+nuhn/6J1EEeb3iBnruOUkyWykFUnc3/N7vwR/9EXz1q/A//yd87WvV+EIVV4yVCtr+d+DfAcXS/3VAWFXVfOl/P9A6146KonxaUZTDiqIcDlwNyV4VVWgIBMQF43ZLzkBLi8QXwmFx6RiN8nyhwPKzz4pVb7GU++A6neJGWgkFkt8Pf/qnkjtgMkny2OioJLX9wz9c+fGruKlxxYSvKMqjwLiqqm9dzv6qqn5dVdWdqqru9FYrE1ZxNaFVy+zoEII3GKSejtksbpwtWxb3ww8Nyf7ptOj7VVUmirGxlVEgdXdDX59MJDabjM3plPdeeunKj1/FTY2VUOncDfyyoiiPABbABXwV8CiKYihZ+T5gaAXOVcW7GVfbb61Vy/R45PmJE+KSeeyxpQeVW1sl2Lthg7hxEglx76zUWAMBSVbT2iaCTEyplEwyVVRxBbhiC19V1f+gqqpPVdU1wK8CL6uq+hvAK8ATpc2eBPZc6bmqeBdDC6gmkyKT1CSSK+m31qSjNpuQ6u7d0qpwOXLRJ56Qej25nFj6q1fLBPKJT6zMGL1eUQ4lEuU6/amUPN+8eWXOUcVNi6upw/888I+KonwJOAp84yqeq4obHZUllmHxFoOXi8UqYi62yujqgs99Tnz5AwNi8X/iEyuXUNbVJf1xtUJ0yaSsIFpa4Ld/e2XOUcVNixUlfFVVfw78vPT8AnDHSh6/incRtNr1WhPwREI08xrRw9VvMTiT3H0+OHRoeiOXb31LsnVVtTwBaH9XAz4ffOYzEhh+6SVx42zeLGR/tc5ZxU2DFdPhrwSqOvwbFN3dYvEODYnF+8QTC5OT3y8dsfr6pMZNPA7794sq5T3vkRaD9fVScG0lte0zxzAzeWrfPti6VYKkvb1yPf39sH49/PIvVxOsqrhusVQdfrW0QhVXhu5uePppsUhXrRJCfPppcXvMR/p798KBA+W6+RMTIo/MZOD116XE8a5dUotnJVoMzuWmmcuFVChIp67RURlPPC4qmd5eKRdRX1++5pldsnp6ZNy1tdDZWU2UquK6RJXwq7gyaLr0ujr5X3t89tm5Cd/vh1deEVfN8LBMEPm8WPJGo5D+xYtCwP/xPwppXol6Z2a/3f5+mXACAVHabNhQJnKLBX72M6m943bLNomE7NfbK9ul0zIpBQKiwx8dlbFevCgTVDgsCpvh4epKoIrrDtVqmVVcGYaGhEwr4fHI63Ohu1sIcWioLDPU6eR5LifEf+ed4jPXyP5K1DuVlvzkpPjo+/uFoI8dEz95MCjbptNyXpNJ/jeZxOo3GmU1EgxKSQWzWcZy8qS4pc6dE7dQXZ08jo7KOa9Gs5cqqrgCVAm/iitDa6tYtZUIh+X1uRAICOEXS0nZWpOSymYlqipF12A6YWuZrcshUy27FsRdo1XxrK2VmvkDA3KsaFTkj3fdVQ4ie71i1cfj4tc/flzeu/VWGUsuJzGIvj65pmhUJpM336x22ariukSV8Ku4Mmi69IkJsYa15088Mff2Wv0Zr1dI1GAQl47ZXC5XEApJhU2YTtgaHI6l163RsmsBzp+XfRVFrPFt28R1c+qUkL3bLY+ZjExY69eXx3DuXFlRdOQI/PjHcry+PlkZjI+LHz+ZlFXKkSPwwx/CX/1VtQZOFdcNqj78Kq4My9Wld3WJD722Vv53OsVVotfLhOH1Qnu7ZL5CmbAr5ZrxuJD2c88t7tfXsmuhHBhWFAkwu1ySPBUIyOubNgn5m81w9mz5vB/6kLigJidlcjp1SrY3mYTw9XohepdLrP58XiavTZvE0s9kFvbnVytjVvEOoSrLrGJ+zNTK79w5vbb85aK7W5qV9PSUXTfpdFnSWVnmYC755MWLst+aNUurR68R6ve/D4ODoqLxeuWcwaBY5PfcI4R97py4ZE6dksJlv/7rsmLJZKSkwqFD4sYJBmV14nbLRDIwABs3yjFdLhmb0ynjes97ZOVQVzeb1Ku19atYAbzj9fBXAlXCv46gkfLZs+JmURSxYlta4KMfvXLiX+pkMlczFUURn3k2K3758+eFkDduhD/8w4Ut6W99q9z03GQS8tXrxRqfnISDB4XoT58Wa729Xci6rU3G+dJL5XthMMDddwux798Pt9xS9utr25jN4hr62c/g0Udnk3p3d3l1oOFq5h9U8a5EVYdfxeXD7xeyP3ZM1CmqKqRksYiV+9OfLu6mWAxaW8LFxqFZvw8/XCZKv1/GoZFlc7MQ6dGjQuhPPjn3xNHdLSRtNkvDkg0bypr8eFykl3Z7WSJqNMr/gYCQPsgqJBqV7FuTSSz8ZFKyYcfGRL2TSMgkmUhIItfx4/L6XGUjAgF5rxJXO8O4ipsW1aBtFbPx4oviNkkmxVINhcrVGnM5qTJZKFx92eFMhU42KyuCf/5n0cKn00K6msvF6xUCnTmuSmnnxo1iiTud5ThDMAg/+pFY91r9GpdLJodz52T/I0dEgXPXXeKjHxkRQt+/X/z0DQ3wwANSYvnChXIA9/hxuZeVzd2hHHiuDCprWKwJSxVVXCaqhF/FbBw+LHLEfF6sWZ1OrN1sVl4rFle2w9N8qFToBINCyOPjEvDV/O+60ld4fFwqV2azs8c1n7TzxRdlIkilxA0zPi5FyyYmxHVkt8vxamokGUvT5b/nPXIPEgmx8Bsbxed/662yEunqEleQNna7XbathEbqXV2yaolG5ZjR6OJNWC4X3d3w+c/Db/6mPFbzBG46VF0673b4/fDtb0t2azIpLobFqjsqipCYTicEB0JGxaIQv80mpLpr19Ud9/nzUoKhqalMiAMD4nO32YREAwGJK1gsZUKeaR3P5zZ57TVxxZw+LaR8//3ixurvl/edTnl9167ptX2CQSF3rR5+c7MEgv1+2T8YlJWQxyMqoFhMVgFaYpbmmtq9u1yyubtb3Dheb/n1lcTllMCo4l2HKuG/m+H3S0/U114T8vF44O234YtflH6p8/3Qb7sN3nhD3BSJhFjT+byQX02NkL5ev/JEUVmX5sIF8ZdrbQcPHxYXS7Eo5K0oQqSFgljsJpMQrVbHphJzSTv7++HSJXG3mM2iqgEh5PPnhXzvv79M9tp7Z87IPWxsFKJPpeQe2e0ybu29mhp57+BBGc+6dTJZaKTe2SnX+sILC0sxV0qyudwSGFW8K1El/HczuruFoGpqymRXXy9EtNAP/eGHhZiCQQnYao/19UKsTufymoYsBk2J89JLQpbZrJD7yIgQ48SEjFmbZIaHxaJvbZX3Jiflf7dbJqmZxw4GZYXT0CC+9ERCJrTWViF+RRGiBlH/bN1a7nNbiXhc4hkNDbL6GR4WFdPkpMQU6upk3PG4TCBut+x34oRY7ZrqZmZ9n3hc/p8ZBF/qdkvB0JBY9pXweGTFVMVNgyrhv5sRCIgVXEmCJpMEJuerdQNCJh//uJDMK6/A9u1CqOm0kO5TT62cVaiRWm+vWMyKIu6P7dvFup+YkECp3y/WeE2NWNP9/WLdd3bCjh2wdq1Y4P39soJZv14IuKdH3CsGgyRJXbgg16fJKf1+eT+ZlEeLRfZrbpZ7d/y4WPqaG6a2Via+H/2orNU3mcqF4O66S8Z86pS4i2b2u/X74Wtfk0mosVFcPnNV4dT+L8UeEsEEk70RsqMTmAaew/WZj+H2uZd+n7USGJplDwuXwKjiXYlq0PbdDK18QaUKJJsVt8hiP3RNNvmVr4h+/NZb5XEhV9DlQCO1XE6sa5tN/r90Scg3EpHtamtFRmk2y/i3boUPf1iCo2vXloujnT4t5B4Oi4LmtdeEzFetkv1ra8UXv3q1EO2uXULWAwPl8sY6ndTkf+97ZZIbG5NxPfaYTDDa5GezybbJpNwvr1fGvW2bTAS9vTLWBx6YnmSlxRQyGXH5BINzl4soBa0TwQRDB4fIZ/KYm+ogGKBnTw8Rf2Tp93m5JTCqeFeiauG/m9HVJVmjr71WrgI5OSlW8lJ/6DNbAvr9SytpsFRo5Od2l0l0zRoJfoZC8no0KuTs9c7Orq2pmV4cbXi4rCTKZGTyCIXkHDabvH7mjOyfzYoy5447RHaZSgkJ7txZDtL+wi9Md8VMTIjr6fx5CRYnEmW1Tk2NrDAMBpmQxsbEgn/oIdlfm9yammRsNpu83tsrcs6ZweZS7GGyN4LRbsRoM6JLxlEbG7B4LAx3Dy/dyr/arRnfAfi7/Zx59gzRoSiuVhebntiEr6uajbwcVAn/3QyfDz77WSGvV14Rgrzllsv/oa+kT1mDFlDt6BBrF8Rt1NEh443FhLB37pRVht8/Xc2iJU1ls+KH14LKqlomtmSyfD5FkX3DYSFaq1Ws9I0b5T2nszwJaUoaLStYiwPcfru4bE6ckOO3tMixh4flPpjNUiLZ65V7AzJJfu97krHr9ZYraWYyMrldvCgrAb+/fC9LdYCyoxOYm+rQJePoE3HiW+/A5DARH5uh318MV6E14ztVBsjf7Wf/0/ux1llxr3KTDqfZ//R+7vrcXVXSXwaqhP9uh88nmuvPf/7Kj7USjcYX6iPb1SUkOj4u5J7PT7foDx2ae3LRYgAejxC/qor7JpWS83V0iGWfTouFvnu3WN1f+pKQvU4n+46OynHSadleWwWVjp+2eUhcCFM4OojJ3ozDHsNQKMgEpXXJ2rxZrPXW1jLZa5OkzycuKr9f9jlzRvbz+eDBB8VVVDmBliSbpoHnUMfGUBsbiG+9g3x9E9loBrvXfiWf5uWh4vPzK23sGb8Tz5qaFZv/58OZZ89grbNiq5NVkfZ45tkzixJ+dWVQRtWHX8XSoSVCBYPiH3/xxeXVfZ+rmcmhQ+JSsdnEt7x7t8QNOjuF7Berg6/p2DMZ2aZYFH+90yl+eoNBrPi33hK3TS4nLhXtOJmMWPLZrKwmHA6x4ltbZWwvvggeD+lQnInBFDmdCb3HhZJMEKpZR35iUiaWpiaJJ/T3y/8a61VOkhs2yDkuXpSJx+WSczU3z3+NPh+uz3yMkdseZWLLe8nVNpKJZkiH07R0tVzxR7oszPj8Xj5SINz9Pd7qeZaDQ/vJ6oNXre9LdCiKxWOZ9prFYyE6FF14yKWVQSaWwb3KTSaWYf/T+/F3+1d+kDcAqhZ+FUuH1yuEpiUqaf7xiYnproj5MN8Kwe+fXSjshRfECj51Sqxit1uUNzOlkiDnnZyU7T76UVHjhEJC3o8+KuOz28Xlo6rwd38nKp2uLvj7v5dj5vNlOejmzWJ5b9ki8Y+HHyYW12HQZdGbLaiqDr1BwZhNk/RtwPXQPTIOrW3j4cNlNUxF0lcCK7HBDIWLKXSnJsBqQdnQicfmxqK1UJyjjo7b52bDYxsY7h4mPhbH7rWzevfq5al0VgIVn18wEeRQwEirI0fLaIKR+gwHhw7S1byLRKB+xU/tanWRDqenLHuAdDiNq9W1wF5XtjJ4N6JK+FUsHVote81qTqXKipkXXxSSO3euHBjWipNpE8FSCoVpLoPXXhPidjjEJ6/VtbnjDnjmmelVNn/hF8Si/+535Ri/8ztC4uGw+NO3bJH33npLtq+tFUK/6y65jvPnZbJobJT3hofLMstLl6C/n5i9iZr4OYoZHaiQr23EfPEMMXc7LlUVN9Tp0xIL0JQ7e/ZIoDweJ5HV0/PDHkynxkgm7RR1HnRpHY7+KJmiiaZMBjPMW0fH7XO/8wQ/ExWfX+9kL43uDnL5OuyJCWxGIdIT/ovs7lh5wt/0xCb2P70fEMs+HU6Tmkix/RPbF9wvOhTFvWr6fbN4LEQGlqFwehehSvhVLB0+n2SMhsNlBc3WrUL6P/uZEOiFC+Vm3jbb9Gbe8zUz0QiuMigMQjCRiJwzl5Na9pGIuFu0EsSvvSYTxhe+IPt84xuy7b/8l+Ie+tGP4Dvfgeefh1/6JRmHx1PuUTs8XA70Op0yWWnqHi256403sDnWE1u1AcfYJfThCVK33Emi1oclMVle5WzeLMcwm8vXmEpBOMzYkUmCpwLUJovYlQzDVh+FXAFL0E8yk6E/Wou95gy1Xj25DzzM0HNnSAQS2L12WrpappF9xB9huHuYRCCBolNABVVV59x2RVHx+UXSEW5dP86b3e3gqkUtQjHjYHwiTdevr/ypfV0+7vrcXZx59gyRgQiuVhfbP7F9USv9clcG71ZUCb+K5WHDhtn127UM2dFRschtNtlGc4toQd3K7lMza8rAdJdPICAunFBIMm7XrROXx+ioKI00SaOiyLaHD4vl73BIOYlt28RN9MMfCun/0i/Bpz4ltXnCYTlPb2+5SYnTKRNXPC6PFotcwz33QCyG++wFRkJWIuu2U9i2g6SllsLFfjYq52BNk2TuWizlksjaNQ4OyrgPvEnzeJwJg4esUUU1GMkqNkajtbQmQ6gmO1mMHIv4yP44QM3aGhyNDrLxLD17etjw2AbcPjcRf4SePT1YPBZ0eh39r/ajKApt97aRS+ambbviqPj83CYXxXQ/71sd4o369xOaMDOhnCXU9hP+/cG/oPVMK09seoIu38qpgnxdvlkEH/FHOPEPJ7j40kVyqRwNWxrY/tvlieByVwbvVlSDtlUsD3NVdxwfF4KNRMrJUloz7xMnJNsVygFWraaMlsxU6fLRNPWKIi4bg0Esbii7kKzW8ngslnKFTEWROv6f/ayQvk4nZH/fffCRj8jxmprEGm9qkhVFKiXErtfLcRVFrP2GhnJxuOFhrNEgjQ9sJb9lO+GCA6PNSPt2O9ah8/CXfynXOjQ0vfZOf7+seKxWgr6djDrWoxotDFg3kNeZMadDJAw1vNX0CMMP/BbZBx4hknWSCqYwu8woOgWzyzyluQcY7h7G4rFgdpkJnQ9hq7dhrbMSOh+ate2Ko+Lz25j3EDHkiT/Swm1PxGl87x56G75CQ3OWVe5VxDIxnt7/NN3+q1eRM+KPcOB/HODM986gKAoWj4Xxk+Ps+5N9U0FZbWVgdpqJDEQwO803tZSzauG/C/COtkSdq7rj/feXa9kEAmLVQjl5aXKyHNSdmchViUqXT2OjkKjVKv8nEjKxeL1C0pqFr9XE19xCGul/9avl4/7t38oKYGxMdPCf+1y5Tr3dLpOM1VquBqrTSbAXJDdAp4O2NuxW6AiflusfGYGn/1LiFvfcI9d36pRo/2tr5TpOnhRr3+WitrOW0KUQpKKsixwlaqonnLcStK/C6G2ktkN6/Oaz+Vm3pVJznwgkcDTKpJiOpEW5okA6lJ617VVB6fOrAW6J+Oke7mYsPsbRkaNsrt/Mmpo1ANTZJGj97JlnL9/KX+SLPdw9zMTpCay1VswuMwA6nY58Kj8tKDvXyuBmRZXwb3BcjVyoRTFX9u2ePWI1Hz4sxGkwCPFpQd2laPUrXT5aiYVUSnziBoNINfV6sdCLRSH3iYnpFTIHByWxrBJ/8ifi7tH652pj/vCHJdBaLMqkFAjI8127ZBI5cULIvliUc1TmHRw4ML365OrV8njsWFlmmUpJcbXRUVrWtpJaa0IfCqIqWUZwYtEn2Wzuw7L7Nuz1oqk3mGb/JLPx7JTm3u61k41nxZp3W8inZYIwu82ztr3a8Ll9+Nzymb7a/ypt7rZp73ssHgYil1mcbQlf7EQgQSaWwdZQ9s/rTDrUjLqoXPNmRZXwb3B0dwvnvfyyPNbVSc7ScnKhrhiVVr/mknE6xcLv6BDiX0rLvsrjRKNC4pprR5NlBoNyPE2lc++95V64g4Miy9y/X4qv3XefBGu/8Q1Jcvo3/0ZUPgA//nG5sYuqlguZeTzwG78hY/D7ZUXQ2Tm9RPLY2NzVJ30+sfAfeUTIqa5Oxp/JYDt3gs6mIuFNXiJRHc2NrTia7CjxGPbh4+jeGEINBPClTMRaN5CJZjA5TGTjWdLhNKt3y4TS0tVCzx5xkdWsr5nmw9f0+dq27yRaXa2E0+Epyx5gMDJIIpvg64e/jtfupaula2qCWBRLSPKze+2YnWZy8dyUhV/MFlGKyk0blF0MVcK/wXHokAhVXC5Z9SYS0rQplXqHe2BXWv1zNeWeq2XffEv2hY7T2Tn3hakq/O7vCtnv2CGkG4vJsbJZcQ85neJ20enEBaUo5d6zmlVvK1uLOJ3lXrYaNFXRQtUnNbK69dZyU3SbDfO5YzRu7KDxzjunJpDk2Utk9+xlQr0TU2MDa5tN6GID+JP1RBLOWZr7Sk1+NpFl1b2rRKVTUDHajNdGnw88sekJnt7/NCCW/WBkkNPB0zy24TEaHY3Es3H29OzhsQ2PzUv6leqjliPHcXd1Yq/k7RkS3pauFgb2DzCwbwBUse7ToTRmt5lNT2yadfyzz5/l6DeOEhuO4WxxsuOTO9j46MYVvQ/XO66Y8BVFaQP+FmgEVODrqqp+VVGUWuA7wBrgEvARVVVDV3q+qwmtLPvhw8IFt90mpeGvpqXc3S31rIaGhCueeGJ55U7OnhXucjrlf6dT+O3s2asz3kWxmBJHw2JL9qUeB4Ts/+APJEC7bZt8aIoikkuXS+SSHo9Y9WNjUgVz+/ZpZMzx42Lhd3aWx7Vzp8ymP/+57GOxTO9U9bQQHB6PvD4xIe6ko0fLHcN27RI1UDgsE8qWLeXVAmAbOo9tZyeeB3aUrydqp8MWhsfvn/MWXxea/Bno8nXxubs+x7NnnmUgMkAim+CxDY+xo1muy2UW5u4e7p6T8CvVR45GB7GchZG/P4xlVQOuVhe1HbXYTdO7mbl9bu78V3dir7dz8aWLpMNpGrZOV+loOPv8WfZ9YR+WGgvuNqnFs+8L+wBuKtJXVFW9sgMoSjPQrKrqEUVRnMBbwAeBjwOTqqr+maIo/x6oUVV1wYIuO3fuVA8fPnxF47lc+P3wrW9Jbo/JJOq/YFAq7/7BH1y9FqNa17lKzlhO17nHHxdD2GqVcWez5Zjmc8+t/JiXhKVEkZ97broFHwwK6abTkkil3YClRqP/+I9lpl6/Xvz9Npu4fQwGmRC2bBHrfmREjvPww3JOjYxVFf7jf5TzLTYubQzzzdYzrw1kdZJMygfk8ZQnseefl2JsWqaw5roqFODTn16hD+Sdx9cPf51GRyM6pSwELKpFxuJjfHrn7Os689wZcklxzSSCCSZeOk7TwEFwe3B0NFGYiNLaacf65EcvywL7v4//X7Kx7DQ9fnIiiclp4tee+7XLu8jrCIqivKWq6s7FtrtiC19V1RFgpPQ8pijKGaAVeAy4r7TZt4CfAytQwevqoLtbRBsXLkjiZS4nscJIREQfX/nKylv6K9F1rrNTDNl0WjwTNptY+VoBx2uChZQ4GrSszWAQ9u0T35TBIElQmzeXE7aW6pf64z8WH/63viUZusWiWNiTk1KTp7NTEsNefrm8T3399F61Ph+hZ7/NWUOYyFgUt8VNR20H9fffLyuDmWOpqD455Y44ehi34sE3fgHrGqavTrRiapUKpx07JDhcXy8TQToNr74qsYkbGF67l3g2PmXZA8Szcbz2OVx7TFcfTfZOUmxsIVJzH5beE3gzUVI1TvwN2+m4zB9hbDiGu22OjNvBmyvjdkV9+IqirAF2AAeBxtJkADCKuHzm2ufTwKcBVs0Mgr2DOHdOSq0MDYns22gst3I9e1YqCjz11MLHWK48ciW6zj3xhKwSvN7pq4Trvq+FVpenu1uULZZSYazJyXJBteVGntvapFPX3r1i3Xs8Mvt1dUmgNxYTYlUUIfkZriJ/xM/b2fO4kwY8NTWkc2kODh3kTudm6rxt85424o9w7FvHSAVS5LN5giYDQdMqbkllsSfmaExeeU2V6qHKx8tYeVf6wK961u0i6GrpYk+PuOQcJgfxbJxwOszu1XO45JiuPpronSDqj5IOp7G415Bdv4Xa9bVXJDd1tjjnzLh1tjgv+5g3IlaM8BVFcQDfA35fVdWoUiGBU1VVVRRlzm+wqqpfB74O4tJZqfEsF5OTstrOZsWy1+vL7+l0wh8Lobtbfrv5vBiu6fT0qgJzYSW6zt2QfS20RiLf/a4Qbj4vFnYuJ0uTaFRcL9okMN8x5gv4Vs7M2naaRf3xj8vrla+VyLj7zHOo27ey5oVDmHv8KNk8GV2R0boodf/uQ/MOpe/FPibPTUoSVI2VfDrPyWCYN3wRXO9x4bVDlxPm/BpoSqPz58vlKu69V1w6S71mSpPON4+RCqZITiZJT6Y5+s2jbHh0A9Z7rfSoPQQSgWWpZaZlsaZzeDd72fHbO5akafe5fTy24bEpnb7X7mX36t3znldTH02en2T8xDg6vQ6jxYjBauDsc2dZ9/51NG4r24zLLXm845M7pnz2WsZtOpRm1+/vWvRa3k1YEcJXFMWIkP23VVX9funlMUVRmlVVHSn5+cdX4lxXCzU14gMvFITgVVW8Anq98M5CBpffL2RvMMjvMJ0WeffmzQsbqZp1DrPjfsvBVehrcfVQGaxdt06s+3gczGaSTV4miVEIDlHsiePcup45y3AtJ/mg0r00kzAfeWTa9oFEgNUmO4qioAI6BYx6I5O5OSp0VmDk8AjWOitGmxGAsC3MMeMxrBesdHygY0qh8rjjDlrePD5dFaAphu66q3xAzcW0jGvu29tHqC+EzqQjPhaXBKREnmPdx+iJ9NC+s53GpqWpZUDI/uDXDtK/rx9LjQWL20LgVIB9X9zH7j/avWTSX6oMU1MfvfCZFzC7zRSzRewNdsxuM6nJFAOvDbDjtyUAPFczlH1f3Mfqe1ZjqbHMubrRArNHv3GUyGAEZ4uTXb+/66YK2MLKqHQU4BvAGVVV/1vFWz8AngT+rPS450rPdTWxYYMIPGIxMfyMRvnN2e1C5DsXCId0d8tE0dAgv2Ptt7qYkXrZ1vk7mlq7OIZPd9P/0rPkRoYwNrey+oEnaNk8z0VU6qt9vqklTmYywEhqDKNiwKwzEFNUnneN8mDEP5s0LqcRyxImCa/di+W1faRaGoh1rgEgmUtiTxcWPLaqqKJPK+GschZ7wY4ZMzpFh8vswjo6Qejbf05L2ChLOlWV+juaL25m60ZNjaR91j/+sXyZbr21XDu/4pqHjwxjqbEQ9UcxWU3ozXp0Jh0HYwdpdDSS78+ja9YtqpbRMNw9TOBUQLJYnaJxV3QK+XT+qpUWdvvcmOwm1j2wjmw8S3wkTi6Rw+w2oxbVKQKfWfJYb9STCWUYeG2A2566bVb9IQ0bH9140xH8TKyEhX838FvACUVRjpVe+0OE6L+rKMongX7gIytwrquGri6xyqNRsfZTKflzucSdrLUlnQs9PeIS6ukR4rfZ5Bg6XTnPZ6HzLsc693cP0/3M2wQKLXi9LXSlh/Ad+JoMPBa7PG3nFWD4dDe933wag6cOU+sqCpEwvd98Gj7+ublJv7JEckeHBFrjcaK6HEbVhj2SJNHWwMivPopxddPcxLSUMsswXUWTSEiAVAuazDFJdLV00Tv+XaKNzVgoks6lSeQSbPV1zW4wXoGW21oYfGMQRadgsBqYzE1ij9up3Vw7tU1rzzD58TFo2V62CHQ6cWM1NJTrC1X6+ysnKZ1OrImDB8v1eiquWVEVUCCXzGG0y0pDQSFmitFp7SQdSZdvlcnBWHzhRDgti9XR4Jh6TW/SU8gUprJYr0Ynqcrqlha3WEvJieTUpAOzSx7HhmNYai1kopmp+kPA8nr+3iRYCZXO64Ayz9sPXOnx3yn4fPDkk8Ij+/ZJ2ZaGBpFfL6TF9/tF2ZNKSen0fL5M+lYrfOxjSzi5349/7wm6j+gIqF68O1fR9VD9rHP6/bDnmXE8BjeNDQrxlIE9P3fx2MXT+Bpz4iIIh8VPtBxt5xWg/6VnMXjqMNZIIEJXeux/6dm5Cb+yXk59PbzvffD666RSYxSaGxl4fzvB995OuqkeR0nGt+AxNMysIz9T83rkiKhhLlwQQp2j2YjP7cOy9QEuDp1kohjGbXGztWEr9QUTeGe4WCrQ/nA78bE4qWCK1GQKt91NsblI8+3N5Y0CARyqYfqSz2oVS0FV51YjVa5kPB5RE9jtIiWtr592zc07mxl4bQCdXkchU0BRFDKxDM3rm4mkInjcnvKtWkAto0HLYh3JjuCv9xMxRHCkHaxKr2JL65bL6zG7hJXpXNUtI4MRVt+7msNfPyzjcpmnBWBzyRxqQcVaVy6qd9VrCt2gqGbaVsDnkwq6n/rU0vfp7haj+tVXxd8fiwnpp1Ji3f/gB5LjM6/Hxe/H/82fsadvM54aHY1KlPhrR9gz1sVjT9ZM26+7Gzz5CVxeOyjgsuVh8CTddOHTH5QBXI628wqQGxnC1DpdaqR3e8gOzSM1mplQZTLBbbdx6jfvZLLOtjQZ31KSsjTNq8EgBOlwSHDl1CkhXS2zdkYGcP3uh6jfk5mulZ8v4asEt8/N9o9vn1LI3O++nyM1Ryg4ChTVIvFsHL1Dz+baNhmDZuGnUnOOYQozV0Mvv1yuVJpMyn5PPglA+0My6YQvhpnomcBkM+FsdnKL+xZeOfsKKW+K4v4ipjUmcrbcvGoZDS1dLRw5eISDFw7izrhxZp1E01GO1R/j7l+8e/mdpJYYd5lZ997kNOHd7MXV6poqNWG0GwmeDQIyKah5lXQkzcb3l90172RNoRsJVcK/QgQCZdfP5KT8fp1OMdpCIdHxz3T/TjN0zg8SDG7AU2cQAseGSwECfXR3d03bT37/NoKBIr2hWiJJA87ROjx2N9hOlDdcrrbzCmBsbqUQCU9Z9gCFSBhj8zxSo7mqbe7ezTYnS5fxzXOMaTdL07z29orsqrGRzMAF0sFhLkbd2F/xU3/rXdR89MnlH3sOzMx+3XDawcizf43l+GksRgu1m3bidOTkmCaTJH0MDooqp6Vl7haRM1cyqkoyGSVaiDA2+jaGYhM10RFa8Mmk86RMOsGOIOnJtFTRHErzyKZH6K/tZzwxjuOIg0cfeXTKTTafW8btc8Oj0P5qO/G34+SyOZpWNeG9z4vf66c4VFxeJ6llxF0qq1tWJmQBmF1mmrc3Y6+3k5pMERmI4FnvwWg34mpyoRbVWfWHluN6Wik31fUkka1ElfCvEF6vuFU1NY/dXi7kmM2Ki7bS/TvL0DmQ5JW+Th7YHmTKtrVYcIQmGAvMPlf/yEZOn/Zjd+apcRSZVGqYDBfwOzbii0QkUjw+LrrzpfSZvUKsfuAJ8dkjln0hEiYfnqDjgwtIjeZIzPLBsmR8iyZ3aZrXZBLsdpL5FEFDBovTgks1kk+l2NOp8qATfHO5Gq6kEJHfT8v3f0zLhRSsuk2+DBf8Uk20tVWKHcViMiGtWUOm+xjhY0OM3vIBTBvWlcmhciVz7hwxk45L7gKxW+9A1+ClEArR//wzFFub8bl9syadSrLcwAaoRfzcZxTYOLfapdItk7AkuP1Dt6P7ldnZsmtb1y6vk9QS4i5zkWRlQpYGk8OEpcbCPZ+/Z9a+M3v+Lsf1dFluqjng7/Zz9JmjFPIFioUiMX+MTCxDy+0tc5Z9eCdRJfwrhNbmVZNwplISX9PUPUbjbNfyNEOnyUbDUJwTl1w8cOuEvJhOEzfVzVrpy7lqMKwzYEkOkQplKLa0sjV2gO4LdfgshySAUChIgPKq10lG/PQf/xz9Lz1LdmgAY3MrHR/8xPwqnQWwHBnfotA0r4UCpNOEQ37MRT3jD99Ntr6GvNWMcfVaThzZi+90dmXrS3d3SwZxXd30zlyZjKw27rlHviw2G+lomsnzSfTGCerCF5hMtlUoTCpWG4ODDFmTxG7djKFBiFPnrqVubGRexc18ZKn5thdzyyyULbvcTlIJnZ3wKz0kcwYsbsus2jgza+loSptsIkvwdJBCroDZbaa2oxaDyTDlrpk5SXQ80jF90luG62klGp5H/BH2//l+YkMxEiMJ4mNxDDYDNetrCF8IX9YEspKoEv4VQsvz+cM/FPdsNCpEr9eLzNztnu5K19q0fv/7pXLG1lvYqJ7kQsBLNK7DocSJT2QJd97K7q7Z51q/HsJhJ+HoRtyd0FoPI8cbOfTyObCN0rVuAt8jm8TnG42+I3WSWzZ3XRbBX1Vomte//mt46y0ypgLx999Frr4GQzzBxB1bcZgc6A6/Di33yAys1dYZGxOX2Gc+c3n3LhCQ5V1tWaWDxSI+vmBQzlV6LzYcR+e0YsolUWOh2QqTipXM0IkfYq+wAgzJFDmvl0BibgWRoihceuXSvGS5WIPvhbJlfe6l95iN+CNcGHXhDZ/CXlNDJp1l5OfnyrVxKHfyymfzjB8cJxPJkE/npfuXx4y1zko+lWdg3wA17TVs//j2eSeJSjnmcpqYr0TD8769fUz2TFLIFUhH0+jNeoq5IpH+CIYOA546z1WTtS4FVcK/Avj95Sx+h0MMuFWrxKo3GoXsn3pqOmeEQlJbq6ZGc9HaeSlwK+9bewFbeoIx1Yv33lXsfqhmTq7p7CzX5QoGSw2Z7C34toyS3PQEe1ImHqsZw0d6bqniYrjS8p3XEzTNq9/P6HNfQxcIoljNTNyxlXRTPfFMlLaEKvdJu5l2e7k/r2bpj4ws7554veKnn6szV2urfFFK7+WSWcyGIqrBSMEtk8CcCpOuLuqO7CURCqFz12JIpjDEE1y6dfOcge2IP0J8PE4qlJqTLGHhBt/+UjereCbOQGSAGksNG+o3sMO0g9jLMQ4HRDFzx2fumCLXiD/CmTmarw93D5Nxebno2Ib1zElsSgJ9SxP+htumauMkAgkUvcJw9zAmu7hsxo6PkZxIsmr3KlLBFOlIGsWgEBuK0ftCL6HzIZytzmn+fZgux1xOE/OVaHg+fETaS+qNetSCit6sRy2q5FN58qn8sieQlUaV8CuwHK7z++Gb35Q6XTU1UlVTr5ff9K23lpswzSTt/n5ZAZjNsso3m8FgtxBu2szj/3vzomOc4dadasjkbTRw6mSa0fEMAwcKfOaeU/g6bVJfZjk3QJMyrlp19SSeK5U45vcT3PciA72HCdgVijtvY9ttD892b/h8tH3sM+zp2YPH4hFrNRMlnA6zqmOnuHHeektqYRQK8kGuXi1unn/4B3lvOfekq0vUQFoRt8rOXB/4gCRRld4z6/IwGcLfZOPvHG/Qc+En1Kl1PFT3EDvZOe0aGn7tKY49/wx1YyPkvF4u3bqZEY+ex1q6Zt3T8aCHmjV1uFpcTPZOClnqFWLDQpZ2r522e9s48XcS7K90yzT+auPUvdro3Thl2W9QNhB/KT6nRQ3Ma20He4KEL4YxOWrJ7nwfE6k82XgWz4SBjtLl2b12ep7vIRlITtX2T4VT2Ops+N/0E/FHSI4nKRQL1LXX0f5QO0MHh0iFU5idZmz1QtIzJ8vluJ5WouG5okouRi6RQ2fUoeZVVFUS8ww2w7InkJVGtYl5CRrXabG0WEz+7+6ef3vNTetwiGG4erVo97UeHXNxWDQqMk2jUXKBjEb5P7rEjmyVfcAHB8XS7+iA3ngTmYExmvQBgsU69ry9Bv9PTy+PSCvLd2oSz7o6eX2l0N0NX/yilAW+cEEuYs8eIazlwO8n9J1vceT8a0Q9NuqwUPfTN/jZq9/EH5l9LK22i81oYyw+hs1o47ENj1G/+yFJoHjrLdnQYJAPJhQSq/yll5Z/T3w+qdlz991yjGRS6uM8+aRMBhXv2T0GzjTX8mcbhvE7wat6iaaifEf9zqwG4C2bu7jlX/wRw7/2KMfvWofS1iYlEmLIPUwmZXWSTMLzPyDyximGDw+jouJZ50ExKBQyBRyNDnLJHNH+KNt+a9usBt9+rx9j0kjkaITzPzlP5GgEY9LISwdemmqgPrPBet+LfUz2TjL45iBDB4coZAtT76VDMtkYbUYUpfSoV6b68AI4fU7Gjo9RyBUw2oxkE1mpCxRJcmnfJfKpPDqTjmKuyPiJcfyH/dgb7eRTec49f46+F/vw7/cT7g9Pk2Mup4n5SjQ8b97ZjN6ox+KxYKuzkUvnKGaL2Bps6I16UhOpOZuzvFOoWvglLLdU8Xxu2jNn4C//Er73vblXCa2tMplsrMjwnphYXsG0mU2hTp0Cey6MbU0jyVCGRmUCj0eh2/uoKFCWap2vRPnO+aD5v/72b2W22rBBJExLKTo017G+9jXCvd201DrIrfeQ87gwoGNtX5Du9rmDmHMGhd3ILF1XJ24Wj0d68BoMkqiVTstrlVjKPZlZxG2e9yzAs9//fYpDLdgzNiktsHYdCX1izgbgc17Dy89NUwIksnpiUR2WzEmyO99HPpXnwk8uYGuw4W5zT5F1ciLJ4GuD1KyvwXenb8oF8+xPnyX3dg5USE+mmTg3AW9BwpXg/V3vn3Zqk8NE4GyAsWNjOJod4odP5/Ef9NPa1Uo2kcVSayEVTpFL5jBYDOTTeYqFIpbachJazB+j8dZGkoEkuWQOk91E445GLvzkAkaLEZPTRCaaQW/QU1ALnPy7k6zevZrg2SBGq5G6DXVE/BEuvXqJVffId1i7nuU0Mb/ShuftD7Uz0TvB8KFhbA02zG4zyUASvUmPZ61nycXnrhaqhF/CcrjO75fihj09YtmvWSP++osXhSPWrZt/9b9SBdOg7N4ZHYWmXIykpYZEnZGtHSEcrlrGJk0QOLT0A65E+c65oGlRNU28xSL+qA0b5AYODy9cdGiuYwWDTLrNuAoK9uM9hG/dQM7lxB2cpGeeIOa80DJdu7tlPFarWPnj4zIZLXZPrtBFFVSDrNu0Dr2uXKLVWDQuvQH4DMnjZO8ktvYGMj0D5FN5DBYDuVSOxFiCte9bC0AymGT81DhqXqXtPW3TXDD6IT3hYpiCv4DBYsBaYyUQDJA+nOZE7wlq19dS21GLrd4mmvfJNI5GB4qioOiUqSJy4yfGWb17NXavHaPVSGI0USp5bMG92j2tPn0ikKDtPW1TPnzNLVLIF3A3uMmn8yh6hUK2gNFuJJfIyQqhCEabkdhQjPhYHM9aDwoKuWSOY988hqPJgVpU3zEtvNvnZtdndtH3Yh8jh0dQFZWW21pof7i9qsO/nrBUrtP4prVVng8MiMXe3i6NkWpqxHqfL+l1JcsZa+6dgQEY66+l0Rhna0eceneOaNKA1xSZP4tzLqzkbFQJTYuay8ljPi8EPzwspD8yIpmvi8Af8TP43NdIhgK06iMYMwXSNgUbFuyXhom3ryLiMi1aNmAWvF5ZKmntCEMh8bXdf7/42xa6J8up3DkP5moAHk6HaXUtcaKdkaCVjqRxOXSkb1lH0Cx+Y1u9uBTs9eLuGDkyQvRSFBQYOjhEbUftlAtmXXIdveFeLBYLRrORaCpKOBlmU3ITqWKKiD/C0OEhrDVWLG4LljoL3m1ehrslYGmwGlCLKvHx+JSrxr/fj6PRQdNtTeQSOcZPjpNL5Tjz3Blaulqwe+3kkjlad7Uy2TtJdDBKaiKF2WFGzam41rhQUEgWkhQyBUxOE7lUDpPLRM36GiwuC7Z6GwargXQoTT6bJ9QXIhVMseb+NbPiDUtNirqcBCq3z83tn7odlpGx/07hilscriSuZYvDpbYbrOxeFwyK6/fMGfEAhMNiEMbjso3NJhwQDsPf//3VG7vfD3u+FcJzrhtHnYm46iAcKvJY+2l8H39weX78q6HS+fKX5SYcPSpB0XxebmAuJ8ujfB7+6I8WHKc/4mdPzx52Pn8EtbGRYjCI+cgxsmYjDmcdznCS8Q0+Tt/VzoPv/fjy9PyVpD2zQ5XPt/A9ma+doc225OStbn83T+9/mjprHR6Lh3A6zERqgs/d9blZLp2ljH/olR7UcJjM7l8gX98EQOhiiPGT4zRsbWCiZ4LeF3sx2Uw0396Mrc5GNpGltauVYqGI3Wvnzb1v4m/0E1Ei6Pw6WoZacEadYmmrCnqLHmeLkzX3rZk6rslpYrJ3kkwkg96ox9HiwGQ3YXabiY3EGNg3QHgwjMVlYd3719F0axPZeJZUKEXrrlaGDw1PuYT6X+1HURQMTgN9P+xDb9KjGBXUgkomlKHhtgZMNhPWGisGs9it2r56s6yU8qk8hWyB5p3NTPZOkhhLoDPpcPlc1KypmSrVkA6nZ1XWhHJjm/CFMNGhKGpOxdZo484/uPOaumXmwlJbHFYJvwJL4bqvf73cn1pDsSjqx2PHpGtWfX25v2wwCLfcAv/7f1/dsfv90P1ikMDhAbxKgK7bivge3nZNyyZPDeyLXywnJ5w+LX5xq1VuXHu7+LMXmVSeO/McyVySjldPYUhlyDts5MfHsF4axBPNEnYYGf34r8yt0lnqOC/HLbPQF2IZPWm7/d08e+ZZhqJDtLpaeWLTE2WyX8oXs2L8CZ2dc6Mu9GtXTyM112oX535wjvD5MKlICpPDhMFiwNXqIhlIkklkqOuso2ZtDed+eA6TzURtZy2jx0ZJTiQl2JvOYfVYUVUVR6ODzU9sJnQxROBkgNW7p59Pb9LTt7ePTCyDZ50Hs0O6WWUiGQwWA44mB84WJ4P7B3E0OvjAf/0Aw93DnP/xeQwWAw23NmCvt9P70176nu8jNSES0/ZH2+l4fweJYIKBfQNYPBax7CNp1KJK665WRg6PoDfrKWQLFPNFTHYpGe0/4Mfd5mbNfWumlD2ZaAajzcimx6cHU9/6q7foe7GPdCiN0WFEQSE1kcK9ys2DX3nwunDRaHjHetreyPD7RXX30kvCQZs3w2//9oK/Jc6fl23Xri2/rxUtXL1aNPlai8RMRozX1asXH8dMroHlEbjPB75P1cOn6q/gjlwFdHdLEPT0aSH5LVvEf59IiGrloYeWRKyBRIBGRyORbR00vnwQgGJ9PZNKnh11t195RvFS+vDOhaVU7lwCunxdc1vzS5XKVozfDqybo9TAcPcwa3avYdA4CHoI9YbIp/MMvzWMs8lJNibKmHwyz6r3rsL/pp/hw8Pk0jksNRYMFgMoYHIKqWfjWQA8qz1iwb8+wPipcYxWI2sfWEsxWqSQK3DxZxdp2tFE+yPtZGNZEsEEntUesvEs5398ntGjo/ju9qGqKsmJJIHTAQw2A8lQEgWF8MUwDVsa0Jl0mB1m8tE88XGplZ/L5ihMSHcwtaDiu9OHrbasiDE7zZjsJgq5wpSVb7KbGHlrhPW/sB6Yv7LmyOERCllxH2mrCGudlfho/IYtvXzTEn5J6MG+feJ3d7tF7fLFL4p3QfstzXTRptPStwKEyCuLKQYC8Cu/AgcOyPO6Oqn+617ge6G1RiwUyt2yTp0CJRZmzegRGutMxNU69rxR5LGxny3fRXOtEQjIjXI6iZx4i2DwPJEmMNaspubDDy3ZGtfS/HVN9Yy9bxfuE70oY2PYvN6rXj5iTmizdE+PyEu3bp39hVgJlORjUbuR4VAviWwSt5LH++2/wb3AqmhmXR2A3hd6cTQ6MLvNFDIFajtqGe4eppApoDfpp2rIgOjJb/nYLYwfH2dg/wAmuwlXm4vUZIpsLIuqqpgcJgDC/WHC/WGMJiMtt7eAAoFTAYq5ImsfXEtkIMLo0VF0Rh3FQhGDyYDRbmTk8AiRSxEatjXQsK2B4397nMlzk5jdZjLRDEMHhlBRqVlTQ7FQpBAvsOruVUQHolz6+SVMVhNtd7ZNTR6hSyGMViPxsTjeLV7i43HCF8IUKTJxZgJVVXGvcVPMFRk7MSburFLgea7Kmqqikk/ksdRNFxQoJoVEIHGln+w1wU1L+N3dQqy1tVLdEmRVnk5PD7JW1r7p7RWyv3RJ/t73PimBrBVT9HpF5KG1TYW5u9VpqGyN2NAgqsDTp8W17RwLcMsGE9hsuCiCzkB3cC2+d6BUwoqiZAEHrXCwNY99zWYcmSKTBpVXl9BqT0Nlmn+xsZbxmi2E0608tuExWKn6O0tFpRWwaZN8wCdPygfY2bmk6ppLxtAQ0UYPPRM9WAwW7CY7KdKMnO0mNlc3sAWgNQqv7ahl6OCQqGFsBmrra3G0OMilcuRzeRLDCRJBIbSGbQ3k03nqN9cTH42TT+elMUqjuGMy0QyBkwGMViNWT7nNo6IopCNpAqcCrLlvDTqdTqSKjTbqOusY6R4h0h+haUcTzTubZXURSGGrt2H2mBnYN4CiExfKRGYCS42F+s31U0HYvr19rLp31bQsW7PTzGTfJDXra7DV22jc3siZZ88w1D2EyWGiZm0NqqoSOBXAaDEycW4CvUk/rbJmJVpua2Hi7ATZWBaT00QxW5SEsTWeG7b08k1L+IGAqGsaGsqv5fOixPv5zyUWZzSKpl4riDYxIb/jtWtl/wsX4EMfKv+25yvT3tkpx5vpHu7ulnN6veXWiLGYBILdSRs2SzMdLUnq3Tkc1jxjk278PYN0z3Gs6xalm3Ix0UtNskDDxV7ME2GCu26hOVxYtNWehuU2xb6qbSArrIBEMMHkqIFs3odp0oar630ru9RvbWW8/xgWlxWzXsjNkcyRaG5c8r3ToDUKt3gstHS1EDgRoJgtYqg3oBgUIpcixEZj6I16UOH8T89TfLFIw9YGMtEMDVsa8O3yEe4PM35yHLPHjNFmxLPOQ2QggsFaphODxYA+pce92o2t1kZ8XFwmo8dGSY4lAXC2OrE12CgWimJNZ/NYa6wYdUYMNgOpcIpivoiKir3BTswfIzYcIzYaIzocpbmreYrwE8EEgVMBCrnClMx0+NAwm57YRGQggqPZgdFqJJ/OY2+2Y3VbiQxGaL2jdaqy5ky0P9xO8FxQXDu5AkarEUuNBc86Dy1dLZf9kV5L3LSE7/WKZZ9IyGMyWdbcr14twdcf/ECI2+0uG3ANDRKQ1XJ1KlcDc5VS7+yEQ4dmq/buuEMy7IeHJbCrxQT6+yXY63IpZBIFDvbWsKsjhMmoomRS7LmwFU/byhV2vOoo3ZTE//kPrD/WT7beQ/DO7ahmI+tfP8WJXUlYYuLhkqtproBUEpiqJxNIBPDavXS1dMn5S7r3RDDB0MEhjHYj5qY61LGxOXupXhGeeAL+8CVsSj0FlxFjNI4xEiP4+GPzFk2b91pi3fR39qMf0rMus451u9ex5sE1Ul6hCEWlSCacoVgoYq2zosvqyKVyFDKFqfaJkcEI6VCamvU11HfWTxFfYjRBPpWfsvDz6TwGk4H6zno2Pb6J9ofbGTo0xD/9yj9Njamusw69SS9BXJOBQqZAPl06hopIPt0WFJ001EuMJzCYDeg79bhb3Qy+Nsiq3auw19uZ7J1E0Ss465zT2hzG/DHWPrCWwMnAVA7A+gfWozfp5wzUVsLtc3PnZ++kb28fw0eGUVSF5p3NtD90fWjqLwc3LeF3dYmvfd8+ybsJBoVoHQ6pXvvmm+Lbt1jk9WxWYo5a7ZyaGhFjnDwJn//8dAFFpRrvuedm932YmCj77QsFiWFeuCAThF5f6mtd74LQGFYTHL/opKNuEnM2hefOzmX17r4u4PNhbmph4G7nVCtEgFQuxfoLoZU/3+U0OZ8BTQbqsXhodDQSz8bZo7mgSm6qyd4IRrsRo82ILhlHbWyY0rKvGCF0dTHwqQ/T8OJruEcCpBrreP3+Dr6T30f0RJTzofPTFT2LXMvatrXEG+NcSl/i1g23Ens5RtvdbSRGE8SH4+itegrRAplQBssqKaMw0TuB0S7JTc4WJ423NE6pcXr29NByRwvWeiuhvhBqUQUFUhMpajtrpyYEV6uL/a/unzau0IUQ3m1eDFYDte21TPRMkI6kKWQLxMfj5FN5HM0OGm9pZPzkOGpBxew203pnKwoKl35+ifHj46y5fw2JsQSKQaG2o5z6rgVjOx7poJCR2vTxkTj9r/WjN+jZ8dSORW+/2+fm9qdu53Zuv8wP8PrCTUv4Pp9Uv62rE5VOOCwZsh/4gFjlP/yhyCtTKckNunhR/PHptLzv8Yhix+8XKfl8Aoq5+j6MjEiJZKNRjm82S7eswUE510c/CrW1DnqPrCd8LkAxkuaxX57ghck7cayumXasyymIeS2wsVDLm8Yw9lwSi9EiDcKNBd5TqF1852Ui1H+Os4YwkbEo3pRC+wS400WZ2Zfo2uke7sZj8UzVgtceu4e78ZXcVNnRCZL1OoYDvRTiE4zt3MVa0ySOgGNFr6fzod9gz1oHHouH4egw3zv7PQxpA9sbtxPLxHh6/9MLavYXupa2gAQ9TU4TeoMes8OMXi+VHnPpHNlEVjT1TQ6GDw6TT+alQqXOPM2K3v7x7dMs4VX3rpqyhFVV5cd/8GMOfvUgHb/YgdVrJXgqyHD3MPZGO3UddRRSBdyr3UT7o6Qn05hdUhDNYJEkLnudnabtTTi8jqnksdXvXc3FVy7S+2IvUX8Up89JYjIxJf3UG/V4t3hx+9y03NHCkWeOoBZUHA0OHC0Ohg8N42x23rDW+uXgpiV8kN/9v/t38jczf6auTgi8pkZeu+ce+NGP5LnbLV6C0VEh+lRq7sxarQTDgQPS7KijQyaRsTFZMbjdsp/ZLFa9qkqsoLZWtqv/gIvonS5sNvA9vgXvcyuiALwmqFndyZ0BK+fyo4RT0iB8m2U1Nd5lVPOcA5VuF52iYzI1iX7ohzjzeixFPeazwxywGNnWsI0We8OSXTuaDLQSDpNDmqpvEjdV8sJf0zf4BtQ3ENl5J0GPmd7xn/D++vfPc9TlI+KPEOuOsWZkDRdsF9ib3Yvb5mZj3cZpjUnmqruj4VzwHOFMmGgmitvipqO2g1prLWPxMVYpq7j0yiWCZ4PojXppCK6q6Aw6SVzKFGja3kQhU0Bn1GGpsTDZOzlFupoVrVnC7f72qczU4e5hVFXlwH89wMGvHmTXZ3dRt6mOyKUI1horKDB8aBhU8G71YrAYsDfYsdRYUBSFVERklQCxnCRuOVucpKIpWm5vIZvIYrKZWH3Palp3ttK7t5ez/3QW71YvZpeZ1ESK+Hhc7qE/xprda6YmKRD9/Y0qr7xc3NSEX4mZAddbbhEffkuLuF3MZiH/hgax2q1Wea1QEHeM0ykBVy3LtrtbyqtrJRjeegtefx2am8Vvn0qJpe92y2SQychjKCQlGu6/f7bCbym9u69bdHVRt2eYuzxboLVi8FeQxVvpqtDr9Lza/yoDkQE2ra9lwxs9uEYiTBos5FIx3up7lfQv/TbrPJ4luXYW6vYEgM/H24+v5/wB8Lg8GC1GzOkclpSF4dbhy76mSlQ2+Fjfup62eBs/GvkRq9yrGI4N0zfZh81oo9HWyFB0aN57dD50HoPOQI21hnQ+zUH/QTZ7N1OXr5uqmV/MF7F5bYQvhGVHpeSHtxpwtDjIJrLUtNeAAplIZur4lZLGmQ1JMrEM//yxf6b/5/3s+uwufuHPf4Gz/3yWQqZA4HSAtrvbKGQKDHcPEx4I42xz0ry9GUeDg3w6DyrEx+OMHB5Bp9NRpEg8ECf+0zgjb41gb7Cz7oF1otBxmXE2O8nFcsT8MRy3OWi8rxG9ST81AS3U/etmQZXwS5gZcL3lFrj9dnjttXLNm49/XLbLZoXMg0EhakURK76tTSx0pxN+53fk8WMfK9e9j8dFCqolYp06Va6fryhi2ReLUoEgnYadO6cbo5fZX/v6wFUYfKWr4lTgFPW2eoZjwxzVBwjf3sgvfy9AIV/AWFPHyZoi/ZMH+dWm1dQvQUO9ULcnDQlLgva72gn3hUmFU1jcFtrvaiduvjIS0eq3vPDyCxy0HySeiNPqbOUD7g/gNDl5a+At2nxt2I12soUsb4+/zRbvlnnv0daGrZwOnCadT2M1WEnlUpwMnOTXkr9GzZoaXC0uzj1/jkw0Q826GnQmHbZ6G4FTAVAgOZGUpiQuad7h9rnnbBauda0yu8z4u/1c+MkFJnomsDXaqL+1nrP/fFZq418Ii/tlPCElGlqdWOos2OvshM6HMNqMWFwWjDYjY8fGMNlNFItFkiNJUvkUerseRS9lFox249S1qkWVptubyEQy+O7yTb0WH4uj6Mrdv7QWi3qT/oaVV14uqoRfgbmSLR99tPy8suijzSYumgMH5LnZLJJOhwM++EHprHfkiKiA7r1XVDhnzpQrA7/4oljzbresEDweUehs3iztaLduFQN4KWO8YbDCg690u0TSETwWD26zG3/UzyVHDUe21mHK5LHWedApOopqkYv+E9R3LL4kWooM1Gv3kjQlabuz7JaKZqJ4jbN9bAuWTqiAZiX3mnp5zv4cbsWNfdxOSBfib7J/Q42xhkwsQ7aQxag3ki1kyRayrK1ZO+tY2j1a7VmN0+Skd7KXUDqEy+LCY/bgHHFiajSh6BQ6Hu0QxZHVSD6TZ9Xdq7A32gmeDeJodEw1BMlnJJA6s1k4lHvo+rv9nPz2SUwOE3Ub64iPxXntj15j00c3sebeNRhtRgYPDBIbimG2m2l+THT4ZreZ4GlpltJ4SyPxkTjpaBqdXkc2nsVoMaKiUiwUyefzmI1m/G9KXfxMJEN8VLavrMKZjWdRdIq8F05jqbGQS+e49PNL1HbWsv3J7Yt+F95NqBL+MqAZqf/hPwi5K4pUxtQscr1eXDG1tfBLvyT7HD4s233gAxKodbnEtXPmjEgzw2Hx3WsxgPFx6Y1xwyhwrhRXoJevdLu4LW7S+TS11lrMejORTIRTq2289+0wxJPYa5qoL5jJTIzDry/NjbSYDHQpqwCYXhxtlXsV4XR43kCrZiX/PPpzaow1OAtOMIEuosPYaORi4iIP1z7MBeMFAokAdbY6nlj7xDTXUyXsaTs9b/dgiBvwuX3c0nELBUcBm9E2lYhldpmx19tp3dXK+PHxqZLD9Rvqcbe5paxxJI3VY6V+o7w2l5xRO96Fn1zA5DBhdpkp5AoYjAZ0Vh2Drw+ydvdaTE4TRpMRnUFHy64WCpkCob4QBouB+i31hM6FpOJlMo+1zko2LCUcdEYdqqqiFlTUnMQZxo6N0bKrBYvHQiaWIXAqQG177bQVSNQfZfzEOImJBKii//e0eXA0OC7bf3/2+bMc/cZRYsOiXNrxyR1sfHTj4jteY1QJ/zJgtUozcYNBrHgQJY7FAmfPigtozRpxC4Hw2eiouG8mJ8Wyb2oSSx9kFTAxIYHa2lpxFXV03DgKnMvGFerlKwl3fc16Xu1/FUVRuLftXvac28MhXYr8tgZ+YdKNJ5LG0dZGbNedKzaDLjUZ7Nkzz1JnrZsqf6w9zhVo1azkseAYXo+XxEhCAqi5PPa8XQrIbergvc3vndonmoliM85O5/Z3+4l/Pc6xzDHMCTN2gx1do47GBxt58gNP4nQ66dnTA4g/22AyUNtRO5VHcPjrh/Gs9lCztqwMU4sqgbOBOXvXaoldiUACe4OdQq5AMVcUzbvDSHw0zvkfn2fgjQFJtiqoJINSlM292k24P0zt+lqatjfRsK2BQq6A3qZnIjEBSEyhkC2gFlQUg0I2kaV5RzNWj5V0JI3b56a2vZZcIje1AjG5TRz7m2PY6m24fC5ycekL4LtTavdoWA6Bn33+LPu+sA9LjQV3m5t0OM2+L+wDuO5Jv0r4y0RlLbBLlyRQq9dLANbhkMBuJiOWemenELcmudTg8Yi658UXJSh8zz0SzNV6g2iunBtFgXPZuEK9fCXhJrIJ7l11LxOpCY6PHuc9be9hODZMWlF4sdXM3W13U2+v57END6/oJSwlGWwoOsQq9yqi6SjD8WGSuSQWg4WR+MisbTUrudHUSFwfx9kivm5USOgT3N5+OzlbjmgmuuCqIuKPcODPD6D0KmxlK/3efiaLk7iGXdT/sB7nXSJH3PDYBoa7hxk8MEjwbFD2HYiw6YlN01YAGsL9YULnQ7h97lm9a7XjHfvbY1KDv9aGzWsjPZkmPh5HzauMnx5HLaro9Dpy2Rz+g37sDXb0Bj25eI50OI17lRujzchtT93G0WeOko1K7Z7YcAxFUTC5TFicFlKBFIVcgXQkPeWXt9ZaiY/F2flpKRz508//FFudyDt1Ot3UtQzsG2DHJ0WHv1wCP/qNo1hqLFPNzrXHo984WiX8dxsqaoHxrW+V/faqKoQdiYhfvq1NVgJr1sAv/zJ88pPlY7S0CJlbLBKk1fz/qlqWfUajN5AC53JRSlIIJoL0TvYSSUdwm1xsDHioWXxvYDbhPnfmOXwuHy6zi2BSjjsaGyWZTy65bs9MzJtxu0S0ulrxR/2MJ8axGC3YjXYmU5MoioJ/Rj0czUq+z3Qf385+m7ySx+6xo1ujI6FP8Dt3/Q7NzuYFVxURf4RDXzvEyJERCvkCtc5ammJNFHNFisUiukkdh752iJr1Ndi9dhSjIoHUZueUr37/0/vZ9lvbSIel76yWaBU4GaBha8O0GjYTfRO88JkXpMBaq4vNH93MqW+fwmA1YDAbyGVyJEYTWGosUmFTgWJB+rwmx5Okw6K7t9RYUPQKF1+5yJnnzuBscdJ2bxuZeIb4SBzPGo8Ea7MqRpcRo8NI5GIEW4ONiXMTDL01RNt72mi6pWnqXkSHothb7IwdG0MtqlI/yG4gGUxOJYUtl8Bjw7FpcQKQWvyRwciSvxPXClXCXya0arj19eJzb2oSZU6xKFa6VnfH5yv75//5n6cfIxCAu+6SOjrnzslr9fUi1+ztlckkHBb3zpe+JDGA226Dhx9+F/nzS0kK8Vdf4pIhTMxXx5g5S/D0W4QnU2zMhFnbeceya+BUBnLrbfXU2+opqkXG4mOXTfbzZtxWHG+hSeGJTU/wBz/+AywGC0bFSCwbI51P8/51759VD0ezkp3dTvKDeV4zvUa0PsraurX87qbfnXIBzXctWtA3EUhgtBrJBXOki2l0Rh16k57shPjDk8HkVM2Zo988irPZOYvwBl8b5I7P3DGtzLJnnQfPas/U+YLnglz46QV0eh3eTV7S4TThS2G2/MYWBl8bZKJvAkVVaNzeSDaepZgpUsgXMLvMU81KLG4Lte216C16ev65B7PLTF1nHelwmlPfPsXOz+xE0SukxlOggKdd2hgmg0mGDw9LaQuPmXQozYWfXqDjkY6p8ZldZsbfHsfeYCcby5JL5kiFUtM6Vy2XwJ0tTlnB1JXdaOlwGmeLc4Fv0vWBKuEvA36/EPIPfiBWeSIh5B6LiZWfTMpfPi/bTkyI2+f0afH5t7fL/hcuSNB2/Xpx+ZjN4vIZGoKPfEQqbr74ogSDt22TY7/xhvjzNWnoDY2KPpHjF49hTMYxdw/gbajBNxjlTGctP4q9xa8FmqnbM7ygT9/vhxf3BTncO4BiD0BrgE3r0tNUK9P088vEghm3JdLt9nfzzJFnKKgFvHYv6Xya4djw1KTQ5evi3lX30jPRQyApgdYH1z5Ie127JHLNgFbaeBObeJInlzVeLejrbHISrYuSmkyhFlUy0Qwmu4lsMkvNmhrsjfapmjP5ZJ5cIjftOBZPWYJZGdg889yZaW4e/5v+qb63Or1uigRTYyl+7blf48xzZ8glc4yfGmf85Dg6nY5sMktyIkliNIFOr8PZ4sS3y8fhvzyM2WVGb9JPO9a5PefY/rHt5JK5qfP2vdhHLpmjZq10rsolpTGLoleI+WNQCo14VnsYPTKKolNwtDrEbRRK07ClXDVxuQS+45M7plw+2oooHUqz6/cXb9N5rVEl/BKefx6+8Q2xsltaxAUzU5L5zW9KLZ2NG4V8/X4h4+3bxWr3+8XSX7tWrP/9+2X7tjax2o8dk8St1lYh/vFx4bKODpko6upk3/37JQ5QWyuWvraKCAbfJaqdCt99f7ARtTeKMVqgpucSr2/wEPEU0eWSnMuPSqLWPBft98O3vhPiXOIIdR4Taq4O/5H38NPod3j/dljtWT2vj3upWDDjFrHsnzn6DAadgQZrA6l8itOB02z2bp42Kdzhu4OtjVunqWmimehlT0TzrSi0oG9tRy2hgRDJUJJUMEUmkkGn12FxWnD5XNNqztgb7CQCCbyUx5IOp3G1zlb+aC4nEDdPuD8sFS0LKsGzQZwt4hYKnAnw1jNvcfzvj2OymLA121AMCrHRGLlYDrWoYqmVpipa56nUZAqz24zBVKYlzdKeeV69UU8yIG4Zi1vq1eeSOfQm/bRa9ZYaCxt/ZSP+A36SgSTWOisb37dxah9YPoFrbp6j3zhKZDCCs8XJrt/fdd377+EdIHxFUR4Cvgrogb9SVfXPrvY5l4vnn4cvfEECrm1tQrJf+IK8p5F+d7cQbl2daOmbm+Wvt1cmiN/4Dam/c/68vP7660L29fVy3KYmseRHRuSxtlaCuSdOiNsnEhFfP8jzfF4s/aRUksVqle0DSy+QeP2iosCQpcnHq5mLpJrs7D6UItZcQyafpqgWJXu0dde8UqXubggU+qj3mESlYi6yCjfh8KMMxV7DYrAsXEZ5CZLQxTJuu4e7GYmOEEwFiWfjOEwO1rrXMhwfxmIok8pSJZxLwUJuJi3Qaqu3sf6B9Vg9VoaPDFNIFvBu82J2mKnfVD9VGgGgcXsjF356geREcorwUhMptn9i+6xzx5wxem/tpfdsL8Z+I+ih0dyIzWujmC0S7AlKoTV/jGN/c4yIPyK+80sm3OvcGE1GcsUcerOexm2NFItFzE4zE+cmpJNWLIujo5wRq1nalQHmygYnxXwRtaiST+fJJrJ4V3unJVPZvXZMdhM7Pl4ulKa1NNRwOQS+8dGNNwTBz8RVJXxFUfTA/wLeD/iBbkVRfqCq6umred7l4hvfEFLWauFoj9/4RpnwAwHJsK2tqPXl9YrPPpMRTjIa4Td/U6z4f/gHkV9q8s3bbpN9Dh2S7T70Ifg//0deq60VcreU+MHtln0SCXkd5Dwm07tEtVPRFrCjtoMXzr2ANZUjXG/DmEiTNKt4LB7i2fiCUqVAALK6CWqMnqnXrLY8qaCP9TXr+fTOBXrKzpCEToz1M/iXezl55zrs6zZMWcyLEfUh/yF6Q72Y9WZcJhfpQpqjY0eJZWPsai1biAtJOLXM2pkyx/nQPdxNYbjA+UPnp/q8eu7w0O3s5n1d75uyhK21VtruasO7yTulotF8/JloZioQa6+3c/e/v5vB1waJDERwtbrY/ontsxp1T000Lg877tlBz5s9DD0yhP5nevK9eVBAzamkI2lMbhO5RA5bnY1UKEU2nmXi3AQGowG7VwqhNd/WjIrKZM8kkcEI7Q+107Onh3wqj8FsmGVpz3QvNW5v5OgzR4mNxHA0OvCu9qLT66bVqp+5MpiZHazhRiXw5eJqW/h3AH2qql4AUBTlH4HHgBUn/MqOc6GQkGhn59JifsPDYtlXwuOZLqX0eoVwU6lyB6t0WiaH3bulJLJWgA3g139djms2y58GzeevKPDgg+K3HxgQf39fX7lwWrEoFn1rq3BeKCQxgCsoPXP9oKIoUL2jli3mNsYne/nxdie3+fO4zDVkdCZqc4YFpUpeL5jCdaRziSkdeippwOSKLO4qqXArBRNBDsZO47Ea6LgQpq8tOS0wu5DW/mzwLHXWOlK5FAUKWA1W0vk0A5EBulqmf1hzSThn1p+ZKXOE2e6bQ8cOUfhZAYvTgs1rIxfP4f+hn1QhxeO/8vg0S3hmNuxMS7ny/cUIb2Y8wxA34K3xMrZ+jNpTteRSOQxWA4VJaRxucVnEH2/UkRhPkAqmsLqt1G2QOvj+g358u3w0bGugdVcrLV0tpKNpep/vJZvILmpp+7p8OJudC06WC13vzYirTfitQAVt4gemOcYURfk08GmAVatWXdZJtL6w4bC4QxwOIdUjR2DvXnjqqYWJsqVF9tUse5D/Wyqa2nR1Se2bvj4hY0URkrbZ4Cc/ge99TySVdrv49B0O8dtPTkpNHg3FoljvBw/K87ExIfSJCenvHSqVh3e5pMbOxIRMLHffXVbpdHdLRc7KGvw31EQwo67Oat9mEnfvpNae4ZLfz6ZLCdamDNia1iwYsO3qgtMX2jkX7qbOBWrOQSiUp/2ui3S1PDht25mkeV//OQoN9fQOnuLoyFGMeiNm1xq8odgUoe3t20u9rX5qn0c6HpntGlLAYXTgMDmIZWLEc3GMOiNNjqZZ287ld491x6bqzwBTj1oVx7ncN8dPHsfn9rHKsYpcMkcmmiEcC5P/YZ7IrtmB1plY6P2FVhsz4xkWt4XIyQjFpiLtbe2A+NEv/OQC6Uga1SWJTQazAZ1RNPCetR50Bh0g2bxjx8eo7ailtrOWg187yOhbo5icJswOM2ablFqI+COzxjtznB2PdMx5Tf5uP2eePUN0KIqr1UXTjqabluzhOgjaqqr6deDrADt37lQX2XwWurvhD/9QCD4UErdLPi8Wu8sl5PrMM+JXn8/S/+Qnyz57j0fIPhSC3//98jY+nyhk9u6ViURVhWzffluSqLR6+GfPlv32994rvvxcTqpqhsPizrFYykFYnU5WBc3N8nzbNlkRbNkik0llMxXtep9+Wian+Wrw3xCoqKvTFvFzpGcPWyweHK27iO+IczYdXrRfrc8HT360hhf33Tal0rn7/UUevu3BWZLJStLsD/fzN8PPUzwXx93QRjqfplAscLj3FayuOsb8bmrMNRwdPcovdv7ignLMzrpORmIjpPIpDDoDrcZWrAYrzc7maWOdz+++ZmQN61vXT9u2sorjXCqhplATQ3VDuFNu8kN5suYshZoCzb3NV9Rxa7HVxsx4Rm1HLWffPIvH5UE1qORT4kdv2NHAwOsDorkvueNz8Rxmt5mGbQ00397MZO8k6XAaVVXZ8NgG+l7sY+C1ATLhDCanNEdPh9MMvDZAfWc9t3+qbDX5u/1Tte3tXjv5dJ7YcGzWdfu7/ex/ev9Uc3Ytv+Cuz901y111s+BqE/4QUOks8ZVeWxFoTcBjMfGjp1JCnqoqrp1YTIg0nV5Y3aL56b/xDXHjtLQI2VeqdED2f+qp8v+f/7yQ7kzf/+SkvAfS6Py//BcJ6OZyUk5h1SqZjE6flsnB45HHZFKCs6HQ/GUVnn1WzjPznJWtFm80LLtfbeW+PvjUb9TzKern3aaSNIPJIKcDp4m2Ktx7NI81meNiahxTKos3b+L4LTac+Qw/GvwR7TXtC8oxQTT2T+9/Gq/Ni8fiIZwOM5Ga4IlNT8w7Bu14E8kJnlOfo2WohQZHA9ts22gyN00rOTyXSmiVZxWFVAF1UiVmi1FDDZ2jnTTVNl1Rx63KapcA8bE4F1++yMnvnqTtzjZ8v+jjkOUQIPGMgqOAdaOVjoEO0sm0dKPa2ko2liUbyRIfi5NP5lFVFZPLJL1gb2/BVm/DXm8ndDFEbChG7wu9nPneGVKTUnFUb9IDYHKayMVzjBwegU/JGCP+CEefOYrOoMPaYCWfyhM4HcC72Tvrus88ewZrnXVWfsGZZ8/Mjk/MWAlsemLTu3JSuNqE3w10KIqyFiH6XwV+fcUO3i2WczYrrhytHr1OJ1ZyLCZumM2bF1e3PProbIJfDENDQt6V8HjKvXFBSLu/X4heWz288YZU1HzPe8rllYeGxH1z/rxs19BQrsWz3HPeiFhyv9rLQCVp9k72YjfZGahz8OYOPQ+HHdQHivQbM/TfvoYxp7TYzRQymA3maceplGNq6PJ18bm7PsezZ55lIDJAq6uVT2z/xKwaOTOJO5gIcipwirQnjXPUSVQX5aXcS9yjvwdPwjMVVJxLJVR7Ry2JHybYfH6z+PATOTKxDL7HfVdU472yZvxE7wRnnzuL0WHEZDORiWW49L8ucce/vAO/0z81MT/58JPEX4pj8VimgqJ5fZ57/997GTs+xsjhETKJDCoquWiOseNjNGxrIJvIcv4n56fq5seGY6RCKYxW4xThq0i7RFUpL/yHu4cp5As4vU4URZlS28SH4xgs0+ksOhTFvWqOhKqB6QlVN9NK4KoSvqqqeUVRfg/4MSLL/GtVVU+t1PEDASH2cFiIM5cT6z6fF9dJOl22/K+GuqW1dW7ff2tr+f+5FECplLRV/OQnZUJKJGRFUlcnFr7BIMldlb7/5ZyziumoJE2tjLJBZyDS4OTMto28tT5BKBkiT5hkJInVYKXD00Eql5p2HE2OOZcv/svv//K0bWduoyjKNOLunexFr+hZ1bSKtrVtTPZOEgwF6fH08LHHPjZlqc6lEtK36PnIkx+h78/7iA/HcTQ7WPvgWuo768lEM8uq8V45zowpw4bQBlbXrWbwjUFpe2jSozfqp6zj8I/CPP7l6X7GiCMyZ1DU1+Uj8lDZTZRL5wicCHDhZxfQGXUYrUYsHgsGqwF7o53YSIz4aBzXKrlHWoJXy23lYJo2KU01OwcMVgPxkTitu6b/CFytrjkTqmbmFyxnJXCj46r78FVVfQF44Woc2+sVQrfbheT1eiF67bnDIX7wVOrquDueeEL851C23icm4BOfKG8zlwKouVks+bY2ceMcOyb1ecxmIXyN+F97bfaqYynnfLfBH/Fz4shedIeP4E2orOrYSf3uh8DnW1Kdm66WLr557JsEU0HOh86DCjaDDZvRRjKXJJqOMhgfxG60s752PXXWOkKZEEbVOKtIWWdt56KlFuaKGRwYOkA8E2dd7Tq2ebcxlhjDoBjoqO3AbrNjr7PTqrYyFh+bCtZq12XWm0nmkiSyiWnurs51nVNkanKYyEQz0ySH/oifvX17OTJ8BFVR2dm8k4faH5p3nGNrxvjZ4Z/xIA+SCCawuC0UMoUpK3ku6xhmB4H93X4Ofe0Q0aEo2USWpu1NuFe5MbvMOB5wkIlmOP63x/Fu9k6RtneLl1QoRcQfIZ/MoygKZqdZeuM+3D51bM1nHzgtS3aDxUAqlELRK9PkmACbntjE/qf3T419vvyCpa4E3g245kHbK0FXF3z3u1K98vXXxTI2mYQI02lxfRSLUqP+amSndnVJsPTZZ8tdsT7xiemTy3wKoDVrygHZkydlrHp9eZtCYW43zVLOeb1hqc0/5oI/4udnr36Tzfv70NXUEPUoHDn/Gl2jY6Qe/gB74ocoFAuMxEc44D/A3r69PLXjqVnHV1AAaLA1MBgdxGl2cmvTrZydOMtAbACL3sJq92qMOiOngqdQVZVGeyNvj71NraWWzvpOdq/evbRSC3PEDPToyRazdA918+O+H+MyudjasBUqZAqVK4iZk0q4FMSeq+7OXNa1P+LnS/u+xOv+18kX8jhMDgbDg4zFx3hy+5P43L5Z19Lc3Aw7oedSDx6Lh0K2QF1n3VRW6nzZt9M+rxnukYHXB7jw0wsYHUa8nbLMNjlM5FI5Sh8JABaXhebbmjHZTXi3eFFUheadzVON0DW0dLUQG47h3ewlPhInNhJDb9Bz21O3zYpb+Lp83PW5uzjz7JkF8wuWuhJ4N+CGJnyfDx54QAhz/XoJdqZSYvF3dorVnM+LnPFqoatrYbJdigJouW6axc55PWE5zT/m3H+4m7V9QQw1deQdNmwAHoW+dID8S89S6GrldOA0dpOdZmczoVSIZ448Q7OzeRoBr6lZwy1NEhQJJoMcHzvOhdAF6m313OW7i0Z7IyPxESZSE0QzURptjTQ7m7ml8RbC6fDUyuGF3hfmLLVwJnCG5848RyAR4MjoEbpaunCZXfRO9lJUiwSSAeLZOE6TE6vBSraQZTQ+yt++/bf4nD7q7HXUW+v5+PaPTxFxNp/l4PhBIpkIRr1RJrPbn5p27vkklv9w4h946dJL2Iw23FY36UKa3lAvTrNzanKaKyDc2NTImGOM+790P/uf3k8xX6RYKC6YfVuJM8+eQW+WsgeR/gjFfFGqgr7pnyL8bDxLw5YGUhMpFEXBYDGQT+cpZovc+rFbpylyZqJykjNYDLTe0bpgopqvy7eoW2apK4F3A25owgd46CFx66xbJ/7wVEqajTgcQvZPPXVta88sRQG0XDfNjaTDX07zj7kQSARYG82SrS+nOFuMFiayIWwjQUbiOuwm+1TiVa21lpH4yDSLey5iyxVynAqcAgXsRjtus5uN9Rs5GzyL0+QkmUtOWb8TyQm+duhrrK9Zz9GRo2QLWSxGC26zmzpLHaeDpzk3eY7RxCjbvNuwGCy82v8q9625j0g6MlUKuaAWsBgsmPQmhmPDxHNxLEaLFFSz102tQgKJAHpFT/dwN3aTHb2i5/zked4ceBOAh9sfXjTA/dLFlzDpTThNEty06WyoqJwNniWQEHfIQmUjfJumW8eKTkExKRz86kHOtJ6ZV8Uy0TtBNpHFZDVhtBsp5ouEB8LkM/lpXai2//Z2zv/kPKlAilQoJc1XOmtpf6h91jFnYrE8g+VmLi91JfBuwA1P+JU5PMmkWM9btiw9y/adwGIKoOW4aW40Hb7W/KMSHouHgcjSZEVeu5eIy4QzmSLvEFJP59LUFU3km8XnXal5T+VTeO3eKVIDUGJtvPKajVzMg2IPMuQ4QtD4Nh6LlNkdjg8zkZxge9N2EtkERYro0NFR20EwGeTU+Cnyap7O2k6CqSCDkUG2NWxjPD/Oy5deRlEVtjZsnSLpjpoOwukwx8eO4zK7ODl+Eovegs1gw6Q3kS1mhfx1FrqauwilQzyw9gGimSjdw9147V729e/DbrKTL+Y5N3EOnaLDZXaxp2cPL198mQfWPjDNHz8TqVwKm8FGvpjHqC8FNxUDkXw5C3mxshGadVzppqmslz+XikVrQag3i3/S4rFgi9so5Auz3E6LZclWYqkkruUSFAtF4iNx/Af89O3tY8dTOxYk8KWsBN4NuOEJH1a+sfdy2qxeQUvWaViqm+ZG0+G3uloJp8NTlj1AOB2m1bU0WVFXSxc/az8lPnyKxI0K2egEt9o7ST3wAQznnyGUClFrrSWVT5HIJtjs3TxFan4/jB+5k1CimzpXiN7RAH0nOqm9dZy1TWL1J3IJcsUcA9EBhqJDZAtZ7my5EyipaXR66ix1HB05SqaQwagzcmL8BBa9BbfFTSafocHRgE6RDNKJ9AT3tt3L4eHDWPVWwukwFr0FnU5HMVnErDdj0BnwWD2k8incZiEuTfb5SMcjfPfUd2l2NDMUG0Kn6EhkEyiKQiafobO2k5OBk4zGR2lyNFFUi7MC1lsatnB4+DDJfBKragUFwpkwjfbGqZIPS81/WI6KpX5DPQOvD0iBMoeRXFx89WvvXzvVhUrDYpY6CIH37e3j4isXcTQ4aNjWQC6ZmzfBbLh7mGKhSOB0AJPdhLPZSSqU4sgzR3A2O684y9bf7efYXx9j/NQ4RquRtQ+sZduvb7thsnffFYS/kujuhj//c9HOJ5Oi8lm9Gv7gD2YTqt8PX/2q1LaPxaSUwptvwmc/e/VWFjeaDl9LTAKmJSZ9YvvSZEU+t48H3/txTjhKKp2wyqqOe6nZ/RA1Ph9PueCZI88wEh/Ba/ey2bsZvU4/RWrd3bCmqYYW/W30TvYSU4YwWvN4gg/ivlVu2ub6zbw99jaTyUnuaLmDdC6N3WznwNABQqkQNdYa9Oh5uf9ljIoRm1Es5/HsOA1KA5FMZMptZDVYCaVDWIwWbmu5jWwhy4c2fog3Bt8gko4wEh9hS/0WimoRm8FGIptga+tWoMKd4vbxwNoHOBk4STARpN5ej4JCkSIOkwOr0cpgZJBwOkwwFeT+NffPUgv99vbfZjAySDQbJZaJkSlkcBqdfP49n59G6EvJf1iOisW3y4fBamDs7bGpcsStd7ZO60K1VGjW+mTvJI5GB4pOYah7CN8u37wJZolAgvhIHJPdRCFXIDIQIZvIUsgU6Nvbx+1PzR8fWAz+bj/7/mQfmUgGS42FYrbIme+dIRFMcOe/uvOGIP0q4VfA7xey7+2VuIDBIETe2yuvf+Ur04n8298W6WRNjSRKxePyf319OdN2pXGj6fCXmpi0EHxuH777n4L75z6+1vJvLmmmVolZp6un3i7ZuCdMJ0mHPYAQvslgwmlxsqN2Bw+sfWBaa8RcIUeLo4U3B9/ErDdj0puI58T14TKJrr/eUc/pgNQDtJvsGPVGwukwZr0Zj8WDzWAjkAjQF+4jr+Y5Hz5Pk72JkdgI2xq20TPZw+uDr6NX9Dx1mwRlH2p/iEwhA4AOHSfGT6BDR4ujhXQ+TSKXYJV7FdlCdsrdA2W1UJeviy/s/sJlqaNmSl0zvsySVSyaimbzhzZPq045UzJZiZnuGqfPScwf4/yPz2OwGEiGkrjb3CiKxDgmeydp3dU6Z4KZ3WvHf8CP0W4k1BdCb5Y8Ap1ex8VXLtL+cPtlE/OZZ8+g5lRsdTZxWVkBBSZOT1x2dvM7jSrhV6BUywsQy95oLNfBGRubXZ7hlVdm9+BWVXl9JuGvlOvnRtThd/m6lkXwy8VCVmpFJWYAOmo7ODc8Stw6wEhshP5wP/3RfrL5LLWWWoLJ4LTWiGcDZzk+dhx/3I+iKkymJskX8tTaatEremLZGF3uLopqkeH4MC6Ti/vX3s/D7Q/zQu8LpHPpqeBrZ00nmXyGTD7Dh7d8mKHoED85/xNanC2sr11Ps6OZQ8OHphRGj214jBf7XuSliy9hNphpsjdh0BtIZBM4TA4UFNyWMsnMzAS+nPs+lyT00u2XqPvnOnz4FlWxLKc6ZcQfoe/FPi6+dFHKG2/zEhmMcPIfT9J2dxvoAAXio3H0Zj3ORicGi5RNriw/UYmWrhb69vYx2TuJ3qxHQSGXyeFe5cZkM10RMUeHoqg6FZ1JN/Wa0WEkOZ6c1nTlekaV8CsQCAjJZ7PingGx8lMpeX1meYZkUki3EiaTkHAlKqt5alnAS6niORduRB3+tURFJWYcDjAV6tlRcx/xtf/AS2NvE86EWeVcBQpcDF+keKHIA+seoN5WTzwbp85WRyKbwKq3kivmqLHWMB4fR1VVikqRe1bdg0lvom+yj2Q+yQc3fHAqmFoZfLUZbZyNnMVisOA0OyUBDLil8RY8Fg93td0FMBW41SaxT93+KR5qf4i9fXt55eIrOMwOulq7ODF+gonUBPc13jd1rVfSylGzsp8feB7VqVK3sQ5dnawc1mxYQ+pXU5hfN8+pYpkroLrp8U2Lnm/KXdPsQFEUhruHpUZOnZXEaAKrx0o+k8ez2kO4P4zFaUFVVfRG/Zw17UEmnB1P7eDH//rHGPIGrB7JB1B0Cg3bGq6ImF2tLlKBFMVscSoonYvnMDvNy8puvpaoEn4FvF4h0KEhIXmrVR6LRXl9ZnmGrVulWmZ9vRB9NiuF0ypr4GhuoqEh+SsUZBJpaZnbTbQUXC0d/o0k91wK/BE/3bFuYmsSDFxYT21gI52ra/jAwymeHRrAEXPQ5GxirXstKiqnAqcIpAKcmziHSW8inA5j0ptYW7uWRnsjA9EBLEYLJp2JVCFFs72ZbQ3b6J3sZV3NOtwWN1ajdcqX3tXSNRV8LapFwukw2XwWh9nBmwNvYjFaaK9pZyg2xH7/fiLpCC6zC4/ZM+06fG4fT93+FA+3Pzzlatni3cJ4fByT3kRRLS65g9ZcmcnOmHMqYzfpSOLOuRk6METrna3Y6+w4TA4SzQne/+X3zzreUur5zwWtUFshV8DisaDoSpLU0wGadjSRjqRp2dmC/6Afk8OEvcGOWlCJj8VZ+8DaWQlZ0+5Xl4/tT24ncDIgx3dbqO2oRW/ST+t0tVxsemIT46fGpTNYyYefCqVYtXvVgi6r6wlVwq9AV5dUsBwZEc18Oi2F2NraROc/k/w+8Qn44hfLXa+KRfHnV7pX9u6FixeluFukFONS1fJKQrP0rzWua7nnEvxhlUSmU3RMpCY4PnpcqlA2b6Ot7QLh9BF8LXdwaPgQwWQQs86MgkLPRA8b6jawpX4L5ybPMRgZ5I7WO9i9ejcv9L7ANu82uoe7WeVaxWR6EqPOyERqgvdsfA+BlJyvqBbprOuc5kt/fNPjU8HXcDpMvphnLDFGMBXEZXZh1Bk55D+E1Wil3laPx+IhlAoxkZyg29+NP+afFZeoLIuwt28vr/e/jqqobLZsZtvENkaPjRLzxuaULVa6a/SKnn39+/juqe/SEmzBoTrQZ/T4s36yhiyNjkYmeyex19kXXDnMrLA5s57/fNBq4ljclqm6OAarAVSJD1g9Vmz1Nny7fIwdH8PkMLF69+pFNfUa2h9qp5ApTCvqNt+qYKnwdfnY/YXd01Q6m35l0w2l0lFUddkl6K8adu7cqR4+fPiajsHvhxdfhJ//XOrVe73ScOmhh+a2xBezin/3d6VpyltvySpAiwvkctL2sL293OrwWuLzn5cAdWUweGJCXFtf/vL8+10JllIHZ1orQodDHPLh8LTGKJVEls6nebX/VQYiA6yvWY/b4iaRTbDLtwuT3sTbY29zS+MtnBo/xcnxk+h0pWYcOiOr3KsoqAW2eLdMNT45HzpPq7MVp8lJ72Qv/qifyfQkJr1J4gHBc2z0bqSzrpN6mwSFi2qRsfgYn9756amxFYoF/unUPxFIBjDqjTQ7mklkE4wkRvC5fLx31XunZKWaHHP3mt3T9PGaAqfyeh0mB2OjYxw5eIRGRyM6iw5XzkV7pp33/sp7pxHRc2eeI5lLSgbv0EHsJjvRdJQjJ4+wyrGK2x23k1bTHEkcYYd1BzWpGprvb+Zi6OK88s/DXz88paDRoBbFEp8pw6zEmefOkEvmKGQLYsXbTahFlUw0Qzaepe3uNjyrPVNEfTk1/pebgHUjQ1GUt1RVnf+Gl1C18GfA54NPfUr+loLF3CuqKn/a85mvXy/z7Tst91yoEfc00i+1Igzqs/QOHSSSjlCXN7J234vU/4Z8SJU1YU4FTlFvq2c4Nkw4HZ5Kyuqd7GVX6y6GokO8p+09dNR2MBgZ5ELoAtlCllg2RjAZpLO2k/H4ODajjUZHI+l8mjcG3+DutrtZX7Oe4fgwddY63rv6vVgMFkLpEM2OZupt9QQTou4ZS4xh1pt55q1npBa83sSR8SMUKbLOsw5FUUjn05KAVSgQzUQZjAzS6mpla+tWzk2eo6AW5q3XM7MGTqAvwLBxmJSS4g7jHST1SfYX9uN4w8H9Hy1LmzTp6MHxg1Nxhf5IPyazCV1ex6uxV/EavVgVK33xPja5NpHMJVFQsBqtU5NP5eekNU3XLHtg3oBqJbResxaPhdauVsZPjBMfj7P2/rU0bm8k5o9dcUvCpej8bzZUCf8qY+dOOH4cmprEI5FOy+tNTRL03bnonPzO4B2Ve/r9DD73NXYGgigNjUS2daBrEut4ZoMRAgGCDj0Hh7qxG+14rB4SmRQnTr5ER+ShWTVhtPLHbrObSEZ8aBaDhXA6TDwbp9XVSjwbp95ez/am7QxEBghlRDffYG/gdPA04UyYRC5BR20Ha2vWAjAUGyKajuKxeLi18dYpa36rdysH/Ac4Pnac3olerCYrdr0dnU7HG4NvcG/bvViMFiLpCNsbt2MxWsgX8vRM9NDibCGTz9Bkb8JqtNJR20G9vZ7XBl6jwdEw7ZZVKnBmloroDfdSY60hr+bRKTocegfY4PDoYe6v0LJqpRQimQg1lpqp++X0OBkaHUI1qawzr0PJKQQyAT5yz0foUXuwGW3zTj5LbRI+E5VqnmwiO9tdcwVuRC1Za/jI8LxF2G5WVAn/KuOhh+Dll8UzoUk89fpygPihh671CAXvmNyz5KJJhgLYG5swJjM0vnyQsfftothYO6vBCF4vF3v3UVSKDEQHSGST1Ob02N3eKdKprAnjtrhJ59PUWmuJZWIkc0lUVZ3Sxj+x6QkODUvXpmAqyJYGSYLqqOng2NgxJtOTxDNxUrkUg5FBtjdtJ5gKMhQdwmF2sK1h2xTZg+juE9kE0WwUk96EWW9mIj3BhroNALzQ9wJNjiaimSixdIysmmUkPoJZZ8ZhduCxeqi31qNTdPRM9mAymDDoDbQ4pgcBK/3oM2vgZM1ZdDkdDotjantj1kjYHp52DK2UglFvJJFLoFN0En8wFXE2OdHH9OQS0oh8Xes6etSeOesQVU4+V9Ik/GpY4BF/hANfPcDI4RHy2TyFTAH/IT+XXr7Erj/YdVOUT1gIusU3qeJK4PNJlu7GjeKzv/VWedywQV6/Hmr9QFnu6XSKG8fpvEoB25KLxlbfRLqQIe+wkXfYcZ/onTs42NXF5MhFxkf6yOWy1OUMGKIJXmtIcy54TjZp6SKcDhPNRFlfs55gMki2mOXBdQ9SUKV08lbvVlHO+Lp43HEH6/a9zfpnX+bOwyPcb+jgYvQiQ7Eh7Aa71NLR6bgQusAPen5AJB3B5/ZNFUULJoNTwzsxfoK1tWtZ7V7Nnb47ubXxVow6I0OxIfrD/UQzsipwmVwcDxzHbpBiaMl8ktH4KPetuo8H1j+A2yIljW1GG0/teAq9Tk80E6WoFolmolMVO2deb1Et4m5yE0qFaC22ggq5VI5oLErHxo5pt1LT9jc7mjk8dJijo0dpsjcxkZwgb8jTvLqZQGuAC9YL6Kw6eoI9U5NLJWZ+Tm6fm02Pb2Lnp3ey6fFN19SS7tvbx8jhEXKZHNHBKJFLESKXIvi7/Rz48wNE/O++GvfLQdXCfwfQ1SVNT1Yi8epq4h0pu1xKfe3Qd3Bw6CAAFpsZZWyMcLp1tqzQ5+NwVwt1py7SFMuTdNu4tH0LMXse0pOySUVNmEQ2wb2r7kVFRVVV2uvapweD/X5aXjlES+0tsFVHMRrBeaCXH9aexdngxqg3Mp4YByBbyBLKhCRYafFyMXyRk+MnOTl2ki0NW6i11XIxdJFf7vxlzofOk8qnsBlteKweeid7aXG04DK50Ck64rk4az1rURSFRkcjJp2JJkcTef7/7b15cFzneaf7fL2v6Aa6G2uDIEiA4AJR3ECKkiWOLFuiFNkybWXi6zixbFmqbI6tiSsex564ZiZOxY7Kurbn3kxJVuxMxTexSw4jmxYpWZYiUQspUFzEHQtJAI2tF/S+L+f+cdDNBtgAAXABSJ6nikXgdPc5Hw7I93zf+73v75fDaXKiU+tYWS2bmR8ZO4JOrSOZTZY0dPRqPS/1vlTaNC3XwNm0YhMOgwODz0A8GKdgLWBeb2bHbZVLNC06C7+77ncZiY3gi/sw68xYNBb6w/3Y9XY21G0gJ+U4FzrHfa33lVZElQTWlhojh0fIZ/JEhiLkU3m5SaoAiUAC/xk/ffv6ZpVfvtlRAv514moLvN2wTLa+OqucbGvaRu9EL3H/GCaX69IN20nUzS0csU7qyGiMJHNJ8pl0KQ8N8/DEnVxhUFVFu3oVB9MHARXt50K86zAgEGys20g0GyWaiWLQGmivbqc3KOvamzVm/Ek/F4IX0Kq0mLXmUr6/+ACr1leTzCZJ5VK0V7eTyCYIpUOsd60vOU8dHD6IUWsklJRn6heCF5CQMGqNU0xPtk6WkRYrcso3TXetuWg16GmbQ8UTUze4i/sT54Pn+dXZX9Hp6qTaWC1vKGcydLo68UQ9CzaYXwyEJMilc+STcrBXqVVISKhVaoRKTDFEvxVRAv4CudmalK4bZa2vTksNTts6kJrkMssZgkiHswOT1sRYbIxgKohNb6PF1UKzrbni+2elKK4DOM2TDx1/D65z4Il4MKqNhFNhVCoVGrWG1Y7VBFIB2fg8PIhZb6bOWscy27KS3MEJ7wl2LN9BV2MXx33HiWVjbGuSy0Dz5LGoLayvXU9BKmDX20vXPeY9RoECJq2JWkttxc3RF06/wPq69RU3TYt/n/WfJZgKlpy5Zgr2UNkboMXeglVvxWawEUqFsBlsdNZ2UmOU91SupcH81aZhSwOebg9SQUIqSBQokM/k0Rl1qA3qKYbotyJKwF8A3d1yw1UmIzdm+Xxyw9Zf/7US9C9LuYHB+Di4XIxsXMXBaDe+Qy9VnJ12NXYxEh1hXe26KWmFrsauudXylzNNXMdpdiIiUTzL19JiDcu6OvkMqXwKvUpPX7CPRDZBZ20noVRIFjCzNpYqf7Y1bZO157Wy8uWOlh2lXHt5rfxAaIDf9P+GdC7N3t696DS6ksOV2+bm2UPPYtFZpgzVorOUykjLSWVT7Ovdx89P/hyT1kQql8KmtxFKhjBqjYxER2ZcLc1ketLuaKeztnPK8Ug6smCphsWibWcbF167QDqcJjkhe91qTBosTRY0Ws0UQ/RbESXgL4Af/1g2WimXVPD75eNKwL+UikF50tB3LvX4M+m2A3Or5S8bx3G7H+uB19E7aml134ZTMjA0dAL13XfQmushU8gwEhuRLRMtDTiMDj4Y/wCj1kiVvgqH0UGVvopENoHNYCOWibHKuWpKegVka8eT3pOc8J3ApDaxsXEja11rSRfSZHIZ4KLPLswciItlpMXj/rif/UP7CaaCrHKsoi/YRywdw2l0YtQaGYuPsc617tLy1klmMj0pr1660lz99N+32+qu2DV8LbC5bWx7ahvSMxKBMwFQyUbnao2ahq6GKYbotyJKp+0CuOceOQ1sNF48lkzKpYxvvrlYo7r6zHv2PMM5yme607tGi92f02eWJq3pkiA6nfl8tnwczokUhiPHKXjHua3zPvbZ/VhXruGV/lcYj48TTUflP5koHY4O0rk0DVUNdLo6+XXPrzkbOCt3xFobuLP5Tr55zzen3JdyH9+iB8Cx8WM8sPIBNjZsBC766qazae5vux+31X1Jrr5SDv/1C68TTAYBcFe5OTp2FI1Kg06tY5VjFaFUiPtX3l/q9J3P7/Va/L4HQgO80v8K9ZZ6MvkME8kJ1Co1D696eE5WjQvlVqvFVzptryEmkzyrLw/4mYx8/GZhzp2wl2F6V2gmn6F3opdvv/lt7m+7n7P+s6xxTVVWnC7zOxOXqxGfaRyZhipGqm7nmPcYP8sdwqaz0RQawGaw8cH4B6XKGKvOSjwbJ1/IU2OoYSw2xgfeD9CqtaXrvjX4FkdHj065J5V8fDUqDUfHjrKxYSP+hJ+DnoOYtCaEECSyCd4beY+tjVvxRD2XbI4W9f7HY+OkcinuabmH/mA/qVwKk9ZEJpchkU3IqZ3JVcdsqZiZcvJXmqv3hD388L0f4k/4qTPXydITgR7C6TDpfJpsPks4EyaRSRDLxPDGvHxuw+euSdC3uW1sfmIzm7l1K3IqoQT8BXDvvbB7NwgxVd5l1+wT0huKvYeP03u0k2zUjq0mTfttYezVFTphL0N5UO4N9PJy/8vEM3Fi2RgTqQkmkhOkc2k2NW4qfWauMr+zmXDPNg5/3F+qklGhosnaxNtDb7POtY5IOkKukEOv1pdy6nXmOiQkTvtOs861bopdYyAR4Pkjz/Pw6oumxZV8fJ1GJ2OxMfk+TPRi1snSA+UPQ0/UU3FVUx6Ii6ua9pp2DnoOUm2opneiF51GRywdo8XWsihlk8UJgi/uo95STzqf5uDwQc74z6BX6znpPUkql0Kj0mDUGBkMDfLq+Vc54z/DJ9d+8pqmeRQuogT8BfD7vy/n7E+fBq9XblK6+275+M2AxwOv77NS5zRQ7UiTTGg4+FodXfcWiFsG5nWuYlDO5DO83P8ykVSEwfAgqXwKf9yPy+TiVz2/AiCVTzEeG0ej1vDExstLiF7OhLvSOKr0VVMDrtE+RT6hwdLAWHSsVDFTY6xBIKgx1DASHbmkMshusDMUHppyrJKPr0lrwqQzyU1UyRB6jZ5kNlmyNyyuTC6XVin+zHaDvaSLX6WrorGqkeW25TTbmhcleBZXUPXWetK5NCatvNz1Jrxkc1kimQhmrdx0FsnID9Wmqia8SS+JbGJBq0eF+aME/AXgdsu+tUu9kWqhdHdDrUOPSh9DqEyYLDkAjh8xsGPn/Ko2igGqd6KXWDrGQHiAZC6JXW9HpVIxkZrAoDbw6rlXWeVcRa2llkZL4xTnp5m4nAn3dMnksdgYrdWtsqm4xlCqvgG5NNGgMXCH+w6GwkOMxccIp8LYDDbqzfU025pptDZWNGRvtE6t/Kjk45spZPjy1i+TlbIUKCAhsa1pW8l2MZaJoRKqeW1gF6uCvrr9q4seKIsrqOLKA0Cv1lMoFIhmomhVWtRCDQKyhSx6lZ54Jo5Ba7hEn0fh2qEE/AVyMzdS+Xxwm7uV7tHJTlitAUkbYXxcKpUczkhRu/7sWQgGcdfU8HtuB09nAiRyCdL5NHa9HaPOCBLkCjmyhSw6rY5PrP5E6TTlzk+zMVPeudIehECUtHUKFNjm3lbSxSmmgkoloK5LS0C1Qsu33vgWcDGQTyQn+Mq2r5SuWXzAbGrYJNsnhgZw29xTfHyLD0GdZqp5STwTZyQ2QjafxWaw0V7Tjt1gv+Q+LMW6+OIKymlyss29reQJXGeuQ6/RE06FiaajaNVaNEJO60SzUbbZtwFz37dRuDKUgK9wCS4XJBIXO2FDyRDanIP7Oltx25wzf7CoXZ/Py64vajWEQjiNRj7tMxJqcuPT+FCpVGTzWaKZKNl8Fq1KSy6fm3KqKw0AlTaLfUkfnoiHzY2bGYuNoVPr8Ma9HPcexxvzcm+rrCxZvmpQCRU6ta4ka/ClLV/ixZ4XGQoPEU6H6XB08Dsdv3PJA8asM2PWmjk6dhSj1jjFW7bSymRVzSq+d+B7NFgaSrr+Bz0H6WrqIp6JX5UKmm5P91UxNa907fL0Wo2xhnWudTRZm9jevJ0DngMMhgYZCA/IXa9CjVqtptZYy+ZGeVP1SuwZFeaOIp6mcAldXfImtC7vZFvTdu6s20m7uYudO2YJ9nBRtmBsTN7Ndjjkv8fGaG7uZP1AiiZrE+l8Gn/CTy4v68ho1BrSufQUUbK5BoA9Z/aw6192se3Zbez6l13sObMHkFMMxU3XYlWMChVCyNru0XSUfb37+N+H/jd9E31srN+ISWsqBa1da3bxUPtDpPNyPrroEPXy+Zf5nVW/wwv/+QV2tu/kl72/5KmXn+K94fdKDxiVUGHVWdnTu4fnjz5PKBVievmz2+Zm15pdPLnlSXat2YUn6qHOUocQApVQYdKaMOvMHPceL6V6EtkEdZa6Us7bE/bM+XdaLBWNpqMssy0jmo7y9LtP0+3pnvVzxQfZ5a5dfIiZtCbGY+OYtCYe6XiEB9seZIV9BY1Vjexo2cFq52rqrfU4TU7uW3EfNaaaS8ThFK4dygxf4RIqNMOyY8ccUlhF2YJwWPZ6BDAYIBTCUbeNB4NbeMsxgDfhxWawYdKYUKvUtNpasRqsHBs/xr3L751z08+eM3v41hvfotpQTbOtmVAqVEq5zLhJa7CTyWcYi48RTAe5e9ndCCHoD/aXbAanG41kchm6R7pLzVgnfCdI59N8Zt1n6Jvo4/sHv89r517jz7f+OVX6KiRJ4kdHfsTL/S/z4eUf5pkHnkEIMduPgi/uK1kpAhg1RgpSQTZMd0lTVivTc95zmYFXKhUtHp9tlj99pTRbvn2mVNPnNnyOfX37ODR6CLfVzcc7Ps6Gug0VS1AVri1XFPCFEH8PfAzIAP3A5yVJCk2+9nXgcSAP/LkkSS9f2VAVricL2qMoyhbYbHInmskkO77YbBCL0bpqK9/98J/y9Ve/jjfpRSBos7exuXEzBanAoZFD8woAzx95nmpD9SVB7Pkjz/PDh35Ymq1Pr4p5f+R9gskgPf4eDGoDjdZGzDqz7Irl3naJ0chB70EKhQKD4UHimTiSJFFjqOFHR37Ep9d9GoFgT+8evnfwe3z1jq/y7z3/zq96fsUDKx/gyU1PIoQoBeUefw8TqQmqDdU4Tc6SqmfRSrGYRgumgmjVWu5tvZdAIkB/up9oOopNL+f2a0w1paqeufRLVCoVtRvsDIZntjTzhD283P8y2VgW9YSa+nQ99TX12Nvs+PS+Of+zcNvcfHHzF/niNNWyritxOVFYEFc6w/8N8HVJknJCiO8AXwe+JoRYC3waWAc0Aq8KIVZJkpS/wuspLGWKwmj19XDypBz083loaZFzRDvkIP7JtZ+s2CF7f9v9s3fXTjMzzw6cx946tVW+WCZZnicvr4oB+MD7ASatCYfRQTwbp3eil/bqdlK5VEWjkeHIMGOxMYw6I1q1lkQ2wS9O/wKtSovT5GRXxy5S+RSvnnuVx/c8DsADKx/g4faH2dq0dYqv7bngOdQqNZ6Ih3QujUVv4e7mu0u9AHc138U297bSKmdD3QaeO/IcGqGhxlhDMpfk4PBB1rrW0mxrnvMMvFKpaCgVoqmqsqVZccwiKUhcSKAxaujR9lAYL9B3uA9HnYPTQ6dvap/Ym5ErCviSJL1S9u0B4NHJrx8B/lWSpDRwXgjRB2wF3r2S6yksccpzQYmELDhUUwPNzVPqVudTP1+i3My8rg5iMT52VuI1/Ri4Lwat8jLJYoqhvCrmuPc4Rq2RbD7LGtcaRqIjCCE4Hz7PypqVpXF4wh4CiQC/Pf9begI9sjQzspKmQPakNRqM+BN+3h95nwZzw5ThPrnpSbY2bS3JR9gNdk76TmLRWzBpTXgiHhDgMDroD/azvXk7IPcCGDSG0iqne6SbTlcnp3ynSOaSGDQGktkkJ7wn+OSaT/JS70tz6jauVCoaSAb4/IbKlmbFB4k77Mav96PX6ikkCnzg+4D6fD0rj67kbN9Z+vb2sfGJjdfMSWqhG81LneKKbz5Kp1eDq5nD/wLws8mvm5AfAEU8k8cuQQjxJPAkwLLpLtoKNx5zyAVdrn6+ImU69gBUVdG19qP0nP03jtUYSkEsmAry2c7Psvv0bnxxH0IIBIJoOspgeJDegDybD6VCVBurMevMXAhdYDw2zsc7Ps6DbQ8CF0XZPrLiIwyGBhmODKNVaTHpTEiSrFufK+QYigwhhODd4alzmTcH3yytVoqpoaLfLsjlqCDn6oMpWRun2AtQroHzUu9LJfni3oneknyxXW+/xN6xSKUN7y53F1/d/lVeOP0Cg+FBmqqappSKTqc4ZmPCyMaqjQxkBwiEA2TJsnZwLZaEBWu7lWQwyeHnDmNtsF71mX65JtEy2zJCqRBPv/s0X93+1Rs66Hd7unnu8HOMxkblpr3J/fxmezN7e/fyxKYnrtnPd9mAL4R4Faiv8NI3JEl6cfI93wBywE/nOwBJkp4FngVZPG2+n1e4MZlTLXl5CufwYXmVUHUxsG1adTeaRIpv6YYZCg/RaG3ks52fJZ6Po83KjT77h/YjSRL3tNxDs62ZYFJWmSwG0FQuxcqalTzS8Qhf3CznmIsz8ip9FVX6Kna0yjP+eCZOIBnAaXKy1rGWU4FTpfx7X7CPTlcnX9z4RX5z/jd8/+D3AXjmgWdKQbnot2vSmtCoNCAgmUti09vwx/0c8x4jlUux+/Tu0kyvvL692DNQFIiD+a2Wutxdcw4kxesabAY0aQ0bzBuwxq1IQQlnzomuWodQCYw1RmKjMUa6R656wF/oRvNSxhP28MyBZxiODnNu4hwFqUAmn0Gn1hFIBojURHjmwDN896PfvSYz/csGfEmSPjLb60KIx4CHgfuki7Vnw0B5D7p78pjCLUJ55Uhxll2QCpdUkcxYYTIthRMRWSZ+9c+cX78MQ30T7TXtOPM61q+/j91lIka7T+9Gm9VSpa/ipPckDqMcJPqD/Wx3b6eztpMDwweoNdeSyWXQaXS4jC52tl10k58uytZe004gHiiJpp0LniORTWBQGTjjP8NAZICV1St56o6ncJgcfEzzMdpq2kpB/y/u+At+2fNL6s31nPSeJJlNYtVbSefSBJIB1jnX8cbgG6UHU7nUwOUC+oJWS3OgZHjeoiX+fpxYIUbGmKHleAuSWsLaaAUgl8xhdpmJ++JXdL1KLGSjeamzt28v50PnZbG7fIpEJkEmn0Gj0mDVW+Wu7HyGvX17eWLz5eVF5suVVunsBP4S2CFJUqLspV8C/58Q4nvIm7btwHtXci2FK2DaZue11oEorxyZPssuD2Ywi559WQrHH/dz1JmmdThP84UJPDUODvf8B13mVVT/3uemXLvH30MoLdsGngueo72mvfQfCZAtCdNxMF/8jMTFhWW3p5u9vXvxxr3UW+u5q/ku2h3trKtdx2n/aYajw6TzaVbVrOK1gdcYiAzQUdPBX971l7jMLiLpCLWW2lJapjzov9z/MolsAm/CS62xlq1NW6k2VnN45DB2g53b624vzeJBzqPvWrPrsgH9WnTelj9IEusTGIYNdJg7iBPHXGtGZ9WRTWTJxDO41rowu8yXP+k8me9G843A4ZHDWLQWORWIIFOQvRHyhTxIEEgGqDXXcnjkMNdC6PNKc/j/C9ADv5msMz4gSdIfSZJ0Ugjxc+AUcqrnT5UKnUWiwmYnL74ob65exaBfvrkWz8TZUL+BZbZlFWfZcNGir1gXf3D4IOFUGK1ay76+fXzRVyhZEfZO9KJx1RHZWoPh6AcEL5xm2JChu83E56zy8hHkB01/sB+NSkO1sRqtWssJ7wnaatpKmjXHfcdprWnlvtb7SmMvyjiMRkd5+t2nsegsJLIJwqkw/3b637h/5f04TA42NWziQ8s+VJJ4tuqsNFmbuNN9Jw6To9RAtKNlB0IInnngmdLPKIQgnU+zs33nlJn6g20PIkkSdZY6VOJiH+RCOo2vRjduOaUHSZl6teejHg4/d5jYaAyzy4xrrQuVWkVj19V3kprvRvONgCTkMly1UF+caAh50lHsQkbimlkxKgYoNzu7d8PQkNz9Gg7LNfH19XLlzFXSc55u+PHW4FsUpAK7OnZxLnyOakM1EhKhVIidbTspSIVSMFOr1Lx+/nVZQTGfQ61So0LF89LHEPEEPbkx3hl6R85hZ3UM5gL07ehEr9YzFhtjc+PmKWYqQ+EhTvlOYdaZyeayHB0/ilql5rPrP4tBY2BPzx4+suIj1JprS+Mvjqc/KNe6O0wOwqkwo7FRvHEvNYYafvjQD0sVMeWBeTw2zqHRQ2yq31TR3WlLwxaa7c2zmrUAM75Wro5ZyUCmyOWMZq4mYU+Yke4R4r44Zpf5mpZm3mxVOj96/0c8f+R5dCodJ/wnSGaScg5fpcOoM9JZ20k2n+ULG79Q2lOaC4oBioJMTw+cOydLHNjtciNUsUb+KvHjoz8mlA4Ry8TwJXxYDVbS2TTveN6hw9lBMidfy2aQg0J5Fcmenj2Mxkax6q1YdBaimSipXIqfVfXTeewcGrsDp8FBIRzinHeYof8kSyAksgnqrfXYDXb29e3DYXLwi1O/oNnWjMvo4pT/FCOxEVLZFBIS3SPdbGnYwn2t92HQGKaMvzieNwfeLOWMbQZbScBsMDw4Y0WMUWvkgZUPyPIIZfX2o7FRDngOsLdvLx9v/zgv97+MChV2o13efzA5S7P4h9ofmjFPP9c6+/l0xF4pNrftutXez2ej+UZgZ9tOXrvwGoFkgAZTAxF1hHgujkltwma0YdAaaKpqmrKndDVRAv7NzsSELGJWtOMymeRgPzFxVU5fTCM0WBowaAxkChkS6QR5Kc9YfIyH2h+aksMvT3uMRkd5d+hdhBCljUyVULGyeiW/Ch+h4SMP4e4Zo200zge6GP9xexWY0yzPJohn4nTWdpLKpfjt+d/y8KqHqdJX8c7gO7KuvbUBnUqH2WRGJVSsda4lnU+XLAPh0uB6wHNg1pzx5TZQu0e6yRfypRVGg7WBwdAgf/f239Hh6EAIwQnvCd4aeIv19etZVbOKZlvzrBuvL/W+hFqoOek9STgdxqa3UW2opj/UPyV1Mx/3L4XFw21z89S2p3ju8HPY9XaCiSBWvZVoJkq1sRqb3sYTm564ZrX4SsC/WSlu1B49KgviWCxyKqemRrbqKmrdXCHdI93UWerIFrIYhRG9Wo/NaCOUDOEwOshLee5qvguBIF/IY9KaSgHyvZH3qDZWyxZ9uQSJXIJNdZtkk/B8AvWyFsZbZHMSQ9xPoeeXeKNjdDg7aLI20TvRywHPAUxaE2ORMaLpKBPJCcxaM6PRUfQaPS6TrEQ5FhtjXe06PFFPRaXK7pFuVKg4Nn6MFfYVJW2e8pzxbGbqu0/v5henfiFX76gNBJIBEtkEE4kJClKBXCFHf7Afq96K3WCnd6IXX9zHV91fLZ27eD99cV9pj0MIwb7+faTzaXL5HNl8Fl/Cx+bGzVM2uvVq/ZzdvxQWly53V8m2slxqo8PZcUM1XiksFTwe+MlPZIniwUFIpyEQuKhied990NFxVS7li/vYsWzHxZmv1iJLFGRj/P1H/37G5Xix1n1jw0ZOeU9RZZBFx/wpP3nydLo6pwQwp9nJvcvv5YTvRKm8Ua1Sk8vnqLfX88q5V2ixt1BrriWRS+BL+Kgx1mDWmam11BJMBbHoLJz2nS6Nu5hzL5qE39F8B0atkf2D+4llYqxyruKhtofwRD0cOXSkNJsul38oz50325r57bnfEs3IipQ2vY2B7AAaoeFC+AJrnWsJpoPEM3FUkoq7mu/CE/XQRdeMmjjDkWEGw4PUGGuwaC2ciZzBm/ByYvxEyXDEbrCTyCZKlUhz7l5WWDQWy9NACfg3I3v3Ql8fDA9DLifP8EGe1dfVwcGD8OlPX5VLucwuzDozuzp28Y7nHXwJHxa9hd9d+7uz5l6LKYjN9ZsJJ8OE02Gy+SzpQpptjdu4f+X9U1IvA6EBTnhP4DA6eP386+g0OlZWr2R93Xr0Gj0D4QE8YQ+JXIJIOoJVZy3tGXjjXgLJAD/94KcEU0FMWhMt9hZimRjPHXmOTldn6cGysWEjK2tWljZMf3L0J/iT/lLN/knvSR7b8FhJpbLctNtpdJIpZFAJFdF0FKPWKHfnak2lcs06qywxrNfoabG3lFIulXLwgUSAl/pewqw1E0qFCKfChFIhXEYX2UKWdC5d0syXJOma1OMr3FwoAf9m5PBh0GhgYEAWLTMaIZuVtW2qqmDlSnkV0HXlm2HFvHZ9VT1/uOEPp1SHzEapg9Ts5MOtH6Z3opfx+DhOk5PPbZBr6/VqPfsH9+ONevElfTRaG6kx1aDT6LDr7bQ72gE46Dkod7xG+mm0NMrpJJODC6EL1BhqCKfCtNpbGY+P02Bp4JTvFFa9FafJSS6fYyQ2UvK1hYu57719e+kL9uEwOkrCZX3BPvb27eXBtgcvMe3uneilydLEcHSYYCpIY1Uja5xrGAwPYtKaiGfjqISqtP9QnnLxxX1TcvWxVIzz4fOMRceoNdWiUqkIpAJyOZ8kkS1kGQwPEkwG8UQ8fGL1JxY8a7za5ZwKSxcl4N+MSJI8qy+W3BqNoNPJs329Xn4Y+OYubzsbC+30nOKQZKphnWYdTammSxqyuhq6+Gf/PwNQZ6ojm88SSobQqXT0TvSy3b2de7Xt1L7/NgVvEGNjFT0tTbwVP89EcoJQMsTtdbfTbGtGJVQ025pJ5pL0TvTiNDmps9ThjXunjK0YiF/pe4VqQ3WpdNKkNVGQChweOVzSzp9u2m3QGFhft554Nk6duQ6bwcZq52pGY6OMx8aptdTS1dSFTq2bknIRQrB/aD8OowM1ag6PHyadT2Mz2PAlfWhVWqSCREFVYCw+hk1nI5PPYNKa8CV9jMXG8IQ98w7UnrCHfzr6T/iSvtIq5sDQAdocbUiSpDwAbjKUgH8zsmULHDsmB3aVCjIZOfibTPLXOp3ccXuVWMjMcrYHRbmWzUnvSTQqDVX6Kkbjo6x2rqbF1sKF8AW0ai26US91bx7Hh4XG27fgHe+j5a2jjG6uo8O9nVO+U3iiHuwBO5Ik4Y15cVlcpXx3g6WBQCJAJB0hlU1x3Hec8dg497XeRywTw6g1Thm3QCAJaUbTbo1aQzqfZkfLjlLaKJQK8YWNXwAubsoWN6+L900gSq5YI7ERClIBvVpPNp9FrVKTzCZJ59NYdBZsBhsWrYVcQe5b2Fy3mdbq1nmXYHrCHv52/99yZEzen2ipaiGRSXBg/AD+hJ+Pr/74jPr6i8XNVpd/vVEC/s3Izp3w2mtw6pScwgmF5NLMqio5j2+zXZV0zpUy04OivMRwODpMLB3DG/OiUWtotDZSa6klnAnL6ZDuQwi7nVWuLejUOs7q8licTXw0YOHVpjxCCNQqNcORYW6ru41TvlOsyK+gqaqJSDqCWqXmiU1PcHT8KK+ff51aSy0fWfERDBoDeSnPYHiwpGKZyqUIJAPcvexuHCZHRdPu5fblPLrm0RndnGYKmgWpwD0t99Af7Mef8FOlq0Kr1tI30UetpZZUNkUwFUQIQbW+mlpLLaudq4ln4mxu3DzvEsxuTzfPHXmONy68gV4lm8P0T/RjUBuw6q2MxEZQCdUV1/NfzXTRzaqeeT1RAv7NiNsNTz0FzzwjV+osXy7P8ONxaGqCJ564plo6c2XPmT08f+R5RqIjNFobeXzj4zy8+uFSfj+TzzAWHcOgNRDPyk5TZ/1nqTXXYtPb+NLWL+E+/xLU1eFPTnBw+CDj8XF0Kg2WkQl6mjS4TPIGZygdwmV20ZptZTQ6yjrXuimz7KPjR6m11JLNZ+mf6Ke9pp073HdwYPgAeSlPMBlEp9GxqmZVqSlm+obuiuoVpQ3d+bo5CSE47j1ONp/FYXSgV+s57j+OQWNAr9ajRo1Ra2SNYw1nA2fJ5DPo1Xo6mzpxmp1E0pE5l2B6wh6eO/wcGpUGrUpLMB1Eo9JgN9gJpAJkChkc4mIvwkLr+bs93Txz8BnGo+No1Bqaq5o55T3F5zZ8bkFB/2ZUz7zeKAH/ZqWrC777Xdi3Dw4dkmvvN22CBx+8omB/tWZss/nRFvP7vRO9LLMt41zonFx1o7cRz8UZjY3ytx/+WwDeTfeTOHYAk7Mel6mWQqFAIR4hYavCqFGTzWcxauX+AE/EQzwbx6q3TjGb8IQ9vH7+deosdVQbqknmkvz8xM8Zi4/hi/toqmqiq7GLHS07pnxGMNWntvj9fO+RJ+zBG/MSTAZxGB1UG6s54TtBIV+gxdbCSGwEnVrHlvot2E124rk4XY1dtFa3YtFZpjSzzYXukW7yUp5aYy16tZ58IU82nyWRSVCggAoVbuvF8S6knt8T9vDt/d/mbOAsOrVO7hNIxwinwtT11c1LNqDIzaieeb1RAv7NjNsNX/yi/OcqMFf/1Lkwmx/t7tW7eaTjEb795rfRqrWscawpCUxZ9VbsejsN1gZePPsiDR1NrHwrRCwU4v14H+sNyxkOnOKNDol8IU8sHyOdT/PomkfxJryYtWaqDFUl1c6tjVt54fQLjMfGiWVjtNpbGYuO8f74++jVepptzZh1Zt4dfpedbTunlGP64j7qrfUllctIOsK+PrlJaj73qHukm+XVy2msaqR3opd0Ps0617pSnnpd7bqSoJaExJ3Nd+IwOtg/uB8hCTY1bprX76D4IErmkug1+pJwV1bKYtFayBayaFQaClJhwfX8+/r2ccp/CotWdvjKSTmi2SihVIhDo4cu8bedCzejeub1Rgn4CnPmauq1jERHaLY1TzlW9KMFOdd9f9v9FUXFEtnElPr37PZVtPYH0F2YwGPM4fvwHSTVXnIJL+lcmuW25WSlLCqhoiAV6KjpKNW5P3f4OfJSnjWuNZz2n+a49zgXQhfQq/SA3PBVrMB5/sjzbGjYwItnX8Sf8MvlmJO18Nvc26gx1rB/cD93L7u7NOaxyBivD77Oz07+jO3u7RU3GYt7FiqhKskjF6QCp32nS525xWaq88HzTCQmGI2NokKFTqvDG5taZXQ5XGYXqVyKU75TpRRSMpskU8hwW+1tGDSGkqDcQuv5D40ewqAxoFVpEUKgFVqMGiNj8THaatouf4IK3Izqmdcb1eXfoqAg44v7sOgsU45ZdBZ88fmXeDZaG0uVMkXK/WhBTu2EUrK2fUEqcD54nl/3/Jo9Z/fQPdyNUW0knU/zeq6Xk3e2s/fDzbx2exU1q9bzkZUf4TO3fYZ7l9+LRW/hjO8Mo7FRklm5JNMf9zMaGyUv5akz16HX6Ol0dWLRWQgkAug1eurMdaVgbzfYGYmOlB56deY60nm5HNOsM9M70UssE0NIonSPenw97D67m1whh1ljJpqO8vS7T9Pt6Z7ycxf3LMqJZWJ0ODt4pOMRTFoT47FxTFoTOrWOsfgYaqGm2liNWqjpmehhX9++Od/7rsYu1Co1a11rMelMZAtZTDoT9y2/j9Wu1ThNTu5w38GTW55k15pdC0rZCUlQa6olmU+SzWfl3oF8lkwuw6bGTfM+H1y0abTqrQyGB7HqrcqG7TxRZvgKc6aSWuTAYJ7hs7fx7OH5eas8vvHxUs6+3I/2K9u+UnpPeenmad9pzoXOYdKaqLfU0zfRx+nAada51pUCrk6tw6AxyHo2k1U1Jq0Jd5WbQCqARmhKDVQHhw8ykZxgRc0KubRy+CBmnZlOVydHR4+iUWlosDTIejjJCQKJADa9jbP+s6xxrSl9BuRyzLHoGE3WJjY1birdo3c872DVW9Fr9GhV2hk3GWcTZZteyfRHe/4Ih9ExpTfAYXTMK01Sfl/XuNbQVt2GUWtEQpI7gG0tl6y+5sumxk34k36SWTngR3NRMvkMq12rS77BC+FmU8+83igzfIU5c8mMeyDL2686aNKvoq4OEgnZW8Xjufy5NjRsYOfKnfgTfo6NHUMt1Pz3Hf+dh1c/POV9bpubXWt24TTJqZW+iT4GI4M4TU4kSeJC+AJ6tZ7+YD8TiQkMGgMXQhcYCg+h1+hZV7uOAgU6XZ0UpALJXBKDxoBKqORuWEsjTrOTbU3b0Kv1jMfH2dK4BY1Kw0RygqHwkGw7V8jwoWUf4lzoHAOhgSmf6Q/2E0wGiaajCATng+eJpCP4k360Ki2pbKq0crEb7AxHhi/5GafP5GfKyQtJTHHoAnlvQ0jikvfORvG+fvPub7KpcRPbm7dz/8r7Wedah1qlpqvxyoLqg20Pcnvd7ax2rabGVIPT7GRj/Ua+efc3l0Q9/62KYoCiMC/KK1D6370Ns+QipfERToWxGWzUa1bR7HLM6q0yX7OObk83/+WV/yLLHXuDrB/K4IpJiNo63msskGmQxdHuXnY3w5Fh1Co1eSlfCl6xdIzVrtVMJCfoneglnArLqxQJzDrzlNJKp9HJhroN/Pjoj/mPC/9BrpDDXeXmU2s+RZe7i/PB85zwnmDH8h0ljZ+3h97mrua7aLG3MBAa4IDnAKl8isMjh9GqtCyzLytp8OcLeVrtrfzDx/5hQff/ufef4+2ht3EYHRg1RpK5JIFkgLua71qwB+q1klZQJBuuH4oBisI1Z2Qsi2Q6jCnvZsLTSk8EhP48m1tV7No1s/zyfDZ/izXjZq2ZhlCeTSeTDBLGa6/BHg3ySI+dbquGD639GK3VrTTbmktNUMPRYb609Ut0j3SXmqSKm6KRdETO5wd66Qv0EU1Hseqt+PV+DngOsMy2jK1NW5GERCwdw6aXhdha7C0ks8nSbHw4OsxdzXfRWt2KP+7nlO8UGpWGWCLGpvpNdI92cz50HrPWjEVrIZAMUJAKPPf+czzY9uC8A+CDbQ8yHhvHn/QzkZxAp9HRVt12RWmSa6XcuFiKkAozowR8hTkzvSwzqO5l/JwWS7gGm1VDtT3PRMDKoZMhPJ7qGXP58zHrKNaMr6pZhfPQfrJmE0a9gWgmSlJk2Fy/iTtGM6jvbAEoBfVilUkx4FTKkcczccbisr5+Mef/ct/LpeYeX8JHtpBFIHjH8w6rXKtKsslFieRnDz1b+ll6J3pLK4aCVGBd3Tp8CV9psziWibHdvZ06Sx0nfSfJ5DPzLml129w8tuGxWWfOnrCHvX17OTxyGElIbGnYUiopVbi1UQK+wpyZPjOvWdnPwKGHyamDuJwOMikVarUKW9Mw3d2tMwb8UCrEL8/+klgmhsPk4K7mu6iz1FVs7ikGtWw+y6pCNRcsKVSTYmX3tNzDh1d8lMNH9nJ6FvOPmXR7/mb/31yyAZov5IlkIoBcSXTWLzcO+ZN+IukI54PnqbfU8+yhZ3GZXQghSl3BR8aOIBAMx4ZLjUtWvRWr3opJZyKUDLGyZiWSJBFMBbEb7AsqaZ1t5uwJe/jBgR/QPdqNWsjduYF4gPHY+II7XBVuHpSArzBnps/M3U3QX+cnGdMRj9RhsuaobfXicKhLYpzT87haoWX/wH4i6Yhs3JFJ8POTP2dHyw6+tO1Ll1yzvGY8WW1hRdZKwJAlL+XZ3LAZYjGWtW/h3VnMP2bKJVfaADXrzCSyCUBONXU4OzgTOINRbSSRTSAQGLXG0nW8MS/hVJjxxDhalZZMIUOhUCCYDBJJR9CoNSBBOBXGbrQDkMwlseltc5IsmEl+Yib29e3jvdH3MGqMWHVWMoUMgVSA86Hz18TfVuHGQqnSUZgz0+vF22va0dWdx9XqZcPdXpatG0FlCdKgW4XLdVF6942BNzg6dpQ3Bt7gO+98B7vBzob6Deg1elQqFXaDnUg6UjEYldeMj65xk57woo0luX/5R3HmdRAKkdl4Ozq1jrcG3mJv316S2WQpVVJMQyWyCeosdaUOW0/Yw6bGTQRTQRLZBJIkye8x12HSmQgkAiXJAbvezv/88P/EaXKyvHo5VfqqkrDY8urlRLOyH6ndYEcqSNzmkpuXzgTOYNXKZZm5Qo5qfTWJST/e9pr2y0oWFOUnopkozbZmopko33rjW+w5s2fGzxwaPYRGpcGqsyKEQK/WY9VZGYoMLahfQuHmQpnhK8yZ6fXiOo2OLZth+NAKRn1x6mpMtFhvQ5110NUlzzZ7JnpwmpxUG6tJ5VKMREaw6Cwsr15ecqTKF/IV9VCKUrg9gR6QYLVzNc5Pf4GuEYEzXgCTiZGNq9gdky0Kd7bvLM3uS+eYZYO40gbo9ubtbKjbwK/7fs1bg29h1Bq5r/U+GqwNHBk7UnHvIZqOsrNtJyqhwh/30zvRi0alwRv3clvdbThMDoLJIEfGjmDWm+lq7EKn0V1WsmA2+YmZZvlCEhg1RllcTaMvHc/lc4q/rYIS8BXmTqVc+Jfv/xRsd9PdLXuqlDdfHTp66JIcebWxmoHwAFsaL1aQVdJDKZfCXeNcQygV4lzoHJ/c/kmc916sET9Ypp0Pl1b8zLZBPNMGKMBAZIAPLftQKXXz4tkX0al1FY3Cm6qaSsedZqesXlkbwaQ1XeJ/O5MefiUuJz9RiU2Nm/D3yw8wSZJAwERygmZb8xXX1ivc+CgBX2FGuk+N8MJvBxgezdLUoOXR+1roWlthw9BWubu2Uo68vaadgyMHCSQCs+qhzFUK93IVP5W6g6dv6E7/eXaf3k2+kOek7+TF/gJzPUItKhqFP7rm0Sn+uzMJjs23TLEoPzFdLKxcfmI6xVXL+dB5hiPDZKUszVXNPLXtqQXn7z1hDz89/lNeP/c6iXyCTlcnn9/weaXj9QZEyeErVKT71AhP/6SXaLTAsiYd0WiBp3/SS/epkTmfo1KOXK/V89DKhxiNjvLbc79lNDrKH9z2B5cEj+HIMHaDfcqxSl2qM+nQFAP69O7gopTwbLPdHn8PJ70nSedk1ct0Ls1J70kCiUDFjtgud9ecO2Xnw+MbHyeYCpb2EwKJAMFUkMc3Pj7jZ4qrlodXPcwn13ySP+v6M7770e8uODh7wh6+f+D77D6zG1Rg19v5wPsB/+ON/3GJJpDC0keZ4StU5IXfDuCwa3BUawFwVKtKx7vWzjzDLKdSjtxldGE32Nm+bHtpNjwQGbjEj3WuUriz6dDA5T13K1XwTKQmUKvUU1JRyWySidTEjLP0SsevtNO0mKd//sjzDIWHaLQ28pVtX5m1SmemsSyU7pFuTgdOU22oLq2SnConyVxSMR65AVECvkJFhkezLGvSTTlmt6kZHM7M+RzF2ebevr28eeFNvEEvqWyKNkcbjVWNs1rozVUKdy4m6jMFwJn0/QWCvJQnkU2U5AvCqTDRdLRUfz8XU5Or4R3w8OqHLxvgryW+uI9oOkqtqbZ0TKfSkZbSl6y2FJY+SkpHoSJNDVpC4fyUY6FwnqYG7bzP1evvZSg6RDwT50L4Aq+ff52fHP0JvYFeoLLE8mxSuHvO7GHXv+xi27Pb2PUvu3i179UF/YzlFTzFh4/dYEdCYp1rHXq1nmAqSDqblm3/zI5LSjvne+7ukRsrDeIyu7DqrcSyF9NmmUKGgigoxiM3IMoMX6Eij97XwtM/kQOy3aYmFM4TCOX4/CfaL/vZYjnlcGQYf9zPUHQIgSAQD5DIJWR3pUKWF8+8yGMbHyOajjIcHeY7+7/DRGqCakM1Hc4Ouhq7+M5HvzPl3NOtEceiY/y3N/8bv7fm97h7+d3zmknPtOFbY6hBrVKzrnYdFp2F1y+8jklr4va62+ds7D0f+YilTFdjF+8MvsP+of1ISOhUOvl3pK/m0TWPLvbwFObJVZnhCyH+QgghCSGck98LIcQPhBB9QogPhBALczxQWDS61jby1cfasVpVDA5nsFpVfPWx9svm74vllNF0lGW2ZfQH+xkMD+KP+cmTR6vWytZ56Rhj8TH29e3j7aG3MWlMnAueI5qOcj50nqHwUMVZdHltulqlRhISVboq3hp6a94z6Zk2fFc5V03ZhE3lUtzTcg9OkxN/3M+7Q+/y9uDbvNL3yoyz/MttJt8ouG1uvnzHl9m1ehcUIJQOsb52PX+946+V/P0NyBXP8IUQzcD9QHnnzINA++SfbcA/TP6tcAPRtbZxzhu0RaaXU+bJo1PrCGfCskOTSg1AJp9Bp9Zx1n+WL2z8AmPxMSx62f80kU0wFhtjXe26S2bR54PnMWqNhFIh9Bo9kXSEKl0VgWSg9J65zqTnajyy+/RuEtkE/ri/ZJRi0BgoUJhxNXG5zeRyyldETVVNFW0QFxO3zc3XPvQ1vvahry32UBSukKsxw38G+EuYUnD9CPB/JJkDgF0I0XAVrqWwxCmWU4ZTYc74z5DKpigUCmQKGfJSnnxB3hew6Czc0XQHVYYqWuwthFPhkma8UWMknA5fktv3hD1IQiKSiWDQGMgX8sQzcQKJADXGmtL7ZppJe8Iedp/ezbOHnmX36d0AcyqnLJZ2HvMew6g1ApDIJri97vYZVxNzMTXxhD18563v8Mcv/TFHx49iN9hntEFUULgaXNEMXwjxCDAsSdIxIaY47jQB5e2AnsljoxXO8STwJMCyZcuuZDgKS4CmqiaGwkP4k370aj0N1gbZfUqtJ5lNotfo0Wv0rLCvIFPI0OnqJJaJYTPYSpaERXGx6YG7e6Sbj7Z+lN1ndxPNRDFrzaiFmonUBB/v+LicKpphJt3t6ea5w88RTofJ5rNoVBr29u3liY1PTOmGrUQxeP/N/r9BhQq70U5nbecUGeYicy3FLFbx7B/cj9PkxKAx0DfRR4ezA4fRoZQ8KlwTLhvwhRCvAvUVXvoG8FfI6ZwFI0nSs8CzIDteXcm5FBafR9c8ylde/gpGjawoWaWvwqgx0lTVRDQdRa/Wk8lnKEgFsoUsD7U9xEBkgHpzPSe9J0lmk+SlPC2ulksCty/u4+7ld2PSmnjl3Cv4E35qjDXc6b6Tu1rumrEss9vTzV+99ldE01Ei6QgqoUKSJJwmJ8+8+wzfvf+7l93gddvcPLDyARLZxIxdu/MpxSxW8cTSMVwmFyqVvNgeiY7QXtNeUVtIQeFKuWzAlyTpI5WOCyFuA1qB4uzeDRwWQmwFhoFyERD35DGFm5wudxf3LLuHs4Gz+OI+HCYHd99+N1kpy+HRwySyCQpSAavOilFj5Nj4Me5feT+eqKfU3FSswJk+Oy5uhJYbWUfSl2rWlFN0zIqmo4zHx2WNGSRMGhPpXJpYNibP9KfZA1aaqV8uL9890l1RkqFSNU+xisdhdBDLytIPOpWOeDZescFMQeFqsOCUjiRJx4FSN4YQ4gKwRZIkvxDil8CfCSH+FXmzNixJ0iXpHIWbk63urXTWdU6ZCUfSEcKpMPFsvJTCSOVS9Ez0UGep44ubv3jZ885nI7RI90g34XSYVC5V0sFRoSKZTaISKox5I29eeHNKwJ9tpj5bk1ePv4fj48eJZCPk8jk0ag2D2kGS2eQl4yo+vO5038nus/J+glalJSflKjaYKShcDa5V49VLwDmgD3gO+JNrdB2FJchM+jWRdKSknqkSKkxaEw6jg0OjczOun8tG6HR8cR+ZfIZqYzW5Qg5JkmSTc/LkpTwOgwNvwjvlM7M1Tbltbnat2cWTW55k15pdU649EB7gQuQCKqHCorOgEiouRC4wEB6Y8R7VV9XzSMcjqFVqRmOjrLSvLDWYKShcba5a45UkScvLvpaAP71a51a4sZhJ7uDE+IlL1DMlJIQkZjhT5XPPR5rAZXahU+vQq/WYtWbimTjpfBo1aqw6KyqVaopsACy8aSqSjqBT6S7Wq0myDEEkHan4cxTvkc1g4/GNj89ba0dBYb4onbYK14RKgXlT4ybeHnpbTqVMatQEU0Huar7rmo2jq7GLvb170al0NFob8UQ8SJJElaGq1MB1z/J7pnzmcpLKM2HVWVlRvYJwWk5dmbQmVlSvQKuqLEdxNUXOFBTmgqKlo3DdeLDtQdqq28hLeSaSE+SlPG3VbTzY9uA1u6bb5uaJTU9g1Blpq2ljtWM1a2vX0mRpYn3dem6vu/2S6y9EUhnkB1pOyrHMtoyN9RtZZltGTsqxqVFpNFdYGgg5+7I02LJli3To0NzyuQo3JlcqGXyl1z3rP0swFaTGUMMq56pZ6+TnO05P2MNPjv4Ef9JPJpdBp9HhNDp5bMNjykxe4ZoihHhfkqQtl32fEvAVFK4ei/VAU7i1mWvAV3L4CkuOpa4tMxtKXl5hKaPk8BWWFNPVNhVtGQWFq4cyw1dYUszVvFxhfnjCHvb17ePQ6CHi6TgWnYUWe0vJd0BZldwaKAFfYUlRVNs84z9DIpvApDVRZ65bUnZ6N1qe3hP28IMDP+C90ffI5XP44j5yUg6H0cFtdbdx0ntS2Vi+RVBSOgpLiip9FUfHj5ItZDFrzWQLWY6OH51SE7+YFGUXEtnEnO0OF5u9fXvpHu1GIBgMDTIcGWY8Ps5wdJjB0CB9wT729u1d7GEqXAeUGb7CkqLF3sLhscOkc2m0Wi3pXJpcIUeLvWWxhwbIsgv+uJ/Xzr1GIBnAYXSwvm59RYG0PWf28PyR5xmJjtBobeTxjY8viiH54ZHDZPIZwqkwwXQQrUZ2HQunwgyEB+R7PnIYNl/3oSlcZ5QZvsKSotpQzadWfwqTxoQv4cOkMfGp1Z+i2lC92EMD4KDnIL/q+RXnQueIpCOcC53jVz2/4qDn4JT3Fb13o5koDqOD/mA/f7L3T/jGq9+47qsBSUikc2kSuQQqoUIgUKFCJVQUKDAeH0cSS6c8W+HaoczwFZYULrMLs87MYxsfKx0rSiAvFuU5+319+4ikI9Saa9GoNOQKOUKpEEdGj0z5TNF716gxMhIbKY1/X98+GqsaeaTjEYDrshewpWEL73neI51Lo1frSeVSFKQCerUerdASSARK41G4uVFm+ApLioXKGlwrpufsY5kYqVyKdD4tv0GAVq0lnA5P+cwJ3wkmEhP0TPRQkApo1VosOgvRTBS7wc6+vn3XbS9gZ9tOVrtWYzfY0aq0CCHQqrXYDXb0Wj3Lq5ezs23nVb+uwtJDCfgKS4qFSCBfS6ZLJVv1Vqr0VSSyCVL5FGqhxmF0YDPYgIsPiCp9FTlyZAtZwqkw6VyaeDZOjbEGi87CodFDM0owX23cNjdPbXuK2+tuZ1n1Mroau9jcsJlaSy1rnWt5attTSoXOLYKS0lFYciylbtXpUsm3193OO0PvoFPraLW3Es/EmUhO8FD7Q8DFB8RDKx/ipyd/SqFQQIWK8cQ4GqHhkVWPEMvEEJLAorNMudZcJJgXSpe7i+9+9Lvs7dvL4ZHDSEJiS8MWdrbtXDL3WuHaowR8BYVZmC6VvGP5DvxxP6OxUbwxL1a9lR0tO/jMbZ8BLj4gtjZvBWBP7x6Go8MYNAY+s/4zdLg6CKVCbGrctCAJ5ivBbXPLzl5KNc4tixLwFRRmYbqtok6tY3vzdmottUiSdMlma/kDYmvzVrY2b+V88DzD0WGa7c2YtKaSJeN87RoVFK4URS1TQeEyzKezttwPtzyQV9qHuNE6dhWWLoo8soLCIqEEcoXrjSKPrKCwSCylTWcFhXKUskwFBQWFWwQl4CsoKCjcIigBX0FBQeEWQQn4CgoKCrcISsBXUFBQuEVYUmWZQggfMLDY4yjDCfgXexAL4EYctzLm64My5uvH9Rx3iyRJl23TXlIBf6khhDg0l9rWpcaNOG5lzNcHZczXj6U4biWlo6CgoHCLoAR8BQUFhVsEJeDPzrOLPYAFciOOWxnz9UEZ8/VjyY1byeErKCgo3CIoM3wFBQWFWwQl4CsoKCjcIigBfwaEEF8SQpwRQpwUQny37PjXhRB9QoizQogHFnOMlRBC/IUQQhJCOCe/F0KIH0yO+QMhxKbFHmMRIcTfT97jD4QQu4UQ9rLXlux9FkLsnBxXnxDivy72eGZCCNEshHhdCHFq8t/xlyeP1wghfiOE6J38u3qxxzodIYRaCHFECLFn8vtWIcTByXv+MyGEbrHHWI4Qwi6EeGHy3/NpIcT2pXiflYBfASHEvcAjwO2SJK0Dnp48vhb4NLAO2An8v0II9aINdBpCiGbgfmCw7PCDQPvknyeBf1iEoc3Eb4BOSZLWAz3A12Fp3+fJcfw/yPd1LfB/TY53KZID/kKSpLXAHcCfTo71vwK/lSSpHfjt5PdLjS8Dp8u+/w7wjCRJbUAQeHxRRjUz3wf2SZK0GrgdeexL7j4rAb8yfwz8nSRJaQBJkryTxx8B/lWSpLQkSeeBPmDrIo2xEs8AfwmU78Q/AvwfSeYAYBdCNCzK6KYhSdIrkiTlJr89ABRF5Jfyfd4K9EmSdE6SpAzwr8jjXXJIkjQqSdLhya+jyEGoCXm8/zT5tn8CPrEoA5wBIYQb+B3gR5PfC+DDwAuTb1lSYxZC2IB7gOcBJEnKSJIUYgneZyXgV2YVcPfkEvINIUTX5PEmYKjsfZ7JY4uOEOIRYFiSpGPTXlqyY57GF4C9k18v5TEv5bHNiBBiObAROAjUSZI0OvnSGFC3WOOagf8beeJSmPzeAYTKJgdL7Z63Aj7gx5NpqB8JIcwswft8yzpeCSFeBeorvPQN5PtSg7wM7gJ+LoRYcR2HV5HLjPmvkNM5S4rZxixJ0ouT7/kGcvrhp9dzbLcKQggL8AvgK5IkReQJs4wkSZIQYsnUZgshHga8kiS9L4T4T4s8nLmiATYBX5Ik6aAQ4vtMS98slft8ywZ8SZI+MtNrQog/Bv5NkpsU3hNCFJCFkIaB5rK3uiePXRdmGrMQ4jbkWcaxyf/MbuCwEGIrS3TMRYQQjwEPA/dJF5tCFnXMl2Epj+0ShBBa5GD/U0mS/m3y8LgQokGSpNHJ9J535jNcd+4CPi6EeAgwAFXI+XG7EEIzOctfavfcA3gkSTo4+f0LyAF/yd1nJaVTmX8H7gUQQqwCdMiqd78EPi2E0AshWpE3Qt9brEEWkSTpuCRJtZIkLZckaTnyP8BNkiSNIY/5Dyerde4AwmXLzEVFCLETeen+cUmSEmUvLcn7PEk30D5ZNaJD3lz+5SKPqSKTue/ngdOSJH2v7KVfAp+b/PpzwIvXe2wzIUnS1yVJck/+O/408JokSb8PvA48Ovm2pTbmMWBICNExeeg+4BRL8D7fsjP8y/CPwD8KIU4AGeBzk7PPk0KInyP/MnPAn0qSlF/Ecc6Fl4CHkDc+E8DnF3c4U/hfgB74zeTK5IAkSX8kSdKSvc+SJOWEEH8GvAyogX+UJOnkIg9rJu4C/gA4LoQ4Onnsr4C/Q05TPo4sR/6fF2d48+JrwL8KIf4GOMLkBukS4kvATycnAeeQ/5+pWGL3WZFWUFBQULhFUFI6CgoKCrcISsBXUFBQuEVQAr6CgoLCLYIS8BUUFBRuEZSAr6CgoHCLoAR8BQUFhVsEJeArKCgo3CL8/0wBo3HO//TTAAAAAElFTkSuQmCC",
+ "text/plain": [
+ "<Figure size 432x288 with 1 Axes>"
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "from sklearn.manifold import TSNE\n",
+ "import matplotlib\n",
+ "import matplotlib.pyplot as plt\n",
+ "\n",
+ "tsne = TSNE(n_components=2, perplexity=15, random_state=42, init='random', learning_rate=200)\n",
+ "vis_dims2 = tsne.fit_transform(matrix)\n",
+ "\n",
+ "x = [x for x,y in vis_dims2]\n",
+ "y = [y for x,y in vis_dims2]\n",
+ "\n",
+ "for category, color in enumerate(['purple', 'green', 'red', 'blue']):\n",
+ " xs = np.array(x)[df.Cluster==category]\n",
+ " ys = np.array(y)[df.Cluster==category]\n",
+ " plt.scatter(xs, ys, color=color, alpha=0.3)\n",
+ "\n",
+ " avg_x = xs.mean()\n",
+ " avg_y = ys.mean()\n",
+ " \n",
+ " plt.scatter(avg_x, avg_y, marker='x', color=color, s=100)\n",
+ "plt.title(\"Clusters identified visualized in language 2d using t-SNE\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Visualization of clusters in a 2d projection. The red cluster clearly represents negative reviews. The blue cluster seems quite different from the others. Let's see a few samples from each cluster."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 2. Text samples in the clusters & naming the clusters\n",
+ "\n",
+ "Let's show random samples from each cluster. We'll use davinci-instruct-beta-v3 to name the clusters, based on a random sample of 6 reviews from that cluster."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 39,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Cluster 0 Theme: All of the customer reviews mention the great flavor of the product.\n",
+ "5, French Vanilla Cappuccino: Great price. Really love the the flavor. No need to add anything to \n",
+ "5, great coffee: A bit pricey once you add the S & H but this is one of the best flavor\n",
+ "5, Love It: First let me say I'm new to drinking tea. So you're not getting a well\n",
+ "----------------------------------------------------------------------------------------------------\n",
+ "Cluster 1 Theme: All three reviews mention the quality of the product.\n",
+ "5, Beautiful: I don't plan to grind these, have plenty other peppers for that. I go\n",
+ "5, Awesome: I can't find this in the stores and thought I would like it. So I bou\n",
+ "5, Came as expected: It was tasty and fresh. The other one I bought was old and tasted mold\n",
+ "----------------------------------------------------------------------------------------------------\n",
+ "Cluster 2 Theme: All reviews are about customer's disappointment.\n",
+ "1, Disappointed...: I should read the fine print, I guess. I mostly went by the picture a\n",
+ "5, Excellent but Price?: I first heard about this on America's Test Kitchen where it won a blin\n",
+ "1, Disappointed: I received the offer from Amazon and had never tried this brand before\n",
+ "----------------------------------------------------------------------------------------------------\n",
+ "Cluster 3 Theme: The reviews for these products have in common that the customers' dogs love them.\n",
+ "5, My Dog's Favorite Snack!: I was first introduced to this snack at my dog's training classes at p\n",
+ "4, Fruitables Crunchy Dog Treats: My lab goes wild for these and I am almost tempted to have a go at som\n",
+ "5, Happy with the product: My dog was suffering with itchy skin. He had been eating Natural Choi\n",
+ "----------------------------------------------------------------------------------------------------\n"
+ ]
+ }
+ ],
+ "source": [
+ "import openai\n",
+ "\n",
+ "# Reading a review which belong to each group.\n",
+ "rev_per_cluster = 3\n",
+ "\n",
+ "for i in range(n_clusters):\n",
+ " print(f\"Cluster {i} Theme:\", end=\" \")\n",
+ " \n",
+ " reviews = \"\\n\".join(df[df.Cluster == i].combined.str.replace(\"Title: \", \"\").str.replace(\"\\n\\nContent: \", \": \").sample(rev_per_cluster, random_state=42).values)\n",
+ " response = openai.Completion.create(\n",
+ " engine=\"davinci-instruct-beta-v3\",\n",
+ " prompt=f\"What do the following customer reviews have in common?\\n\\nCustomer reviews:\\n\\\"\\\"\\\"\\n{reviews}\\n\\\"\\\"\\\"\\n\\nTheme:\",\n",
+ " temperature=0,\n",
+ " max_tokens=64,\n",
+ " top_p=1,\n",
+ " frequency_penalty=0,\n",
+ " presence_penalty=0\n",
+ " )\n",
+ " print(response[\"choices\"][0][\"text\"].replace('\\n',''))\n",
+ "\n",
+ " sample_cluster_rows = df[df.Cluster == i].sample(rev_per_cluster, random_state=42) \n",
+ " for j in range(rev_per_cluster):\n",
+ " print(sample_cluster_rows.Score.values[j], end=\", \")\n",
+ " print(sample_cluster_rows.Summary.values[j], end=\": \")\n",
+ " print(sample_cluster_rows.Text.str[:70].values[j])\n",
+ " \n",
+ " print(\"-\" * 100)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We can see based on the average ratings per cluster, that Cluster 2 contains mostly negative reviews. Cluster 0 and 1 contain mostly positive reviews, whilst Cluster 3 appears to contain reviews about dog products."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "It's important to note that clusters will not necessarily match what you intend to use them for. A larger amount of clusters will focus on more specific patterns, whereas a small number of clusters will usually focus on largest discrepencies in the data."
+ ]
+ }
+ ],
+ "metadata": {
+ "interpreter": {
+ "hash": "be4b5d5b73a21c599de40d6deb1129796d12dc1cc33a738f7bac13269cfcafe8"
+ },
+ "kernelspec": {
+ "display_name": "Python 3.7.3 64-bit ('base': conda)",
+ "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.7.3"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
examples/embeddings/Code_search.ipynb
@@ -0,0 +1,396 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Code search\n",
+ "\n",
+ "We index our own openai-python code repository, and show how it can be searched. We implement a simple version of file parsing and extracting of functions from python files. The dataset is created in the [Obtain_dataset Notebook](Obtain_dataset.ipynb)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Total number of py files: 40\n",
+ "Total number of functions extracted: 64\n"
+ ]
+ }
+ ],
+ "source": [
+ "import os\n",
+ "from glob import glob\n",
+ "import pandas as pd\n",
+ "\n",
+ "def get_function_name(code):\n",
+ " \"\"\"\n",
+ " Extract function name from a line beginning with \"def \"\n",
+ " \"\"\"\n",
+ " assert code.startswith(\"def \")\n",
+ " return code[len(\"def \"): code.index(\"(\")]\n",
+ "\n",
+ "def get_until_no_space(all_lines, i) -> str:\n",
+ " \"\"\"\n",
+ " Get all lines until a line outside the function definition is found.\n",
+ " \"\"\"\n",
+ " ret = [all_lines[i]]\n",
+ " for j in range(i + 1, i + 10000):\n",
+ " if j < len(all_lines):\n",
+ " if len(all_lines[j]) == 0 or all_lines[j][0] in [\" \", \"\\t\", \")\"]:\n",
+ " ret.append(all_lines[j])\n",
+ " else:\n",
+ " break\n",
+ " return \"\\n\".join(ret)\n",
+ "\n",
+ "def get_functions(filepath):\n",
+ " \"\"\"\n",
+ " Get all functions in a Python file.\n",
+ " \"\"\"\n",
+ " whole_code = open(filepath).read().replace(\"\\r\", \"\\n\")\n",
+ " all_lines = whole_code.split(\"\\n\")\n",
+ " for i, l in enumerate(all_lines):\n",
+ " if l.startswith(\"def \"):\n",
+ " code = get_until_no_space(all_lines, i)\n",
+ " function_name = get_function_name(code)\n",
+ " yield {\"code\": code, \"function_name\": function_name, \"filepath\": filepath}\n",
+ "\n",
+ "\n",
+ "# get user root directory\n",
+ "root_dir = os.path.expanduser(\"~\")\n",
+ "\n",
+ "# path to code repository directory\n",
+ "code_root = root_dir + \"/openai-python\"\n",
+ "code_files = [y for x in os.walk(code_root) for y in glob(os.path.join(x[0], '*.py'))]\n",
+ "print(\"Total number of py files:\", len(code_files))\n",
+ "all_funcs = []\n",
+ "for code_file in code_files:\n",
+ " funcs = list(get_functions(code_file))\n",
+ " for func in funcs:\n",
+ " all_funcs.append(func)\n",
+ "\n",
+ "print(\"Total number of functions extracted:\", len(all_funcs))\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "For code search models we use babbage-code-search-code to obtain embeddings for code snippets, and code-search-text to embed natural language queries."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "<div>\n",
+ "<style scoped>\n",
+ " .dataframe tbody tr th:only-of-type {\n",
+ " vertical-align: middle;\n",
+ " }\n",
+ "\n",
+ " .dataframe tbody tr th {\n",
+ " vertical-align: top;\n",
+ " }\n",
+ "\n",
+ " .dataframe thead th {\n",
+ " text-align: right;\n",
+ " }\n",
+ "</style>\n",
+ "<table border=\"1\" class=\"dataframe\">\n",
+ " <thead>\n",
+ " <tr style=\"text-align: right;\">\n",
+ " <th></th>\n",
+ " <th>code</th>\n",
+ " <th>function_name</th>\n",
+ " <th>filepath</th>\n",
+ " <th>code_embedding</th>\n",
+ " </tr>\n",
+ " </thead>\n",
+ " <tbody>\n",
+ " <tr>\n",
+ " <th>0</th>\n",
+ " <td>def semantic_search(engine, query, documents):...</td>\n",
+ " <td>semantic_search</td>\n",
+ " <td>/examples/semanticsearch/semanticsearch.py</td>\n",
+ " <td>[-0.038976121693849564, -0.0031428150832653046...</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>1</th>\n",
+ " <td>def main():\\n parser = argparse.ArgumentPar...</td>\n",
+ " <td>main</td>\n",
+ " <td>/examples/semanticsearch/semanticsearch.py</td>\n",
+ " <td>[-0.024289356544613838, -0.017748363316059113,...</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>2</th>\n",
+ " <td>def get_candidates(\\n prompt: str,\\n sto...</td>\n",
+ " <td>get_candidates</td>\n",
+ " <td>/examples/codex/backtranslation.py</td>\n",
+ " <td>[-0.04161201789975166, -0.0169310811907053, 0....</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>3</th>\n",
+ " <td>def rindex(lst: List, value: str) -> int:\\n ...</td>\n",
+ " <td>rindex</td>\n",
+ " <td>/examples/codex/backtranslation.py</td>\n",
+ " <td>[-0.027255680412054062, -0.007931121625006199,...</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>4</th>\n",
+ " <td>def eval_candidate(\\n candidate_answer: str...</td>\n",
+ " <td>eval_candidate</td>\n",
+ " <td>/examples/codex/backtranslation.py</td>\n",
+ " <td>[-0.00999179296195507, -0.01640152558684349, 0...</td>\n",
+ " </tr>\n",
+ " </tbody>\n",
+ "</table>\n",
+ "</div>"
+ ],
+ "text/plain": [
+ " code function_name \\\n",
+ "0 def semantic_search(engine, query, documents):... semantic_search \n",
+ "1 def main():\\n parser = argparse.ArgumentPar... main \n",
+ "2 def get_candidates(\\n prompt: str,\\n sto... get_candidates \n",
+ "3 def rindex(lst: List, value: str) -> int:\\n ... rindex \n",
+ "4 def eval_candidate(\\n candidate_answer: str... eval_candidate \n",
+ "\n",
+ " filepath \\\n",
+ "0 /examples/semanticsearch/semanticsearch.py \n",
+ "1 /examples/semanticsearch/semanticsearch.py \n",
+ "2 /examples/codex/backtranslation.py \n",
+ "3 /examples/codex/backtranslation.py \n",
+ "4 /examples/codex/backtranslation.py \n",
+ "\n",
+ " code_embedding \n",
+ "0 [-0.038976121693849564, -0.0031428150832653046... \n",
+ "1 [-0.024289356544613838, -0.017748363316059113,... \n",
+ "2 [-0.04161201789975166, -0.0169310811907053, 0.... \n",
+ "3 [-0.027255680412054062, -0.007931121625006199,... \n",
+ "4 [-0.00999179296195507, -0.01640152558684349, 0... "
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "from utils import get_embedding\n",
+ "\n",
+ "df = pd.DataFrame(all_funcs)\n",
+ "df['code_embedding'] = df['code'].apply(lambda x: get_embedding(x, engine='babbage-code-search-code'))\n",
+ "df['filepath'] = df['filepath'].apply(lambda x: x.replace(code_root, \"\"))\n",
+ "df.to_csv(\"output/code_search_openai-python.csv\", index=False)\n",
+ "df.head()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "/openai/tests/test_endpoints.py:test_completions_multiple_prompts score=0.681\n",
+ "def test_completions_multiple_prompts():\n",
+ " result = openai.Completion.create(\n",
+ " prompt=[\"This was a test\", \"This was another test\"], n=5, engine=\"ada\"\n",
+ " )\n",
+ " assert len(result.choices) == 10\n",
+ "\n",
+ "----------------------------------------------------------------------\n",
+ "/openai/tests/test_endpoints.py:test_completions score=0.675\n",
+ "def test_completions():\n",
+ " result = openai.Completion.create(prompt=\"This was a test\", n=5, engine=\"ada\")\n",
+ " assert len(result.choices) == 5\n",
+ "\n",
+ "\n",
+ "----------------------------------------------------------------------\n",
+ "/openai/tests/test_api_requestor.py:test_requestor_sets_request_id score=0.635\n",
+ "def test_requestor_sets_request_id(mocker: MockerFixture) -> None:\n",
+ " # Fake out 'requests' and confirm that the X-Request-Id header is set.\n",
+ "\n",
+ " got_headers = {}\n",
+ "\n",
+ " def fake_request(self, *args, **kwargs):\n",
+ " nonlocal got_headers\n",
+ "----------------------------------------------------------------------\n"
+ ]
+ }
+ ],
+ "source": [
+ "from utils import cosine_similarity\n",
+ "\n",
+ "def search_functions(df, code_query, n=3, pprint=True, n_lines=7):\n",
+ " embedding = get_embedding(code_query, engine='babbage-code-search-text')\n",
+ " df['similarities'] = df.code_embedding.apply(lambda x: cosine_similarity(x, embedding))\n",
+ "\n",
+ " res = df.sort_values('similarities', ascending=False).head(n)\n",
+ " if pprint:\n",
+ " for r in res.iterrows():\n",
+ " print(r[1].filepath+\":\"+r[1].function_name + \" score=\" + str(round(r[1].similarities, 3)))\n",
+ " print(\"\\n\".join(r[1].code.split(\"\\n\")[:n_lines]))\n",
+ " print('-'*70)\n",
+ " return res\n",
+ "res = search_functions(df, 'Completions API tests', n=3)\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "/openai/validators.py:format_inferrer_validator score=0.655\n",
+ "def format_inferrer_validator(df):\n",
+ " \"\"\"\n",
+ " This validator will infer the likely fine-tuning format of the data, and display it to the user if it is classification.\n",
+ " It will also suggest to use ada, --no_packing and explain train/validation split benefits.\n",
+ " \"\"\"\n",
+ " ft_type = infer_task_type(df)\n",
+ " immediate_msg = None\n",
+ "----------------------------------------------------------------------\n",
+ "/openai/validators.py:long_examples_validator score=0.649\n",
+ "def long_examples_validator(df):\n",
+ " \"\"\"\n",
+ " This validator will suggest to the user to remove examples that are too long.\n",
+ " \"\"\"\n",
+ " immediate_msg = None\n",
+ " optional_msg = None\n",
+ " optional_fn = None\n",
+ "----------------------------------------------------------------------\n",
+ "/openai/validators.py:non_empty_completion_validator score=0.646\n",
+ "def non_empty_completion_validator(df):\n",
+ " \"\"\"\n",
+ " This validator will ensure that no completion is empty.\n",
+ " \"\"\"\n",
+ " necessary_msg = None\n",
+ " necessary_fn = None\n",
+ " immediate_msg = None\n",
+ "----------------------------------------------------------------------\n"
+ ]
+ }
+ ],
+ "source": [
+ "res = search_functions(df, 'fine-tuning input data validation logic', n=3)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "/openai/validators.py:common_completion_suffix_validator score=0.665\n",
+ "def common_completion_suffix_validator(df):\n",
+ " \"\"\"\n",
+ " This validator will suggest to add a common suffix to the completion if one doesn't already exist in case of classification or conditional generation.\n",
+ " \"\"\"\n",
+ " error_msg = None\n",
+ " immediate_msg = None\n",
+ " optional_msg = None\n",
+ " optional_fn = None\n",
+ "\n",
+ " ft_type = infer_task_type(df)\n",
+ "----------------------------------------------------------------------\n",
+ "/openai/validators.py:get_outfnames score=0.66\n",
+ "def get_outfnames(fname, split):\n",
+ " suffixes = [\"_train\", \"_valid\"] if split else [\"\"]\n",
+ " i = 0\n",
+ " while True:\n",
+ " index_suffix = f\" ({i})\" if i > 0 else \"\"\n",
+ " candidate_fnames = [\n",
+ " fname.split(\".\")[0] + \"_prepared\" + suffix + index_suffix + \".jsonl\"\n",
+ " for suffix in suffixes\n",
+ " ]\n",
+ " if not any(os.path.isfile(f) for f in candidate_fnames):\n",
+ "----------------------------------------------------------------------\n"
+ ]
+ }
+ ],
+ "source": [
+ "res = search_functions(df, 'find common suffix', n=2, n_lines=10)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "/openai/cli.py:tools_register score=0.651\n",
+ "def tools_register(parser):\n",
+ " subparsers = parser.add_subparsers(\n",
+ " title=\"Tools\", help=\"Convenience client side tools\"\n",
+ " )\n",
+ "\n",
+ " def help(args):\n",
+ " parser.print_help()\n",
+ "\n",
+ " parser.set_defaults(func=help)\n",
+ "\n",
+ " sub = subparsers.add_parser(\"fine_tunes.prepare_data\")\n",
+ " sub.add_argument(\n",
+ " \"-f\",\n",
+ " \"--file\",\n",
+ " required=True,\n",
+ " help=\"JSONL, JSON, CSV, TSV, TXT or XLSX file containing prompt-completion examples to be analyzed.\"\n",
+ " \"This should be the local file path.\",\n",
+ " )\n",
+ " sub.add_argument(\n",
+ " \"-q\",\n",
+ "----------------------------------------------------------------------\n"
+ ]
+ }
+ ],
+ "source": [
+ "res = search_functions(df, 'Command line interface for fine-tuning', n=1, n_lines=20)"
+ ]
+ }
+ ],
+ "metadata": {
+ "interpreter": {
+ "hash": "be4b5d5b73a21c599de40d6deb1129796d12dc1cc33a738f7bac13269cfcafe8"
+ },
+ "kernelspec": {
+ "display_name": "Python 3.7.3 64-bit ('base': conda)",
+ "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.7.3"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
examples/embeddings/Get_embeddings.ipynb
@@ -0,0 +1,107 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Get embeddings\n",
+ "\n",
+ "The function `get_embedding` will give us an embedding for an input text."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "12288"
+ ]
+ },
+ "execution_count": 1,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import openai\n",
+ "\n",
+ "embedding = openai.Engine(id=\"davinci-similarity\").embeddings(input=\"Sample document text goes here\")['data'][0]['embedding']\n",
+ "len(embedding)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1024\n"
+ ]
+ }
+ ],
+ "source": [
+ "import openai\n",
+ "from tenacity import retry, wait_random_exponential, stop_after_attempt\n",
+ "\n",
+ "@retry(wait=wait_random_exponential(min=1, max=20), stop=stop_after_attempt(6))\n",
+ "def get_embedding(text, engine=\"davinci-similarity\"):\n",
+ "\n",
+ " # replace newlines, which can negatively affect performance.\n",
+ " text = text.replace(\"\\n\", \" \")\n",
+ "\n",
+ " return openai.Engine(id=engine).embeddings(input = [text])['data'][0]['embedding']\n",
+ "\n",
+ "embedding = get_embedding(\"Sample query text goes here\", engine=\"ada-search-query\")\n",
+ "print(len(embedding))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 53,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1024\n"
+ ]
+ }
+ ],
+ "source": [
+ "embedding = get_embedding(\"Sample document text goes here\", engine=\"ada-search-document\")\n",
+ "print(len(embedding))"
+ ]
+ }
+ ],
+ "metadata": {
+ "interpreter": {
+ "hash": "be4b5d5b73a21c599de40d6deb1129796d12dc1cc33a738f7bac13269cfcafe8"
+ },
+ "kernelspec": {
+ "display_name": "Python 3.7.3 64-bit ('base': conda)",
+ "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.7.3"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
examples/embeddings/Obtain_dataset.ipynb
@@ -0,0 +1,192 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 1. Load the dataset\n",
+ "\n",
+ "The dataset used in this example is [fine-food reviews](https://www.kaggle.com/snap/amazon-fine-food-reviews) from Amazon. The dataset contains a total of 568,454 food reviews Amazon users left up to October 2012. We will use a subset of this dataset, consisting of 1,000 most recent reviews for illustration purposes. The reviews are in English and tend to be positive or negative. Each review has a ProductId, UserId, Score, review title (Summary) and review body (Text).\n",
+ "\n",
+ "We will combine the review summary and review text into a single combined text. The model will encode this combined text and it will output a single vector embedding."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "<div>\n",
+ "<style scoped>\n",
+ " .dataframe tbody tr th:only-of-type {\n",
+ " vertical-align: middle;\n",
+ " }\n",
+ "\n",
+ " .dataframe tbody tr th {\n",
+ " vertical-align: top;\n",
+ " }\n",
+ "\n",
+ " .dataframe thead th {\n",
+ " text-align: right;\n",
+ " }\n",
+ "</style>\n",
+ "<table border=\"1\" class=\"dataframe\">\n",
+ " <thead>\n",
+ " <tr style=\"text-align: right;\">\n",
+ " <th></th>\n",
+ " <th>Time</th>\n",
+ " <th>ProductId</th>\n",
+ " <th>UserId</th>\n",
+ " <th>Score</th>\n",
+ " <th>Summary</th>\n",
+ " <th>Text</th>\n",
+ " <th>combined</th>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>Id</th>\n",
+ " <th></th>\n",
+ " <th></th>\n",
+ " <th></th>\n",
+ " <th></th>\n",
+ " <th></th>\n",
+ " <th></th>\n",
+ " <th></th>\n",
+ " </tr>\n",
+ " </thead>\n",
+ " <tbody>\n",
+ " <tr>\n",
+ " <th>1</th>\n",
+ " <td>1303862400</td>\n",
+ " <td>B001E4KFG0</td>\n",
+ " <td>A3SGXH7AUHU8GW</td>\n",
+ " <td>5</td>\n",
+ " <td>Good Quality Dog Food</td>\n",
+ " <td>I have bought several of the Vitality canned d...</td>\n",
+ " <td>Title: Good Quality Dog Food; Content: I have ...</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>2</th>\n",
+ " <td>1346976000</td>\n",
+ " <td>B00813GRG4</td>\n",
+ " <td>A1D87F6ZCVE5NK</td>\n",
+ " <td>1</td>\n",
+ " <td>Not as Advertised</td>\n",
+ " <td>Product arrived labeled as Jumbo Salted Peanut...</td>\n",
+ " <td>Title: Not as Advertised; Content: Product arr...</td>\n",
+ " </tr>\n",
+ " </tbody>\n",
+ "</table>\n",
+ "</div>"
+ ],
+ "text/plain": [
+ " Time ProductId UserId Score Summary \\\n",
+ "Id \n",
+ "1 1303862400 B001E4KFG0 A3SGXH7AUHU8GW 5 Good Quality Dog Food \n",
+ "2 1346976000 B00813GRG4 A1D87F6ZCVE5NK 1 Not as Advertised \n",
+ "\n",
+ " Text \\\n",
+ "Id \n",
+ "1 I have bought several of the Vitality canned d... \n",
+ "2 Product arrived labeled as Jumbo Salted Peanut... \n",
+ "\n",
+ " combined \n",
+ "Id \n",
+ "1 Title: Good Quality Dog Food; Content: I have ... \n",
+ "2 Title: Not as Advertised; Content: Product arr... "
+ ]
+ },
+ "execution_count": 1,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import pandas as pd\n",
+ "\n",
+ "df = pd.read_csv('input/Reviews.csv', index_col=0)\n",
+ "df = df[['Time', 'ProductId', 'UserId', 'Score', 'Summary', 'Text']]\n",
+ "df = df.dropna()\n",
+ "df['combined'] = \"Title: \" + df.Summary.str.strip() + \"; Content: \" + df.Text.str.strip()\n",
+ "df.head(2)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "1000"
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# subsample to 1k most recent reviews and remove samples that are too long\n",
+ "df = df.sort_values('Time').tail(1_100)\n",
+ "df.drop('Time', axis=1, inplace=True)\n",
+ "\n",
+ "from transformers import GPT2TokenizerFast\n",
+ "tokenizer = GPT2TokenizerFast.from_pretrained(\"gpt2\")\n",
+ "\n",
+ "# remove reviews that are too long\n",
+ "df['n_tokens'] = df.combined.apply(lambda x: len(tokenizer.encode(x)))\n",
+ "df = df[df.n_tokens<2000].tail(1_000)\n",
+ "len(df)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 2. Get embeddings and save them for future reuse"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from utils import get_embedding\n",
+ "\n",
+ "# This will take just under 10 minutes\n",
+ "df['babbage_similarity'] = df.combined.apply(lambda x: get_embedding(x, engine='babbage-similarity'))\n",
+ "df['babbage_search'] = df.combined.apply(lambda x: get_embedding(x, engine='babbage-search-document'))\n",
+ "df.to_csv('output/embedded_1k_reviews.csv')"
+ ]
+ }
+ ],
+ "metadata": {
+ "interpreter": {
+ "hash": "be4b5d5b73a21c599de40d6deb1129796d12dc1cc33a738f7bac13269cfcafe8"
+ },
+ "kernelspec": {
+ "display_name": "Python 3.7.3 64-bit ('base': conda)",
+ "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.7.3"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
examples/embeddings/Regression.ipynb
@@ -0,0 +1,109 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Regression using the embeddings\n",
+ "\n",
+ "Regression means predicting a number, rather than one of the categories. We will predict the score based on the embedding of the review's text. We split the dataset into a training and a testing set for all of the following tasks, so we can realistically evaluate performance on unseen data. The dataset is created in the [Obtain_dataset Notebook](Obtain_dataset.ipynb).\n",
+ "\n",
+ "We're predicting the score of the review, which is a number between 1 and 5 (1-star being negative and 5-star positive)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Babbage similarity embedding performance on 1k Amazon reviews: mse=0.38, mae=0.39\n"
+ ]
+ }
+ ],
+ "source": [
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "\n",
+ "from sklearn.ensemble import RandomForestRegressor\n",
+ "from sklearn.model_selection import train_test_split\n",
+ "from sklearn.metrics import mean_squared_error, mean_absolute_error\n",
+ "\n",
+ "df = pd.read_csv('output/embedded_1k_reviews.csv')\n",
+ "df['babbage_similarity'] = df.babbage_similarity.apply(eval).apply(np.array)\n",
+ "\n",
+ "X_train, X_test, y_train, y_test = train_test_split(list(df.babbage_similarity.values), df.Score, test_size = 0.2, random_state=42)\n",
+ "\n",
+ "rfr = RandomForestRegressor(n_estimators=100)\n",
+ "rfr.fit(X_train, y_train)\n",
+ "preds = rfr.predict(X_test)\n",
+ "\n",
+ "\n",
+ "mse = mean_squared_error(y_test, preds)\n",
+ "mae = mean_absolute_error(y_test, preds)\n",
+ "\n",
+ "print(f\"Babbage similarity embedding performance on 1k Amazon reviews: mse={mse:.2f}, mae={mae:.2f}\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 26,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Dummy mean prediction performance on Amazon reviews: mse=1.77, mae=1.04\n"
+ ]
+ }
+ ],
+ "source": [
+ "bmse = mean_squared_error(y_test, np.repeat(y_test.mean(), len(y_test)))\n",
+ "bmae = mean_absolute_error(y_test, np.repeat(y_test.mean(), len(y_test)))\n",
+ "print(f\"Dummy mean prediction performance on Amazon reviews: mse={bmse:.2f}, mae={bmae:.2f}\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We can see that the embeddings are able to predict the scores with an average error of 0.39 per score prediction. This is roughly equivalent to predicting 2 out of 3 reviews perfectly, and 1 out of three reviews by a one star error."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "You could also train a classifier to predict the label, or use the embeddings within an existing ML model to encode free text features."
+ ]
+ }
+ ],
+ "metadata": {
+ "interpreter": {
+ "hash": "be4b5d5b73a21c599de40d6deb1129796d12dc1cc33a738f7bac13269cfcafe8"
+ },
+ "kernelspec": {
+ "display_name": "Python 3.7.3 64-bit ('base': conda)",
+ "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.7.3"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
examples/embeddings/Semantic_text_search_using_embeddings.ipynb
@@ -0,0 +1,185 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Semantic text search using embeddings\n",
+ "\n",
+ "We can search through all our reviews semantically in a very efficient manner and at very low cost, by simply embedding our search query, and then finding the most similar reviews. The dataset is created in the [Obtain_dataset Notebook](Obtain_dataset.ipynb)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "\n",
+ "\n",
+ "df = pd.read_csv('output/embedded_1k_reviews.csv')\n",
+ "df['babbage_search'] = df.babbage_search.apply(eval).apply(np.array)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Remember to use the documents embedding engine for documents (in this case reviews), and query embedding engine for queries. Note that here we just compare the cosine similarity of the embeddings of the query and the documents, and show top_n best matches."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Jamaican Blue beans: Excellent coffee bean for roasting. Our family just purchased another 5 pounds for more roasting. Plenty of flavor and mild on acidity when roasted to a dark brown bean and befor\n",
+ "\n",
+ "Good Buy: I liked the beans. They were vacuum sealed, plump and moist. Would recommend them for any use. I personally split and stuck them in some vodka to make vanilla extract. Yum!\n",
+ "\n",
+ "Fantastic Instant Refried beans: Fantastic Instant Refried Beans have been a staple for my family now for nearly 20 years. All 7 of us love it and my grown kids are passing on the tradition.\n",
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "from utils import get_embedding, cosine_similarity\n",
+ "\n",
+ "# search through the reviews for a specific product\n",
+ "def search_reviews(df, product_description, n=3, pprint=True):\n",
+ " embedding = get_embedding(product_description, engine='babbage-search-query')\n",
+ " df['similarities'] = df.babbage_search.apply(lambda x: cosine_similarity(x, embedding))\n",
+ "\n",
+ " res = df.sort_values('similarities', ascending=False).head(n).combined.str.replace('Title: ','').str.replace('; Content:', ': ')\n",
+ " if pprint:\n",
+ " for r in res:\n",
+ " print(r[:200])\n",
+ " print()\n",
+ " return res\n",
+ "res = search_reviews(df, 'delicious beans', n=3)\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Rustichella ROCKS!: Anything this company makes is worthwhile eating! My favorite is their Trenne.<br />Their whole wheat pasta is the best I have ever had.\n",
+ "\n",
+ "sooo good: tastes so good. Worth the money. My boyfriend hates wheat pasta and LOVES this. cooks fast tastes great.I love this brand and started buying more of their pastas. Bulk is best.\n",
+ "\n",
+ "Wonderful: Came quickly. Was plentiful and delicious and cheaper than in the store. You will enjoy it if you like thick pasta.\n",
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "res = search_reviews(df, 'whole wheat pasta', n=3)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We can search through these reviews easily. To speed up computation, we can use a special algorithm, aimed at faster search through embeddings."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "great product, poor delivery: The coffee is excellent and I am a repeat buyer. Problem this time was with the UPS delivery. They left the box in front of my garage door in the middle of the drivewa\n",
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "res = search_reviews(df, 'bad delivery', n=1)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "As we can see, this can immediately deliver a lot of value. In this example we show being able to quickly find the examples of delivery failures."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Extremely dissapointed: Hi,<br />I am very disappointed with the past shipment I received of the ONE coconut water. 3 of the boxes were leaking and the coconut water was spoiled.<br /><br />Thanks.<b\n",
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "res = search_reviews(df, 'spoilt', n=1)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Good food: The only dry food my queen cat will eat. Helps prevent hair balls. Good packaging. Arrives promptly. Recommended by a friend who sells pet food.\n",
+ "\n",
+ "A great deal on Greenies: Paid only $22 with free shipping for 96 teenies compared to about $35 at the pet store. How can you go wrong with a deal like that? The dog begs for his daily Greenie. Got \n",
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "res = search_reviews(df, 'pet food', n=2)"
+ ]
+ }
+ ],
+ "metadata": {
+ "interpreter": {
+ "hash": "be4b5d5b73a21c599de40d6deb1129796d12dc1cc33a738f7bac13269cfcafe8"
+ },
+ "kernelspec": {
+ "display_name": "Python 3.7.3 64-bit ('base': conda)",
+ "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.7.3"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
examples/embeddings/User_and_product_embeddings.ipynb
@@ -0,0 +1,177 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## User and product embeddings\n",
+ "\n",
+ "We calculate user and product embeddings based on the training set, and evaluate the results on the unseen test set. We will evaluate the results by plotting the user and product similarity versus the review score. The dataset is created in the [Obtain_dataset Notebook](Obtain_dataset.ipynb)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 1. Calculate user and product embeddings\n",
+ "\n",
+ "We calculate these embeddings simply by averaging all the reviews about the same product or written by the same user within the training set."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(24502, 19035)"
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "from sklearn.model_selection import train_test_split\n",
+ "\n",
+ "df = pd.read_csv('output/embedded_babbage_similarity_50k.csv', index_col=0)\n",
+ "df['babbage_similarity'] = df.babbage_similarity.apply(eval).apply(np.array)\n",
+ "X_train, X_test, y_train, y_test = train_test_split(df, df.Score, test_size = 0.2, random_state=42)\n",
+ "\n",
+ "user_embeddings = X_train.groupby('UserId').babbage_similarity.apply(np.mean)\n",
+ "prod_embeddings = X_train.groupby('ProductId').babbage_similarity.apply(np.mean)\n",
+ "len(user_embeddings), len(prod_embeddings)\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We can see that most of the users and products appear within the 50k examples only once."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 2. Evaluate the embeddings\n",
+ "\n",
+ "To evaluate the recommendations, we look at the similarity of the user and product embeddings amongst the reviews in the unseen test set. We calculate the cosine distance between the user and product embeddings, which gives us a similarity score between 0 and 1. We then normalize the scores to be evenly split between 0 and 1, by calculating the percentile of the similarity score amongst all predicted scores."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from utils import cosine_similarity\n",
+ "\n",
+ "# evaluate embeddings as recommendations on X_test\n",
+ "def evaluate_single_match(row):\n",
+ " user_id = row.UserId\n",
+ " product_id = row.ProductId\n",
+ " try:\n",
+ " user_embedding = user_embeddings[user_id]\n",
+ " product_embedding = prod_embeddings[product_id]\n",
+ " similarity = cosine_similarity(user_embedding, product_embedding)\n",
+ " return similarity\n",
+ " except Exception as e:\n",
+ " return np.nan\n",
+ "\n",
+ "X_test['cosine_similarity'] = X_test.apply(evaluate_single_match, axis=1)\n",
+ "X_test['percentile_cosine_similarity'] = X_test.cosine_similarity.rank(pct=True)\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### 2.1 Visualize cosine similarity by review score\n",
+ "\n",
+ "We group the cosine similarity scores by the review score, and plot the distribution of cosine similarity scores for each review score."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 18,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Correlation between user&vector similarity percentile metric and review number of stars (score): 22.11%\n"
+ ]
+ },
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAX4AAAEcCAYAAADA5t+tAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/Z1A+gAAAACXBIWXMAAAsTAAALEwEAmpwYAAAaO0lEQVR4nO3de5Qc5X3m8e+j0QUMWEhgTwAJDY5lBa2IAQlYDt5YWhEsbEciCUkgNjGLYMxiJfJhFySIFzA+2YPjS7LGJFnFloEQJBx8OQqIiw3TdnzBIK42wmR1QLJGsCtuQgwgpBG//aNKuJnumWnoalXPvM/nnDp0Vb1d9etXwzPvvF1drYjAzMzSMabsAszMbO9y8JuZJcbBb2aWGAe/mVliHPxmZolx8JuZJcbBb3uVpJD03rLrKJOkuZJ6h9iffB9Zazn4EyVpo6RXJfVJekHSrZKmll3XHpLOlvSjsusYySSNl/QlSb35v/NGSX9bdl1WPgd/2n4vIvYHDgH+H3B1yfW0jKSxZddQgkuAOcDxwAHAXOCBIk+QaL+OeA5+IyJ2ADcDM/dskzRR0vWSnpG0SdJnJI2RNDkfQf5e3m5/SRsk/Vm+fq2kf5D0PUkvSfqBpGn1zjvEOY4E/gE4MR+pbhvk+UdI+mF+nu9LukbSDfm+rnzKZLGkXwF358f+TH6urfm5J+bta6Zf8hHyyfnjKyTdLOmm/HwPSHp/VdtDJX0rfy1PSvqLqn375v3ygqT1wHEN/LN8WNITkp6V9IW89vGSnpd0VNWx3y3pFUnvqnOM44DvRMRTkdkYEddXPXeqpG/nNT8n6av59qH6qaZf8+3nSHosf413DPZvbu3BwW9IegfwJ8A9VZuvBiYC7wE+CPwZ8F8i4nngHOAfJb0b+BvgoepAAT4GfA44GHgI+OdBTj3YOR4Dzgd+GhH7R8SBgzz/RuBe4CDgCuCsOm0+CBwJfAg4O1/m5efcH/jqIMeuZxHwL8Dk/NzflTRO0hjgX4GHgcOA+cCnJX0of97lwG/my4eATzRwrt8nG60fm5/3nIjYCawGPl7V7kzgroh4ps4x7gEulHSBpKMkac8OSR3ALcAmoCuve3W++2yG76c3+lXSIuBS4A+AdwH/Bqxq4DVaWSLCS4ILsBHoA7YBu4CngKPyfR3ATmBmVftPApWq9auBnwNbgIOqtl8LrK5a3x/YDUzN1wN473DnIAueHw1R/+FAP/COqm03ADfkj7vyc72nav9dwAVV6zPy1z6WbBqkt04fnZw/vgK4p2rfGOBp4D8BJwC/GvDcS4Bv5I+fABZU7eseeK4Bz40B7S8gC3f2nAtQvr4O+ONBjtMBfAr4MfBa/m/8iXzficAzwNg6zxuqn+r1623A4gF98wowreyfcy/1F4/403ZaZKPpfYAlwA8k/QbZSH0c2Whwj01ko8I9VgCzgGsj4rkBx92850FE9AHPA4cOaNPIOYZyKPB8RLxS77yDbDu0zvnGAp0NnrP6db0O9ObHnAYcKmnbnoVsBLznuIcOqKO6hmHPlbc/ND/vz8hCda6k3yL7Jbqm3gEiYndEXBMRJwEHAn8FrMyn0qYCmyKiv85TG+mn6vqmAf+r6rU/D4jG/y1tL3Pw256A+DbZyPwDwLNkI7zqedrDyUb3e6YJVgDXAxeo9tLDN64OkrQ/2dTIUwPaDHkOslHlUJ4GJufTVDXnrX55VY+fqnO+frI3tl8G3jhW/hoHzptXv64xwJT8mJuBJyPiwKrlgIj4cFWt1bUdPsxrG/haDufN/Xcd2XTPWcDNkb1HM6SIeDUirgFeIHsvZzNw+CBvzg7VT28csurxZuCTA17/vhHxk+HqspKU/SeHl3IW3jyNIbJ55H7gP+TbbgC+Q3Y1yDTgl8C5+b7/AfyEbCrh0j2P833XAtvJfoGMJ3sP4MdV5w3gvQ2cY0Fe4/ghXsM9wF/n5zkReJHaqZ6xVe3PBf4PcATZFNTNVe0nko2kP0L2l8jleX9UT/XsIpvHHgtcmNc3Lu+HB4BlwL75+izguPy5nwd+AEwi+2XxCMNP9dyVt5+a90t31f6pZKPqTcDvDHGcT5NNYe2b1/wJsimf9+Q1Pgx8EdiP7K++kxrop3r9+vvAL/j1z85E4I/K/hn3MsT//2UX4KWkf/gstF4lm+d/Kf8f92NV+yflwfwM2YjuMrK/EGeTjRr3hHcH2RzyX+br15JdkfO9/Ng/BI6oOm518Nc9R75vPHBrHnDPDvIafpPsjcSX8qBcAXw931cvoMbk59icn/MGYFLV/rPJRudbgf9O7Rz/zcBN+fkeBI6teu6hZG9o/t+8f+6peu47yP462gasBy5i+OD/C7L3Bp4DvkT+i7Wqzffz+jTEcbqB+8l+IW4jeyP8o1X7Dwe+m5/jWeArw/VTvX7Nt59F9p7P9vx5K8v+Gfcy+LLnDSKzQki6lizUPlPCuW8CfhkRl7fg2FeQ/cL6+HBt9wZJK4GnyuhnG/n84QsbsSQdR/YXwZPAKWTTVVeVWtReIKmLbMrpmJJLsRHKb+7aSPYbQIVsSukrwH+NiAdLrajFJH2ObFruCxHxZNn12MjkqR4zs8R4xG9mlhgHv5lZYhz8ZmaJcfCbmSXGwW9mlhgHv5lZYhz8ZmaJcfCbmSXGwW9mlpjS7tVz8MEHR1dXV1mnf5OXX36Z/fbbr+wy2or7pJb7pJb7pFY79cn999//bETUfB9zacHf1dXFunXryjr9m1QqFebOnVt2GW3FfVLLfVLLfVKrnfpEUt1ve/NUj5lZYhz8ZmaJcfCbmSXGwW9mlphhg1/SSklbJf1ikP2S9BVJGyQ9IunY4ss0M7OiNDLivxZYMMT+U4Hp+dIN/H3zZZmZWasMG/wR8UOy7zUdzCLg+sjcAxwo6ZCiCjQzs2IVMcd/GLC5ar0332ZmZm1or36AS1I32XQQnZ2dVCqVvXn6QfX19bVNLe0itT6ZN29eYcfq6ekp7Fhlcp/UGi19UkTwbwGmVq1PybfViIgVwAqAOXPmRLt8uq2dPmnXLlLrk4gYtk3X8lvZeNVH9kI17cF9Umu09EkRwb8GWCJpNXAC8GJEPF3Aca1FJBVynEb+JzCz9tPI5ZyrgJ8CMyT1Slos6XxJ5+dN1gJPABuAfwQuaFm1VoiIGHaZtuyWYduY2cg07Ig/Is4cZn8AnyqsIjMzayl/ctfMLDFJB/+qVauYNWsW8+fPZ9asWaxatarskszMWi7Z4F+1ahVLly7l5ZdfBrIvT1i6dKnD38xGvWSD/+KLL2bXrl1v2rZr1y4uvvjikioyM9s7kg3+3t7emitTIoLe3t6SKjIz2ztK++rFdtDR0cHKlSvZvXs3HR0dnH766WWXZGbWcsmO+KH2A0i+Nt3MUpD0iH/37t2cc845bNq0iWnTprF79+6ySzIza7lkR/xTpkyhv7+fLVu2EBFs2bKF/v5+pkyZUnZpZmYtlWzwn3baaezYsYPJkycjicmTJ7Njxw5OO+20skszM2upZIO/p6eHhQsXsm3bNiKCbdu2sXDhwlFz+1gzs8EkO8e/fv16XnnlFW677bY3rupZvHgxGzduLLs0M7OWSnbEP378eJYsWcK8efMYO3Ys8+bNY8mSJYwfP77s0szMWirZEf/OnTu54oorWL58Obt27WLcuHHss88+7Ny5s+zSzMxaKtkR/6RJk+jr6+Oggw5izJgxHHTQQfT19TFp0qSySzMza6lkR/zbt29n0qRJ3HjjjW/65O727dvLLs3MrKWSDf7+/n6OPvpo5s+fT0QgiXnz5nH33XeXXZqZWUslG/wdHR1UKhW++MUvMnPmTNavX89FF11ER0dH2aWZmbVUsnP8g92Xx/frMbPRLtkR/+uvv053dzeXXnopr732GhMmTODcc89lxYoVZZdmZtZSyY74J0yYwIwZM9ixYwc9PT3s2LGDGTNmMGHChLJLMzNrqWRH/Oeddx7Lli0DYObMmXz5y19m2bJlnH/++SVXZmbWWskG/9VXXw3wpqme888//43tZmajVbJTPZCFf/VUj0PfzFIw6kf8kgo5jq/2MbPRYtSP+CNi2GXasluGbWNmNlqM+uA3M7M3c/CbmSXGwW9mlhgHv5lZYhoKfkkLJD0uaYOk5XX2Hy6pR9KDkh6R9OHiSzUzsyIMG/ySOoBrgFOBmcCZkmYOaPYZ4JsRcQxwBvB3RRdqZmbFaGTEfzywISKeiIidwGpg0YA2AbwzfzwReKq4Es3MrEiNfIDrMGBz1XovcMKANlcAd0r6c2A/4ORCqjMzs8IV9cndM4FrI+JLkk4E/knSrIh4vbqRpG6gG6Czs5NKpVLQ6ZvXTrW0C/dJLfdJLfdJrXbvk0aCfwswtWp9Sr6t2mJgAUBE/FTSPsDBwNbqRhGxAlgBMGfOnJg7d+7bq7pot99K29TSLtwntdwntUZZn7z/s3fy4qu7mj7O2be/3NTzJ+47jocvP6XpOgbTSPDfB0yXdARZ4J8B/OmANr8C5gPXSjoS2Ad4pshCzcxa7cVXd7Hxqo80dYxKpdL0L8Ou5bc29fzhDPvmbkT0A0uAO4DHyK7eeVTSlZIW5s3+G3CepIeBVcDZ4RvcmJm1pYbm+CNiLbB2wLbLqh6vB04qtjQzM2sFf3LXzCwxDn4zs8Q4+M3MEuPgNzNLjIPfzCwxDn4zs8Q4+M3MEuPgNzNLTFE3aTOzEaao+9I0e3uBVt+Xxmo5+M0Slcp9aayWp3rMzBLj4DczS4yD38wsMQ5+M7PEOPjNzBLj4DczS4yD38wsMQ5+M7PEOPjNzBLjT+5aEnx7ArNfc/BbEnx7ArNf81SPmVliHPxmZolx8JuZJcbBb2aWGAe/mVliHPxmZolx8JuZJcbBb2aWGAe/mVliHPxmZolpKPglLZD0uKQNkpYP0uaPJa2X9KikG4st08zMijLsvXokdQDXAL8L9AL3SVoTEeur2kwHLgFOiogXJL27VQWbmVlzGhnxHw9siIgnImInsBpYNKDNecA1EfECQERsLbZMMzMrSiN35zwM2Fy13gucMKDN+wAk/RjoAK6IiNsHHkhSN9AN0NnZSaVSeRslt0Y71dIuRlufNPt6+vr6CumTdupX90mtJPokIoZcgNOBr1WtnwV8dUCbW4DvAOOAI8h+URw41HFnz54d7WLaslvKLqHtjLY+KeL19PT0tEUdRXGf1BptfQKsizr528hUzxZgatX6lHxbtV5gTUTsiogngX8Hpr/dX0ZmZtY6jUz13AdMl3QEWeCfAfzpgDbfBc4EviHpYLKpnycKrNMaVNQ3TYG/bcpstBo2+COiX9IS4A6y+fuVEfGopCvJ/oxYk+87RdJ6YDdwUUQ818rCrb4ivmkK/G1TZqNZQ1+9GBFrgbUDtl1W9TiAC/PFzMzamD+5a2aWGAe/mVliHPxmZolpaI7fzCwFBxy5nKOuq3s7srfmumbrAGj+Io3BOPjNzHIvPXZV01fFjYQr4jzVY2aWGAe/mVliHPxmZolx8JuZJcbBb2aWGAe/mVliHPxmZolx8JuZJcbBb2aWGAe/mVliHPxmZonxvXrMEpXKDcmsloPfLFGp3JDManmqx8wsMQ5+M7PEOPjNzBLj4DczS4yD38wsMQ5+M7PEjOjLOd//2Tt58dVdhRyr2UvKJu47jocvP6WQWszMWmlEB/+Lr+5q+jpk8LXIZpYWT/WYmSXGwW9mlhgHv5lZYhz8ZmaJaSj4JS2Q9LikDZIGvZ2fpD+UFJLmFFeimZkVadjgl9QBXAOcCswEzpQ0s067A4ClwM+KLtLMzIrTyIj/eGBDRDwRETuB1cCiOu0+B3we2FFgfWZmVrBGruM/DNhctd4LnFDdQNKxwNSIuFXSRYMdSFI30A3Q2dlJpVJ5ywUPVMQx+vr62qaWIrhP6mu2FvdJLfdJrRHRJxEx5AKcDnytav0s4KtV62OACtCVr1eAOcMdd/bs2dGsactuafoYERE9PT1NH6OoWprlPqmviFrcJ7XcJ7XaqU+AdVEnfxuZ6tkCTK1an5Jv2+MAYBZQkbQR+I/AGr/Ba2bWnhoJ/vuA6ZKOkDQeOANYs2dnRLwYEQdHRFdEdAH3AAsjYl1LKjYzs6YMG/wR0Q8sAe4AHgO+GRGPSrpS0sJWF2hmZsVq6CZtEbEWWDtg22WDtJ3bfFlmxTrgyOUcdd2gH0Fp3HXN1gHQ/I0FzZoxou/Oadaolx67quk7ufourjZa+JYNZmaJcfCbmSXGwW9mlhjP8Y8yhb2JCX4j02yUcvCPMkW8iQl+I9NsNPNUj5lZYhz8ZmaJcfCbmSXGwW9mlhgHv5lZYhz8ZmaJcfCbmSVmRF/H7w8rmZm9dSM6+P1hJTOzt25EB7+ZWdEKGcTd3twxJu47rvkahuDgNzPLFTGD0LX81kKO00p+c9fMLDEOfjOzxDj4zcwS4+A3M0uMg9/MLDEOfjOzxDj4zcwS4+A3M0uMP8BllrAUPqVqtRz8ZolK5VOqVstTPWZmiXHwm5klxsFvZpaYhoJf0gJJj0vaIKnmm08kXShpvaRHJN0laVrxpZqZWRGGDX5JHcA1wKnATOBMSTMHNHsQmBMRvw3cDPx10YWamVkxGhnxHw9siIgnImInsBpYVN0gInoi4pV89R5gSrFlmplZURoJ/sOAzVXrvfm2wSwGbmumKDMza51Cr+OX9HFgDvDBQfZ3A90AnZ2dVCqVps9ZxDH6+vrappYiFPb9v01+MGe/ce3TJ9B8LaPt56Qoo+31FKHt+yQihlyAE4E7qtYvAS6p0+5k4DHg3cMdMyKYPXt2NGvasluaPkZERE9PT9PHKKqWduHXU8s/J7VG2+spQjv1CbAu6uRvI1M99wHTJR0haTxwBrCmuoGkY4D/DSyMiK0F/U4yM7MWGDb4I6IfWALcQTai/2ZEPCrpSkkL82ZfAPYH/kXSQ5LWDHI4MzMrWUNz/BGxFlg7YNtlVY9PLrguMzNrkRF/k7Z2eSPTdxg0s5FiRAd/UXcF9B0GzSwlvlePmVliHPxmZokZ0VM9Zm+Fv23KLOPgtyT426bMfs1TPWZmiXHwm5klxsFvZpYYB7+ZWWIc/GZmiXHwm5klxsFvZpYYB7+ZWWIc/GZmiXHwm5klxsFvZpYYB7+ZWWIc/GZmiXHwm5klxsFvZpYYB7+ZWWIc/GZmiXHwm5klxsFvZpYYB7+ZWWIc/GZmiXHwm5klxsFvZpYYB7+ZWWIaCn5JCyQ9LmmDpOV19k+QdFO+/2eSugqv1MzMCjFs8EvqAK4BTgVmAmdKmjmg2WLghYh4L/A3wOeLLtTMzIrRyIj/eGBDRDwRETuB1cCiAW0WAdflj28G5ktScWWamVlRGgn+w4DNVeu9+ba6bSKiH3gROKiIAs3MrFhj9+bJJHUD3QCdnZ1UKpWWn3PevHkNtdMwk1M9PT0FVNMe3Ce1iuoTGD394j6pNVr6pJHg3wJMrVqfkm+r16ZX0lhgIvDcwANFxApgBcCcOXNi7ty5b6PktyYihm1TqVTYG7W0C/dJLfdJLfdJrdHSJ41M9dwHTJd0hKTxwBnAmgFt1gCfyB+fDtwdjfSQmZntdcOO+COiX9IS4A6gA1gZEY9KuhJYFxFrgK8D/yRpA/A82S8HMzNrQw3N8UfEWmDtgG2XVT3eAfxRsaWZmVkr+JO7ZmaJcfCbmSXGwW9mlhgHv5lZYhz8ZmaJUVmX20t6BthUyslrHQw8W3YRbcZ9Ust9Ust9Uqud+mRaRLxr4MbSgr+dSFoXEXPKrqOduE9quU9quU9qjYQ+8VSPmVliHPxmZolx8GdWlF1AG3Kf1HKf1HKf1Gr7PvEcv5lZYjziNzNLTNLBL2mlpK2SflF2Le1A0lRJPZLWS3pU0tKyayqbpH0k3Svp4bxPPlt2Te1CUoekByXdUnYt7ULSRkk/l/SQpHVl1zOYpKd6JP0O0AdcHxGzyq6nbJIOAQ6JiAckHQDcD5wWEetLLq00+XdH7xcRfZLGAT8ClkbEPSWXVjpJFwJzgHdGxEfLrqcdSNoIzImIdrmOv66kR/wR8UOy7w8wICKejogH8scvAY9R+/3KSYlMX746Ll/SHS3lJE0BPgJ8rexa7K1LOvhtcJK6gGOAn5VcSunyKY2HgK3A9yIi+T4B/ha4GHi95DraTQB3Sro//47xtuTgtxqS9ge+BXw6IraXXU/ZImJ3RBxN9n3Tx0tKelpQ0keBrRFxf9m1tKEPRMSxwKnAp/Lp5Lbj4Lc3yeexvwX8c0R8u+x62klEbAN6gAUll1K2k4CF+Xz2auA/S7qh3JLaQ0Rsyf+7FfgOcHy5FdXn4Lc35G9kfh14LCK+XHY97UDSuyQdmD/eF/hd4JelFlWyiLgkIqZERBfZ92vfHREfL7ms0knaL78oAkn7AacAbXnFYNLBL2kV8FNghqReSYvLrqlkJwFnkY3gHsqXD5ddVMkOAXokPQLcRzbH78sXrZ5O4EeSHgbuBW6NiNtLrqmupC/nNDNLUdIjfjOzFDn4zcwS4+A3M0uMg9/MLDEOfjOzxDj4LVmS/jK/4+Yj+aWrJ5Rdk9neMLbsAszKIOlE4KPAsRHxmqSDgfFNHG9sRPQXVqBZC3nEb6k6BHg2Il4DiIhnI+IpScdJ+kl+//17JR2Q35P/G/l91h+UNA9A0tmS1ki6G7gr/+Tmyvx5D0paVOYLNBuMR/yWqjuByyT9O/B94CayT3HfBPxJRNwn6Z3Aq8BSsjs0HyXpt8juvvi+/DjHAr8dEc9L+p9kty84J7/Nw72Svh8RL+/l12Y2JI/4LUn5PfZnA93AM2SB/0ng6Yi4L2+zPZ+++QBwQ77tl8AmYE/wfy8i9nynwynA8vwWzhVgH+DwvfF6zN4Kj/gtWRGxmyygK5J+DnzqbRymejQv4A8j4vECyjNrGY/4LUmSZkiaXrXpaLJvHDtE0nF5mwMkjQX+DfhYvu19ZKP4euF+B/Dn+V1OkXRM616B2dvnEb+lan/g6nwuvh/YQDbt8418+75k8/snA38H/H3+V0E/cHZ+JdDAY36O7JupHpE0BniS7Mohs7biu3OamSXGUz1mZolx8JuZJcbBb2aWGAe/mVliHPxmZolx8JuZJcbBb2aWGAe/mVli/j93vt+d34eekwAAAABJRU5ErkJggg==",
+ "text/plain": [
+ "<Figure size 432x288 with 1 Axes>"
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "import matplotlib.pyplot as plt\n",
+ "import statsmodels.api as sm\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "correlation = X_test[['percentile_cosine_similarity', 'Score']].corr().values[0,1]\n",
+ "print('Correlation between user&vector similarity percentile metric and review number of stars (score): %.2f%%' % (100*correlation))\n",
+ "\n",
+ "\n",
+ "# boxplot of cosine similarity for each score\n",
+ "X_test.boxplot(column='percentile_cosine_similarity', by='Score')\n",
+ "plt.title('')\n",
+ "plt.show()\n",
+ "plt.close()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We can observe a weak trend, showing that the higher the similarity score between the user and the product embedding, the higher the review score. Therefore, the user and product embeddings can weakly predict the review score - even before the user receives the product!\n",
+ "\n",
+ "Because this signal works in a different way than the more commonly used collaborative filtering, it can act as an additional feature to slightly improve the performance on existing problems."
+ ]
+ }
+ ],
+ "metadata": {
+ "interpreter": {
+ "hash": "be4b5d5b73a21c599de40d6deb1129796d12dc1cc33a738f7bac13269cfcafe8"
+ },
+ "kernelspec": {
+ "display_name": "Python 3.7.3 64-bit ('base': conda)",
+ "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.7.3"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
examples/embeddings/utils.py
@@ -0,0 +1,94 @@
+import openai
+import pandas as pd
+import numpy as np
+import matplotlib.pyplot as plt
+
+from tenacity import retry, wait_random_exponential, stop_after_attempt
+from sklearn.metrics import precision_recall_curve
+from sklearn.metrics import average_precision_score
+
+
+@retry(wait=wait_random_exponential(min=1, max=20), stop=stop_after_attempt(6))
+def get_embedding(text, engine="davinci-similarity"):
+
+ # replace newlines, which can negatively affect performance.
+ text = text.replace("\n", " ")
+
+ return openai.Engine(id=engine).embeddings(input = [text])['data'][0]['embedding']
+
+
+def cosine_similarity(a, b):
+ return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
+
+
+def plot_multiclass_precision_recall(
+ y_score, y_true_untransformed, class_list, classifier_name
+):
+ """
+ Precision-Recall plotting for a multiclass problem. It plots average precision-recall, per class precision recall and reference f1 contours.
+
+ Code slightly modified, but heavily based on https://scikit-learn.org/stable/auto_examples/model_selection/plot_precision_recall.html
+ """
+ n_classes = len(class_list)
+ y_true = pd.concat(
+ [(y_true_untransformed == class_list[i]) for i in range(n_classes)], axis=1
+ ).values
+
+ # For each class
+ precision = dict()
+ recall = dict()
+ average_precision = dict()
+ for i in range(n_classes):
+ precision[i], recall[i], _ = precision_recall_curve(y_true[:, i], y_score[:, i])
+ average_precision[i] = average_precision_score(y_true[:, i], y_score[:, i])
+
+ # A "micro-average": quantifying score on all classes jointly
+ precision["micro"], recall["micro"], _ = precision_recall_curve(
+ y_true.ravel(), y_score.ravel()
+ )
+ average_precision["micro"] = average_precision_score(
+ y_true, y_score, average="micro"
+ )
+ print(
+ str(classifier_name)
+ + " - Average precision score over all classes: {0:0.2f}".format(
+ average_precision["micro"]
+ )
+ )
+
+ # setup plot details
+ plt.figure(figsize=(9, 10))
+ f_scores = np.linspace(0.2, 0.8, num=4)
+ lines = []
+ labels = []
+ for f_score in f_scores:
+ x = np.linspace(0.01, 1)
+ y = f_score * x / (2 * x - f_score)
+ (l,) = plt.plot(x[y >= 0], y[y >= 0], color="gray", alpha=0.2)
+ plt.annotate("f1={0:0.1f}".format(f_score), xy=(0.9, y[45] + 0.02))
+
+ lines.append(l)
+ labels.append("iso-f1 curves")
+ (l,) = plt.plot(recall["micro"], precision["micro"], color="gold", lw=2)
+ lines.append(l)
+ labels.append(
+ "average Precision-recall (auprc = {0:0.2f})"
+ "".format(average_precision["micro"])
+ )
+
+ for i in range(n_classes):
+ (l,) = plt.plot(recall[i], precision[i], lw=2)
+ lines.append(l)
+ labels.append(
+ "Precision-recall for class `{0}` (auprc = {1:0.2f})"
+ "".format(class_list[i], average_precision[i])
+ )
+
+ fig = plt.gcf()
+ fig.subplots_adjust(bottom=0.25)
+ plt.xlim([0.0, 1.0])
+ plt.ylim([0.0, 1.05])
+ plt.xlabel("Recall")
+ plt.ylabel("Precision")
+ plt.title(f"{classifier_name}: Precision-Recall curve for each class")
+ plt.legend(lines, labels)
\ No newline at end of file
examples/embeddings/Visualize_in_2d.ipynb
@@ -0,0 +1,142 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Visualizing the embeddings in 2D\n",
+ "\n",
+ "We will use t-SNE to reduce the dimensionality of the embeddings from 2048 to 2. Once the embeddings are reduced to two dimensions, we can plot them in a 2D scatter plot. The dataset is created in the [Obtain_dataset Notebook](Obtain_dataset.ipynb)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 1. Reduce dimensionality\n",
+ "\n",
+ "We reduce the dimensionality to 2 dimensions using t-SNE decomposition."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(1000, 2)"
+ ]
+ },
+ "execution_count": 19,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import pandas as pd\n",
+ "from sklearn.manifold import TSNE\n",
+ "\n",
+ "# Load the embeddings\n",
+ "df = pd.read_csv('output/embedded_1k_reviews.csv')\n",
+ "\n",
+ "# Convert to a list of lists of floats\n",
+ "matrix = df.babbage_similarity.apply(eval).to_list()\n",
+ "\n",
+ "# Create a t-SNE model and transform the data\n",
+ "tsne = TSNE(n_components=2, perplexity=15, random_state=42, init='random', learning_rate=200)\n",
+ "vis_dims = tsne.fit_transform(matrix)\n",
+ "vis_dims.shape"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 2. Plotting the embeddings\n",
+ "\n",
+ "We colour each review by its star rating, ranging from red to green."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We can observe a decent data separation even in the reduced 2 dimensions. There seems to be a cluster of mostly negative reviews."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 20,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "Text(0.5, 1.0, 'Amazon ratings visualized in language using t-SNE')"
+ ]
+ },
+ "execution_count": 20,
+ "metadata": {},
+ "output_type": "execute_result"
+ },
+ {
+ "data": {
+ "image/png": "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",
+ "text/plain": [
+ "<Figure size 432x288 with 1 Axes>"
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "import matplotlib.pyplot as plt\n",
+ "import matplotlib\n",
+ "import numpy as np\n",
+ "\n",
+ "colors = [\"red\", \"darkorange\", \"gold\", \"turquoise\", \"darkgreen\"]\n",
+ "x = [x for x,y in vis_dims]\n",
+ "y = [y for x,y in vis_dims]\n",
+ "color_indices = df.Score.values - 1\n",
+ "\n",
+ "colormap = matplotlib.colors.ListedColormap(colors)\n",
+ "plt.scatter(x, y, c=color_indices, cmap=colormap, alpha=0.3)\n",
+ "for score in [0,1,2,3,4]:\n",
+ " avg_x = np.array(x)[df.Score-1==score].mean()\n",
+ " avg_y = np.array(y)[df.Score-1==score].mean()\n",
+ " color = colors[score]\n",
+ " plt.scatter(avg_x, avg_y, marker='x', color=color, s=100)\n",
+ "plt.title(\"Amazon ratings visualized in language using t-SNE\")"
+ ]
+ }
+ ],
+ "metadata": {
+ "interpreter": {
+ "hash": "be4b5d5b73a21c599de40d6deb1129796d12dc1cc33a738f7bac13269cfcafe8"
+ },
+ "kernelspec": {
+ "display_name": "Python 3.7.3 64-bit ('base': conda)",
+ "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.7.3"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
examples/embeddings/Zero-shot_classification.ipynb
@@ -0,0 +1,226 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Zero-shot classification using the embeddings\n",
+ "\n",
+ "In this notebook we will classify the sentiment of reviews using embeddings and zero labeled data! The dataset is created in the [Obtain_dataset Notebook](Obtain_dataset.ipynb).\n",
+ "\n",
+ "We'll define positive sentiment to be 4 and 5-star reviews, and negative sentiment to be 1 and 2-star reviews. 3-star reviews are considered neutral and we won't use them for this example.\n",
+ "\n",
+ "We will perform zero-shot classification by embedding descriptions of each class and then comparing new samples to those class embeddings."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "\n",
+ "from sklearn.ensemble import RandomForestClassifier\n",
+ "from sklearn.model_selection import train_test_split\n",
+ "from sklearn.metrics import classification_report, accuracy_score\n",
+ "\n",
+ "df = pd.read_csv('output/embedded_1k_reviews.csv')\n",
+ "df['babbage_similarity'] = df.babbage_similarity.apply(eval).apply(np.array)\n",
+ "df['babbage_search'] = df.babbage_search.apply(eval).apply(np.array)\n",
+ "\n",
+ "df= df[df.Score!=3]\n",
+ "df['sentiment'] = df.Score.replace({1:'negative', 2:'negative', 4:'positive', 5:'positive'})"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Zero-Shot Classification\n",
+ "To perform zero shot classification, we want to predict labels for our samples without any training. To do this, we can simply embed short descriptions of each label, such as positive and negative, and then compare the cosine distance between embeddings of samples and label descriptions. \n",
+ "\n",
+ "The highest similarity label to the sample input is the predicted label. We can also define a prediction score to be the difference between the cosine distance to the positive and to the negative label. This score can be used for plotting a precision-recall curve, which can be used to select a different tradeoff between precision and recall, by selecting a different threshold."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ " precision recall f1-score support\n",
+ "\n",
+ " negative 0.67 0.88 0.76 136\n",
+ " positive 0.98 0.93 0.95 789\n",
+ "\n",
+ " accuracy 0.92 925\n",
+ " macro avg 0.82 0.90 0.86 925\n",
+ "weighted avg 0.93 0.92 0.92 925\n",
+ "\n"
+ ]
+ },
+ {
+ "data": {
+ "image/png": "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FzscsyqVfP0tAHO/WcZWrVrW+PkbdBPT0qVLad26tZODZSaJ1q1bu9Zp9cI7M+YCMGzylwU5f4NOEICTg601/5ux+uLRc/cp6PkbfIIwM2uoWjQr7Ee4E0SBff7555xyyil06dKFPffck6OOOoopU6Ywc+ZMdt111xq7Tv/+/XnttdcAGDlyJN26daNHjx6UlJRw0kknrde5I4KDDjqIhQsXrlr37LPPIokPP/xw1bqZM2ey4YYb0qNHD7p27cpFF11EWVnZel37zTffZI899qBZs2YMHjy40v3GjBnDD37wA3bccUcuv/xyIpJZcefNm8ehhx7KTjvtxKGHHsrXX38NwIsvvkj//v3XKzazhs4JooAiguOPP57evXszffp0xowZw0033cQXX3xR49caMGAAhxxyCACPPfYY1157LePGjaN9+/ZVfrBWtHLlmg/Nv/zyy3Tv3p1NN/3u2chBgwax//77M2jQoNX27dKlC+PGjWPChAl88MEHPPvss+tWoFTHjh156KGHOO2006rc7+KLL+Yvf/kLU6dOZerUqbz66qsA3HzzzRx88MFMnTqVgw8+mJtvvhmAPn368MILL7BkyZL1is+sIWvQdzHluuGFSXzw2cLqd1wLXbfdlF8d3a3S7cOHD6d58+ZcdNFFq9Z1794dSL5tl5s5cyZnnnkm33yTTLdx11130atXL2bPns3JJ5/MwoULWblyJffccw+9evXi3HPPZfTo0UjinHPO4Re/+AX9+vWjb9++zJ8/n6eeeoohQ4bwyiuvcOONN9K3b18mTpxIaWkp11xzDSNGjGDZsmVceumlXHjhhYwYMYLrr7+eLbbYgg8//JApU6asVo7HHnuMCy64YNXy4sWLeeuttxg+fDhHH300N9xwwxplb9asGb169WLatGnr9N6W69SpEwBNmlT+XWb27NksXLiQH/7whwCcddZZPPvssxx55JE899xzjBgxAoCzzz6b3r17c8sttyCJ3r178+KLL/LTn/50vWI0a6gaTYIohokTJ7LnnntWu99WW23F0KFDadmyJVOnTuXUU09l9OjRPP744xx++OFcd911lJaWsmTJEsaNG0dJSQkTJ04EYP78+aud67zzzuOtt96ib9++nHTSSaslogceeIDNNtuMUaNGsWzZMvbbbz8OO+wwAMaOHcvEiRPz3tr59ttvc999961afu655zjiiCPYeeedad26NWPGjFmjnEuWLGHYsGEMGDBgjfMdcMABLFq0aI31t91226pa0NooKSmhQ4cOq5Y7dOhASUkJAF988QXt2rUDYJtttlmt9tazZ09GjhzpBGFWiUaTIKr6pl9sK1as4LLLLmPcuHE0bdp01Tf4vfbai3POOYcVK1Zw3HHH0aNHD3bYYQdmzJjBz3/+c/r06bPqAz6Lf/zjH0yYMGFVk9OCBQuYOnUqLVq0YO+99670vv958+bRqlWrVcuDBg3iiiuuAOCUU05h0KBBqxLE9OnT6dGjB5I49thjOfLII9c438iRIzPHXJMkrXaH0lZbbcVnn31WlFjM6oNGkyCKoVu3bpna///whz+w9dZbM378eMrKymjZMnng5Uc/+hFvvvkmL730Ev369ePKK6/krLPOYvz48QwZMoR7772Xp556igcffDBTPBHBn/70Jw4//PDV1o8YMYKNN9640uOaNWtGWVkZTZo0Yd68ebz++uu8//77SKK0tBRJ3HrrrcB3fRBVqekaRPv27Zk1a9aq5VmzZtG+fXsAtt56a2bPnk27du2YPXs2W2211ar9li5dyoYbbrjW1zNrLNxJXUAHHXQQy5Yt4/7771+1bsKECWt8g16wYAHt2rWjSZMmPPLII5SWlgLw8ccfs/XWW3P++edz3nnnMXbsWL766ivKyso48cQT+e1vf8vYsWMzx3P44Ydzzz33sGJFMpL7lClTVvV7VOV73/seM2bMAGDw4MGceeaZfPzxx8ycOZNPP/2Uzp07r1WtYOTIkYwbN26Nn3VJDgDt2rVj00035d133yUiePjhhzn22GMBOOaYYxg4cCAAAwcOXLUekvLX5J1kZsXyzbLCzMjgBFFAkvj73//Oa6+9RpcuXejWrRvXXnst22yzzWr7XXLJJQwcOJDu3bvz4Ycfrvo2P2LECLp3787uu+/Ok08+yRVXXEFJSQm9e/emR48enHHGGdx0002Z4znvvPPo2rUre+yxB7vuuisXXnhh3ruWKurTp8+qjt5BgwZx/PHHr7b9xBNPXONuppoyatQoOnTowNNPP82FF15It27fNRX26NFj1eu7776b8847jx133JEuXbqsatq65pprGDp0KDvttBOvvfYa11xzzapjhg8fTp8+fQoSt1ltWLI8+f/725cmF+T8Kr9fvL7r2bNnjB49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",
+ "text/plain": [
+ "<Figure size 432x288 with 1 Axes>"
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "from utils import cosine_similarity, get_embedding\n",
+ "from sklearn.metrics import PrecisionRecallDisplay\n",
+ "\n",
+ "def evaluate_emeddings_approach(\n",
+ " labels = ['negative', 'positive'], \n",
+ " engine = 'babbage-similarity',\n",
+ "):\n",
+ " label_embeddings = [get_embedding(label, engine=engine) for label in labels]\n",
+ "\n",
+ " def label_score(review_embedding, label_embeddings):\n",
+ " return cosine_similarity(review_embedding, label_embeddings[1]) - cosine_similarity(review_embedding, label_embeddings[0])\n",
+ "\n",
+ " engine_col_name = engine.replace('-','_').replace('_query','')\n",
+ " probas = df[engine_col_name].apply(lambda x: label_score(x, label_embeddings))\n",
+ " preds = probas.apply(lambda x: 'positive' if x>0 else 'negative')\n",
+ "\n",
+ " report = classification_report(df.sentiment, preds)\n",
+ " print(report)\n",
+ "\n",
+ " display = PrecisionRecallDisplay.from_predictions(df.sentiment, probas, pos_label='positive')\n",
+ " _ = display.ax_.set_title(\"2-class Precision-Recall curve\")\n",
+ "\n",
+ "evaluate_emeddings_approach(labels=['negative', 'positive'], engine='babbage-similarity')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We can see that this classifier already performs extremely well. We used similarity embeddings, and the simplest possible label name. Let's try to improve on this by using more descriptive label names, and search embeddings."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ " precision recall f1-score support\n",
+ "\n",
+ " negative 0.65 0.93 0.76 136\n",
+ " positive 0.99 0.91 0.95 789\n",
+ "\n",
+ " accuracy 0.92 925\n",
+ " macro avg 0.82 0.92 0.86 925\n",
+ "weighted avg 0.94 0.92 0.92 925\n",
+ "\n"
+ ]
+ },
+ {
+ "data": {
+ "image/png": "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3fn+97/Pe++9x+zZs9lpp53q7DxXXnklzzzzDADjx4+nT58+9OvXj3nz5nH88cfX6tgRwf7778/SpUsryh5++GEk8c4771SUzZ49m9atW9OvXz969+7NueeeS1nZN+Z5WicvvPACu+22G82bN2fUqKpHfp84cSI777wz2267LRdeeCERyay4Cxcu5KCDDmK77bbjoIMOYtGiRQA8/vjjXHnllVUez8ycIAoqIjjmmGMYNGgQs2bNYuLEiVxzzTV88skndX6u4cOHc+CBBwJw7733ctlllzF58mS6dOlS7QdrZWvWfPOh+SeffJK+ffvStu3Xz0aOHDmSfffdl5EjR661b69evZg8eTJTp07lrbfe4uGHH16/CqW6devGXXfdxcknn1ztfueddx5/+ctfmDFjBjNmzODpp58G4Nprr+WAAw5gxowZHHDAAVx77bUADB48mMcee4zly5fXKj6zpqxJ38WU6+rHpvPWR0tr3nEd9N6qLb88ok+V28eOHUuLFi0499xzK8r69u0LJN+2y82ePZtTTz2VL79Mptu4+eabGTBgAPPnz+fEE09k6dKlrFmzhltuuYUBAwbwox/9iAkTJiCJM888k5/97GcMHTqUww8/nMWLF/PAAw8wevRonnrqKX7zm99w+OGHM23aNEpLS7n00ksZN24cq1at4ic/+QnnnHMO48aN44orrmCzzTbjnXfe4b333lurHvfeey9nn312xfqyZct48cUXGTt2LEcccQRXX331N+revHlzBgwYwMyZM9frvS3Xo0cPAJo1q/q7zPz581m6dCl77bUXAKeddhoPP/wwhx12GI888gjjxo0D4PTTT2fQoEFcd911SGLQoEE8/vjjnHDCCbWK0ayp2mASRDFMmzaN3Xffvcb9tthiC8aMGUOrVq2YMWMGQ4YMYcKECfztb3/jkEMO4fLLL6e0tJTly5czefJk5s2bx7Rp0wBYvHjxWsc666yzePHFFzn88MM5/vjj10pEd9xxB+3ateP1119n1apV7LPPPhx88MEATJo0iWnTpuW9tfOll17itttuq1h/5JFHOPTQQ9l+++3p0KEDEydO/EY9ly9fzrPPPsvw4cO/cbyBAwfyxRdffKP8hhtuqLgKWhfz5s2ja9euFetdu3Zl3rxkdttPPvmEzp07A7DllluudfXWv39/xo8f7wRhVoUNJkFU902/2FavXs3555/P5MmTKSkpqfgGv8cee3DmmWeyevVqjj76aPr168c222zD+++/zwUXXMDgwYMrPuCz+Oc//8nUqVMrmpyWLFnCjBkzaNmyJXvuuWeV9/0vXLiQTTfdtGJ95MiR/PSnPwXgpJNOYuTIkRUJYtasWfTr1w9JHHXUURx22GHfON748eMzx1yXJK11h9IWW2zBRx99VJRYzBqDDSZBFEOfPn0ytf//4Q9/oFOnTkyZMoWysjJatWoFwHe/+11eeOEFnnjiCYYOHcpFF13EaaedxpQpUxg9ejS33norDzzwAHfeeWemeCKCP/7xjxxyyCFrlY8bN442bdpU+brmzZtTVlZGs2bNWLhwIc899xxvvvkmkigtLUUS119/PfB1H0R16voKokuXLsydO7dife7cuXTp0gWATp06MX/+fDp37sz8+fPZYostKvZbuXIlrVu3XufzmTUUf/vXHADGvvMpB/buVOfHdyd1Ae2///6sWrWK22+/vaJs6tSp3/gGvWTJEjp37kyzZs245557KC0tBeCDDz6gU6dODBs2jLPOOotJkybx2WefUVZWxnHHHcevf/1rJk2alDmeQw45hFtuuYXVq5OR3N97772Kfo/qfPvb3+b9998HYNSoUZx66ql88MEHzJ49mw8//JCePXuu01XB+PHjmTx58jd+1ic5AHTu3Jm2bdvy6quvEhHcfffdHHXUUQAceeSRjBgxAoARI0ZUlENS/7q8k8ysvp2//7YAzP685v/H68MJooAk8Y9//INnnnmGXr160adPHy677DK23HLLtfb78Y9/zIgRI+jbty/vvPNOxbf5cePG0bdvX3bddVfuv/9+fvrTnzJv3jwGDRpEv379OOWUU7jmmmsyx3PWWWfRu3dvdtttN3baaSfOOeecvHctVTZ48OCKjt6RI0dyzDHHrLX9uOOO+8bdTHXl9ddfp2vXrjz44IOcc8459OnzdVNhv379Kpb//Oc/c9ZZZ7HtttvSq1eviqatSy+9lDFjxrDddtvxzDPPcOmll1a8ZuzYsQwePLggcZvVhwG9OgDw6yfeLsjxVX6/eGPXv3//mDBhwlplb7/9NjvuuGORImo65s+fz2mnncaYMWOKHUqd+eSTTzj55JN59tln8273vx1rDMrKgm3+60mGDezJ5YN7r9cxJE2MiP75trkPwmrUuXNn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",
+ "text/plain": [
+ "<Figure size 432x288 with 1 Axes>"
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "evaluate_emeddings_approach(labels=['An Amazon review with a negative sentiment.', 'An Amazon review with a positive sentiment.'], engine='babbage-similarity')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Using the search embeddings and descriptive names leads to an additional improvement in performance."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ " precision recall f1-score support\n",
+ "\n",
+ " negative 0.77 0.79 0.78 136\n",
+ " positive 0.96 0.96 0.96 789\n",
+ "\n",
+ " accuracy 0.94 925\n",
+ " macro avg 0.87 0.88 0.87 925\n",
+ "weighted avg 0.94 0.94 0.94 925\n",
+ "\n"
+ ]
+ },
+ {
+ "data": {
+ "image/png": "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oZhVafbCpYx+77Oinb9eJ4hZs2bRokULOnXqhKRSh2N1QETwxRdfMGvWLDp37lzqcMwKmv/1ClavCRo3qv7PuHrdxLRs2TJatWrl5GCZSaJVq1audVqdcMCubYt6/nqdIAAnB1tv/puxuqLndlsV9fz1PkGYmdmGcYIosk8++YSTTz6ZLl26sOeee3LEEUcwdepUZs6cyW677VZt17nuuut44YUXABg7dizdunWjZ8+ezJ49mxNOOGGjzh0RHHDAASxevLh82xNPPIEk3n333fJtM2fOZLPNNqNnz5507dqVAQMGsGbNxg1F/PLLL7PHHnvQpEkThg6tfFiu8ePHs/vuu7PTTjtx+eWXExEAzJ8/n4MPPpidd96Zgw8+mAULFgDw9NNPc91111V6PjNzgiiqiODYY4+lb9++vP/++4wfP55bbrmFTz/9tNqvNXDgQA466CAAHnnkEa655homTJhAhw4dqvxgrWjVqlXrbBs+fDg9evSgZcuW5duGDBnC97//fYYMGbLWsV26dGHChAlMmjSJt99+myeeeGLDCpTafvvtefDBBzn11FOrPO6iiy7ij3/8I9OmTWPatGk899xzANx6660ceOCBTJs2jQMPPJBbb70VgH79+vHUU0+xZMmSjYrPrD6r13cx5brxqSm8PWdx4QPXQ9dtW3L9kd0q3T969GiaNm3KgAEDyrf16NEDSL5tl5k5cyZnnHEGX3/9NQC/+93v6NOnD3PnzuWkk05i8eLFrFq1ij/84Q/06dOHc889l3HjxiGJc845h5/85CecddZZ9O/fn4ULF/LYY48xYsQInn32WX7xi1/Qv39/Jk+ezOrVq7n66qsZM2YMy5cv55JLLuHCCy9kzJgxXHvttWy99da8++67TJ06da1yPPLII1xwwQXl61999RWvvPIKo0eP5sgjj+TGG29cp+xNmjShT58+TJ8+fYPe2zKdOnUCoFGjyr/LzJ07l8WLF7P33nsDcOaZZ/LEE09w+OGH8+STTzJmzBgAfvzjH9O3b19uu+02JNG3b1+efvppTjzxxI2K0ay+ajAJohQmT57MnnvuWfC4tm3bMnLkSJo1a8a0adM45ZRTGDduHH/5y1849NBD+fnPf87q1atZsmQJEyZMYPbs2UyePBmAhQsXrnWu8847j1deeYX+/ftzwgknrJWIHnjgAbbccktef/11li9fzr777sshhxwCwBtvvMHkyZPz3tr5z3/+k/vuu698/cknn+Swww5jl112oVWrVowfP36dci5ZsoQXX3yRgQMHrnO+/fbbjy+//HKd7XfccUd5LWh9zJ49m44dO5avd+zYkdmzk6lHPv30U9q3bw/ANttss1btrVevXowdO9YJwqwSDSZBVPVNv9RWrlzJpZdeyoQJE2jcuHH5N/i99tqLc845h5UrV3LMMcfQs2dPdtxxR2bMmMFll11Gv379yj/gs3j++eeZNGlSeZPTokWLmDZtGptssgm9e/eu9L7/+fPn06JFi/L1IUOGcMUVVwBw8sknM2TIkPIE8f7779OzZ08kcfTRR3P44Yevc76xY8dmjrk6SVrrDqW2bdsyZ86cksRiVhc0mARRCt26dcvU/v/rX/+adu3aMXHiRNasWUOzZskUgj/4wQ94+eWXeeaZZzjrrLO48sorOfPMM5k4cSIjRozg3nvv5bHHHmPQoEGZ4okI7r77bg499NC1to8ZM4Ytttii0tc1adKENWvW0KhRI+bPn8+oUaN46623kMTq1auRxO233w580wdRlequQXTo0IFZs2aVr8+aNYsOHZLpz9u1a8fcuXNp3749c+fOpW3bb+4bX7ZsGZttttl6X8+soXAndREdcMABLF++nPvvv79826RJk9b5Br1o0SLat29Po0aNePjhh1m9OpmW+8MPP6Rdu3acf/75nHfeebzxxht8/vnnrFmzhuOPP56bb76ZN954I3M8hx56KH/4wx9YuXIlAFOnTi3v96jKt7/9bWbMmAHA0KFDOeOMM/jwww+ZOXMmH3/8MZ07d16vWsHYsWOZMGHCOj8bkhwA2rdvT8uWLXn11VeJCB566CGOPvpoAI466igGDx4MwODBg8u3Q1L+6ryTzKxUxn+4oCjndYIoIkn84x//4IUXXqBLly5069aNa665hm222Wat4y6++GIGDx5Mjx49ePfdd8u/zY8ZM4YePXrw3e9+l0cffZQrrriC2bNn07dvX3r27Mnpp5/OLbfckjme8847j65du7LHHnuw2267ceGFF+a9a6mifv36lXf0DhkyhGOPPXat/ccff/w6dzNVl9dff52OHTvyt7/9jQsvvJBu3b5pKuzZs2f58u9//3vOO+88dtppJ7p06VLetHX11VczcuRIdt55Z1544QWuvvrq8teM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",
+ "text/plain": [
+ "<Figure size 432x288 with 1 Axes>"
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "evaluate_emeddings_approach(labels=['An Amazon review with a negative sentiment.', 'An Amazon review with a positive sentiment.'], engine='babbage-search-query')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "As shown above, zero-shot classification with embeddings can lead to great results, especially when the labels are more descriptive than just simple words."
+ ]
+ }
+ ],
+ "metadata": {
+ "interpreter": {
+ "hash": "be4b5d5b73a21c599de40d6deb1129796d12dc1cc33a738f7bac13269cfcafe8"
+ },
+ "kernelspec": {
+ "display_name": "Python 3.7.3 64-bit ('base': conda)",
+ "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.7.3"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
examples/finetuning/answers-with-ft.py → examples/finetuning/answers_with_ft.py
@@ -67,8 +67,14 @@ def answer_question(
print("Context:\n" + context)
print("\n\n")
try:
+ # fine-tuned models requires model parameter, whereas other models require engine parameter
+ model_param = (
+ {"model": fine_tuned_qa_model}
+ if ":" in fine_tuned_qa_model
+ and fine_tuned_qa_model.split(":")[1].startswith("ft")
+ else {"engine": fine_tuned_qa_model}
+ )
response = openai.Completion.create(
- model=fine_tuned_qa_model,
prompt=f"Answer the question based on the context below\n\nText: {context}\n\n---\n\nQuestion: {question}\nAnswer:",
temperature=0,
max_tokens=max_tokens,
@@ -76,6 +82,7 @@ def answer_question(
frequency_penalty=0,
presence_penalty=0,
stop=stop_sequence,
+ **model_param,
)
return response["choices"][0]["text"]
except Exception as e:
examples/finetuning/olympics-1-collect-data.ipynb
@@ -0,0 +1,513 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# 1. Collect Wikipedia data about Olympic Games 2020\n",
+ "\n",
+ "The idea of this project is to create a question answering model, based on a few paragraphs of provided text. Base GPT-3 models do a good job at answering questions when the answer is contained within the paragraph, however if the answer isn't contained, the base models tend to try their best to answer anyway, often leading to confabulated answers. \n",
+ "\n",
+ "To create a model which answers questions only if there is sufficient context for doing so, we first create a dataset of questions and answers based on paragraphs of text. In order to train the model to answer only when the answer is present, we also add adversarial examples, where the question doesn't match the context. In those cases, we ask the model to output \"No sufficient context for answering the question\". \n",
+ "\n",
+ "We will perform this task in three notebooks:\n",
+ "1. The first (this) notebook focuses on collecting recent data, which GPT-3 didn't see during it's pre-training. We picked the topic of Olympic Games 2020 (which actually took place in the summer of 2021), and downloaded 713 unique pages. We organized the dataset by individual sections, which will serve as context for asking and answering the questions.\n",
+ "2. The [second notebook](olympics-2-create-qa.ipynb) will utilize Davinci-instruct to ask a few questions based on a Wikipedia section, as well as answer those questions, based on that section.\n",
+ "3. The [third notebook](olympics-3-train-qa.ipynb) will utilize the dataset of context, question and answer pairs to additionally create adversarial questions and context pairs, where the question was not generated on that context. In those cases the model will be prompted to answer \"No sufficient context for answering the question\". We will also train a discriminator model, which predicts whether the question can be answered based on the context or not."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 1.1 Data extraction using the wikipedia API\n",
+ "Extracting the data will take about half an hour, and processing will likely take about as much."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "909"
+ ]
+ },
+ "execution_count": 1,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import pandas as pd\n",
+ "import wikipedia\n",
+ "\n",
+ "\n",
+ "def filter_olympic_2020_titles(titles):\n",
+ " \"\"\"\n",
+ " Get the titles which are related to Olympic games hosted in 2020, given a list of titles\n",
+ " \"\"\"\n",
+ " titles = [title for title in titles if '2020' in title and 'olympi' in title.lower()]\n",
+ " \n",
+ " return titles\n",
+ "\n",
+ "def get_wiki_page(title):\n",
+ " \"\"\"\n",
+ " Get the wikipedia page given a title\n",
+ " \"\"\"\n",
+ " try:\n",
+ " return wikipedia.page(title)\n",
+ " except wikipedia.exceptions.DisambiguationError as e:\n",
+ " return wikipedia.page(e.options[0])\n",
+ " except wikipedia.exceptions.PageError as e:\n",
+ " return None\n",
+ "\n",
+ "def recursively_find_all_pages(titles, titles_so_far=set()):\n",
+ " \"\"\"\n",
+ " Recursively find all the pages that are linked to the Wikipedia titles in the list\n",
+ " \"\"\"\n",
+ " all_pages = []\n",
+ " \n",
+ " titles = list(set(titles) - titles_so_far)\n",
+ " titles = filter_olympic_2020_titles(titles)\n",
+ " titles_so_far.update(titles)\n",
+ " for title in titles:\n",
+ " page = get_wiki_page(title)\n",
+ " if page is None:\n",
+ " continue\n",
+ " all_pages.append(page)\n",
+ "\n",
+ " new_pages = recursively_find_all_pages(page.links, titles_so_far)\n",
+ " for pg in new_pages:\n",
+ " if pg.title not in [p.title for p in all_pages]:\n",
+ " all_pages.append(pg)\n",
+ " titles_so_far.update(page.links)\n",
+ " return all_pages\n",
+ "\n",
+ "\n",
+ "pages = recursively_find_all_pages([\"2020 Summer Olympics\"])\n",
+ "len(pages)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 1.2 Filtering the Wikipedia pages and splitting them into sections by headings\n",
+ "We remove sections unlikely to contain textual information, and ensure that each section is not longer than the token limit"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "('Bermuda at the 2020 Summer Olympics',\n",
+ " 'Equestrian',\n",
+ " \"Bermuda entered one dressage rider into the Olympic competition by finishing in the top four, outside the group selection, of the individual FEI Olympic Rankings for Groups D and E (North, Central, and South America), marking the country's recurrence to the sport after an eight-year absence. The quota was later withdrawn, following an injury of Annabelle Collins' main horse Joyero and a failure to obtain minimum eligibility requirements (MER) aboard a new horse Chuppy Checker.\",\n",
+ " 104)"
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "\n",
+ "import re\n",
+ "from typing import Set\n",
+ "from transformers import GPT2TokenizerFast\n",
+ "\n",
+ "import numpy as np\n",
+ "from nltk.tokenize import sent_tokenize\n",
+ "\n",
+ "tokenizer = GPT2TokenizerFast.from_pretrained(\"gpt2\")\n",
+ "\n",
+ "def count_tokens(text: str) -> int:\n",
+ " \"\"\"count the number of tokens in a string\"\"\"\n",
+ " return len(tokenizer.encode(text))\n",
+ "\n",
+ "def reduce_long(\n",
+ " long_text: str, long_text_tokens: bool = False, max_len: int = 590\n",
+ ") -> str:\n",
+ " \"\"\"\n",
+ " Reduce a long text to a maximum of `max_len` tokens by potentially cutting at a sentence end\n",
+ " \"\"\"\n",
+ " if not long_text_tokens:\n",
+ " long_text_tokens = count_tokens(long_text)\n",
+ " if long_text_tokens > max_len:\n",
+ " sentences = sent_tokenize(long_text.replace(\"\\n\", \" \"))\n",
+ " ntokens = 0\n",
+ " for i, sentence in enumerate(sentences):\n",
+ " ntokens += 1 + count_tokens(sentence)\n",
+ " if ntokens > max_len:\n",
+ " return \". \".join(sentences[:i][:-1]) + \".\"\n",
+ "\n",
+ " return long_text\n",
+ "\n",
+ "discard_categories = ['See also', 'References', 'External links', 'Further reading', \"Footnotes\",\n",
+ " \"Bibliography\", \"Sources\", \"Citations\", \"Literature\", \"Footnotes\", \"Notes and references\",\n",
+ " \"Photo gallery\", \"Works cited\", \"Photos\", \"Gallery\", \"Notes\", \"References and sources\",\n",
+ " \"References and notes\",]\n",
+ "\n",
+ "\n",
+ "def extract_sections(\n",
+ " wiki_text: str,\n",
+ " title: str,\n",
+ " max_len: int = 1500,\n",
+ " discard_categories: Set[str] = discard_categories,\n",
+ ") -> str:\n",
+ " \"\"\"\n",
+ " Extract the sections of a Wikipedia page, discarding the the references and other low information sections\n",
+ " \"\"\"\n",
+ " if len(wiki_text) == 0:\n",
+ " return []\n",
+ "\n",
+ " # find all headings and the coresponding contents\n",
+ " headings = re.findall(\"==+ .* ==+\", wiki_text)\n",
+ " for heading in headings:\n",
+ " wiki_text = wiki_text.replace(heading, \"==+ !! ==+\")\n",
+ " contents = wiki_text.split(\"==+ !! ==+\")\n",
+ " contents = [c.strip() for c in contents]\n",
+ " assert len(headings) == len(contents) - 1\n",
+ "\n",
+ " cont = contents.pop(0).strip()\n",
+ " outputs = [(title, \"Summary\", cont, count_tokens(cont)+4)]\n",
+ " \n",
+ " # discard the discard categories, accounting for a tree structure\n",
+ " max_level = 100\n",
+ " keep_group_level = max_level\n",
+ " remove_group_level = max_level\n",
+ " nheadings, ncontents = [], []\n",
+ " for heading, content in zip(headings, contents):\n",
+ " plain_heading = \" \".join(heading.split(\" \")[1:-1])\n",
+ " num_equals = len(heading.split(\" \")[0])\n",
+ " if num_equals <= keep_group_level:\n",
+ " keep_group_level = max_level\n",
+ "\n",
+ " if num_equals > remove_group_level:\n",
+ " if (\n",
+ " num_equals <= keep_group_level\n",
+ " ):\n",
+ " continue\n",
+ " keep_group_level = max_level\n",
+ " if plain_heading in discard_categories:\n",
+ " remove_group_level = num_equals\n",
+ " keep_group_level = max_level\n",
+ " continue\n",
+ " nheadings.append(heading.replace(\"=\", \"\").strip())\n",
+ " ncontents.append(content)\n",
+ " remove_group_level = max_level\n",
+ "\n",
+ " # count the tokens of each section\n",
+ " ncontent_ntokens = [\n",
+ " count_tokens(c)\n",
+ " + 3\n",
+ " + count_tokens(\" \".join(h.split(\" \")[1:-1]))\n",
+ " - (1 if len(c) == 0 else 0)\n",
+ " for h, c in zip(nheadings, ncontents)\n",
+ " ]\n",
+ "\n",
+ " # Create a tuple of (title, section_name, content, number of tokens)\n",
+ " outputs += [(title, h, c, t) if t<max_len \n",
+ " else (title, h, reduce_long(c, max_len), count_tokens(reduce_long(c,max_len))) \n",
+ " for h, c, t in zip(nheadings, ncontents, ncontent_ntokens)]\n",
+ " \n",
+ " return outputs\n",
+ "\n",
+ "# Example page being processed into sections\n",
+ "bermuda_page = get_wiki_page('Bermuda at the 2020 Summer Olympics')\n",
+ "ber = extract_sections(bermuda_page.content, bermuda_page.title)\n",
+ "\n",
+ "# Example section\n",
+ "ber[-1]\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 1.2.1 We create a dataset and filter out any sections with fewer than 40 tokens, as those are unlikely to contain enough context to ask a good question."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "Token indices sequence length is longer than the specified maximum sequence length for this model (1060 > 1024). Running this sequence through the model will result in indexing errors\n"
+ ]
+ },
+ {
+ "data": {
+ "text/html": [
+ "<div>\n",
+ "<style scoped>\n",
+ " .dataframe tbody tr th:only-of-type {\n",
+ " vertical-align: middle;\n",
+ " }\n",
+ "\n",
+ " .dataframe tbody tr th {\n",
+ " vertical-align: top;\n",
+ " }\n",
+ "\n",
+ " .dataframe thead th {\n",
+ " text-align: right;\n",
+ " }\n",
+ "</style>\n",
+ "<table border=\"1\" class=\"dataframe\">\n",
+ " <thead>\n",
+ " <tr style=\"text-align: right;\">\n",
+ " <th></th>\n",
+ " <th>title</th>\n",
+ " <th>heading</th>\n",
+ " <th>content</th>\n",
+ " <th>tokens</th>\n",
+ " </tr>\n",
+ " </thead>\n",
+ " <tbody>\n",
+ " <tr>\n",
+ " <th>0</th>\n",
+ " <td>2020 Summer Olympics</td>\n",
+ " <td>Summary</td>\n",
+ " <td>The 2020 Summer Olympics (Japanese: 2020年夏季オリン...</td>\n",
+ " <td>713</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>1</th>\n",
+ " <td>2020 Summer Olympics</td>\n",
+ " <td>Host city selection</td>\n",
+ " <td>The International Olympic Committee (IOC) vote...</td>\n",
+ " <td>126</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>2</th>\n",
+ " <td>2020 Summer Olympics</td>\n",
+ " <td>Impact of the COVID-19 pandemic</td>\n",
+ " <td>In January 2020, concerns were raised about th...</td>\n",
+ " <td>369</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>3</th>\n",
+ " <td>2020 Summer Olympics</td>\n",
+ " <td>Qualifying event cancellation and postponement</td>\n",
+ " <td>Concerns about the pandemic began to affect qu...</td>\n",
+ " <td>298</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>4</th>\n",
+ " <td>2020 Summer Olympics</td>\n",
+ " <td>Effect on doping tests</td>\n",
+ " <td>Mandatory doping tests were being severely res...</td>\n",
+ " <td>163</td>\n",
+ " </tr>\n",
+ " </tbody>\n",
+ "</table>\n",
+ "</div>"
+ ],
+ "text/plain": [
+ " title heading \\\n",
+ "0 2020 Summer Olympics Summary \n",
+ "1 2020 Summer Olympics Host city selection \n",
+ "2 2020 Summer Olympics Impact of the COVID-19 pandemic \n",
+ "3 2020 Summer Olympics Qualifying event cancellation and postponement \n",
+ "4 2020 Summer Olympics Effect on doping tests \n",
+ "\n",
+ " content tokens \n",
+ "0 The 2020 Summer Olympics (Japanese: 2020年夏季オリン... 713 \n",
+ "1 The International Olympic Committee (IOC) vote... 126 \n",
+ "2 In January 2020, concerns were raised about th... 369 \n",
+ "3 Concerns about the pandemic began to affect qu... 298 \n",
+ "4 Mandatory doping tests were being severely res... 163 "
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "res = []\n",
+ "for page in pages:\n",
+ " res += extract_sections(page.content, page.title)\n",
+ "df = pd.DataFrame(res, columns=[\"title\", \"heading\", \"content\", \"tokens\"])\n",
+ "df = df[df.tokens>40]\n",
+ "df = df.drop_duplicates(['title','heading'])\n",
+ "df = df.reset_index().drop('index',axis=1) # reset index\n",
+ "df.head()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Save the section dataset\n",
+ "We will save the section dataset, for the [next notebook](olympics-2-create-qa.ipynb)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "df.to_csv('olympics-data/olympics_sections.csv', index=False)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 1.3 (Optional) Exploring the data "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "Concerns and controversies at the 2020 Summer Olympics 51\n",
+ "United States at the 2020 Summer Olympics 46\n",
+ "Great Britain at the 2020 Summer Olympics 42\n",
+ "Canada at the 2020 Summer Olympics 39\n",
+ "Olympic Games 39\n",
+ "Name: title, dtype: int64"
+ ]
+ },
+ "execution_count": 5,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "df.title.value_counts().head()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "There appear to be winter and summer Olympics 2020. We chose to leave a little ambiguity and noise in the dataset, even though we were interested in only Summer Olympics 2020."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True 3567\n",
+ "False 305\n",
+ "Name: title, dtype: int64"
+ ]
+ },
+ "execution_count": 6,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "df.title.str.contains('Summer').value_counts()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "False 3774\n",
+ "True 98\n",
+ "Name: title, dtype: int64"
+ ]
+ },
+ "execution_count": 7,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "df.title.str.contains('Winter').value_counts()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYsAAAEWCAYAAACXGLsWAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/Z1A+gAAAACXBIWXMAAAsTAAALEwEAmpwYAAAr20lEQVR4nO3deZwcVbn/8c+XsCdI2MwNEAibelEuCBHxojgBZRfUHyhcwABRREFB8UrABRQRXABFEERZXQiIC7sIXCIqsgWBsEqAsIRNIIQEBAl5fn+c06Sm6emumUzNFJnv+/Xq11SdU8vTNdX1dNU5XaWIwMzMrJ3FBjsAMzOrPycLMzPryMnCzMw6crIwM7OOnCzMzKwjJwszM+vIyaJA0qmSvtZPy1pD0lxJw/L4FEmf7I9l5+VdLmlCfy2vF+v9lqSnJT0x0OtuiqNL0qODuP6PSHok/4/f2Q/LC0nr9kdsfVh3t3214nW99hlr9z+U9D5J91YUw1mSvlX1evqDpMMl/Wyw44AhlCwkzZD0L0lzJD0n6TpJ+0t6bRtExP4RcVTJZX2g3TQR8XBEjIiIV/sh9iMl/aJp+dtFxNkLu+xexrEGcAiwfkT8x0Cuu4a+DxyY/8d/b64czIN/by3MvirpXkkfL4xvnt97c9kcSYuX/YxFxJ8j4q29jae3Bmo9ZbRKnhHx7Yjoty+ZC2PIJIvsQxGxHLAmcCxwKHB6f69E0uL9vcyaWAN4JiKeGuxA+lMf/19rAnf2dyxvQNcCWxTGtwDuaVH2t4iYN5CBWT+LiCHxAmYAH2gq2xSYD7wjj58FfCsPrwxcAjwHPAv8mZRcf57n+RcwF/gyMBYIYCLwMOkD1ChbPC9vCnAMcCPwPHAhsGKu6wIebRUvsC3wb+CVvL7bCsv7ZB5eDPgq8BDwFHAOsHyua8QxIcf2NPCVNttp+Tz/P/PyvpqX/4H8nufnOM5qMW8X8Cjp7OMp4HFgn0L9azHn8b2BvxTGA/gscB8wBzgKWAe4Lm+z84Elm9Z1eH5PM4A9CstaivTt/2HgSeBUYJmmeQ8FngB+3uK9tNymeblzc6wvAPe3mPfaQv1c4OO5/FPAdNL+dBGwatN7XzcPvxd4BOjK4/sCdwOzgCuANZvm2z9vs+eAkwHlunWBPwGz8zY6r4f/eWMfKe6rRwF/zf+HPwIr9zDvXsC0wvhl+f/aXPbVFp+xLgr7PfB54C5g9RZ1M4DDcv0s4Exg6UL9jsCteRtcB/xXoe6dwC35vZwHTG4TwyTg/jztXcBH2nxWNgVuJu2bTwLHF+o2y3E8B9zW+F/muhVz/I/l9/J7YDjdP19zgVWBI4FfFObdifQl5bn8f/rPpm30JeD2/D8/r7GN6OF41qtjaJUH6Dq9aJEscvnDwGda7MjHkA4wS+TX+1jwIey2LBZ82M7J//RlaP0BnAm8I0/zm8ZO0LzDNq+jeYcpLK+RLPYlHYTWBkYAvyUfAAtx/DTHtSHwcnEna1ruOaREtlye9x/AxJ7ibJq3C5gHfDNvs+2BF4EVmmPO43vz+mRxIfAm4O05zqvz+1qe9OGd0LSu40kH8PeTDs5vzfUnkA7IK+b3cjFwTNO838nzLtPivfS4TQuxrttmW3SrB7YkHbA3zuv8EXBt8/SkLwePAJvm8p1zHP8JLE5KYNc1zXcJMJJ05vdPYNtcdy7wFVLiWxp4bw+xNvaR4r56P/CWvM9MAY7tYd41SQe4FfN6nsrzPFIomw1s0eIz1kXen4Cvkw7oq7Ta10ifhzuAMXm5fy0s5515ve8GhpG+GM3I23lJUsL/Ammf3IX0xaunZLEr6SC9GPBx0j41uof3/jdgrzw8AtgsD68GPEPa/xcDPpjHG+/tUtKBfIUc0/vbHAeOZMFx4i05ng/m+b5M2jeWLGyjG3P8K5K+YOzf6XhW9jXULkO18hhpwzZ7BRhN+hb3SqRrm9FhWUdGxAsR8a8e6n8eEXdExAvA14CP9VOj4h6kbzUPRMRc0jew3Zour3wjIv4VEbeRvuls2LyQHMtuwGERMSciZgDHkb49lvUK8M28zS4jfUPqzTXh70bE8xFxJ+ng8Mf8vmYDl5MODEVfi4iXI+JPpA/hxyQJ2A/4QkQ8GxFzgG/n99YwHzgiz9vq/1Vmm/bGHsAZEXFLRLycl/ceSWML0+wK/ATYLiJuzGX7k5Lc3ZEu43wb2EjSmoX5jo2I5yLiYeAaYKNc/grpYL5qRLwUEX/pRbxnRsQ/8rY5v7DMbiLiIdIXrveR9qn78jx/LZQtCdzQw3ok6Xhga2B8RPyzTUwnRcQjEfEscDSwey7fD/hJRNwQEa9Gast7mfTtfjPSwfEHeZ+8ALippxVExK8j4rGImB8R55HO2DbtYfJXgHUlrRwRcyPi+ly+J3BZRFyWl3Ml6Qxke0mjge1IB/FZOaY/tXnPRR8HLo2IKyPiFdKZ8zLAfxemOTHH/yzpC9JGhVh7ezzrxskifQt4tkX590hZ+4+SHpA0qcSyHulF/UOknXjlUlG2t2peXnHZiwOjCmXF3ksvkr4JNVs5x9S8rNV6Ecsz0f3adE/r6smTheF/tRgvLmtWTrwND5G2xSrAssDU3JnhOeAPubzhnxHxUps4ymzT3ui2vJyAnqH7tj0YOD8i7iiUrQn8sPA+ngXUNF9P/9sv52lvlHSnpH17EW+Z/aWh0W6xBenyBsBfCmU35gTZykjSwf6Y/IWgnebPz6p5eE3gkMY2yttpTK5fFZjZdGAs/l+7kfQJSbcWlvMOev6MTiR9279H0k2SdizEs2tTPO8lHazHAM9GxKwO77WV5n1oPmmblNkX+nI862ZIJwtJ7yJt6Nd948rfrA+JiLVJ1wm/KGmrRnUPi+yUqccUhtcgZfunSaeWyxbiGkb3A1un5T5G2kGLy55H9wNtGU+z4NtocVkze7mcnnR7n8DC9qhaQdLwwvgapG3xNCmxvD0iRubX8hFRPOAN1DZtubwc90p037a7Ah+WdFCh7BHg04X3MTIilomI6zqtMCKeiIhPRcSqwKeBH1fUQ6uRLN7HgmTx50LZtW3mnUVqbzhT0uYd1tP8+XksDz8CHN20jZaNiHNJ7War5bPN4ryvk8/WfgocCKwUESNJZ7dqNX1E3BcRuwNvJl3SvCD/Xx8hXUUoxjM8Io7NdStKGtlqkR3ef/M+JNI26fj57HA8K2VIJgtJb8rfAiaTrgdOazHNjpLWzf+Q2cCrpEsXkA4Ya/dh1XtKWl/SsqTr+hdE6q74D2BpSTtIWoJ0XXqpwnxPAmOL3XybnAt8QdJakkaQLlWcF73sfZJjOR84WtJy+cPzReAX7ecs7Vbgo5KWzQetif2wzG9IWlLS+0gHnV/nb1w/BU6Q9GYASatJ2qYXy13Ybdq8j5wL7CNpI0lL5eXdkC/1NTwGbAUcJOkzuexU4DBJb8/vY3lJu5YJQNKuklbPo7NIB6P5bWbpq2tJlwe3IF1+ApgGrAWMp32yICKmkC7T/VZST5d8AA6QtLqkFUltMefl8p8C+0t6t5Lh+bO0HKldYR7weUlLSPooPV9WGk7aRv8EkLQP6cyiJUl7Slol72/P5eL5pM/LhyRtI2mYpKVzt9jVI+Jx0uXUH0taIcfU6Dn2JLCSpOV7WOX5wA6StsrHiUNIl9s6fnHocDwrZagli4slzSFl96+QGkf36WHa9YCrSNfc/wb8OCKuyXXHAF/Np5hf6sX6f05q4HuC1OD4eYB8+v1Z4GekbwkvkHrrNPw6/31G0i0tlntGXva1wIPAS8DnehFX0efy+h8gnXH9Ki+/P5xA6tn1JHA28MuFXN4TpIPgY3lZ+0fEPbnuUNJp9/WSnif9L3vTdrKw2/RI4Oy8j3wsIq4itVP9hvRtdx26t6EA6TcPpIQxSdInI+J3pG+tk/P7uIN0zbuMdwE3SJpLauw/KCIe6MV7KCUi/kE6wD4REc/lsvmkxtY3UeJglq/r70v6jG7cw2S/IvXMeoDUAP+tPO/NpJ5mJ5H2h+mkzhNExL+Bj+bxZ0nX/X/bQwx3kdro/kbaRzdgQfJrZVvgzrx9fwjsFqld8BFSx4TDSdvlEeB/WXC83Yt0Bn8PqWH+4Lz+e0hfKh7I+82qhXUREfeS2kN+RDp7/hDp5wD/bhNjQ7vjWSmN3j1mZrUlaQapJ91Vgx3LUDXUzizMzKwPnCzMzKwjX4YyM7OOfGZhZmYdLZI3vFt55ZVj7NixLeteeOEFhg8f3rKubhxrNRxrNRxrNQYy1qlTpz4dEau0rIyFvOdSHV+bbLJJ9OSaa67psa5uHGs1HGs1HGs1BjJW4ObwvaHMzKyvnCzMzKwjJwszM+vIycLMzDpysjAzs46cLMzMrCMnCzMz68jJwszMOnKyMDOzjhbJ230srLGTLh2U9c44dodBWa+ZWSc+szAzs46cLMzMrCMnCzMz68jJwszMOnKyMDOzjpwszMysIycLMzPrqLJkIWlpSTdKuk3SnZK+kcvXknSDpOmSzpO0ZC5fKo9Pz/VjC8s6LJffK2mbqmI2M7PWqjyzeBnYMiI2BDYCtpW0GfAd4ISIWBeYBUzM008EZuXyE/J0SFof2A14O7At8GNJwyqM28zMmlSWLPIjXefm0SXyK4AtgQty+dnAh/PwznmcXL+VJOXyyRHxckQ8CEwHNq0qbjMze71K2ywkDZN0K/AUcCVwP/BcRMzLkzwKrJaHVwMeAcj1s4GViuUt5jEzswFQ6b2hIuJVYCNJI4HfAW+ral2S9gP2Axg1ahRTpkxpOd3cuXN7rGs4ZIN5beur0hxXmVjrwrFWw7FWw7H23oDcSDAinpN0DfAeYKSkxfPZw+rAzDzZTGAM8KikxYHlgWcK5Q3FeYrrOA04DWDcuHHR1dXVMpYpU6bQU13D3oN1I8E9urqNl4m1LhxrNRxrNRxr71XZG2qVfEaBpGWADwJ3A9cAu+TJJgAX5uGL8ji5/v8iInL5brm31FrAesCNVcVtZmavV+WZxWjg7NxzaTHg/Ii4RNJdwGRJ3wL+Dpyepz8d+Lmk6cCzpB5QRMSdks4H7gLmAQfky1tmZjZAKksWEXE78M4W5Q/QojdTRLwE7NrDso4Gju7vGM3MrBz/gtvMzDpysjAzs46cLMzMrCMnCzMz68jJwszMOnKyMDOzjpwszMysIycLMzPrqGOykLS5pOF5eE9Jx0tas/rQzMysLsqcWZwCvChpQ+AQ0m3Gz6k0KjMzq5UyyWJevqHfzsBJEXEysFy1YZmZWZ2UuTfUHEmHAXsCW0hajPTUOzMzGyLKnFl8nPQ87YkR8QTpeRLfqzQqMzOrlY5nFjlBHF8Yfxi3WZiZDSllekN9VNJ9kmZLel7SHEnPD0RwZmZWD2XaLL4LfCgi7q46GDMzq6cybRZPOlGYmQ1tZc4sbpZ0HvB7UkM3ABHx26qCMjOzeimTLN4EvAhsXSgLwMnCzGyIKNMbap+BCMTMzOqrTG+o1SX9TtJT+fUbSasPRHBmZlYPZRq4zwQuAlbNr4tzmZmZDRFlksUqEXFmRMzLr7OAVSqOy8zMaqRMsngm35p8WH7tCTxTdWBmZlYfZZLFvsDHgCeAx4FdgI6N3pLGSLpG0l2S7pR0UC4/UtJMSbfm1/aFeQ6TNF3SvZK2KZRvm8umS5rU2zdpZmYLp0xvqIeAnfqw7HnAIRFxi6TlgKmSrsx1J0TE94sTS1of2A14O6lt5CpJb8nVJwMfBB4FbpJ0UUTc1YeYzMysD3pMFpK+HBHflfQj0u8quomIz7dbcEQ8TjoTISLmSLobWK3NLDsDkyPiZeBBSdOBTXPd9Ih4IMc1OU/rZGFmNkCUnmvUokL6UERcLGlCq/qIOLv0SqSxwLXAO4AvAnsDzwM3k84+Zkk6Cbg+In6R5zkduDwvYtuI+GQu3wt4d0Qc2LSO/YD9AEaNGrXJ5MmTW8Yyd+5cRowY0TbeaTNnl31r/WqD1ZbvNl4m1rpwrNVwrNVwrK2NHz9+akSMa1XX45lFRFycB1+MiF8X6yTtWnblkkYAvwEOjojnJZ0CHEU6WzkKOI7ULrJQIuI04DSAcePGRVdXV8vppkyZQk91DXtPunRhw+mTGXt0dRsvE2tdONZqONZqONbeK9PAfVjJsteRtAQpUfyycS+piHgyIl6NiPnAT1lwqWkmMKYw++q5rKdyMzMbIO3aLLYDtgdWk3RioepNpMbrtiQJOB24OyKOL5SPzu0ZAB8B7sjDFwG/knQ8qYF7PeBGQMB6ktYiJYndgP8p9/bMzKw/tOsN9RipTWEnYGqhfA7whRLL3hzYC5gm6dZcdjiwu6SNSJehZgCfBoiIOyWdT2q4ngccEBGvAkg6ELgCGAacERF3lli/mZn1k3ZtFrcBt0n6HfBC4cA9DFiq04Ij4i+ks4Jml7WZ52jg6Bbll7Wbz8zMqlWmzeKPwDKF8WWAq6oJx8zM6qhMslg6IuY2RvLwstWFZGZmdVMmWbwgaePGiKRNgH9VF5KZmdVNmSflHQz8WtJjpDaI/wA+XmVQZmZWL2XuDXWTpLcBb81F90bEK9WGZWZmdVLmSXnLAocCB0XEHcBYSTtWHpmZmdVG2Sfl/Rt4Tx6fCXyrsojMzKx2yiSLdSLiu8ArABHxIq1/P2FmZouoMsni35KWId+mXNI6wMuVRmVmZrVSpjfUEcAfgDGSfkm6jcfeVQZlZmb1UqY31JWSbgE2I11+Oiginq48MjMzq40yvaE2B16KiEuBkcDhktasOjAzM6uPMm0WpwAvStqQ9JS7+4FzKo3KzMxqpUyymBfp2as7AydHxMnActWGZWZmdVKmgXuOpMOAPYEtJC0GLFFtWGZmVidlziw+TuoqOzEiniA91vR7lUZlZma1UqY31BPA8YXxh3GbhZnZkFLmzMLMzIY4JwszM+vIycLMzDrq2GYhaT3gGGB9YOlGeUSsXWFcZmZWI2VvUX4KMA8YT2rc/kWVQZmZWb2USRbLRMTVgCLioYg4Etih2rDMzKxOyiSLl/MP8e6TdKCkjwAjOs0kaYykayTdJelOSQfl8hUlXSnpvvx3hVwuSSdKmi7pdkkbF5Y1IU9/n6QJfXyvZmbWR2WSxUHAssDngU2AvYAyB+x5wCERsT7pjrUHSFofmARcHRHrAVfncYDtgPXyaz/SpS8krUi6Tfq7gU2BIxoJxszMBkaZH+XdlAfnAvuUXXBEPA48nofnSLobWI10j6muPNnZwBTSM753Bs7J96G6XtJISaPztFdGxLMAkq4EtgXOLRuLmZktnB6ThaQfRMTBki4mPyWvKCJ2KrsSSWOBdwI3AKNyIgF4AhiVh1cDHinM9mgu66nczMwGSLszi5/nv99fmBVIGgH8Bjg4Ip6XFjy+OyJC0usSUR/Xsx/p8hWjRo1iypQpLaebO3duj3UNh2wwrz9C6rXmuMrEWheOtRqOtRqOtfd6TBYRMTX//VNfFy5pCVKi+GVE/DYXPylpdEQ8ni8zPZXLZwJjCrOvnstmsuCyVaN8Sot4TwNOAxg3blx0dXU1TwKkA3JPdQ17T7q0bX1VZuzR1W28TKx14Vir4Vir4Vh7r8cGbknTcq+klq9OC1Y6hTgduDsiji9UXcSCBvIJwIWF8k/kXlGbAbPz5aorgK0lrZAbtrfOZWZmNkDaXYbaMf89IP9tXJbakxZtGC1sTuo5NU3SrbnscOBY4HxJE4GHgI/lusuA7YHpwIvkxvSIeFbSUUCjof2bjcZuMzMbGO0uQz0EIOmDEfHOQtWhkm5hQZfXnub/C6AeqrdqMX2wIDE1150BnNFufWZmVp0yv7OQpM0LI/9dcj4zM1tElHms6kTgDEnL5/HngH0ri8jMzGqnzI/ypgIbNpJFRMyuPCozM6uVjpeTJI2SdDowOSJmS1o/N06bmdkQUabt4SxSV9VV8/g/gIMrisfMzGqoTLJYOSLOB+YDRMQ84NVKozIzs1opkyxekLQS+bcVjR/MVRqVmZnVSpneUF8k/bp6HUl/BVYBdqk0KjMzq5UyvaFukfR+4K2kH9ndGxGvVB6ZmZnVRsdkIWlp4LPAe0mXov4s6dSIeKnq4MzMrB7KXIY6B5gD/CiP/w/pPlG7VhWUmZnVS5lk8Y78aNSGayTdVVVAZmZWP2V6Q92Se0ABIOndwM3VhWRmZnVT5sxiE+A6SQ/n8TWAeyVNI90s9r8qi87MzGqhTLLYtvIozMys1npMFpLeFBHPkxq3X8cPIDIzGzranVn8ivS0vKmkLrPFBxkFsHaFcZmZWY20e1LejvnvWs11+fnaZmY2RJS5Rfk3m8YXA35RWURmZlY7ZbrOjpF0GICkpYDfAfdVGpWZmdVKmWSxL7BBThgXA9dExJGVRmVmZrXSrjfUxoXRHwI/Af4KXCtp44i4pergzMysHtr1hjquaXwWsH4uD2DLqoIyM7N6adcbavxABmJmZvXVY5uFpD3z3y+2enVasKQzJD0l6Y5C2ZGSZkq6Nb+2L9QdJmm6pHslbVMo3zaXTZc0qe9v1czM+qrdZajh+e9yfVz2WcBJpFucF50QEd8vFkhaH9gNeDuwKnCVpLfk6pOBDwKPAjdJuigifNdbM7MB1C5ZPCnpzRHxjb4sOCKulTS25OQ7A5Mj4mXgQUnTgU1z3fSIeABA0uQ8rZOFmdkAUkS0rpAuAN4DvAhcR+oJdV1E3NFyhtbLGAtcEhHvyONHAnsDz5Nuc35IRMySdBJwfUT8Ik93OnB5Xsy2EfHJXL4X8O6IOLDFuvYD9gMYNWrUJpMnT24Z09y5cxkxYkTbuKfNnF32LfarDVZbvtt4mVjrwrFWw7FWw7G2Nn78+KkRMa5VXbsG7l0AJK1FShr/DXxa0hrATRGxfU/ztnEKcBSpN9VRpJ5V+/ZhOa3iPQ04DWDcuHHR1dXVcropU6bQU13D3pMu7Y+Qem3GHl3dxsvEWheOtRqOtRqOtfc63qI8Ih7Mv9xeJr+Wzn97LSKebAxL+ilwSR6dCYwpTLp6LqNNuZmZDZB2vaEOl3SxpOuBw4AlSQ3W/9XXbrWSRhdGPwI0LmldBOwmaal8JrMecCNwE7CepLUkLUlqBL+oL+s2M7O+a3dm8QngBdItPq4DboiI0hfzJZ0LdAErS3oUOALokrQR6TLUDODTABFxp6TzSQ3X84ADIuLVvJwDgSuAYcAZEXFnL96fmZn1g3ZtFm+TtCKpraILmCRpBHAbqaH7zHYLjojdWxSf3mb6o4GjW5RfBlzWbl1mZlattm0W+Wl4l0j6A+lZ3FuQzgb2BdomCzMzW3S0u5HgTqSzis1JP5a7k9R99hDSZSkzMxsi2p1Z7E1KDl8GpkbEvwckIjMzq512bRYfHchAzMysvso8/MjMzIY4JwszM+uo3Y/yrs5/vzNw4ZiZWR21a+AeLem/gZ3y3V5VrPRjVc3Mho52yeLrwNdI92M6vqnOj1U1MxtC2vWGugC4QNLXIuKoAYzJzMxqpsxdZ4/KP9DbIhdNiYhL2s1jZmaLlo69oSQdAxxEusnfXcBBkr5ddWBmZlYfHc8sgB2AjSJiPoCks4G/A4dXGZiZmdVH2d9ZjCwML9/TRGZmtmgqc2ZxDPB3SdeQus9uAUyqNCozM6uVMg3c50qaArwrFx0aEU9UGpWZmdVKmTMLIuJx/DhTM7Mhy/eGMjOzjpwszMyso7bJQtIwSfcMVDBmZlZPbZNFRLwK3CtpjQGKx8zMaqhMA/cKwJ2SbgReaBRGxE6VRWVmZrVSJll8rfIozMys1sr8zuJPktYE1ouIqyQtCwyrPjQzM6uLMjcS/BRwAfCTXLQa8PsS850h6SlJdxTKVpR0paT78t8VcrkknShpuqTbJW1cmGdCnv4+SRN6+f7MzKwflOk6ewCwOfA8QETcB7y5xHxnAds2lU0Cro6I9YCrWXDbkO2A9fJrP+AUSMkFOAJ4N7ApcEQjwZiZ2cApkyxejoh/N0YkLU56Ul5bEXEt8GxT8c7A2Xn4bODDhfJzIrkeGClpNLANcGVEPBsRs4AreX0CMjOziimi/XFf0neB54BPAJ8DPgvcFRFf6bhwaSxwSUS8I48/FxEj87CAWRExUtIlwLER8ZdcdzVwKNAFLB0R38rlXwP+FRHfb7Gu/UhnJYwaNWqTyZMnt4xp7ty5jBgxom3c02bO7vTWKrHBat1v6Fsm1rpwrNVwrNVwrK2NHz9+akSMa1VXpjfUJGAiMA34NHAZ8LOFDSoiQlLHM5ReLO804DSAcePGRVdXV8vppkyZQk91DXtPurS/wuqVGXt0dRsvE2tdONZqONZqONbeK9Mban5+4NENpMtP90an05GePSlpdEQ8ni8zPZXLZwJjCtOtnstmks4uiuVT+rhuMzProzK9oXYA7gdOBE4Cpkvaro/ruwho9GiaAFxYKP9E7hW1GTA73+n2CmBrSSvkhu2tc5mZmQ2gMpehjgPGR8R0AEnrAJcCl7ebSdK5pLOClSU9SurVdCxwvqSJwEPAx/LklwHbA9OBF4F9ACLiWUlHATfl6b4ZEc2N5mZmVrEyyWJOI1FkDwBzOs0UEbv3ULVVi2mD1EW31XLOAM4oEaeZmVWkx2Qh6aN58GZJlwHnk9osdmXBN30zMxsC2p1ZfKgw/CTw/jz8T2CZyiIyM7Pa6TFZRMQ+AxmImZnVV8c2C0lrkX6MN7Y4vW9RbmY2dJRp4P49cDpwMTC/0mjMzKyWyiSLlyLixMojMTOz2iqTLH4o6Qjgj8DLjcKIuKWyqMzMrFbKJIsNgL2ALVlwGSryuJmZDQFlksWuwNrF25SbmdnQUuZ5FncAIyuOw8zMaqzMmcVI4B5JN9G9zcJdZ83MhogyyeKIyqMwM7NaK/M8iz8NRCBmZlZfZX7BPYcFz9xeElgCeCEi3lRlYGZmVh9lziyWawzn52bvDGxWZVBmZlYvZXpDvSaS3wPbVBOOmZnVUZnLUB8tjC4GjANeqiwiMzOrnTK9oYrPtZgHzCBdijIzsyGiTJuFn2thZjbEtXus6tfbzBcRcVQF8ZiZWQ21O7N4oUXZcGAisBLgZGFmNkS0e6zqcY1hScsBBwH7AJOB43qaz8zMFj1t2ywkrQh8EdgDOBvYOCJmDURgZmZWHz3+zkLS94CbgDnABhFxZH8lCkkzJE2TdKukm3PZipKulHRf/rtCLpekEyVNl3S7pI37IwYzMyuv3Y/yDgFWBb4KPCbp+fyaI+n5flj3+IjYKCLG5fFJwNURsR5wdR4H2A5YL7/2A07ph3WbmVkvtGuz6NWvu/vBzkBXHj4bmAIcmsvPiYgArpc0UtLoiHh8gOMzMxuylI7BA7xS6UFgFukGhT+JiNMkPRcRI3O9gFkRMVLSJcCxEfGXXHc1cGhE3Ny0zP1IZx6MGjVqk8mTJ7dc99y5cxkxYkTb+KbNnL0wb6/PNlht+W7jZWKtC8daDcdaDcfa2vjx46cWrvZ0U+YX3FV4b0TMlPRm4EpJ9xQrIyIk9SqLRcRpwGkA48aNi66urpbTTZkyhZ7qGvaedGlvVt1vZuzR1W28TKx14Vir4Vir4Vh7b6AvNQEQETPz36eA3wGbAk9KGg2Q/z6VJ58JjCnMvnouMzOzATLgyULS8Py7DSQNB7YmPef7ImBCnmwCcGEevgj4RO4VtRkw2+0VZmYDazAuQ40CfpeaJVgc+FVE/CE/4/t8SROBh4CP5ekvA7YHpgMvkn4YaGZmA2jAk0VEPABs2KL8GWCrFuUBHDAAoQ26sU1tJYdsMG/A2k9mHLvDgKzHzN6YBqXNwszM3licLMzMrCMnCzMz68jJwszMOnKyMDOzjpwszMysIycLMzPryMnCzMw6crIwM7OOnCzMzKwjJwszM+vIycLMzDpysjAzs46cLMzMrCMnCzMz68jJwszMOnKyMDOzjgbjsapWQ81P6eutvj7Vz0/oM3tj8JmFmZl15GRhZmYdOVmYmVlHThZmZtaRk4WZmXXkZGFmZh29YbrOStoW+CEwDPhZRBw7yCFZP1jYLrt90dduvv3F3YXtjegNcWYhaRhwMrAdsD6wu6T1BzcqM7Oh441yZrEpMD0iHgCQNBnYGbhrUKMy64PenE0N9llQb7SL1WdTb3yKiMGOoSNJuwDbRsQn8/hewLsj4sDCNPsB++XRtwL39rC4lYGnKwy3PznWajjWajjWagxkrGtGxCqtKt4oZxYdRcRpwGmdppN0c0SMG4CQFppjrYZjrYZjrUZdYn1DtFkAM4ExhfHVc5mZmQ2AN0qyuAlYT9JakpYEdgMuGuSYzMyGjDfEZaiImCfpQOAKUtfZMyLizj4uruOlqhpxrNVwrNVwrNWoRaxviAZuMzMbXG+Uy1BmZjaInCzMzKyjIZMsJG0r6V5J0yVNqkE8YyRdI+kuSXdKOiiXryjpSkn35b8r5HJJOjHHf7ukjQch5mGS/i7pkjy+lqQbckzn5c4HSFoqj0/P9WMHOM6Rki6QdI+kuyW9p67bVdIX8v//DknnSlq6LttV0hmSnpJ0R6Gs19tR0oQ8/X2SJgxgrN/L+8Dtkn4naWSh7rAc672StimUV36caBVroe4QSSFp5Tw+qNu1m4hY5F+kRvH7gbWBJYHbgPUHOabRwMZ5eDngH6RbmXwXmJTLJwHfycPbA5cDAjYDbhiEmL8I/Aq4JI+fD+yWh08FPpOHPwucmod3A84b4DjPBj6Zh5cERtZxuwKrAQ8CyxS259512a7AFsDGwB2Fsl5tR2BF4IH8d4U8vMIAxbo1sHge/k4h1vXzMWApYK18bBg2UMeJVrHm8jGkTjwPASvXYbt2i6/qD0QdXsB7gCsK44cBhw12XE0xXgh8kPTL89G5bDRwbx7+CbB7YfrXphug+FYHrga2BC7JO+/ThQ/ja9s47/DvycOL5+k0QHEunw/Aaiqv3XYlJYtH8gd+8bxdt6nTdgXGNh2Ae7Udgd2BnxTKu01XZaxNdR8BfpmHu33+G9t1II8TrWIFLgA2BGawIFkM+nZtvIbKZajGh7Lh0VxWC/lywjuBG4BREfF4rnoCGJWHB/s9/AD4MjA/j68EPBcR81rE81qsuX52nn4grAX8EzgzXzL7maTh1HC7RsRM4PvAw8DjpO00lXpu14bebsfB3m8b9iV9Q4caxippZ2BmRNzWVFWbWIdKsqgtSSOA3wAHR8TzxbpIXxkGvW+zpB2BpyJi6mDHUsLipFP8UyLincALpMslr6nRdl2BdEPMtYBVgeHAtoMaVC/UZTt2IukrwDzgl4MdSyuSlgUOB74+2LG0M1SSRS1vFyJpCVKi+GVE/DYXPylpdK4fDTyVywfzPWwO7CRpBjCZdCnqh8BISY0fdhbjeS3WXL888MwAxfoo8GhE3JDHLyAljzpu1w8AD0bEPyPiFeC3pG1dx+3a0NvtOKifPUl7AzsCe+TkRpuYBivWdUhfGG7Ln7HVgVsk/UedYh0qyaJ2twuRJOB04O6IOL5QdRHQ6NkwgdSW0Sj/RO4dsRkwu3A5oFIRcVhErB4RY0nb7v8iYg/gGmCXHmJtvIdd8vQD8g00Ip4AHpH01ly0FelW9rXbrqTLT5tJWjbvD41Ya7ddC3q7Ha8Atpa0Qj6T2jqXVU7pgWlfBnaKiBeb3sNuuXfZWsB6wI0M0nEiIqZFxJsjYmz+jD1K6vzyBHXarlU2iNTpRepV8A9Sb4ev1CCe95JO4W8Hbs2v7UnXoK8G7gOuAlbM04v0AKj7gWnAuEGKu4sFvaHWJn3IpgO/BpbK5Uvn8em5fu0BjnEj4Oa8bX9P6i1Sy+0KfAO4B7gD+Dmph04ttitwLqkt5RXSAWxiX7Yjqb1gen7tM4CxTidd1298vk4tTP+VHOu9wHaF8sqPE61ibaqfwYIG7kHdrsWXb/dhZmYdDZXLUGZmthCcLMzMrCMnCzMz68jJwszMOnKyMDOzjpws7A0v36XzuML4lyQd2U/LPkvSLp2nXOj17Kp0h9xrmsrHSvqfEvPvLemk6iK0oc7JwhYFLwMfbdzWuS4Kv8IuYyLwqYgY31Q+FuiYLMyq5mRhi4J5pOcUf6G5ovnMQNLc/LdL0p8kXSjpAUnHStpD0o2Spklap7CYD0i6WdI/8n2yGs/2+J6km/JzBj5dWO6fJV1E+jV2czy75+XfIek7uezrpB9pni7pe02zHAu8T9KtSs++WFrSmXkZf5fUnFyQtIOkv0laWdLWefgWSb/O9yJD0gxJ38jl0yS9LZe/P6/r1rz85cr/G2xR5mRhi4qTgT0kLd+LeTYE9gf+E9gLeEtEbAr8DPhcYbqxwKbADsCpkpYmnQnMjoh3Ae8CPpVvHQHpXlQHRcRbiiuTtCrpuQpbkn5l/i5JH46Ib5J+cb5HRPxvU4yTgD9HxEYRcQJwAOkefhuQblN9do6nsY6P5Hm2z0VfBT4QERvndXyxsOync/kpwJdy2ZeAAyJiI+B9wL/ab0IbKpwsbJEQ6Y695wCf78VsN0XE4xHxMul2Cn/M5dNICaLh/IiYHxH3kR4y8zbSvXg+IelW0q3lVyLdYwjgxoh4sMX63gVMiXTjwMZdULfoRbyQzkB+ARAR95AelNNISlsChwI7RMQs0sNy1gf+muOcAKxZWFbj5pVTC+/3r8Dxkj4PjIwFt0q3Ic7JwhYlPyB94x9eKJtH3s8lLUZ6AlrDy4Xh+YXx+aRbnTc03xMnSPfs+Vz+xr9RRKwVEY1k88LCvImFcD/pqYuN5CHgykKM60fExML0jff7Kvn9RsSxwCeBZUhJ5m0DE7rVnZOFLTIi4lnSI0mLB8QZwCZ5eCdgiT4seldJi+V2jLVJN5+7AviM0m3mkfQWpYcstXMj8P7cljCMdBnpTx3mmUNKAA1/BvZorBNYI8cD6Szj/wHnSHo7cD2wuaR18/TD8zw9krROpLugfod0F1YnCwOcLGzRcxxQ7BX1U9IB+jbSYzP78q3/YdKB/nJg/4h4idSucRfpuQN3kB5r2bb3U6RbS08i3YL8NmBqRFzYbh7SnXNflXSbpC8APwYWkzQNOA/YO19Ga6zjHlIy+TXwJtIzvc+VdDvwNzof/A/Oje+3k+6KenmH6W2I8F1nzcysI59ZmJlZR04WZmbWkZOFmZl15GRhZmYdOVmYmVlHThZmZtaRk4WZmXX0/wFZfduL32Si2AAAAABJRU5ErkJggg==",
+ "text/plain": [
+ "<Figure size 432x288 with 1 Axes>"
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "import pandas as pd\n",
+ "from matplotlib import pyplot as plt\n",
+ "\n",
+ "df = pd.read_csv('olympics-data/olympics_sections.csv')\n",
+ "df[['tokens']].hist()\n",
+ "# add axis descriptions and title\n",
+ "plt.xlabel('Number of tokens')\n",
+ "plt.ylabel('Number of Wikipedia sections')\n",
+ "plt.title('Distribution of number of tokens in Wikipedia sections')\n",
+ "plt.show()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We can see that the majority of section are fairly short (less than 500 tokens)."
+ ]
+ }
+ ],
+ "metadata": {
+ "interpreter": {
+ "hash": "be4b5d5b73a21c599de40d6deb1129796d12dc1cc33a738f7bac13269cfcafe8"
+ },
+ "kernelspec": {
+ "display_name": "Python 3.7.3 64-bit ('base': conda)",
+ "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.7.3"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
examples/finetuning/olympics-2-create-qa.ipynb
@@ -0,0 +1,751 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# 2. Creating a synthetic Q&A dataset\n",
+ "We use [`davinci-instruct-beta-v2`](https://beta.openai.com/docs/engines/instruct-series-beta), a model specialized in following instructions, to create questions based on the given context. Then we also use [`davinci-instruct-beta-v2`](https://beta.openai.com/docs/engines/instruct-series-beta) to answer those questions, given the same context. \n",
+ "\n",
+ "This is expensive, and will also take a long time, as we call the davinci engine for each section. You can simply download the final dataset instead.\n",
+ "\n",
+ "We're using the dataset created using the [previous notebook](olympics-1-collect-data.ipynb)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 2.1 Read in the data, and create a context\n",
+ "Create a context by concatenating the title, the heading and the content of that section"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "<div>\n",
+ "<style scoped>\n",
+ " .dataframe tbody tr th:only-of-type {\n",
+ " vertical-align: middle;\n",
+ " }\n",
+ "\n",
+ " .dataframe tbody tr th {\n",
+ " vertical-align: top;\n",
+ " }\n",
+ "\n",
+ " .dataframe thead th {\n",
+ " text-align: right;\n",
+ " }\n",
+ "</style>\n",
+ "<table border=\"1\" class=\"dataframe\">\n",
+ " <thead>\n",
+ " <tr style=\"text-align: right;\">\n",
+ " <th></th>\n",
+ " <th>title</th>\n",
+ " <th>heading</th>\n",
+ " <th>content</th>\n",
+ " <th>tokens</th>\n",
+ " <th>context</th>\n",
+ " </tr>\n",
+ " </thead>\n",
+ " <tbody>\n",
+ " <tr>\n",
+ " <th>0</th>\n",
+ " <td>2020 Summer Olympics</td>\n",
+ " <td>Summary</td>\n",
+ " <td>The 2020 Summer Olympics (Japanese: 2020年夏季オリン...</td>\n",
+ " <td>713</td>\n",
+ " <td>2020 Summer Olympics\\nSummary\\n\\nThe 2020 Summ...</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>1</th>\n",
+ " <td>2020 Summer Olympics</td>\n",
+ " <td>Host city selection</td>\n",
+ " <td>The International Olympic Committee (IOC) vote...</td>\n",
+ " <td>126</td>\n",
+ " <td>2020 Summer Olympics\\nHost city selection\\n\\nT...</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>2</th>\n",
+ " <td>2020 Summer Olympics</td>\n",
+ " <td>Impact of the COVID-19 pandemic</td>\n",
+ " <td>In January 2020, concerns were raised about th...</td>\n",
+ " <td>369</td>\n",
+ " <td>2020 Summer Olympics\\nImpact of the COVID-19 p...</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>3</th>\n",
+ " <td>2020 Summer Olympics</td>\n",
+ " <td>Qualifying event cancellation and postponement</td>\n",
+ " <td>Concerns about the pandemic began to affect qu...</td>\n",
+ " <td>298</td>\n",
+ " <td>2020 Summer Olympics\\nQualifying event cancell...</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>4</th>\n",
+ " <td>2020 Summer Olympics</td>\n",
+ " <td>Effect on doping tests</td>\n",
+ " <td>Mandatory doping tests were being severely res...</td>\n",
+ " <td>163</td>\n",
+ " <td>2020 Summer Olympics\\nEffect on doping tests\\n...</td>\n",
+ " </tr>\n",
+ " </tbody>\n",
+ "</table>\n",
+ "</div>"
+ ],
+ "text/plain": [
+ " title heading \\\n",
+ "0 2020 Summer Olympics Summary \n",
+ "1 2020 Summer Olympics Host city selection \n",
+ "2 2020 Summer Olympics Impact of the COVID-19 pandemic \n",
+ "3 2020 Summer Olympics Qualifying event cancellation and postponement \n",
+ "4 2020 Summer Olympics Effect on doping tests \n",
+ "\n",
+ " content tokens \\\n",
+ "0 The 2020 Summer Olympics (Japanese: 2020年夏季オリン... 713 \n",
+ "1 The International Olympic Committee (IOC) vote... 126 \n",
+ "2 In January 2020, concerns were raised about th... 369 \n",
+ "3 Concerns about the pandemic began to affect qu... 298 \n",
+ "4 Mandatory doping tests were being severely res... 163 \n",
+ "\n",
+ " context \n",
+ "0 2020 Summer Olympics\\nSummary\\n\\nThe 2020 Summ... \n",
+ "1 2020 Summer Olympics\\nHost city selection\\n\\nT... \n",
+ "2 2020 Summer Olympics\\nImpact of the COVID-19 p... \n",
+ "3 2020 Summer Olympics\\nQualifying event cancell... \n",
+ "4 2020 Summer Olympics\\nEffect on doping tests\\n... "
+ ]
+ },
+ "execution_count": 1,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import pandas as pd\n",
+ "df = pd.read_csv('olympics-data/olympics_sections.csv')\n",
+ "df['context'] = df.title + \"\\n\" + df.heading + \"\\n\\n\" + df.content\n",
+ "df.head()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 2.2 Create questions based on the context\n",
+ "Use davinci-instruct to generate a number of plausible questions relating to the Wikipedia section contents.\n",
+ "\n",
+ "Note: We have used temperature=0, but it may be beneficial to experiment with a higher temperature to get a higher diversity of questions.\n",
+ "\n",
+ "<span style=\"color:orange\">**WARNING: This step will last a long time, and consume a lot of tokens, as it calls davinci-instruct for every section to generate a number of questions.**</span>"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1. What is the 2020 Summer Olympics?\n",
+ "2. When did the 2020 Summer Olympics take place?\n",
+ "3. Who won the most medals at the 2020 Summer Olympics?\n",
+ "4. Who won the most gold medals at the 2020 Summer Olympics?\n",
+ "5. Who won the most medals at the 2020 Summer Olympics?\n"
+ ]
+ }
+ ],
+ "source": [
+ "import openai\n",
+ "\n",
+ "def get_questions(context):\n",
+ " try:\n",
+ " response = openai.Completion.create(\n",
+ " engine=\"davinci-instruct-beta-v2\",\n",
+ " prompt=f\"Write questions based on the text below\\n\\nText: {context}\\n\\nQuestions:\\n1.\",\n",
+ " temperature=0,\n",
+ " max_tokens=257,\n",
+ " top_p=1,\n",
+ " frequency_penalty=0,\n",
+ " presence_penalty=0,\n",
+ " stop=[\"\\n\\n\"]\n",
+ " )\n",
+ " return response['choices'][0]['text']\n",
+ " except:\n",
+ " return \"\"\n",
+ "\n",
+ "\n",
+ "df['questions']= df.context.apply(get_questions)\n",
+ "df['questions'] = \"1.\" + df.questions\n",
+ "print(df[['questions']].values[0][0])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The prompt is designed to generate a number of questions. Example questions above were generated based on the summary section of the 2020 Summer Olympics page.\n",
+ "\n",
+ "We can observe that the questions 3 and 5 above repeat. Sometimes the generated questions could be ambiguous without the context. We will show that even despite these limitations we can create a successful model."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "The 2020 Summer Olympics (Japanese: 2020年夏季オリンピック, Hepburn: Nisen Nijū-nen Kaki Orinpikku), officially the Games of the XXXII Olympiad (第三十二回オリンピック競技大会, Dai Sanjūni-kai Orinpikku Kyōgi Taikai) and branded as Tokyo 2020 (東京2020, Tōkyō Nii Zero Nii Zero), was an international multi-sport event held from 23 July to 8 August 2021 in Tokyo, Japan, with some preliminary events that began on 21 July.\n",
+ "Tokyo was selected as the host city during the 125th IOC Session in Buenos Aires, Argentina, on 7 September 2013. Originally scheduled to take place from 24 July to 9 August 2020, the event was postponed to 2021 in March 2020 as a result of the COVID-19 pandemic, the first such instance in the history of the Olympic Games (previous games had been cancelled but not rescheduled). However, the event retained the Tokyo 2020 name for marketing and branding purposes. It was largely held behind closed doors with no public spectators permitted due to the declaration of a state of emergency in the Greater Tokyo Area in response to the pandemic. The Summer Paralympics were held between 24 August and 5 September 2021, 16 days after the completion of the Olympics.The 2020 Games were the fourth Olympic Games to be held in Japan, following the Tokyo 1964 (Summer), Sapporo 1972 (Winter) and Nagano 1998 (Winter) games. Tokyo is the first city in Asia to hold the Summer Games twice. The 2020 Games were the second of three consecutive Olympics to be held in East Asia, following the 2018 Winter Olympics in Pyeongchang, South Korea and preceding the 2022 Winter Olympics in Beijing, China.\n",
+ "New events were introduced in existing sports for 2020, including 3x3 basketball, freestyle BMX and mixed gender team events in a number of existing sports, as well as the return of madison cycling for men and an introduction of the same event for women. New IOC policies also allowed the host organizing committee to add new sports to the Olympic program for just one Games. The disciplines added by the Japanese Olympic Committee were baseball and softball, karate, sport climbing, surfing and skateboarding, the last four of which made their Olympic debuts, and the last three of which will remain on the Olympic program.The United States topped the medal count by both total golds (39) and total medals (113), with China finishing second by both respects (38 and 88). Host nation Japan finished third, setting a record for the most gold medals and total medals ever won by their delegation at an Olympic Games with 27 and 58. Great Britain finished fourth, with a total of 22 gold and 65 medals, becoming the first nation at the Summer Olympics to increase or equal their total medals won in the two Games subsequent to hosting them. The Russian delegation competing as the ROC (not to be confused with the Republic of China (Taiwan) which competed as Chinese Taipei, not ROC) finished fifth with 20 gold medals and third in the overall medal count, with 71 medals. Bermuda, the Philippines and Qatar won their first-ever Olympic gold medals. Burkina Faso, San Marino and Turkmenistan won their first-ever Olympic medals.\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(df.content.values[0])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 2.3 Create answers based on the context\n",
+ "Use davinci-instruct to answer the questions given the relevant Wikipedia section contents\n",
+ "\n",
+ "Note: We have used temperature=0, but it may be beneficial to experiment with a higher temperature to get a higher diversity of questions.\n",
+ "\n",
+ "<span style=\"color:orange\">**WARNING: This step will last a long time, and consume a lot of tokens, as it calls davinci-instruct for every section to answer all the questions.**</span>"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1. The 2020 Summer Olympics is an international multi-sport event held from 23 July to 8 August 2021 in Tokyo, Japan.\n",
+ "2. The 2020 Summer Olympics took place from 23 July to 8 August 2021.\n",
+ "3. The United States topped the medal count by both total golds (39) and total medals (113), with China finishing second by both respects (38 and 88).\n",
+ "4. The United States topped the medal count by both total golds (39) and total medals (113), with China finishing second by both respects (38 and 88).\n",
+ "5. The United States topped the medal count by both total golds (39) and total medals (113), with China finishing second by both respects (38 and 88).\n"
+ ]
+ }
+ ],
+ "source": [
+ "def get_answers(row):\n",
+ " try:\n",
+ " response = openai.Completion.create(\n",
+ " engine=\"davinci-instruct-beta-v2\",\n",
+ " prompt=f\"Write questions based on the text below\\n\\nText: {row.context}\\n\\nQuestions:\\n{row.questions}\\n\\nAnswers:\\n1.\",\n",
+ " temperature=0,\n",
+ " max_tokens=257,\n",
+ " top_p=1,\n",
+ " frequency_penalty=0,\n",
+ " presence_penalty=0\n",
+ " )\n",
+ " return response['choices'][0]['text']\n",
+ " except Exception as e:\n",
+ " print (e)\n",
+ " return \"\"\n",
+ "\n",
+ "\n",
+ "df['answers']= df.apply(get_answers, axis=1)\n",
+ "df['answers'] = \"1.\" + df.answers\n",
+ "df = df.dropna().reset_index().drop('index',axis=1)\n",
+ "print(df[['answers']].values[0][0])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "These are the answers to the questions above based on the context around the host city selection. \n",
+ "\n",
+ "We can see that answers 3-5 contain the correct answer, but instead of answering the question directly, the answer is a verbatim extraction. Despite these occasional lower quality answers, we will show that the model can learn the task reasonably well, given a high number of examples."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 2.4 Save the Olympics Q&A dataset based on Wikipedia sections\n",
+ "We save the file for use in the [next notebook](olympics-3-train-qa.ipynb)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "df.to_csv('olympics-data/olympics_qa.csv', index=False)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 2.5 Search file\n",
+ "We create a search file ([API reference](https://beta.openai.com/docs/api-reference/files/list)), which can be used to retrieve the relevant context when a question is asked.\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "df = df[df.tokens<2000]\n",
+ "df[['context', 'tokens']].rename(columns={'context':'text','tokens':'metadata'}).to_json('olympics-data/olympics_search.jsonl', orient='records', lines=True)\n",
+ "\n",
+ "search_file = openai.File.create(\n",
+ " file=open(\"olympics-data/olympics_search.jsonl\"),\n",
+ " purpose='search'\n",
+ ")\n",
+ "olympics_search_fileid = search_file['id']"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 2.6 Answer questions based on the context provided\n",
+ "\n",
+ "We will use a simple implementation of the answers endpoint. This works by simply using the [/search endpoint](https://beta.openai.com/docs/api-reference/searches), which searches over an indexed file to obtain the relevant sections which can be included in the context, following by a question and answering prompt given a specified model."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Athletics at the 2020 Summer Olympics – Women's 4 × 100 metres relay\n",
+ "Summary\n",
+ "\n",
+ "The women's 4 × 100 metres relay event at the 2020 Summer Olympics took place on 5 and 6 August 2021 at the Japan National Stadium. There were 16 competing relay teams, with each team having 5 members from which 4 were selected in each round.\n",
+ "\n",
+ "###\n",
+ "\n",
+ "Athletics at the 2020 Summer Olympics – Men's 4 × 100 metres relay\n",
+ "Qualification\n",
+ "\n",
+ "National Olympic Committees (NOCs) could qualify one relay team in one of three following ways:\n",
+ "The top 8 NOCs at the 2019 World Athletics Championships qualified a relay team.\n",
+ "The top 8 NOCs at the 2021 World Athletics Relays qualified a relay team.\n",
+ "Where an NOC placed in the top 8 at both the 2019 World Championships and the 2021 World Relays, the quota place was allocated to the world top list as of 29 June 2021. In this case, 4 teams did so, so there are 4 places available through the world rankings.A total of five athletes may be entered for a relay team. Should a NOC have also entered individual athletes in the corresponding individual event (100 m), the entered individual athletes must be included in the total of five (5) athletes entered for the relay event. In addition of five, NOCs can nominate a maximum of one alternate athlete for each team.\n",
+ "The qualifying period was originally from 1 May 2019 to 29 June 2020. Due to the COVID-19 pandemic, the period was suspended from 6 April 2020 to 30 November 2020, with the end date extended to 29 June 2021. The qualifying time standards could be obtained in various meets during the given period that have the approval of the IAAF. Both indoor and outdoor meets are eligible. The most recent Area Championships may be counted in the ranking, even if not during the qualifying period.\n"
+ ]
+ }
+ ],
+ "source": [
+ "from answers_with_ft import create_context, answer_question\n",
+ "print(create_context(\"Where did women's 4 x 100 metres relay event take place during the 2020 Summer Olympics?\", olympics_search_fileid, max_len=400))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "' Japan National Stadium'"
+ ]
+ },
+ "execution_count": 8,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "answer_question(olympics_search_fileid, \"davinci-instruct-beta-v2\", \n",
+ " \"Where did women's 4 x 100 metres relay event take place during the 2020 Summer Olympics?\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "After we fine-tune the model for Q&A we'll be able to use it instead of [`davinci-instruct-beta-v2`](https://beta.openai.com/docs/engines/instruct-series-beta), to obtain better answers when the question can't be answered based on the context. We see a downside of [`davinci-instruct-beta-v2`](https://beta.openai.com/docs/engines/instruct-series-beta), which always attempts to answer the question, regardless of the relevant context being present or not. (Note the second question is asking about a future event, set in 2024.)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "' Japan National Stadium'"
+ ]
+ },
+ "execution_count": 9,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "answer_question(olympics_search_fileid, \"davinci-instruct-beta-v2\", \n",
+ " \"Where did women's 4 x 100 metres relay event take place during the 2048 Summer Olympics?\", max_len=1000)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We can see that davinci has a tendency to answer the question, even if the question can't be answered given the context provided. Note the question asked regarding 2048 Summer Olympics, which didn't happen yet, and the retrieved content has only returned results for 2020."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 2.7 (Optional) Investigation into how likely the search endpoint is to return the relevant context"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "(0, 58)\n"
+ ]
+ }
+ ],
+ "source": [
+ "def check_context(title, heading, question, max_len=1800, search_model='ada', max_rerank=10):\n",
+ " \"\"\"\n",
+ " Evaluate the performance of the search model in retrieving the correct context\n",
+ "\n",
+ " Parameters\n",
+ " ----------\n",
+ " title: str\n",
+ " The title of the Wikipedia page\n",
+ " heading: str\n",
+ " The heading of the Wikipedia section\n",
+ " qusetion: str\n",
+ " The question\n",
+ " max_len: int\n",
+ " The maximum length of the context\n",
+ " search_model: str\n",
+ " The search model to use - `ada` is most cost effective\n",
+ " max_rerank: int\n",
+ " The maximum number of reranking documents to use the search model on\n",
+ "\n",
+ " Returns\n",
+ " -------\n",
+ " rank: int\n",
+ " The rank of the correct context\n",
+ " token_length: int\n",
+ " The number of tokens needed to obtain the correct context\n",
+ " \"\"\"\n",
+ " \n",
+ " try:\n",
+ " results = openai.Engine(search_model).search(\n",
+ " search_model=search_model, \n",
+ " query=question, \n",
+ " max_rerank=max_rerank,\n",
+ " file=olympics_search_fileid,\n",
+ " return_metadata=True\n",
+ " )\n",
+ " index=-1\n",
+ " returns = []\n",
+ " cur_len = 0\n",
+ " for result in results['data']:\n",
+ " cur_len += int(result['metadata']) + 4 # we add 4 tokens for the separator `\\n\\n###\\n\\n`\n",
+ " if cur_len > max_len:\n",
+ " break\n",
+ " returns.append(result['text'])\n",
+ " res = result['text'].split('\\n')\n",
+ " if res[0] == title and res[1] == heading:\n",
+ " index = len(returns) - 1\n",
+ " break\n",
+ " return index, cur_len\n",
+ " except Exception as e:\n",
+ " #print (e)\n",
+ " return []\n",
+ "print(check_context(\"Athletics at the 2020 Summer Olympics – Women's 4 × 100 metres relay\", \"Summary\", \"Where did women's 4 x 100 metres relay event take place during the 2020 Summer Olympics?\", max_len=10000))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We utilize the generated questions based on context to estimate how often we can retrieve the original context. These questions are noisy, so this is not a perfect estimate.\n",
+ "\n",
+ "Our questions and answers are prefixed with numbered bullet points, however due to the way they were generated, they are missing the first number, hence we add \"1.\" to the list of questions (and answers).\n",
+ "\n",
+ "We calculate the rank of the section retrieved using ada search, and the number of tokens in the context needed to retrieve the relevant section in full."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "0 [(132, 27104), (-1, 22939), (8, 2151), (2, 121...\n",
+ "1 [(4, 1737), (0, 130), (8, 744), (96, 17208), (...\n",
+ "2 [(0, 373), (0, 373), (-1, 40610), (1, 570)]\n",
+ "3 [(0, 302), (0, 302), (5, 968), (8, 1425)]\n",
+ "4 [(0, 167), (0, 167), (2, 1442)]\n",
+ "Name: ada, dtype: object"
+ ]
+ },
+ "execution_count": 12,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "ada_results = df.apply(lambda x: [\n",
+ " check_context( x.title, \n",
+ " x.heading, \n",
+ " q[3:], # remove the number prefix\n",
+ " max_len=1000000, # set a large number to get the full context \n",
+ " search_model='ada', \n",
+ " max_rerank=200,\n",
+ " ) \n",
+ " for q in (x.questions).split('\\n') # split the questions\n",
+ " if len(q) >10 # remove the empty questions\n",
+ " ], axis=1)\n",
+ "ada_results.head()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "out = pd.concat([ada_results], axis=1)\n",
+ "out.columns = ['ada']\n",
+ "out.to_csv('olympics-data/search_engine_results.csv')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def expand_lists(out):\n",
+ " \"\"\"\n",
+ " Expand a pandas series containing lists into a series, where each list element becomes a value on its own\n",
+ "\n",
+ " Input is a row per paragraph, which has multiple questions\n",
+ " Output is a row per question\n",
+ " \"\"\"\n",
+ " cols = [pd.DataFrame(out[name].tolist()).stack().reset_index(level=1, drop=True).rename(name) for name in out.columns] \n",
+ " return pd.concat(cols, axis=1)\n",
+ "\n",
+ "out_expanded = expand_lists(out)\n",
+ "out_expanded['rank'] = out_expanded.ada.apply(lambda x: x[0] if x != [] else -2)\n",
+ "out_expanded['tokens'] = out_expanded.ada.apply(lambda x: x[1] if x != [] else -2)\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "74.3% of relevant paragraphs are retrieved within the first 2k tokens\n"
+ ]
+ }
+ ],
+ "source": [
+ "within_2k = (out_expanded.tokens < 2000).mean()\n",
+ "print(f\"{within_2k*100:.1f}% of relevant paragraphs are retrieved within the first 2k tokens\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The relevant context can be obtained 74% of the time on this dataset"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "7.4% of relevant paragraphs are not retrieved within the first 200 results\n"
+ ]
+ }
+ ],
+ "source": [
+ "outside_200 = (out_expanded['rank'] == -1).mean()\n",
+ "print(f\"{outside_200*100:.1f}% of relevant paragraphs are not retrieved within the first 200 results\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "7.4% of the time, this is due to the keyword search part of the search algorithm not retrieving the relevant context within the first 200 results.\n",
+ "18.3% of the time this is due to the semantic search not placing the relevant context within the first 2000 tokens."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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",
+ "text/plain": [
+ "<Figure size 432x288 with 1 Axes>"
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "import matplotlib.pyplot as plt\n",
+ "\n",
+ "# plot a histogram, and add axis descriptions and title\n",
+ "out_expanded[(out_expanded['rank'] >=0)&(out_expanded['rank'] <30)]['rank'].hist(bins=29)\n",
+ "plt.xlabel('rank')\n",
+ "plt.ylabel('count')\n",
+ "plt.title('Histogram of ranks of retrieved paragraphs')\n",
+ "plt.show()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 18,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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",
+ "text/plain": [
+ "<Figure size 432x288 with 1 Axes>"
+ ]
+ },
+ "metadata": {
+ "needs_background": "light"
+ },
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "out_expanded[(out_expanded.tokens>=0)&(out_expanded.tokens < 2000)]['tokens'].hist(bins=29)\n",
+ "plt.xlabel('tokens')\n",
+ "plt.ylabel('count')\n",
+ "plt.title('Histogram of the number of minimum tokens needed')\n",
+ "plt.show()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We can observe that the context is most likely to be returned as one of the first results, and most likely to be returned within the first 200-500 tokens."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "-2 0.000063\n",
+ "-1 0.074428\n",
+ " 0 0.453420\n",
+ " 1 0.089515\n",
+ " 2 0.047146\n",
+ " 3 0.032437\n",
+ " 4 0.024139\n",
+ " 5 0.019676\n",
+ " 6 0.015967\n",
+ " 7 0.013452\n",
+ " 8 0.011189\n",
+ " 9 0.009869\n",
+ " 10 0.009178\n",
+ "Name: rank, dtype: float64"
+ ]
+ },
+ "execution_count": 20,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# normalized value_counts\n",
+ "out_expanded['rank'].value_counts(normalize=True).sort_index()[:13]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "probabilities of the relevant context being returned at each rank. (-2 means a processing error, -1 means the rank is >200)"
+ ]
+ }
+ ],
+ "metadata": {
+ "interpreter": {
+ "hash": "be4b5d5b73a21c599de40d6deb1129796d12dc1cc33a738f7bac13269cfcafe8"
+ },
+ "kernelspec": {
+ "display_name": "Python 3.7.3 64-bit ('base': conda)",
+ "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.7.3"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
examples/finetuning/olympics-3-train-qa.ipynb
@@ -0,0 +1,637 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# 3. Train a fine-tuning model specialized for Q&A\n",
+ "This notebook will utilize the dataset of context, question and answer pairs to additionally create adversarial questions and context pairs, where the question was not generated on that context. In those cases the model will be prompted to answer \"No sufficient context for answering the question\". We will also train a discriminator model, which predicts whether the question can be answered based on the context or not.\n",
+ "\n",
+ "We will add hard adversarial examples as well, which will be based either on semantically similar sections, or neighbouring sections, originating from the same article."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "<div>\n",
+ "<style scoped>\n",
+ " .dataframe tbody tr th:only-of-type {\n",
+ " vertical-align: middle;\n",
+ " }\n",
+ "\n",
+ " .dataframe tbody tr th {\n",
+ " vertical-align: top;\n",
+ " }\n",
+ "\n",
+ " .dataframe thead th {\n",
+ " text-align: right;\n",
+ " }\n",
+ "</style>\n",
+ "<table border=\"1\" class=\"dataframe\">\n",
+ " <thead>\n",
+ " <tr style=\"text-align: right;\">\n",
+ " <th></th>\n",
+ " <th>title</th>\n",
+ " <th>heading</th>\n",
+ " <th>content</th>\n",
+ " <th>tokens</th>\n",
+ " <th>context</th>\n",
+ " <th>questions</th>\n",
+ " <th>answers</th>\n",
+ " </tr>\n",
+ " </thead>\n",
+ " <tbody>\n",
+ " <tr>\n",
+ " <th>0</th>\n",
+ " <td>2020 Summer Olympics</td>\n",
+ " <td>Summary</td>\n",
+ " <td>The 2020 Summer Olympics (Japanese: 2020年夏季オリン...</td>\n",
+ " <td>713</td>\n",
+ " <td>2020 Summer Olympics\\nSummary\\n\\nThe 2020 Summ...</td>\n",
+ " <td>1. What is the 2020 Summer Olympics?\\n2. When ...</td>\n",
+ " <td>1. The 2020 Summer Olympics is an internationa...</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>1</th>\n",
+ " <td>2020 Summer Olympics</td>\n",
+ " <td>Host city selection</td>\n",
+ " <td>The International Olympic Committee (IOC) vote...</td>\n",
+ " <td>126</td>\n",
+ " <td>2020 Summer Olympics\\nHost city selection\\n\\nT...</td>\n",
+ " <td>1. \\n2. \\n3. \\n4.</td>\n",
+ " <td>1. What is the International Olympic Committee...</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>2</th>\n",
+ " <td>2020 Summer Olympics</td>\n",
+ " <td>Impact of the COVID-19 pandemic</td>\n",
+ " <td>In January 2020, concerns were raised about th...</td>\n",
+ " <td>369</td>\n",
+ " <td>2020 Summer Olympics\\nImpact of the COVID-19 p...</td>\n",
+ " <td>1. What was the COVID-19 pandemic?\\n2. How did...</td>\n",
+ " <td>1. The COVID-19 pandemic was a pandemic that o...</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>3</th>\n",
+ " <td>2020 Summer Olympics</td>\n",
+ " <td>Qualifying event cancellation and postponement</td>\n",
+ " <td>Concerns about the pandemic began to affect qu...</td>\n",
+ " <td>298</td>\n",
+ " <td>2020 Summer Olympics\\nQualifying event cancell...</td>\n",
+ " <td>1. What was the original location of the Asia ...</td>\n",
+ " <td>1. The original location of the Asia & Oceania...</td>\n",
+ " </tr>\n",
+ " <tr>\n",
+ " <th>4</th>\n",
+ " <td>2020 Summer Olympics</td>\n",
+ " <td>Effect on doping tests</td>\n",
+ " <td>Mandatory doping tests were being severely res...</td>\n",
+ " <td>163</td>\n",
+ " <td>2020 Summer Olympics\\nEffect on doping tests\\n...</td>\n",
+ " <td>1. What was the COVID-19 pandemic?\\n2. What di...</td>\n",
+ " <td>1. The COVID-19 pandemic was a pandemic that o...</td>\n",
+ " </tr>\n",
+ " </tbody>\n",
+ "</table>\n",
+ "</div>"
+ ],
+ "text/plain": [
+ " title heading \\\n",
+ "0 2020 Summer Olympics Summary \n",
+ "1 2020 Summer Olympics Host city selection \n",
+ "2 2020 Summer Olympics Impact of the COVID-19 pandemic \n",
+ "3 2020 Summer Olympics Qualifying event cancellation and postponement \n",
+ "4 2020 Summer Olympics Effect on doping tests \n",
+ "\n",
+ " content tokens \\\n",
+ "0 The 2020 Summer Olympics (Japanese: 2020年夏季オリン... 713 \n",
+ "1 The International Olympic Committee (IOC) vote... 126 \n",
+ "2 In January 2020, concerns were raised about th... 369 \n",
+ "3 Concerns about the pandemic began to affect qu... 298 \n",
+ "4 Mandatory doping tests were being severely res... 163 \n",
+ "\n",
+ " context \\\n",
+ "0 2020 Summer Olympics\\nSummary\\n\\nThe 2020 Summ... \n",
+ "1 2020 Summer Olympics\\nHost city selection\\n\\nT... \n",
+ "2 2020 Summer Olympics\\nImpact of the COVID-19 p... \n",
+ "3 2020 Summer Olympics\\nQualifying event cancell... \n",
+ "4 2020 Summer Olympics\\nEffect on doping tests\\n... \n",
+ "\n",
+ " questions \\\n",
+ "0 1. What is the 2020 Summer Olympics?\\n2. When ... \n",
+ "1 1. \\n2. \\n3. \\n4. \n",
+ "2 1. What was the COVID-19 pandemic?\\n2. How did... \n",
+ "3 1. What was the original location of the Asia ... \n",
+ "4 1. What was the COVID-19 pandemic?\\n2. What di... \n",
+ "\n",
+ " answers \n",
+ "0 1. The 2020 Summer Olympics is an internationa... \n",
+ "1 1. What is the International Olympic Committee... \n",
+ "2 1. The COVID-19 pandemic was a pandemic that o... \n",
+ "3 1. The original location of the Asia & Oceania... \n",
+ "4 1. The COVID-19 pandemic was a pandemic that o... "
+ ]
+ },
+ "execution_count": 1,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import openai\n",
+ "import pandas as pd\n",
+ "df = pd.read_csv('olympics-data/olympics_qa.csv')\n",
+ "olympics_search_fileid = \"file-c3shd8wqF3vSCKaukW4Jr1TT\"\n",
+ "df.head()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Split the sections into a training and testing set"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(3014, 754)"
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "from sklearn.model_selection import train_test_split\n",
+ "train_df, test_df = train_test_split(df, test_size=0.2, random_state=42)\n",
+ "len(train_df), len(test_df)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "we check that he separator we intend to use isn't present within the contexts"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "0"
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "df.context.str.contains('->').sum()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 3.1 Create the fine-tuning datasets for Q&A and discriminator models\n",
+ "The fine-tuning dataset is created in the following way. For every corresponding question, answer and context pair we create:\n",
+ "- Positive example: correct question, answer, context pair\n",
+ "- Negative examples:\n",
+ " - random negative example, where the random context is paired with the question \n",
+ " - two hard negative examples\n",
+ " - one originating from the same wikipedia article\n",
+ " - another, which is most similar to the correct context\n",
+ "\n",
+ "This process is noisy, as sometimes the question might be answerable given a different context, but on average we hope this won't affect the peformance too much.\n",
+ "\n",
+ "We apply the same process of dataset creation for both the discriminator, and the Q&A answering model. We apply the process separately for the training and testing set, to ensure that the examples from the traing set don't feature within the test set."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import random\n",
+ "\n",
+ "def get_random_similar_contexts(question, context, file_id=olympics_search_fileid, search_model='ada', max_rerank=10):\n",
+ " \"\"\"\n",
+ " Find similar contexts to the given context using the search file\n",
+ " \"\"\"\n",
+ " try:\n",
+ " results = openai.Engine(search_model).search(\n",
+ " search_model=search_model, \n",
+ " query=question, \n",
+ " max_rerank=max_rerank,\n",
+ " file=file_id\n",
+ " )\n",
+ " candidates = []\n",
+ " for result in results['data'][:3]:\n",
+ " if result['text'] == context:\n",
+ " continue\n",
+ " candidates.append(result['text'])\n",
+ " random_candidate = random.choice(candidates)\n",
+ " return random_candidate\n",
+ " except Exception as e:\n",
+ " print(e)\n",
+ " return \"\"\n",
+ "\n",
+ "def create_fine_tuning_dataset(df, discriminator=False, n_negative=1, add_related=False):\n",
+ " \"\"\"\n",
+ " Create a dataset for fine tuning the OpenAI model; either for a discriminator model, \n",
+ " or a model specializing in Q&A, where it says if no relevant context is found.\n",
+ "\n",
+ " Parameters\n",
+ " ----------\n",
+ " df: pd.DataFrame\n",
+ " The dataframe containing the question, answer and context pairs\n",
+ " discriminator: bool\n",
+ " Whether to create a dataset for the discriminator\n",
+ " n_negative: int\n",
+ " The number of random negative samples to add (using a random context)\n",
+ " add_related: bool\n",
+ " Whether to add the related contexts to the correct context. These are hard negative examples\n",
+ "\n",
+ " Returns\n",
+ " -------\n",
+ " pd.DataFrame\n",
+ " The dataframe containing the prompts and completions, ready for fine-tuning\n",
+ " \"\"\"\n",
+ " rows = []\n",
+ " for i, row in df.iterrows():\n",
+ " for q, a in zip((\"1.\" + row.questions).split('\\n'), (\"1.\" + row.answers).split('\\n')):\n",
+ " if len(q) >10 and len(a) >10:\n",
+ " if discriminator:\n",
+ " rows.append({\"prompt\":f\"{row.context}\\nQuestion: {q[2:].strip()}\\n Related:\", \"completion\":f\" yes\"})\n",
+ " else:\n",
+ " rows.append({\"prompt\":f\"{row.context}\\nQuestion: {q[2:].strip()}\\nAnswer:\", \"completion\":f\" {a[2:].strip()}\"})\n",
+ "\n",
+ " for i, row in df.iterrows():\n",
+ " for q in (\"1.\" + row.questions).split('\\n'):\n",
+ " if len(q) >10:\n",
+ " for j in range(n_negative + (2 if add_related else 0)):\n",
+ " random_context = \"\"\n",
+ " if j == 0 and add_related:\n",
+ " # add the related contexts based on originating from the same wikipedia page\n",
+ " subset = df[(df.title == row.title) & (df.context != row.context)]\n",
+ " \n",
+ " if len(subset) < 1:\n",
+ " continue\n",
+ " random_context = subset.sample(1).iloc[0].context\n",
+ " if j == 1 and add_related:\n",
+ " # add the related contexts based on the most similar contexts according to the search\n",
+ " random_context = get_random_similar_contexts(q[2:].strip(), row.context, search_model='ada', max_rerank=10)\n",
+ " else:\n",
+ " while True:\n",
+ " # add random context, which isn't the correct context\n",
+ " random_context = df.sample(1).iloc[0].context\n",
+ " if random_context != row.context:\n",
+ " break\n",
+ " if discriminator:\n",
+ " rows.append({\"prompt\":f\"{random_context}\\nQuestion: {q[2:].strip()}\\n Related:\", \"completion\":f\" no\"})\n",
+ " else:\n",
+ " rows.append({\"prompt\":f\"{random_context}\\nQuestion: {q[2:].strip()}\\nAnswer:\", \"completion\":f\" No appropriate context found to answer the question.\"})\n",
+ "\n",
+ " return pd.DataFrame(rows) "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We apply the same process of dataset creation for both the discriminator, and the Q&A answering model. We apply the process separately for the training and testing set, to ensure that the examples from the traing set don't feature within the test set."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": []
+ },
+ "execution_count": 5,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "for name, is_disc in [('discriminator', True), ('qa', False)]:\n",
+ " for train_test, dt in [('train', train_df), ('test', test_df)]:\n",
+ " ft = create_fine_tuning_dataset(dt, discriminator=is_disc, n_negative=1, add_related=True)\n",
+ " ft.to_json(f'{name}_{train_test}.jsonl', orient='records', lines=True)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We formatted the data according to the recommendations from the fine-tuning tool, which is available using\n",
+ "> openai tools fine_tunes.prepare_data -f qa_train.jsonl\n",
+ "\n",
+ "We highly recommend that you use this tool, which suggests improvements in your data formatting for fine-tuning.\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 3.2 Submit the datasets for fine-tuning"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": []
+ },
+ "execution_count": 6,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "!openai api fine_tunes.create -t \"olympics-data/discriminator_train.jsonl\" -v \"olympics-data/discriminator_test.jsonl\" --no_packing --batch_size 16 --compute_classification_metrics --classification_positive_class \" yes\" --model ada"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": []
+ },
+ "execution_count": 7,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "!openai api fine_tunes.create -t \"olympics-data/qa_train.jsonl\" -v \"olympics-data/qa_test.jsonl\" --no_packing --batch_size 16"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 3.3 Using the fine-tuned models\n",
+ "\n",
+ "We will now use the fine-tuned discriminator and the fine-tuned Q&A model. By requesting logprobs, we can see how certain the discriminator is in a `yes` vs `no` answer."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[<OpenAIObject at 0x7fe812e602b0> JSON: {\n",
+ " \" no\": -10.819577,\n",
+ " \" yes\": -2.045765e-05\n",
+ " }]"
+ ]
+ },
+ "execution_count": 8,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "ft_discriminator = \"curie:ft-openai-internal-2021-08-23-23-58-57\"\n",
+ "ft_qa = \"curie:ft-openai-internal-2021-08-23-17-54-10\"\n",
+ "\n",
+ "def apply_ft_discriminator(context, question, discriminator_model):\n",
+ " \"\"\"\n",
+ " Apply the fine tuned discriminator to a question, to assess whether it can be answered from the context.\n",
+ " \"\"\"\n",
+ " prompt = f\"{context}\\nQuestion: {question}\\n Related:\"\n",
+ " result = openai.Completion.create(model=discriminator_model, prompt=prompt, max_tokens=1, temperature=0, top_p=1, n=1, logprobs=2)\n",
+ " return result['choices'][0]['logprobs']['top_logprobs']\n",
+ "\n",
+ "apply_ft_discriminator('The first human-made object in space was the Soviet Union satellite Sputnik 1 on 4 October 1957.', \n",
+ " 'What was the first human-made object in space?', ft_discriminator)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We can see that the model can generalize well to different contexts and questions. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "' The first human-made object in space was the Soviet Union satellite Sputnik 1 on 4 October 1957'"
+ ]
+ },
+ "execution_count": 9,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "def apply_ft_qa_answer(context, question, answering_model):\n",
+ " \"\"\"\n",
+ " Apply the fine tuned discriminator to a question\n",
+ " \"\"\"\n",
+ " prompt = f\"{context}\\nQuestion: {question}\\nAnswer:\"\n",
+ " result = openai.Completion.create(model=answering_model, prompt=prompt, max_tokens=30, temperature=0, top_p=1, n=1, stop=['.','\\n'])\n",
+ " return result['choices'][0]['text']\n",
+ "\n",
+ "apply_ft_qa_answer('The first human-made object in space was the Soviet Union satellite Sputnik 1 on 4 October 1957.', \n",
+ " 'What was the first human-made object in space?', ft_qa)\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We can see that the model can answer the question, when the context is appropriate."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "' The Soviet Union was the first country to successfully launch a satellite into space'"
+ ]
+ },
+ "execution_count": 10,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "apply_ft_qa_answer('The first human-made object in space was the Soviet Union satellite Sputnik 1 on 4 October 1957.',\n",
+ " 'What is impressive about the Soviet Union?', ft_qa)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "' No appropriate context found to answer the question'"
+ ]
+ },
+ "execution_count": 11,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "apply_ft_qa_answer('The first human-made object in space was the Soviet Union satellite Sputnik 1 on 4 October 1957.',\n",
+ " 'How many cars were produced in the Soviet Union in 1970?', ft_qa)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We can see that the model knows when to answer the question, and when to say that insufficient context is present to answer the question."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We can also combine a discriminator and a base model, or a fine-tuned Q&A model. Discriminator can essentially serve as a decision whether the question can be answered given the context or not."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "' Weather could cause a sport event to have no crowd'"
+ ]
+ },
+ "execution_count": 12,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "def answer_question_conditionally(answering_model, discriminator_model, context, question, discriminator_logprob_yes_modifier=0):\n",
+ " logprobs = apply_ft_discriminator(context, question, discriminator_model)\n",
+ " yes_logprob = logprobs[' yes'] if ' yes' in logprobs else -100\n",
+ " no_logprob = logprobs[' no'] if ' no' in logprobs else -100\n",
+ " if yes_logprob + discriminator_logprob_yes_modifier < no_logprob:\n",
+ " return \" No appropriate context found to answer the question based on the discriminator.\"\n",
+ " return apply_ft_qa_answer(context, question, answering_model)\n",
+ "answer_question_conditionally(ft_qa, ft_discriminator, \n",
+ " \"Crowdless games are a rare although not unheard-of occurrence in sports. \\\n",
+ " When they do occur, it is usually the result of events beyond the control \\\n",
+ " of the teams or fans, such as weather-related concerns, public health concerns, \\\n",
+ " or wider civil disturbances unrelated to the game. For instance, \\\n",
+ " the COVID-19 pandemic caused many sports leagues around the world \\\n",
+ " to be played behind closed doors.\",\n",
+ " \"Could weather cause a sport event to have no crowd?\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The above function illustrates how to potentially combine a discriminator and a fine-tuned Q&A model. This gives a more fine-grained control over how certain we want the model to be before it answers the question.\n",
+ "\n",
+ "We'll now take a look on how answers endpoint works - combining search to retrieve the relevant context from a knowledge base, and then using the fine-tuned Q&A model to answer the question."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 3.4 Answering the question based on a knowledge base\n",
+ "Finally we can use a logic similar to the [/answers](https://beta.openai.com/docs/api-reference/answers) endpoint, where we first search for the relevant context, and then ask a Q&A model to answer the question given that context. If you'd like to see the implementation details, check out the [`answers_with_ft.py`](answers_with_ft.py) file."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "\" Canada won the Women's football tournament at the 2020 Olympic games\""
+ ]
+ },
+ "execution_count": 13,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "from answers_with_ft import answer_question\n",
+ "answer_question(olympics_search_fileid, ft_qa, \"Which country won the Women's football tournament at the 2020 Olympic games?\")"
+ ]
+ }
+ ],
+ "metadata": {
+ "interpreter": {
+ "hash": "be4b5d5b73a21c599de40d6deb1129796d12dc1cc33a738f7bac13269cfcafe8"
+ },
+ "kernelspec": {
+ "display_name": "Python 3.7.3 64-bit ('base': conda)",
+ "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.7.3"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
openai/validators.py
@@ -654,7 +654,8 @@ def get_batch_size_suggestion(df, no_packing):
batch_size = BATCH_SIZE_TO_N_EXAMPLES_RATIO * n_examples
else:
batch_size = BATCH_SIZE_TO_N_CHARACTERS_RATIO * n_characters
- batch_size = 2 ** int(np.log2(batch_size))
+
+ batch_size = max(1, int(2 ** np.ceil(np.log2(batch_size))))
batch_size_suggestion = f" --batch_size {batch_size}"
return batch_size_suggestion
@@ -694,7 +695,7 @@ def write_out_file(df, fname, any_remediations, auto_accept):
input_text = "\n\nYour data will be written to a new JSONL file. Proceed [Y/n]: "
- if not any_remediations:
+ if not any_remediations and not split:
sys.stdout.write(
f'\nYou can use your file for fine-tuning:\n> openai api fine_tunes.create -t "{fname}"{additional_params}\n\nAfter you’ve fine-tuned a model, remember that your prompt has to end with the indicator string `{common_prompt_suffix_new_line_handled}` for the model to start generating completions, rather than continuing with the prompt.{optional_ending_string}\n'
)
openai/version.py
@@ -1,1 +1,1 @@
-VERSION = "0.11.0"
+VERSION = "0.11.1"