private/AdvancedNlpCourse/OpinionSentiment: Word_Vectors_and_Sentiment.ipynb

File Word_Vectors_and_Sentiment.ipynb, 41.3 KB (added by Zuzana Nevěřilová, 4 months ago)
Line 
1{
2 "cells": [
3  {
4   "cell_type": "markdown",
5   "metadata": {
6    "nbpresent": {
7     "id": "f3dbef4d-9bf4-4e24-bcd0-a4ce3dd00fb8"
8    }
9   },
10   "source": [
11    "# Sentiment Analysis Notebook\n",
12    "\n",
13    "Inspired by https://www.kaggle.com/gabrielaltay/word-vectors-from-pmi-matrix and https://www.kaggle.com/rosado/sentiment-analysis-text-mining.\n",
14    "\n",
15    "The notebook can handle two different datasets: Cestina 2.0 and Urban Dictionary. Select the one close to your language knowledge.\n",
16    "\n",
17    "The aim of this notebook is to demonstrate sentiment analysis, particularly on new words from the crowd-sourced website http://cestina20.cz or https://www.urbandictionary.com/. We scraped the data from Cestina 2.0 into a CSV file that is part of this project. In case of Urban Dictionary, we downloaded the CSV from Kaggle: https://www.kaggle.com/athontz/urban-dictionary-terms#urban_dictionary.csv\n",
18    "\n",
19    "First, we try to recognize the sentiment of dictionary entries using the Liu's Opinion Lexicon (https://www.cs.uic.edu/~liub/FBS/sentiment-analysis.html#lexicon). For Czech, we automatically translated the entries using Google Translate. The Opinion Lexicon as well as the translation are part of this project and can be found in `positive-words-en.txt`, `negative-words-en.txt`, `positive-words-cs.txt`, and `negative-words-cs.txt`.\n",
20    "\n",
21    "**OPTIONAL TASK**: If you are not familiar with Cestina 2.0/Urban Dictionary, go to the website and go through some dictionary entries to see example of the data.\n"
22   ]
23  },
24  {
25   "cell_type": "markdown",
26   "metadata": {
27    "nbpresent": {
28     "id": "96ff352e-308d-4ab7-a68e-244141128deb"
29    }
30   },
31   "source": [
32    "## Tools\n",
33    "### Tokenizer\n",
34    "We use NLTK standard tokenizer to split the texts by words. Splitting by spaces is not enough, since we want e.g. \"word\" and \"word,\" to be one token. Tokenization is not strongly language dependent, so NLTK standard tokenizer is enough. If we want to process languages that do not use spaces (CJK, or Chinese, Japanese, Korean), we should modify this part.\n",
35    "\n",
36    "### Stopwords\n",
37    "For training the word vectors, we use stoplists of English/Czech most common words. This helps especially in cases we have small data (our case)."
38   ]
39  },
40  {
41   "cell_type": "code",
42   "execution_count": null,
43   "metadata": {
44    "nbpresent": {
45     "id": "020e99ab-4d42-47c9-b637-d2b7dc72285c"
46    }
47   },
48   "outputs": [],
49   "source": [
50    "!wget https://raw.githubusercontent.com/stopwords-iso/stopwords-cs/master/stopwords-cs.txt\n",
51    "!wget https://raw.githubusercontent.com/stopwords-iso/stopwords-en/master/stopwords-en.txt"
52   ]
53  },
54  {
55   "cell_type": "markdown",
56   "metadata": {
57    "nbpresent": {
58     "id": "60ff129a-80bd-4c96-8f5e-8c2284f71f1c"
59    }
60   },
61   "source": [
62    "### Python packages\n",
63    "#### Pandas\n",
64    "Pandas is a data science standard that allows easy work with large tabular data. Pandas DataFrame is the object we use in this project.\n",
65    "\n",
66    "#### SciKit Learn\n",
67    "SciKit Learn (`sklearn`) is a standard machine learning package for Python. We use its `cosine_similarity` function.\n",
68    "\n",
69    "#### Numpy\n",
70    "Together with `sklearn` a Python machine learning standard. Provides straightforward matrix computation, so we avoid unhealthy nested for-cycles."
71   ]
72  },
73  {
74   "cell_type": "code",
75   "execution_count": null,
76   "metadata": {},
77   "outputs": [],
78   "source": [
79    "# it depends on installation but probably this is not necessary\n",
80    "# in case it does not work, try pip instead of pip3\n",
81    "!pip3 install --user nltk\n",
82    "!pip3 install --user sklearn"
83   ]
84  },
85  {
86   "cell_type": "code",
87   "execution_count": null,
88   "metadata": {
89    "nbpresent": {
90     "id": "2ce12ebd-fed3-40ea-ade5-7c7031f112b0"
91    }
92   },
93   "outputs": [],
94   "source": [
95    "from collections import Counter\n",
96    "import itertools\n",
97    "\n",
98    "import os\n",
99    "import nltk\n",
100    "nltk.download('punkt')\n",
101    "from nltk.tokenize import word_tokenize\n",
102    "\n",
103    "import numpy as np\n",
104    "import pandas as pd\n",
105    "from scipy import sparse\n",
106    "from sklearn.preprocessing import normalize\n",
107    "from sklearn.metrics.pairwise import cosine_similarity"
108   ]
109  },
110  {
111   "cell_type": "code",
112   "execution_count": null,
113   "metadata": {
114    "nbpresent": {
115     "id": "e5b6eb2f-46cb-4ad5-8732-7fd7792b42ba"
116    }
117   },
118   "outputs": [],
119   "source": [
120    "LANG_SETTINGS = {\"en\": {\"filename\":\"urban_dictionary.csv\", \"sep\":\",\", \"explanation\":\"definition\"},\n",
121    "                 \"cs\": {\"filename\":\"cestina20.csv\", \"sep\":\";\", \"explanation\":\"explanation\"}\n",
122    "                }\n",
123    "selected_language = 'cs'\n",
124    "settings = LANG_SETTINGS[selected_language]"
125   ]
126  },
127  {
128   "cell_type": "markdown",
129   "metadata": {
130    "nbpresent": {
131     "id": "b7a32c00-a4c7-49de-92fe-62ac6eae3a2e"
132    }
133   },
134   "source": [
135    "## Data\n",
136    "We prepared the data in advance using web crawling and parsing of the HTML pages. Look at a sample of the CSV."
137   ]
138  },
139  {
140   "cell_type": "code",
141   "execution_count": null,
142   "metadata": {
143    "nbpresent": {
144     "id": "2a521a06-187b-43fc-b7cb-8ce3f56e0a13"
145    }
146   },
147   "outputs": [],
148   "source": [
149    "df = pd.read_csv(settings['filename'], sep=settings['sep'])\n",
150    "df.head()"
151   ]
152  },
153  {
154   "cell_type": "markdown",
155   "metadata": {
156    "nbpresent": {
157     "id": "2015e579-b211-40e4-a3cd-f0af5008b018"
158    }
159   },
160   "source": [
161    "### Explanations\n",
162    "We try to recognize dictionary entry sentiment from the explanation. Let's see an example, next, let's convert the explanations into token sequences and remove stopwords."
163   ]
164  },
165  {
166   "cell_type": "code",
167   "execution_count": null,
168   "metadata": {
169    "nbpresent": {
170     "id": "6cd5d476-5808-4544-a652-d70c566e51c6"
171    }
172   },
173   "outputs": [],
174   "source": [
175    "df[settings['explanation']][1000]"
176   ]
177  },
178  {
179   "cell_type": "code",
180   "execution_count": null,
181   "metadata": {
182    "nbpresent": {
183     "id": "f34815e0-c51e-42d5-a17d-04a497c6e17b"
184    }
185   },
186   "outputs": [],
187   "source": [
188    "explanations = df[settings['explanation']].tolist()\n",
189    "# remove stopwords\n",
190    "stopwords_set = ['-','.',':',';','\"',',', '!', '(', ')', '``', \"'\", \"''\", \"„\", \"”\", \"...\", \"apod\", \"viz\", 'např', \"například\", \"příklad\"]\n",
191    "with open('stopwords-{}.txt'.format(selected_language), encoding='utf-8') as f:\n",
192    "    stopwords_set.extend(list(set([w.strip() for w in f.readlines()])))\n",
193    "#print(stopwords_set)\n",
194    "explanations = [\n",
195    "    [tok.lower() for tok in word_tokenize(explanation.replace('…', '...').replace('&#8230', '...')) if tok.lower() not in stopwords_set] for explanation in explanations\n",
196    "]\n",
197    "# show results\n",
198    "explanations[1]"
199   ]
200  },
201  {
202   "cell_type": "markdown",
203   "metadata": {
204    "nbpresent": {
205     "id": "51434e41-a231-41e1-a087-1e788710ef58"
206    }
207   },
208   "source": [
209    "## Recognize sentiment using the Opinion Lexicon\n",
210    "\n",
211    "**TASK 1**: Look in the original opinion lexicon, look in the translated version. Comment on what you see in both resources.\n",
212    "\n",
213    "The easiest way is to go through all tokens in the explanation and sum their sentiment according to the Opinion Lexicon. Since some opinion lexicons distinguish *strong* and *weak* opinions we convert the input data into positive or negative numbers in a similar way, except we do not distinguish the intensity of the sentiment, only the polarity: -2 for negative words, 2 for positive words, 0 for words present in both files.\n"
214   ]
215  },
216  {
217   "cell_type": "code",
218   "execution_count": null,
219   "metadata": {
220    "nbpresent": {
221     "id": "74d938a4-4600-41ae-8cab-dd359e64cfa5"
222    },
223    "scrolled": true
224   },
225   "outputs": [],
226   "source": [
227    "with open('positive-words-{}.txt'.format(selected_language),'rb') as f:\n",
228    "    positive_words = [w.strip().lower() for w in f.read().decode('utf-8','ignore').split('\\n')]\n",
229    "with open('negative-words-{}.txt'.format(selected_language),'rb') as f:\n",
230    "    negative_words = [w.strip().lower() for w in f.read().decode('utf-8','ignore').split('\\n')]"
231   ]
232  },
233  {
234   "cell_type": "code",
235   "execution_count": null,
236   "metadata": {
237    "nbpresent": {
238     "id": "64ab734f-91f4-45c1-82a7-ce2cfbf80b2f"
239    }
240   },
241   "outputs": [],
242   "source": [
243    "score_word_dict = {k:2.00001 for k in positive_words} # we put a small epsilon in order to distinguish sentences with no recognized sentiment from sentences with positive+negative sentiment\n",
244    "score_word_dict.update({k:0 for k in negative_words if k in positive_words})\n",
245    "score_word_dict.update({k:-2 for k in negative_words if k not in positive_words})"
246   ]
247  },
248  {
249   "cell_type": "code",
250   "execution_count": null,
251   "metadata": {
252    "nbpresent": {
253     "id": "c3764e84-53bf-40df-b60b-070fae9140ee"
254    }
255   },
256   "outputs": [],
257   "source": [
258    "def get_sentiment_sequence(tokens, score_word_dict):\n",
259    "    sentiment = 0\n",
260    "    for token in tokens:\n",
261    "        sentiment += score_word_dict.get(token, 0)\n",
262    "    return sentiment\n",
263    "df[settings['explanation']][1], get_sentiment_sequence(explanations[1], score_word_dict)"
264   ]
265  },
266  {
267   "cell_type": "markdown",
268   "metadata": {
269    "nbpresent": {
270     "id": "69c017ce-9d2f-4e23-9ceb-36e8a09889e0"
271    }
272   },
273   "source": [
274    "Calculate sentiment for all explanations and a column to the DataFrame."
275   ]
276  },
277  {
278   "cell_type": "code",
279   "execution_count": null,
280   "metadata": {
281    "nbpresent": {
282     "id": "c7dc10b2-16ff-43df-9402-ce79b38f4d8c"
283    }
284   },
285   "outputs": [],
286   "source": [
287    "scores=[]\n",
288    "for d in explanations:\n",
289    "    score = get_sentiment_sequence(d, score_word_dict)\n",
290    "    scores.append(score)\n",
291    "df['feeling_score_lexicon'] = scores\n",
292    "df.head()"
293   ]
294  },
295  {
296   "cell_type": "code",
297   "execution_count": null,
298   "metadata": {
299    "nbpresent": {
300     "id": "d63764e7-e961-4508-9148-263112f0f5a4"
301    }
302   },
303   "outputs": [],
304   "source": [
305    "df.sort_values(by=['feeling_score_lexicon'], ascending=False).head()"
306   ]
307  },
308  {
309   "cell_type": "markdown",
310   "metadata": {
311    "nbpresent": {
312     "id": "d0a48142-bed2-48de-a84b-219d3139581f"
313    }
314   },
315   "source": [
316    "## Result 1\n",
317    "\n",
318    "**TASK 2**: Add statistics about the dataset. How many dictionary entries have explanation? How many explanations have sentiment recognized?\n"
319   ]
320  },
321  {
322   "cell_type": "markdown",
323   "metadata": {
324    "nbpresent": {
325     "id": "ee81f282-5b75-4077-bbf5-c4632d0a2d96"
326    }
327   },
328   "source": [
329    "## Word Vectors\n",
330    "The main problems of the naive solution are:\n",
331    "* small recall because of rather low quality of the lexicon (due to the automatic translation),\n",
332    "* small recall due to only one form of the word present in the lexicon. However, in Czech language, many different forms for a word exist, e.g. tlustý, tlustým, tlustých, tlustá, tlustého, tlustou.\n",
333    "* no context awareness of the method\n",
334    " \n",
335    "    \n",
336    "We try to improve the sentiment recognition using word vectors. The main idea is the *distributional semantics* - an observation that similar words appear in similar contexts. There are many methods how to calculate word vectors, however, all of them take into account not only a token but also tokens in its surrounding (the context). Most techniques use a fixed window, in our case, the window is (-2, +2). For example, for the sentence \"The quick brown fox jumped over the lazy dog.\", using a sliding window we have the following sequences (stopword removal applied in the example):\n",
337    "\n",
338    "\\[quick, brown, fox, jumped, lazy\\]<br>\n",
339    "\\[brown, fox, jumped, lazy, dog\\]\n",
340    "\n",
341    "The distributional semantics assumes that *fox* is similar to other words that appear around the words *quick*, *brown*, *jumped*, *lazy*, *dog*."
342   ]
343  },
344  {
345   "cell_type": "markdown",
346   "metadata": {
347    "nbpresent": {
348     "id": "8950d61e-500f-4004-917a-6613dec78eac"
349    }
350   },
351   "source": [
352    "### Token index\n",
353    "We convert the tokens in explanations (without stopwords) into an index. This is handy, since we will only calculate with numbers and provide the respective tokens via this token index only."
354   ]
355  },
356  {
357   "cell_type": "code",
358   "execution_count": null,
359   "metadata": {
360    "nbpresent": {
361     "id": "c5c51550-7869-4d63-a72e-73a3305c82f7"
362    }
363   },
364   "outputs": [],
365   "source": [
366    "tok2indx = dict()\n",
367    "unigram_counts = Counter()\n",
368    "for ii, explanation in enumerate(explanations):\n",
369    "    for token in explanation:\n",
370    "        unigram_counts[token] += 1\n",
371    "        if token not in tok2indx:\n",
372    "            tok2indx[token] = len(tok2indx)\n",
373    "indx2tok = {indx:tok for tok,indx in tok2indx.items()}\n",
374    "print('done')\n",
375    "print('vocabulary size: {}'.format(len(unigram_counts)))\n",
376    "print('most common: {}'.format(unigram_counts.most_common(10)))"
377   ]
378  },
379  {
380   "cell_type": "markdown",
381   "metadata": {
382    "nbpresent": {
383     "id": "122732e5-5b39-4ba8-9fbf-6834c9f6b085"
384    }
385   },
386   "source": [
387    "### Skipgrams\n",
388    "We calculate the frequencies of word tuples appearing in the same sliding window. You can see the most frequent tuples."
389   ]
390  },
391  {
392   "cell_type": "code",
393   "execution_count": null,
394   "metadata": {
395    "nbpresent": {
396     "id": "86272d04-2637-4206-885b-4873f4b50a80"
397    }
398   },
399   "outputs": [],
400   "source": [
401    "back_window = 2\n",
402    "front_window = 2\n",
403    "skipgram_counts = Counter()\n",
404    "for i, explanation in enumerate(explanations):\n",
405    "    for ifw, fw in enumerate(explanation):\n",
406    "        icw_min = max(0, ifw - back_window)\n",
407    "        icw_max = min(len(explanation) - 1, ifw + front_window)\n",
408    "        icws = [ii for ii in range(icw_min, icw_max + 1) if ii != ifw]\n",
409    "        for icw in icws:\n",
410    "            skipgram = (explanation[ifw], explanation[icw])\n",
411    "            skipgram_counts[skipgram] += 1    \n",
412    "        \n",
413    "print('done')\n",
414    "print('number of skipgrams: {}'.format(len(skipgram_counts)))\n",
415    "print('most common: {}'.format(skipgram_counts.most_common(10)))"
416   ]
417  },
418  {
419   "cell_type": "markdown",
420   "metadata": {
421    "nbpresent": {
422     "id": "d233effc-9d8e-40df-9765-b53dfdff3c68"
423    }
424   },
425   "source": [
426    "## Token matrix\n",
427    "We store the skipgram frequencies in a (symmetric) matrix.\n",
428    "\n",
429    "**OPTIONAL TASK**: Why is the matrix symmetric?"
430   ]
431  },
432  {
433   "cell_type": "code",
434   "execution_count": null,
435   "metadata": {
436    "nbpresent": {
437     "id": "9dda77d1-4b69-48c2-b603-750748d4af25"
438    }
439   },
440   "outputs": [],
441   "source": [
442    "row_indxs = []\n",
443    "col_indxs = []\n",
444    "dat_values = []\n",
445    "ii = 0\n",
446    "for (tok1, tok2), sg_count in skipgram_counts.items():\n",
447    "    ii += 1\n",
448    "    if ii % 1000000 == 0:\n",
449    "        print(f'finished {ii/len(skipgram_counts):.2%} of skipgrams')\n",
450    "    tok1_indx = tok2indx[tok1]\n",
451    "    tok2_indx = tok2indx[tok2]\n",
452    "        \n",
453    "    row_indxs.append(tok1_indx)\n",
454    "    col_indxs.append(tok2_indx)\n",
455    "    dat_values.append(sg_count)\n",
456    "    \n",
457    "wwcnt_mat = sparse.csr_matrix((dat_values, (row_indxs, col_indxs)))\n",
458    "print('done')"
459   ]
460  },
461  {
462   "cell_type": "markdown",
463   "metadata": {
464    "nbpresent": {
465     "id": "7a8821c7-2bd8-4330-a54e-48f61b0516b7"
466    }
467   },
468   "source": [
469    "## Token similarity\n",
470    "In the token matrix, each row correspond to a token, the row is the word vector. The numbers in tha matrix show how often the token appears together with other tokens.\n",
471    "The following method calculates token similarity as a cosine of the angle between two word vectors."
472   ]
473  },
474  {
475   "cell_type": "code",
476   "execution_count": null,
477   "metadata": {
478    "nbpresent": {
479     "id": "f06795b7-b03f-4954-9ca6-3a1fb19fa500"
480    }
481   },
482   "outputs": [],
483   "source": [
484    "def ww_sim(token, matrix, topn=10):\n",
485    "    \"\"\"Calculate topn most similar words to word\"\"\"\n",
486    "    if token not in tok2indx:\n",
487    "        return 0\n",
488    "    indx = tok2indx[token]\n",
489    "    if isinstance(matrix, sparse.csr_matrix):\n",
490    "        v1 = matrix.getrow(indx)\n",
491    "    else:\n",
492    "        v1 = matrix[indx:indx+1, :]\n",
493    "    sims = cosine_similarity(matrix, v1).flatten()\n",
494    "    sindxs = np.argsort(-sims)\n",
495    "    sim_word_scores = [(indx2tok[sindx], sims[sindx]) for sindx in sindxs[0:topn]]\n",
496    "    return sim_word_scores"
497   ]
498  },
499  {
500   "cell_type": "code",
501   "execution_count": null,
502   "metadata": {
503    "nbpresent": {
504     "id": "de5b327b-9089-482f-ae6f-39e6fe3dac32"
505    }
506   },
507   "outputs": [],
508   "source": [
509    "import pprint\n",
510    "if selected_language == \"cs\":\n",
511    "    pprint.pprint(ww_sim('obézní', wwcnt_mat))\n",
512    "    pprint.pprint(ww_sim('hezká', wwcnt_mat))\n",
513    "else:\n",
514    "    pprint.pprint(ww_sim('ugly', wwcnt_mat))\n",
515    "    pprint.pprint(ww_sim('girl', wwcnt_mat))"
516   ]
517  },
518  {
519   "cell_type": "markdown",
520   "metadata": {
521    "nbpresent": {
522     "id": "5c48f967-8d12-43d2-87e8-a08e5ebfb660"
523    }
524   },
525   "source": [
526    "## Calculate sentiment for OOVs\n",
527    "Out-of-vocabulary terms is one of the problems in our first try. Let's try to expand the Opinion Lexicon by similar words. You can see that we now know the sentiment of words *not* present in the Opinion Lexicon."
528   ]
529  },
530  {
531   "cell_type": "code",
532   "execution_count": null,
533   "metadata": {
534    "nbpresent": {
535     "id": "cf2caeae-95b8-45d3-8f78-6293cf823920"
536    }
537   },
538   "outputs": [],
539   "source": [
540    "def get_sentiment(token, score_word_dict, ww_matrix):\n",
541    "#    if token in score_word_dict.keys(): # alternative: calculate from vectors iff the word is not in the lexicon\n",
542    "#        return score_word_dict[token]\n",
543    "    sentiment = score_word_dict.get(token, 0)\n",
544    "    k = ww_sim(token, ww_matrix)\n",
545    "    if not k:\n",
546    "        return 0\n",
547    "    for sim, score in k:\n",
548    "        sentiment += score * score_word_dict.get(sim, 0)\n",
549    "    return sentiment\n",
550    "if selected_language==\"cs\":\n",
551    "    print('andrej', get_sentiment('andrej', score_word_dict, wwcnt_mat), score_word_dict.get('andrej'))\n",
552    "else:\n",
553    "    print('donald', get_sentiment('donald', score_word_dict, wwcnt_mat), score_word_dict.get('donald'))"
554   ]
555  },
556  {
557   "cell_type": "code",
558   "execution_count": null,
559   "metadata": {
560    "nbpresent": {
561     "id": "8a29bb08-cd2f-4c83-b858-15c44d56030e"
562    }
563   },
564   "outputs": [],
565   "source": [
566    "def get_sentiment_sequence(tokens, score_word_dict, ww_matrix):\n",
567    "    sentiment = 0\n",
568    "    for token in tokens:\n",
569    "        sentiment += get_sentiment(token, score_word_dict, ww_matrix)\n",
570    "    return sentiment\n",
571    "df[settings['explanation']][1], get_sentiment_sequence(explanations[1], score_word_dict, wwcnt_mat)"
572   ]
573  },
574  {
575   "cell_type": "code",
576   "execution_count": null,
577   "metadata": {
578    "nbpresent": {
579     "id": "c0a1ebc8-217f-4d49-9bcd-eeca4debf726"
580    }
581   },
582   "outputs": [],
583   "source": [
584    "scores=[]\n",
585    "for d in explanations:\n",
586    "    score = get_sentiment_sequence(d, score_word_dict, wwcnt_mat)\n",
587    "    scores.append(score)\n",
588    "df['feeling_score_wv'] = scores\n",
589    "df.head()"
590   ]
591  },
592  {
593   "cell_type": "code",
594   "execution_count": null,
595   "metadata": {
596    "nbpresent": {
597     "id": "61acf6bd-aeec-49fb-874a-ec19691ee757"
598    }
599   },
600   "outputs": [],
601   "source": [
602    "df.sort_values(by=['feeling_score_wv']).head()"
603   ]
604  },
605  {
606   "cell_type": "markdown",
607   "metadata": {
608    "nbpresent": {
609     "id": "9fcfcdbd-7424-4cdc-a7be-23d241c7a20a"
610    }
611   },
612   "source": [
613    "## Result 2\n",
614    "\n",
615    "**TASK 3**: Calculate the same statistics as for Result 1. How did word vectors improve the number of recognized words in the explanations?"
616   ]
617  },
618  {
619   "cell_type": "markdown",
620   "metadata": {
621    "nbpresent": {
622     "id": "6e503bce-561b-49d9-883d-8b93c8f176ca"
623    }
624   },
625   "source": [
626    "## Evaluation\n",
627    "For this course, we manually annotated sentiment for 400 Czech explanations. We will compare the sentiment recognized by our methods with the manual annotation."
628   ]
629  },
630  {
631   "cell_type": "code",
632   "execution_count": null,
633   "metadata": {
634    "nbpresent": {
635     "id": "9874742a-f8f7-4cf9-8f3c-a040b47c41d9"
636    }
637   },
638   "outputs": [],
639   "source": [
640    "if selected_language==\"cs\":\n",
641    "    dfa = pd.read_csv('cestina20_annotation.csv', sep=';')\n",
642    "    annotation = df.loc[:len(dfa)-1,]\n",
643    "    annotation['ground_truth'] = dfa.annotation\n",
644    "    annotation\n",
645    "else:\n",
646    "    print(\"no ground truth (manual annotations) available\")"
647   ]
648  },
649  {
650   "cell_type": "markdown",
651   "metadata": {
652    "nbpresent": {
653     "id": "f5a8fe74-4b1e-4ad3-b45b-344ae29f540e"
654    }
655   },
656   "source": [
657    "**TASK 4 (cs)**: Insert code to calculate confusion matrix for both `feeling_score_lexicon` and `feeling_score_wv`. Assume that the opinion recognition is correct if the score == 0 or the same polarity. Which sentiment recognition is more accurate? Why?\n",
658    "\n",
659    "**TASK 4 (en)**: Go through 100 classifications and try to annotate manually the sentiment, -1 for negative, 0 for neutral, and 1 for positive is enough, i.e. do not consider *intensity*, only *polarity*."
660   ]
661  },
662  {
663   "cell_type": "code",
664   "execution_count": null,
665   "metadata": {
666    "nbpresent": {
667     "id": "332417aa-251e-4477-bac7-59e34406c66e"
668    }
669   },
670   "outputs": [],
671   "source": []
672  }
673 ],
674 "metadata": {
675  "kernelspec": {
676   "display_name": "Python 3",
677   "language": "python",
678   "name": "python3"
679  },
680  "language_info": {
681   "codemirror_mode": {
682    "name": "ipython",
683    "version": 3
684   },
685   "file_extension": ".py",
686   "mimetype": "text/x-python",
687   "name": "python",
688   "nbconvert_exporter": "python",
689   "pygments_lexer": "ipython3",
690   "version": "3.6.8"
691  },
692  "nbpresent": {
693   "slides": {
694    "004b13a1-f767-463b-80f7-8599c4e09e5a": {
695     "id": "004b13a1-f767-463b-80f7-8599c4e09e5a",
696     "prev": "af9260f5-c3c0-4457-8946-fc08623fdff8",
697     "regions": {
698      "a6fcc3e3-cb1a-44bf-b8c6-342f5fe53056": {
699       "attrs": {
700        "height": 0.8,
701        "width": 0.8,
702        "x": 0.1,
703        "y": 0.1
704       },
705       "content": {
706        "cell": "5c48f967-8d12-43d2-87e8-a08e5ebfb660",
707        "part": "whole"
708       },
709       "id": "a6fcc3e3-cb1a-44bf-b8c6-342f5fe53056"
710      }
711     }
712    },
713    "09c98d86-d894-4fd9-847e-1b89789b4e7f": {
714     "id": "09c98d86-d894-4fd9-847e-1b89789b4e7f",
715     "prev": null,
716     "regions": {
717      "2256868b-7797-45fd-8b58-fc7f5a861635": {
718       "attrs": {
719        "height": 0.8,
720        "width": 0.8,
721        "x": 0.1,
722        "y": 0.1
723       },
724       "content": {
725        "cell": "f3dbef4d-9bf4-4e24-bcd0-a4ce3dd00fb8",
726        "part": "whole"
727       },
728       "id": "2256868b-7797-45fd-8b58-fc7f5a861635"
729      }
730     }
731    },
732    "190227c4-a075-4074-ae84-e9ddf8e69560": {
733     "id": "190227c4-a075-4074-ae84-e9ddf8e69560",
734     "prev": "9726092c-f997-4a46-bef8-d0ea1cc64a60",
735     "regions": {
736      "68b26cc7-174a-4407-aea6-8930a804b4ec": {
737       "attrs": {
738        "height": 0.8,
739        "width": 0.8,
740        "x": 0.1,
741        "y": 0.1
742       },
743       "content": {
744        "cell": "9874742a-f8f7-4cf9-8f3c-a040b47c41d9",
745        "part": "whole"
746       },
747       "id": "68b26cc7-174a-4407-aea6-8930a804b4ec"
748      }
749     }
750    },
751    "1b6bbadb-1200-45d3-a5e8-717091642c54": {
752     "id": "1b6bbadb-1200-45d3-a5e8-717091642c54",
753     "prev": "dab15b59-64b4-4c70-b208-dfdc24a948aa",
754     "regions": {
755      "7ce7bd82-d3d4-4803-8dd9-528da5d2c270": {
756       "attrs": {
757        "height": 0.8,
758        "width": 0.8,
759        "x": 0.1,
760        "y": 0.1
761       },
762       "content": {
763        "cell": "60ff129a-80bd-4c96-8f5e-8c2284f71f1c",
764        "part": "whole"
765       },
766       "id": "7ce7bd82-d3d4-4803-8dd9-528da5d2c270"
767      }
768     }
769    },
770    "1ba27192-2b68-45b9-96f2-381167e1f808": {
771     "id": "1ba27192-2b68-45b9-96f2-381167e1f808",
772     "prev": "8f08e261-fb4a-4f9e-a021-23e6542c4a69",
773     "regions": {
774      "f20f9b58-448a-4e09-8a7a-e557b96affff": {
775       "attrs": {
776        "height": 0.8,
777        "width": 0.8,
778        "x": 0.1,
779        "y": 0.1
780       },
781       "content": {
782        "cell": "9dda77d1-4b69-48c2-b603-750748d4af25",
783        "part": "whole"
784       },
785       "id": "f20f9b58-448a-4e09-8a7a-e557b96affff"
786      }
787     }
788    },
789    "24da9cf4-1ecd-4314-a35e-fa3ed8056970": {
790     "id": "24da9cf4-1ecd-4314-a35e-fa3ed8056970",
791     "prev": "6a61d64d-530f-4f94-a29e-7bdf66bfaadb",
792     "regions": {
793      "c935fde2-6e13-4ad3-a10d-107d6cd77246": {
794       "attrs": {
795        "height": 0.8,
796        "width": 0.8,
797        "x": 0.1,
798        "y": 0.1
799       },
800       "content": {
801        "cell": "f06795b7-b03f-4954-9ca6-3a1fb19fa500",
802        "part": "whole"
803       },
804       "id": "c935fde2-6e13-4ad3-a10d-107d6cd77246"
805      }
806     }
807    },
808    "2c78a52b-56af-4232-ab1b-16abbe0a79bc": {
809     "id": "2c78a52b-56af-4232-ab1b-16abbe0a79bc",
810     "prev": "eb9a3413-8bc3-4e0b-b188-ef05e5f0c461",
811     "regions": {
812      "5e590248-29f7-48a3-a6f3-55d4b67755a6": {
813       "attrs": {
814        "height": 0.8,
815        "width": 0.8,
816        "x": 0.1,
817        "y": 0.1
818       },
819       "content": {
820        "cell": "74d938a4-4600-41ae-8cab-dd359e64cfa5",
821        "part": "whole"
822       },
823       "id": "5e590248-29f7-48a3-a6f3-55d4b67755a6"
824      }
825     }
826    },
827    "375c8fec-6f3b-4b01-89ad-410c4f27a4d0": {
828     "id": "375c8fec-6f3b-4b01-89ad-410c4f27a4d0",
829     "prev": "c24ac2b3-9975-4ee4-b59c-df7f94db8722",
830     "regions": {
831      "7a6d15da-c3bd-480c-9dcf-52f2a1805a2c": {
832       "attrs": {
833        "height": 0.8,
834        "width": 0.8,
835        "x": 0.1,
836        "y": 0.1
837       },
838       "content": {
839        "cell": "61acf6bd-aeec-49fb-874a-ec19691ee757",
840        "part": "whole"
841       },
842       "id": "7a6d15da-c3bd-480c-9dcf-52f2a1805a2c"
843      }
844     }
845    },
846    "3feede8b-0bbd-42b9-915c-56e40727cf62": {
847     "id": "3feede8b-0bbd-42b9-915c-56e40727cf62",
848     "prev": "f066aa28-05ba-4dde-81e2-7a9b7f104c55",
849     "regions": {
850      "35b0bd5b-37e5-4d53-95b0-d70d8d1ba55c": {
851       "attrs": {
852        "height": 0.8,
853        "width": 0.8,
854        "x": 0.1,
855        "y": 0.1
856       },
857       "content": {
858        "cell": "d0a48142-bed2-48de-a84b-219d3139581f",
859        "part": "whole"
860       },
861       "id": "35b0bd5b-37e5-4d53-95b0-d70d8d1ba55c"
862      }
863     }
864    },
865    "49ff324a-a018-43ac-92a1-caeefeda1d0b": {
866     "id": "49ff324a-a018-43ac-92a1-caeefeda1d0b",
867     "prev": "e81dcf87-fb95-4d33-89f9-6d820212ff9e",
868     "regions": {
869      "52348175-fe80-4346-9fe7-e76b63ac6c47": {
870       "attrs": {
871        "height": 0.8,
872        "width": 0.8,
873        "x": 0.1,
874        "y": 0.1
875       },
876       "content": {
877        "cell": "332417aa-251e-4477-bac7-59e34406c66e",
878        "part": "whole"
879       },
880       "id": "52348175-fe80-4346-9fe7-e76b63ac6c47"
881      }
882     }
883    },
884    "5381dda5-fd2a-4efd-8724-7c45c1f92c09": {
885     "id": "5381dda5-fd2a-4efd-8724-7c45c1f92c09",
886     "prev": "ec51efe5-ec7a-4b07-b785-fb71cabc2319",
887     "regions": {
888      "43c43c1a-872e-4494-85df-a7d10f9b0550": {
889       "attrs": {
890        "height": 0.8,
891        "width": 0.8,
892        "x": 0.1,
893        "y": 0.1
894       },
895       "content": {
896        "cell": "8a29bb08-cd2f-4c83-b858-15c44d56030e",
897        "part": "whole"
898       },
899       "id": "43c43c1a-872e-4494-85df-a7d10f9b0550"
900      }
901     }
902    },
903    "550158c0-8f2f-40c4-92cb-c10c8bf2f930": {
904     "id": "550158c0-8f2f-40c4-92cb-c10c8bf2f930",
905     "prev": "7427ba6e-da4a-4c0a-a357-799c13de2113",
906     "regions": {
907      "3e87230b-64d2-49cb-9527-3e26bff3fc6e": {
908       "attrs": {
909        "height": 0.8,
910        "width": 0.8,
911        "x": 0.1,
912        "y": 0.1
913       },
914       "content": {
915        "cell": "e5b6eb2f-46cb-4ad5-8732-7fd7792b42ba",
916        "part": "whole"
917       },
918       "id": "3e87230b-64d2-49cb-9527-3e26bff3fc6e"
919      }
920     }
921    },
922    "5b3a114a-ab45-43a4-8860-0245a98b26b9": {
923     "id": "5b3a114a-ab45-43a4-8860-0245a98b26b9",
924     "prev": "c7bf609c-1b48-4a11-8706-463abede978d",
925     "regions": {
926      "d70f470c-24d9-4c71-bd31-b0ff5a000dea": {
927       "attrs": {
928        "height": 0.8,
929        "width": 0.8,
930        "x": 0.1,
931        "y": 0.1
932       },
933       "content": {
934        "cell": "c7dc10b2-16ff-43df-9402-ce79b38f4d8c",
935        "part": "whole"
936       },
937       "id": "d70f470c-24d9-4c71-bd31-b0ff5a000dea"
938      }
939     }
940    },
941    "69429285-5c7f-4b7d-9243-ffc917b8f9ce": {
942     "id": "69429285-5c7f-4b7d-9243-ffc917b8f9ce",
943     "prev": "84264ee2-a515-4a95-b20c-491a0b8782d1",
944     "regions": {
945      "c9737b90-5ddc-42b1-a601-3c83808677eb": {
946       "attrs": {
947        "height": 0.8,
948        "width": 0.8,
949        "x": 0.1,
950        "y": 0.1
951       },
952       "content": {
953        "cell": "86272d04-2637-4206-885b-4873f4b50a80",
954        "part": "whole"
955       },
956       "id": "c9737b90-5ddc-42b1-a601-3c83808677eb"
957      }
958     }
959    },
960    "6a61d64d-530f-4f94-a29e-7bdf66bfaadb": {
961     "id": "6a61d64d-530f-4f94-a29e-7bdf66bfaadb",
962     "prev": "1ba27192-2b68-45b9-96f2-381167e1f808",
963     "regions": {
964      "6b39e02f-f47d-45eb-8c9a-74bdacfcefbd": {
965       "attrs": {
966        "height": 0.8,
967        "width": 0.8,
968        "x": 0.1,
969        "y": 0.1
970       },
971       "content": {
972        "cell": "7a8821c7-2bd8-4330-a54e-48f61b0516b7",
973        "part": "whole"
974       },
975       "id": "6b39e02f-f47d-45eb-8c9a-74bdacfcefbd"
976      }
977     }
978    },
979    "6e077d54-1b52-4b86-bcc3-43c44fd3f6e7": {
980     "id": "6e077d54-1b52-4b86-bcc3-43c44fd3f6e7",
981     "prev": "09c98d86-d894-4fd9-847e-1b89789b4e7f",
982     "regions": {
983      "93aee066-0ee3-491f-8ec5-7b73809d608f": {
984       "attrs": {
985        "height": 0.8,
986        "width": 0.8,
987        "x": 0.1,
988        "y": 0.1
989       },
990       "content": {
991        "cell": "96ff352e-308d-4ab7-a68e-244141128deb",
992        "part": "whole"
993       },
994       "id": "93aee066-0ee3-491f-8ec5-7b73809d608f"
995      }
996     }
997    },
998    "7427ba6e-da4a-4c0a-a357-799c13de2113": {
999     "id": "7427ba6e-da4a-4c0a-a357-799c13de2113",
1000     "prev": "1b6bbadb-1200-45d3-a5e8-717091642c54",
1001     "regions": {
1002      "eb62c709-b1e2-4c5e-966b-c081b616e056": {
1003       "attrs": {
1004        "height": 0.8,
1005        "width": 0.8,
1006        "x": 0.1,
1007        "y": 0.1
1008       },
1009       "content": {
1010        "cell": "2ce12ebd-fed3-40ea-ade5-7c7031f112b0",
1011        "part": "whole"
1012       },
1013       "id": "eb62c709-b1e2-4c5e-966b-c081b616e056"
1014      }
1015     }
1016    },
1017    "82ef1bf7-b0ce-4b1e-bc4c-c22909ee151b": {
1018     "id": "82ef1bf7-b0ce-4b1e-bc4c-c22909ee151b",
1019     "prev": "a303924c-421d-46f2-a6ad-d056562ce673",
1020     "regions": {
1021      "277ec992-07c7-4baa-a94c-1b76972aa2e7": {
1022       "attrs": {
1023        "height": 0.8,
1024        "width": 0.8,
1025        "x": 0.1,
1026        "y": 0.1
1027       },
1028       "content": {
1029        "cell": "2015e579-b211-40e4-a3cd-f0af5008b018",
1030        "part": "whole"
1031       },
1032       "id": "277ec992-07c7-4baa-a94c-1b76972aa2e7"
1033      }
1034     }
1035    },
1036    "84264ee2-a515-4a95-b20c-491a0b8782d1": {
1037     "id": "84264ee2-a515-4a95-b20c-491a0b8782d1",
1038     "prev": "ddce1e58-49ae-43ce-8fec-2c4eefbe4150",
1039     "regions": {
1040      "3c987ec2-8841-4b25-92d2-1e9cdb8d22aa": {
1041       "attrs": {
1042        "height": 0.8,
1043        "width": 0.8,
1044        "x": 0.1,
1045        "y": 0.1
1046       },
1047       "content": {
1048        "cell": "122732e5-5b39-4ba8-9fbf-6834c9f6b085",
1049        "part": "whole"
1050       },
1051       "id": "3c987ec2-8841-4b25-92d2-1e9cdb8d22aa"
1052      }
1053     }
1054    },
1055    "8f08e261-fb4a-4f9e-a021-23e6542c4a69": {
1056     "id": "8f08e261-fb4a-4f9e-a021-23e6542c4a69",
1057     "prev": "69429285-5c7f-4b7d-9243-ffc917b8f9ce",
1058     "regions": {
1059      "f80acf31-ec63-4ed8-a556-c02639b9febf": {
1060       "attrs": {
1061        "height": 0.8,
1062        "width": 0.8,
1063        "x": 0.1,
1064        "y": 0.1
1065       },
1066       "content": {
1067        "cell": "d233effc-9d8e-40df-9765-b53dfdff3c68",
1068        "part": "whole"
1069       },
1070       "id": "f80acf31-ec63-4ed8-a556-c02639b9febf"
1071      }
1072     }
1073    },
1074    "9726092c-f997-4a46-bef8-d0ea1cc64a60": {
1075     "id": "9726092c-f997-4a46-bef8-d0ea1cc64a60",
1076     "prev": "f5da5529-f64c-4678-a224-aa88b1466107",
1077     "regions": {
1078      "6eba12aa-1328-44e4-b933-26cc140b4418": {
1079       "attrs": {
1080        "height": 0.8,
1081        "width": 0.8,
1082        "x": 0.1,
1083        "y": 0.1
1084       },
1085       "content": {
1086        "cell": "6e503bce-561b-49d9-883d-8b93c8f176ca",
1087        "part": "whole"
1088       },
1089       "id": "6eba12aa-1328-44e4-b933-26cc140b4418"
1090      }
1091     }
1092    },
1093    "9c16251f-341a-47cd-8681-36b426db2f9b": {
1094     "id": "9c16251f-341a-47cd-8681-36b426db2f9b",
1095     "prev": "b3321028-c076-46dc-95cf-d0e796eb2e9a",
1096     "regions": {
1097      "294ce83c-a6fe-47f0-9e51-fac58920b355": {
1098       "attrs": {
1099        "height": 0.8,
1100        "width": 0.8,
1101        "x": 0.1,
1102        "y": 0.1
1103       },
1104       "content": {
1105        "cell": "c3764e84-53bf-40df-b60b-070fae9140ee",
1106        "part": "whole"
1107       },
1108       "id": "294ce83c-a6fe-47f0-9e51-fac58920b355"
1109      }
1110     }
1111    },
1112    "9cf17728-2436-4f54-8c1c-4eafc4392021": {
1113     "id": "9cf17728-2436-4f54-8c1c-4eafc4392021",
1114     "prev": "550158c0-8f2f-40c4-92cb-c10c8bf2f930",
1115     "regions": {
1116      "d15d9370-cf49-4953-b12f-b925c0c2991d": {
1117       "attrs": {
1118        "height": 0.8,
1119        "width": 0.8,
1120        "x": 0.1,
1121        "y": 0.1
1122       },
1123       "content": {
1124        "cell": "b7a32c00-a4c7-49de-92fe-62ac6eae3a2e",
1125        "part": "whole"
1126       },
1127       "id": "d15d9370-cf49-4953-b12f-b925c0c2991d"
1128      }
1129     }
1130    },
1131    "a303924c-421d-46f2-a6ad-d056562ce673": {
1132     "id": "a303924c-421d-46f2-a6ad-d056562ce673",
1133     "prev": "9cf17728-2436-4f54-8c1c-4eafc4392021",
1134     "regions": {
1135      "5863ab77-2ce5-4da3-b392-7b3628f45d6a": {
1136       "attrs": {
1137        "height": 0.8,
1138        "width": 0.8,
1139        "x": 0.1,
1140        "y": 0.1
1141       },
1142       "content": {
1143        "cell": "2a521a06-187b-43fc-b7cb-8ce3f56e0a13",
1144        "part": "whole"
1145       },
1146       "id": "5863ab77-2ce5-4da3-b392-7b3628f45d6a"
1147      }
1148     }
1149    },
1150    "af9260f5-c3c0-4457-8946-fc08623fdff8": {
1151     "id": "af9260f5-c3c0-4457-8946-fc08623fdff8",
1152     "prev": "24da9cf4-1ecd-4314-a35e-fa3ed8056970",
1153     "regions": {
1154      "0607cc59-9de9-4fec-9a0b-cc94c72b6726": {
1155       "attrs": {
1156        "height": 0.8,
1157        "width": 0.8,
1158        "x": 0.1,
1159        "y": 0.1
1160       },
1161       "content": {
1162        "cell": "de5b327b-9089-482f-ae6f-39e6fe3dac32",
1163        "part": "whole"
1164       },
1165       "id": "0607cc59-9de9-4fec-9a0b-cc94c72b6726"
1166      }
1167     }
1168    },
1169    "b3321028-c076-46dc-95cf-d0e796eb2e9a": {
1170     "id": "b3321028-c076-46dc-95cf-d0e796eb2e9a",
1171     "prev": "2c78a52b-56af-4232-ab1b-16abbe0a79bc",
1172     "regions": {
1173      "9914a8c1-c8a1-431c-b3c3-4eb766c2d453": {
1174       "attrs": {
1175        "height": 0.8,
1176        "width": 0.8,
1177        "x": 0.1,
1178        "y": 0.1
1179       },
1180       "content": {
1181        "cell": "64ab734f-91f4-45c1-82a7-ce2cfbf80b2f",
1182        "part": "whole"
1183       },
1184       "id": "9914a8c1-c8a1-431c-b3c3-4eb766c2d453"
1185      }
1186     }
1187    },
1188    "ba9d22c2-c855-4506-9d76-3609d7331ae2": {
1189     "id": "ba9d22c2-c855-4506-9d76-3609d7331ae2",
1190     "prev": "82ef1bf7-b0ce-4b1e-bc4c-c22909ee151b",
1191     "regions": {
1192      "956bdaae-0aa8-4cfa-b9c8-6f208b2e2711": {
1193       "attrs": {
1194        "height": 0.8,
1195        "width": 0.8,
1196        "x": 0.1,
1197        "y": 0.1
1198       },
1199       "content": {
1200        "cell": "6cd5d476-5808-4544-a652-d70c566e51c6",
1201        "part": "whole"
1202       },
1203       "id": "956bdaae-0aa8-4cfa-b9c8-6f208b2e2711"
1204      }
1205     }
1206    },
1207    "c1674358-a4a8-49d6-8c9e-b9b654dec8d1": {
1208     "id": "c1674358-a4a8-49d6-8c9e-b9b654dec8d1",
1209     "prev": "ba9d22c2-c855-4506-9d76-3609d7331ae2",
1210     "regions": {
1211      "3ce06210-7b25-4f08-a488-aa45acb1eb25": {
1212       "attrs": {
1213        "height": 0.8,
1214        "width": 0.8,
1215        "x": 0.1,
1216        "y": 0.1
1217       },
1218       "content": {
1219        "cell": "f34815e0-c51e-42d5-a17d-04a497c6e17b",
1220        "part": "whole"
1221       },
1222       "id": "3ce06210-7b25-4f08-a488-aa45acb1eb25"
1223      }
1224     }
1225    },
1226    "c24ac2b3-9975-4ee4-b59c-df7f94db8722": {
1227     "id": "c24ac2b3-9975-4ee4-b59c-df7f94db8722",
1228     "prev": "5381dda5-fd2a-4efd-8724-7c45c1f92c09",
1229     "regions": {
1230      "fa876f10-c1e4-4cd5-b136-bf7e86ec8e93": {
1231       "attrs": {
1232        "height": 0.8,
1233        "width": 0.8,
1234        "x": 0.1,
1235        "y": 0.1
1236       },
1237       "content": {
1238        "cell": "c0a1ebc8-217f-4d49-9bcd-eeca4debf726",
1239        "part": "whole"
1240       },
1241       "id": "fa876f10-c1e4-4cd5-b136-bf7e86ec8e93"
1242      }
1243     }
1244    },
1245    "c7bf609c-1b48-4a11-8706-463abede978d": {
1246     "id": "c7bf609c-1b48-4a11-8706-463abede978d",
1247     "prev": "9c16251f-341a-47cd-8681-36b426db2f9b",
1248     "regions": {
1249      "af05ade8-5cca-41a1-b602-4aa86f78c2af": {
1250       "attrs": {
1251        "height": 0.8,
1252        "width": 0.8,
1253        "x": 0.1,
1254        "y": 0.1
1255       },
1256       "content": {
1257        "cell": "69c017ce-9d2f-4e23-9ceb-36e8a09889e0",
1258        "part": "whole"
1259       },
1260       "id": "af05ade8-5cca-41a1-b602-4aa86f78c2af"
1261      }
1262     }
1263    },
1264    "dab15b59-64b4-4c70-b208-dfdc24a948aa": {
1265     "id": "dab15b59-64b4-4c70-b208-dfdc24a948aa",
1266     "prev": "6e077d54-1b52-4b86-bcc3-43c44fd3f6e7",
1267     "regions": {
1268      "712cca5c-f412-4c2d-8507-66ea68041569": {
1269       "attrs": {
1270        "height": 0.8,
1271        "width": 0.8,
1272        "x": 0.1,
1273        "y": 0.1
1274       },
1275       "content": {
1276        "cell": "020e99ab-4d42-47c9-b637-d2b7dc72285c",
1277        "part": "whole"
1278       },
1279       "id": "712cca5c-f412-4c2d-8507-66ea68041569"
1280      }
1281     }
1282    },
1283    "ddce1e58-49ae-43ce-8fec-2c4eefbe4150": {
1284     "id": "ddce1e58-49ae-43ce-8fec-2c4eefbe4150",
1285     "prev": "e2bc7986-85cd-4e1d-b58e-b88847240960",
1286     "regions": {
1287      "e3925122-fe2c-46fe-bf26-5685cf07236d": {
1288       "attrs": {
1289        "height": 0.8,
1290        "width": 0.8,
1291        "x": 0.1,
1292        "y": 0.1
1293       },
1294       "content": {
1295        "cell": "c5c51550-7869-4d63-a72e-73a3305c82f7",
1296        "part": "whole"
1297       },
1298       "id": "e3925122-fe2c-46fe-bf26-5685cf07236d"
1299      }
1300     }
1301    },
1302    "e2bc7986-85cd-4e1d-b58e-b88847240960": {
1303     "id": "e2bc7986-85cd-4e1d-b58e-b88847240960",
1304     "prev": "fce974f8-f2a7-4753-8aea-fcc4fbb83df1",
1305     "regions": {
1306      "e59ee17e-ed54-45f5-b48a-2c251c4685fe": {
1307       "attrs": {
1308        "height": 0.8,
1309        "width": 0.8,
1310        "x": 0.1,
1311        "y": 0.1
1312       },
1313       "content": {
1314        "cell": "8950d61e-500f-4004-917a-6613dec78eac",
1315        "part": "whole"
1316       },
1317       "id": "e59ee17e-ed54-45f5-b48a-2c251c4685fe"
1318      }
1319     }
1320    },
1321    "e81dcf87-fb95-4d33-89f9-6d820212ff9e": {
1322     "id": "e81dcf87-fb95-4d33-89f9-6d820212ff9e",
1323     "prev": "190227c4-a075-4074-ae84-e9ddf8e69560",
1324     "regions": {
1325      "f7ec68ba-436f-42e5-aa80-3c24042a5632": {
1326       "attrs": {
1327        "height": 0.8,
1328        "width": 0.8,
1329        "x": 0.1,
1330        "y": 0.1
1331       },
1332       "content": {
1333        "cell": "f5a8fe74-4b1e-4ad3-b45b-344ae29f540e",
1334        "part": "whole"
1335       },
1336       "id": "f7ec68ba-436f-42e5-aa80-3c24042a5632"
1337      }
1338     }
1339    },
1340    "eb9a3413-8bc3-4e0b-b188-ef05e5f0c461": {
1341     "id": "eb9a3413-8bc3-4e0b-b188-ef05e5f0c461",
1342     "prev": "c1674358-a4a8-49d6-8c9e-b9b654dec8d1",
1343     "regions": {
1344      "e0ec3cdf-6b8b-44dc-88e4-ae4ad5bb151c": {
1345       "attrs": {
1346        "height": 0.8,
1347        "width": 0.8,
1348        "x": 0.1,
1349        "y": 0.1
1350       },
1351       "content": {
1352        "cell": "51434e41-a231-41e1-a087-1e788710ef58",
1353        "part": "whole"
1354       },
1355       "id": "e0ec3cdf-6b8b-44dc-88e4-ae4ad5bb151c"
1356      }
1357     }
1358    },
1359    "ec51efe5-ec7a-4b07-b785-fb71cabc2319": {
1360     "id": "ec51efe5-ec7a-4b07-b785-fb71cabc2319",
1361     "prev": "004b13a1-f767-463b-80f7-8599c4e09e5a",
1362     "regions": {
1363      "486a07de-4f1a-4d49-b42b-5164ae74c3ae": {
1364       "attrs": {
1365        "height": 0.8,
1366        "width": 0.8,
1367        "x": 0.1,
1368        "y": 0.1
1369       },
1370       "content": {
1371        "cell": "cf2caeae-95b8-45d3-8f78-6293cf823920",
1372        "part": "whole"
1373       },
1374       "id": "486a07de-4f1a-4d49-b42b-5164ae74c3ae"
1375      }
1376     }
1377    },
1378    "f066aa28-05ba-4dde-81e2-7a9b7f104c55": {
1379     "id": "f066aa28-05ba-4dde-81e2-7a9b7f104c55",
1380     "prev": "5b3a114a-ab45-43a4-8860-0245a98b26b9",
1381     "regions": {
1382      "7f0b334e-0138-480d-9f9f-5394ca004335": {
1383       "attrs": {
1384        "height": 0.8,
1385        "width": 0.8,
1386        "x": 0.1,
1387        "y": 0.1
1388       },
1389       "content": {
1390        "cell": "d63764e7-e961-4508-9148-263112f0f5a4",
1391        "part": "whole"
1392       },
1393       "id": "7f0b334e-0138-480d-9f9f-5394ca004335"
1394      }
1395     }
1396    },
1397    "f5da5529-f64c-4678-a224-aa88b1466107": {
1398     "id": "f5da5529-f64c-4678-a224-aa88b1466107",
1399     "prev": "375c8fec-6f3b-4b01-89ad-410c4f27a4d0",
1400     "regions": {
1401      "84471409-37dd-4cbf-a258-ef06e4e8d072": {
1402       "attrs": {
1403        "height": 0.8,
1404        "width": 0.8,
1405        "x": 0.1,
1406        "y": 0.1
1407       },
1408       "content": {
1409        "cell": "9fcfcdbd-7424-4cdc-a7be-23d241c7a20a",
1410        "part": "whole"
1411       },
1412       "id": "84471409-37dd-4cbf-a258-ef06e4e8d072"
1413      }
1414     }
1415    },
1416    "fce974f8-f2a7-4753-8aea-fcc4fbb83df1": {
1417     "id": "fce974f8-f2a7-4753-8aea-fcc4fbb83df1",
1418     "prev": "3feede8b-0bbd-42b9-915c-56e40727cf62",
1419     "regions": {
1420      "26c6a0b6-d747-4851-a539-42ffd65b2be7": {
1421       "attrs": {
1422        "height": 0.8,
1423        "width": 0.8,
1424        "x": 0.1,
1425        "y": 0.1
1426       },
1427       "content": {
1428        "cell": "ee81f282-5b75-4077-bbf5-c4632d0a2d96",
1429        "part": "whole"
1430       },
1431       "id": "26c6a0b6-d747-4851-a539-42ffd65b2be7"
1432      }
1433     }
1434    }
1435   },
1436   "themes": {}
1437  }
1438 },
1439 "nbformat": 4,
1440 "nbformat_minor": 2
1441}