{"nbformat":4,"nbformat_minor":0,"metadata":{"colab":{"name":"politweet_testing.ipynb","provenance":[],"collapsed_sections":[],"authorship_tag":"ABX9TyOvid8Nx1s+2JocSEkaFApl"},"kernelspec":{"name":"python3","display_name":"Python 3"},"language_info":{"name":"python"},"gpuClass":"standard"},"cells":[{"cell_type":"code","source":["from google.colab import drive\n","drive.mount(\"/content/drive\")\n","import os\n","os.chdir(\"/content/drive/MyDrive/Softhouse-Twitter-Analyzer/twint-master\")\n","!pip3 install . -r requirements.txt\n","os.chdir(\"/content\")\n","#!pip install Twint\n","import asyncio\n","loop = asyncio.get_event_loop()\n","loop.is_running()\n","import twint\n","import nest_asyncio \n","import time \n","import regex as re \n","import pickle\n","nest_asyncio.apply() "],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"-yTijgZIo9Sa","executionInfo":{"status":"ok","timestamp":1657263446955,"user_tz":-120,"elapsed":54535,"user":{"displayName":"Marcus Ascard","userId":"03011699740768629907"}},"outputId":"45350a2e-b593-4f17-d028-3beac2701fa7"},"execution_count":3,"outputs":[{"output_type":"stream","name":"stdout","text":["Mounted at /content/drive\n","Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/\n","Processing /content/drive/MyDrive/Softhouse-Twitter-Analyzer/twint-master\n","\u001b[33m DEPRECATION: A future pip version will change local packages to be built in-place without first copying to a temporary directory. We recommend you use --use-feature=in-tree-build to test your packages with this new behavior before it becomes the default.\n"," pip 21.3 will remove support for this functionality. You can find discussion regarding this at https://github.com/pypa/pip/issues/7555.\u001b[0m\n","Collecting aiohttp==3.7.0\n"," Downloading aiohttp-3.7.0-cp37-cp37m-manylinux2014_x86_64.whl (1.3 MB)\n","\u001b[K |████████████████████████████████| 1.3 MB 5.1 MB/s \n","\u001b[?25hCollecting aiodns\n"," Downloading aiodns-3.0.0-py3-none-any.whl (5.0 kB)\n","Requirement already satisfied: beautifulsoup4 in /usr/local/lib/python3.7/dist-packages (from -r requirements.txt (line 3)) (4.6.3)\n","Collecting cchardet\n"," Downloading cchardet-2.1.7-cp37-cp37m-manylinux2010_x86_64.whl (263 kB)\n","\u001b[K |████████████████████████████████| 263 kB 57.2 MB/s \n","\u001b[?25hCollecting dataclasses\n"," Downloading dataclasses-0.6-py3-none-any.whl (14 kB)\n","Collecting elasticsearch\n"," Downloading elasticsearch-8.3.1-py3-none-any.whl (382 kB)\n","\u001b[K |████████████████████████████████| 382 kB 57.6 MB/s \n","\u001b[?25hRequirement already satisfied: pysocks in /usr/local/lib/python3.7/dist-packages (from -r requirements.txt (line 7)) (1.7.1)\n","Requirement already satisfied: pandas>=0.23.0 in /usr/local/lib/python3.7/dist-packages (from -r requirements.txt (line 8)) (1.3.5)\n","Collecting aiohttp_socks<=0.4.1\n"," Downloading aiohttp_socks-0.4.1-py3-none-any.whl (17 kB)\n","Collecting schedule\n"," Downloading schedule-1.1.0-py2.py3-none-any.whl (10 kB)\n","Requirement already satisfied: geopy in /usr/local/lib/python3.7/dist-packages (from -r requirements.txt (line 11)) (1.17.0)\n","Collecting fake-useragent\n"," Downloading fake-useragent-0.1.11.tar.gz (13 kB)\n","Collecting googletransx\n"," Downloading googletransx-2.4.2.tar.gz (13 kB)\n","Collecting yarl<2.0,>=1.0\n"," Downloading yarl-1.7.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (271 kB)\n","\u001b[K |████████████████████████████████| 271 kB 54.5 MB/s \n","\u001b[?25hCollecting async-timeout<4.0,>=3.0\n"," Downloading async_timeout-3.0.1-py3-none-any.whl (8.2 kB)\n","Collecting multidict<7.0,>=4.5\n"," Downloading multidict-6.0.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (94 kB)\n","\u001b[K |████████████████████████████████| 94 kB 3.7 MB/s \n","\u001b[?25hRequirement already satisfied: attrs>=17.3.0 in /usr/local/lib/python3.7/dist-packages (from aiohttp==3.7.0->-r requirements.txt (line 1)) (21.4.0)\n","Requirement already satisfied: chardet<4.0,>=2.0 in /usr/local/lib/python3.7/dist-packages (from aiohttp==3.7.0->-r requirements.txt (line 1)) (3.0.4)\n","Requirement already satisfied: pytz>=2017.3 in /usr/local/lib/python3.7/dist-packages (from pandas>=0.23.0->-r requirements.txt (line 8)) (2022.1)\n","Requirement already satisfied: python-dateutil>=2.7.3 in /usr/local/lib/python3.7/dist-packages (from pandas>=0.23.0->-r requirements.txt (line 8)) (2.8.2)\n","Requirement already satisfied: numpy>=1.17.3 in /usr/local/lib/python3.7/dist-packages (from pandas>=0.23.0->-r requirements.txt (line 8)) (1.21.6)\n","Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.7/dist-packages (from python-dateutil>=2.7.3->pandas>=0.23.0->-r requirements.txt (line 8)) (1.15.0)\n","Requirement already satisfied: idna>=2.0 in /usr/local/lib/python3.7/dist-packages (from yarl<2.0,>=1.0->aiohttp==3.7.0->-r requirements.txt (line 1)) (2.10)\n","Requirement already satisfied: typing-extensions>=3.7.4 in /usr/local/lib/python3.7/dist-packages (from yarl<2.0,>=1.0->aiohttp==3.7.0->-r requirements.txt (line 1)) (4.1.1)\n","Collecting pycares>=4.0.0\n"," Downloading pycares-4.2.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (291 kB)\n","\u001b[K |████████████████████████████████| 291 kB 60.4 MB/s \n","\u001b[?25hRequirement already satisfied: cffi>=1.5.0 in /usr/local/lib/python3.7/dist-packages (from pycares>=4.0.0->aiodns->-r requirements.txt (line 2)) (1.15.0)\n","Requirement already satisfied: pycparser in /usr/local/lib/python3.7/dist-packages (from cffi>=1.5.0->pycares>=4.0.0->aiodns->-r requirements.txt (line 2)) (2.21)\n","Collecting elastic-transport<9,>=8\n"," Downloading elastic_transport-8.1.2-py3-none-any.whl (59 kB)\n","\u001b[K |████████████████████████████████| 59 kB 6.7 MB/s \n","\u001b[?25hRequirement already satisfied: certifi in /usr/local/lib/python3.7/dist-packages (from elastic-transport<9,>=8->elasticsearch->-r requirements.txt (line 6)) (2022.6.15)\n","Collecting urllib3<2,>=1.26.2\n"," Downloading urllib3-1.26.10-py2.py3-none-any.whl (139 kB)\n","\u001b[K |████████████████████████████████| 139 kB 52.8 MB/s \n","\u001b[?25hRequirement already satisfied: geographiclib<2,>=1.49 in /usr/local/lib/python3.7/dist-packages (from geopy->-r requirements.txt (line 11)) (1.52)\n","Requirement already satisfied: requests in /usr/local/lib/python3.7/dist-packages (from googletransx->-r requirements.txt (line 13)) (2.23.0)\n","Collecting requests\n"," Downloading requests-2.28.1-py3-none-any.whl (62 kB)\n","\u001b[K |████████████████████████████████| 62 kB 1.4 MB/s \n","\u001b[?25hRequirement already satisfied: charset-normalizer<3,>=2 in /usr/local/lib/python3.7/dist-packages (from requests->googletransx->-r requirements.txt (line 13)) (2.1.0)\n","Building wheels for collected packages: twint, fake-useragent, googletransx\n"," Building wheel for twint (setup.py) ... \u001b[?25l\u001b[?25hdone\n"," Created wheel for twint: filename=twint-2.1.21-py3-none-any.whl size=40342 sha256=ab435542e517c6684d7bc526437ab6b8fde38ddd9685ea359198458c3ee157a2\n"," Stored in directory: /root/.cache/pip/wheels/02/e9/8e/fdc7249d98c95617fdb2cc7123f3ad532825effce792eed488\n"," Building wheel for fake-useragent (setup.py) ... \u001b[?25l\u001b[?25hdone\n"," Created wheel for fake-useragent: filename=fake_useragent-0.1.11-py3-none-any.whl size=13502 sha256=4c707776b5cefb8f7f8e2fbcb9b9bbbbfb21dbe836c717551fa0c6397632dfe3\n"," Stored in directory: /root/.cache/pip/wheels/ed/f7/62/50ab6c9a0b5567267ab76a9daa9d06315704209b2c5d032031\n"," Building wheel for googletransx (setup.py) ... \u001b[?25l\u001b[?25hdone\n"," Created wheel for googletransx: filename=googletransx-2.4.2-py3-none-any.whl size=15968 sha256=8092ee41751ac9e000eb58bb7007d9b53928cb074346e63b6e8ce111061a961d\n"," Stored in directory: /root/.cache/pip/wheels/66/d5/b1/31104b338f7fd45aa8f7d22587765db06773b13df48a89735f\n","Successfully built twint fake-useragent googletransx\n","Installing collected packages: multidict, yarl, urllib3, async-timeout, requests, pycares, elastic-transport, aiohttp, schedule, googletransx, fake-useragent, elasticsearch, dataclasses, cchardet, aiohttp-socks, aiodns, twint\n"," Attempting uninstall: urllib3\n"," Found existing installation: urllib3 1.24.3\n"," Uninstalling urllib3-1.24.3:\n"," Successfully uninstalled urllib3-1.24.3\n"," Attempting uninstall: requests\n"," Found existing installation: requests 2.23.0\n"," Uninstalling requests-2.23.0:\n"," Successfully uninstalled requests-2.23.0\n","\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n","google-colab 1.0.0 requires requests~=2.23.0, but you have requests 2.28.1 which is incompatible.\n","datascience 0.10.6 requires folium==0.2.1, but you have folium 0.8.3 which is incompatible.\u001b[0m\n","Successfully installed aiodns-3.0.0 aiohttp-3.7.0 aiohttp-socks-0.4.1 async-timeout-3.0.1 cchardet-2.1.7 dataclasses-0.6 elastic-transport-8.1.2 elasticsearch-8.3.1 fake-useragent-0.1.11 googletransx-2.4.2 multidict-6.0.2 pycares-4.2.1 requests-2.28.1 schedule-1.1.0 twint-2.1.21 urllib3-1.26.10 yarl-1.7.2\n"]}]},{"cell_type":"code","source":["#############################################################################\n","####################### TWITTER SCRAPER V2 FUNCTIONS ########################\n","############################################################################# \n","\n","def get_tweets_v2(search_str, from_date, to_date, num_tweets,u_or_s='s'):\n"," import time\n"," time_out= time.time()+2*60\n"," _dict={}\n"," c=twint.Config()\n"," if u_or_s.lower() ==\"u\":\n"," c.Search = \"from:@\"+search_str # topic\n"," else: \n"," c.Search = search_str # topic \n"," c.Pandas = True\n"," num_tweets_and_replies=num_tweets\n"," c.Count=True\n"," for j in range(1,5):\n"," prev_num_tweets=len(list(_dict.keys()))\n"," c.Limit = num_tweets_and_replies \n"," c.Since = from_date\n"," c.Until = to_date \n"," c.Hide_output =True\n"," twint.run.Search(c)\n"," tweet_info=twint.output.panda.Tweets_df\n"," t_count=0\n"," try:\n"," _keys=tweet_info[\"tweet\"]\n","\n"," for i in range (len(_keys)):\n"," tweet = _keys[i]\n"," tweet = tweet.split(' ')\n"," tweet_len = len(tweet)\n"," short_with_link = tweet_len < 5 \n"," if _keys[i] in _dict.keys() or _keys[i].startswith(\"@\") or short_with_link:\n"," pass\n"," else:\n","\n"," _dict[_keys[i]] = {\"hour\": tweet_info[\"hour\"][i], \n"," \"nlikes\": tweet_info[\"nlikes\"][i],\n"," \"nreplies\":tweet_info[\"nreplies\"][i] , \n"," \"nretweets\": tweet_info[\"nretweets\"][i],\"topic\":\"\"}\n"," if len(list(_dict.keys()))==num_tweets:\n"," break\n"," except:\n","\n"," pass\n"," print(len(list(_dict.keys())), \" of them are Tweets\")\n"," if len(list(_dict.keys())) < num_tweets:\n"," num_tweets_and_replies= num_tweets_and_replies+100*3**j\n"," elif time_out =1.2.3 in /usr/local/lib/python3.7/dist-packages (from openai) (1.3.5)\n","Requirement already satisfied: openpyxl>=3.0.7 in /usr/local/lib/python3.7/dist-packages (from openai) (3.0.10)\n","Requirement already satisfied: pandas-stubs>=1.1.0.11 in /usr/local/lib/python3.7/dist-packages (from openai) (1.2.0.62)\n","Requirement already satisfied: requests>=2.20 in /usr/local/lib/python3.7/dist-packages (from openai) (2.28.1)\n","Requirement already satisfied: et-xmlfile in /usr/local/lib/python3.7/dist-packages (from openpyxl>=3.0.7->openai) (1.1.0)\n","Requirement already satisfied: python-dateutil>=2.7.3 in /usr/local/lib/python3.7/dist-packages (from pandas>=1.2.3->openai) (2.8.2)\n","Requirement already satisfied: numpy>=1.17.3 in /usr/local/lib/python3.7/dist-packages (from pandas>=1.2.3->openai) (1.21.6)\n","Requirement already satisfied: pytz>=2017.3 in /usr/local/lib/python3.7/dist-packages (from pandas>=1.2.3->openai) (2022.1)\n","Requirement already satisfied: typing-extensions>=3.7.4.3 in /usr/local/lib/python3.7/dist-packages (from pandas-stubs>=1.1.0.11->openai) (4.1.1)\n","Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.7/dist-packages (from python-dateutil>=2.7.3->pandas>=1.2.3->openai) (1.15.0)\n","Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests>=2.20->openai) (2.10)\n","Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from requests>=2.20->openai) (2022.6.15)\n","Requirement already satisfied: urllib3<1.27,>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from requests>=2.20->openai) (1.26.10)\n","Requirement already satisfied: charset-normalizer<3,>=2 in /usr/local/lib/python3.7/dist-packages (from requests>=2.20->openai) (2.1.0)\n"]}],"source":["!pip install openai\n","import openai\n","import regex as re\n","import itertools\n","from difflib import SequenceMatcher \n","from Levenshtein import distance \n","openai.api_key = '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'\n","\n","\n","class TextClassifier:\n","\n"," def classify_topics(tweet_dict):\n"," tweet_list = list(tweet_dict.keys())\n"," prediction_dict = {}\n"," \n","\n"," for tweet in tweet_list:\n"," prompt_string = \"Classify this tweet with a general topic and two sub-topics:\\n\\\"\"\n"," prompt_string += tweet\n"," prompt_string += \"\\\".\\nGeneral topic: \\nSub topic 1: \\nSub topic 2:\\n. The classifications should not be \" \\\n"," \"more than 5 words. Numerate each topic in the output. END \"\n"," response = openai.Completion.create(\n"," model=\"text-davinci-002\",\n"," prompt=prompt_string,\n"," temperature=0,\n"," max_tokens=892,\n"," top_p=1,\n"," frequency_penalty=0,\n"," presence_penalty=0\n"," )\n","\n"," classifications_unclean = response.choices[0]['text']\n"," prediction_dict[tweet] = classifications_unclean\n","\n"," return TextClassifier.cleanup_topic_results(prediction_dict, tweet_dict)\n","\n"," def classify_sentiments(tweet_dict):\n"," tweet_list = list(tweet_dict.keys())\n","\n"," for tweet in tweet_list:\n"," prompt_string = \"Classify one sentiment for this tweet:\\n \\\"\"\n"," prompt_string += tweet\n"," prompt_string += \"\\\" \\nFor example:\\nSupport,\\nOpposition,\\nCriticism,\\nPraise,\\nDisagreement,\" \\\n"," \"\\nAgreement,\\nSkepticism,\\nAdmiration,\\nAnecdotes,\\nJokes,\\nMemes,\\nSarcasm,\\nSatire,\" \\\n"," \"\\nQuestions,\\nStatements,\\nOpinions,\\nPredictions.\\nSENTIMENT=\"\n","\n"," response = openai.Completion.create(\n"," model=\"text-davinci-002\",\n"," prompt=prompt_string,\n"," temperature=0,\n"," max_tokens=256,\n"," top_p=1,\n"," frequency_penalty=0,\n"," presence_penalty=0,\n"," logprobs = 5\n"," )\n"," classification_unclean = response.choices[0]['text']\n"," classification_clean = TextClassifier.cleanup_sentiment_results(classification_unclean) \n"," tweet_dict[tweet]['sentiment'] = classification_clean.lower() \n"," \n"," \n"," return tweet_dict\n","\n","\n"," def cleanup_sentiment_results(classification_unclean):\n"," classification_clean = classification_unclean.replace('\\n\\n', \"\")\n"," classification_clean = classification_clean.replace('\\n', \"\")\n"," if classification_clean.startswith(\" \"):\n"," classification_clean = classification_clean.replace(\" \", \"\")\n","\n"," return classification_clean \n","\n"," def analyze_sentiment(tweet_dict): \n","\n"," for tweet, val_dict in tweet_dict.items():\n"," sentiment = val_dict['sentiment'] \n"," prompt_string = \"Who is the TARGET of this \"\n"," prompt_string += sentiment\n"," prompt_string += \" TWEET?\\\\nTWEET=\\\"\"\n"," prompt_string += tweet\n"," prompt_string += \"\\\"\\\\n.TARGET should consist of less than 5 words.\\\\nTARGET=\"\n"," \n"," response = openai.Completion.create(\n"," model=\"text-davinci-002\",\n"," prompt=prompt_string,\n"," temperature=0,\n"," max_tokens=256,\n"," top_p=1,\n"," frequency_penalty=0,\n"," presence_penalty=0\n"," )\n"," \n"," analyzed_sentiment = response.choices[0]['text'] \n","\n"," #Remove spaces at the start/end of the response \n"," if analyzed_sentiment.startswith(' '):\n"," analyzed_sentiment = analyzed_sentiment[1:]\n"," if analyzed_sentiment.endswith(' '):\n"," analyzed_sentiment = analyzed_sentiment[:-1]\n","\n"," # Sometimes GPT-3 gives faulty results, so a simple filter is introduced\n"," # If the prediction is bad\n"," # -> set target value to N/A (not applicable)\n"," if len(analyzed_sentiment) > 10:\n"," analyzed_sentiment = \"N/A\"\n"," \n"," # An attempt to merge target responses that should be the same\n"," analyzed_sentiment = re.sub(\"\\(\", \"\", analyzed_sentiment)\n"," analyzed_sentiment = re.sub(\"\\)\", \"\", analyzed_sentiment)\n"," \n","\n"," s_list = [\"s\", \"the swedish social democratic party\"]\n"," m_list = [ \"m\", \"the swedish moderate party\", \"the moderate party\"]\n"," mp_list = [\"mp\", \"the swedish green party\"]\n","\n"," if analyzed_sentiment.lower() == \"v\":\n"," analyzed_sentiment = \"Vänsterpartiet\"\n"," elif analyzed_sentiment.lower() == \"mp\":\n"," analyzed_sentiment = \"Miljöpartiet\" \n"," elif analyzed_sentiment.lower() in s_list:\n"," analyzed_sentiment = \"Socialdemokraterna\" \n"," elif analyzed_sentiment.lower() == \"c\":\n"," analyzed_sentiment = \"Centerpartiet\"\n"," elif analyzed_sentiment.lower() == \"l\":\n"," analyzed_sentiment = \"Liberalerna\"\n"," elif analyzed_sentiment.lower() == \"kd\":\n"," analyzed_sentiment = \"Kristdemokraterna\"\n"," elif analyzed_sentiment.lower() in m_list:\n"," analyzed_sentiment = \"Moderaterna\"\n"," elif analyzed_sentiment.lower() == \"sd\":\n"," analyzed_sentiment = \"Sverigedemokraterna\"\n"," elif analyzed_sentiment.lower() == \"the swedish government\":\n"," analyzed_sentiment = \"Regeringen\"\n"," \n"," tweet_dict[tweet]['target'] = analyzed_sentiment\n","\n"," return tweet_dict \n"," \n","\n"," def cleanup_topic_results(prediction_dict, tweet_dict):\n"," temp_list = []\n","\n"," for tweet, item in prediction_dict.items():\n"," temp_list = []\n"," new_item = item.replace(\"\\n\", \" \")\n"," new_item = new_item.replace(\" \", \" \")\n"," new_item = new_item[4:]\n"," new_item = re.sub('\\d', '', new_item)\n"," sub_list = new_item.split(\".\")\n","\n"," for item in sub_list:\n"," if item.startswith(' '):\n"," item = item[1:]\n"," if item.endswith(' '):\n"," item = item[:-1]\n"," temp_list.append(item)\n"," tweet_dict[tweet]['topic'] = temp_list\n","\n"," return tweet_dict \n","\n"," def print_sentiment_results(results_dict):\n"," print('\\033[1m' + \"RESULTS\" + '\\033[0m', \"\\n\")\n"," for key in results_dict.keys():\n"," predictions = results_dict[key]['sentiment']\n"," print(\"\\\"\" + key + \"\\\"\" + \"\\n\" + str(predictions), \"\\n\" + \"---------------------------------\")\n","\n","\n"," def print_topic_results(results_dict):\n"," print('\\033[1m' + \"RESULTS\" + '\\033[0m', \"\\n\")\n"," for key in results_dict.keys():\n"," predictions = results_dict[key]\n"," print(\"\\\"\" + key + \"\\\"\" + \"\\n\" + str(predictions), \"\\n\" + \"---------------------------------\")\n","\n","\n"," def print_results(tweet_dict):\n"," for tweet, val_dict in tweet_dict.items():\n"," topics = val_dict['topic']\n"," sentiment = val_dict['sentiment']\n"," target = val_dict['target']\n","\n"," print(tweet, \"\\n\", \"Sentiment: \" + sentiment + \"\\n\", \" Target: \" + target, \"\\n\", topics, \"\\n\" + \"---------------------------------\") \n","\n"," def print_stats(result_dict):\n"," user = \"\"\n"," freq_dict = {}\n"," mean_likes = {}\n"," mean_retweets = {}\n"," mean_replies = {}\n"," sentiment_dict = {}\n"," target_dict = {}\n"," nbr_sentiment = 0\n"," nbr_topics = 0\n"," nbr_targets = 0\n"," new_topic_list = []\n"," sentiment_list = []\n"," target_list = []\n","\n"," for key, value in result_dict.items():\n","\n"," nlikes = value['nlikes']\n"," nreplies = value['nreplies']\n"," nretweets = value['nretweets']\n"," topic_list = value['topic'] \n"," sentiment = value['sentiment']\n"," target = value['target'] \n","\n"," # Count sentiment frequency\n"," if sentiment in sentiment_dict.keys():\n"," sentiment_dict[sentiment] += 1\n"," else:\n"," sentiment_dict[sentiment] = 1\n"," nbr_sentiment += 1\n"," \n"," \n"," # Count target frequency \n"," if target in target_dict.keys():\n"," target_dict[target] += 1\n"," else:\n"," # for s1 in target_list:\n"," # matching_percentage = SequenceMatcher(None, s1, target).ratio() \n"," # if matching_percentage > 0.85:\n"," # print(\"Two targets with a sequence matching > 0.85 were detected: \" + s1 + \" AND \" + target)\n"," # print(\"Merging targets...\" + \"\\n\")\n"," # target = s1\n"," target_dict[target] = 1\n"," nbr_targets += 1\n"," # target_list.append(target) \n","\n"," # Count topic frequency\n"," for topic in topic_list: \n"," topic_key = topic\n"," if topic in freq_dict.keys():\n"," freq_dict[topic] += 1\n","\n"," else: \n"," # for s1 in new_topic_list:\n"," # matching_percentage = SequenceMatcher(None, s1, topic).ratio() \n"," # if matching_percentage > 0.85:\n"," # print(\"Two topics with a sequence matching > 0.85 were detected: \" + s1 + \" AND \" + topic)\n"," # print(\"Merging topics...\" + \"\\n\") \n"," # topic = s1\n"," # freq_dict[topic] += 1\n"," \n"," freq_dict[topic] = 1\n"," nbr_topics += 1\n"," # new_topic_list.append(topic) \n"," \n"," # Count total likes per topic\n"," if topic_key in mean_likes.keys(): \n"," mean_likes[topic_key] += nlikes\n"," else:\n"," mean_likes[topic_key] = nlikes\n","\n"," # Count total retweets per topic\n"," if topic_key in mean_retweets.keys():\n"," mean_retweets[topic_key] += nretweets\n"," else:\n"," mean_retweets[topic_key] = nretweets\n","\n"," # Count total replies per topic\n"," if topic_key in mean_replies.keys():\n"," mean_replies[topic_key] += nreplies\n"," else:\n"," mean_replies[topic_key] = nreplies\n","\n"," # Count mean of likes\n"," for key in mean_likes.keys():\n"," mean_likes[key] = mean_likes[key] / freq_dict[key]\n","\n"," # Count mean of retweets\n"," for key in mean_retweets.keys():\n"," mean_retweets[key] = mean_retweets[key] / freq_dict[key]\n"," \n"," # Print the names of the columns.\n"," print('\\033[1m' + \"USER: \" + '\\033[0m', user)\n"," print('\\033[1m' + \"NBR OF TWEETS SCRAPED: \" + '\\033[0m', len(list(result_dict.keys())))\n"," print('\\033[1m' + \"NBR OF DIFFERENT TOPICS: \" + '\\033[0m', nbr_topics, \"\\n\")\n"," print(\"{:<60} {:<20} {:<30} {:<30} {:<30} {:<30}\".format('\\033[1m' + 'TOPIC', 'TOPIC FREQUENCY',\n"," 'AVERAGE NBR OF LIKES', 'AVERAGE NBR OF RETWEETS',\n"," 'AVERAGE NBR OF REPLIES', 'REACH AVERAGE' + '\\033[0m'))\n","\n"," # print each data item.\n"," for key, value in mean_likes.items():\n"," topic = key\n"," mean_likes = value\n"," reach_avg = (mean_likes + mean_retweets[topic] + mean_replies[topic]) / 3\n"," print( \n"," \"{:<60} {:<20} {:<30} {:<30} {:<30} {:<30}\".format(topic, freq_dict[topic], \"{:.2f}\".format(mean_likes),\n"," \"{:.2f}\".format(mean_retweets[topic]),\n"," mean_replies[topic], \"{:.2f}\".format(reach_avg)))\n","\n"," print(\"\\n\")\n"," print('\\033[1m' + \"NBR OF DIFFERENT SENTIMENTS: \" + '\\033[0m', nbr_sentiment, \"\\n\")\n"," print(\"{:<60} {:<20}\".format('\\033[1m' + 'SENTIMENT', 'SENTIMENT FREQUENCY' + '\\033[0m'))\n"," for key, value in sentiment_dict.items():\n"," sentiment = key\n"," sentiment_frequency = value\n"," print(\"{:<60} {:<20}\".format(sentiment, sentiment_dict[sentiment], \"{:.2f}\".format(sentiment_frequency)))\n","\n"," print(\"\\n\")\n"," print('\\033[1m' + \"NBR OF DIFFERENT TARGETS: \" + '\\033[0m', nbr_targets, \"\\n\")\n"," print(\"{:<60} {:<20}\".format('\\033[1m' + 'TARGET', 'TARGET FREQUENCY' + '\\033[0m'))\n"," for key, value in target_dict.items():\n"," target = key\n"," target_frequency = value\n"," print(\"{:<60} {:<20}\".format(target, target_dict[target], \"{:.2f}\".format(target_frequency)))\n"," "]},{"cell_type":"code","source":["os.chdir(\"/content/drive/MyDrive/Softhouse-Twitter-Analyzer/\") \n","a_file = open(\"data_dict.pkl\", \"rb\")\n","data_dict = pickle.load(a_file)\n","os.chdir(\"/content\") \n","\n","scrape_dict= get_tweets_v2(\"BuschEbba\",from_date= \"2021-01-15\", to_date=\"2022-07-01\", num_tweets =10, u_or_s=\"u\") \n","\n","classify_dict = {}\n","nbr_new_tweets = 0\n","for key, value in scrape_dict.items():\n"," if key not in data_dict.keys():\n"," classify_dict[key] = value \n"," nbr_new_tweets += 1\n"," print(\"A tweet was found that is not in our database: \" + \"\\\"\" + key + \"\\\"\")\n","print(str(nbr_new_tweets) + \" new tweets will be classified...\")"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"cklUyu37rEM3","executionInfo":{"status":"ok","timestamp":1657282431087,"user_tz":-120,"elapsed":6870,"user":{"displayName":"Marcus Ascard","userId":"03011699740768629907"}},"outputId":"762ba71a-e70e-41c2-ef7e-5d31af689bb1"},"execution_count":253,"outputs":[{"output_type":"stream","name":"stdout","text":["[+] Finished: Successfully collected 10 Tweets_and_replies.\n","8 of them are Tweets\n","[+] Finished: Successfully collected 320 Tweets_and_replies.\n","10 of them are Tweets\n","A tweet was found that is not in our database: \"14% alltså. Inte illa. Campa med mig och mitt parti från september och framåt. Jag lovar - det blir både kul och vore bra för Sverige! 🇸🇪 https://t.co/Cr27YqzQur\"\n","A tweet was found that is not in our database: \"25 stopp senaste halvåret. Imorgon drar jag vidare på turné. Laddar upp inför Almedalen med en rad Sverigesnack och flera andra fina stopp i sommarsverige. Hoppas vi ses! https://t.co/F4AgpQioYy\"\n","A tweet was found that is not in our database: \"Det har blivit dyrt att vara svensk. El-, bränsle- & matpriserna svider rejält just nu. Detta drabbar vanligt folk. Med vår politik sänker vi drivmedelspriset. Det skulle hjälpa småbarnsfamiljer, landsbygdsbor & lantbruket. Sverige behöver en ny start & en ny regering. https://t.co/ysA7w3YVFq\"\n","A tweet was found that is not in our database: \"Den nya överenskommelsen ska inte användas av Erdoğan som en förevändning för utökat förtryck mot kurder i Turkiet som alltjämt finns. Här uppfattar jag att Sverige står rakryggat och enat  – även i fortsättningen.\"\n","A tweet was found that is not in our database: \"Goda nyheter från Natotoppmötet i Madrid. Viktiga steg tas för att Sverige och Finland ska upptas som medlemmar. Tillsammans stärker vi den norra flanken och bidrar till fred, stabilitet och säkerhet i vårt närområde. #StrongerTogether #WeAreNato\"\n","A tweet was found that is not in our database: \"Åtta av åtta partier i Sverige står upp för aborträtten. Vi har därför föreslagit ett kontrakt idag om att försvara svensk abortlagstiftning. Jag har skrivit under. Jag uppmanar de andra partiledarna att göra detsamma. https://t.co/SQjk4AtFia\"\n","A tweet was found that is not in our database: \"Redo. Strax dags för debatt med Märta Stenevi i Aktuellt. https://t.co/iMjv8EZpqz\"\n","A tweet was found that is not in our database: \"Det har nu gått 124 dagar sedan Ryssland invaderade Ukraina. Europa och den demokratiska världen behöver stå enade och agera med tydlighet. För KD är det en självklarhet att det svenska stödet till Ukraina måste fortsätta med full kraft. Slava Ukraini! https://t.co/4LaoJPNHea\"\n","A tweet was found that is not in our database: \"Det har gått mer än fyra månader sedan Ryssland invaderade Ukraina. Idag talar jag vid Måndagsrörelsen på Norrmalmstorg, till stöd för alla som kämpar för friheten i Ukraina. https://t.co/5zh23AXcln\"\n","A tweet was found that is not in our database: \"Skrivit en lite längre text om Oslo och USA. Läs gärna den här: https://t.co/ujOf81WUxc\"\n","10 new tweets will be classified...\n"]}]},{"cell_type":"code","source":["topic_results = TextClassifier.classify_topics(classify_dict) "],"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":325},"id":"FYrWv5aTpbIP","executionInfo":{"status":"error","timestamp":1657282499038,"user_tz":-120,"elapsed":2987,"user":{"displayName":"Marcus Ascard","userId":"03011699740768629907"}},"outputId":"e31c3520-6387-414e-f4e6-8ed52e893c79"},"execution_count":254,"outputs":[{"output_type":"error","ename":"KeyboardInterrupt","evalue":"ignored","traceback":["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m","\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)","\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mtopic_results\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mTextClassifier\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mclassify_topics\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mclassify_dict\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m","\u001b[0;32m\u001b[0m in \u001b[0;36mclassify_topics\u001b[0;34m(tweet_dict)\u001b[0m\n\u001b[1;32m 26\u001b[0m \u001b[0mtop_p\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 27\u001b[0m \u001b[0mfrequency_penalty\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 28\u001b[0;31m \u001b[0mpresence_penalty\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 29\u001b[0m )\n\u001b[1;32m 30\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;32m/usr/local/lib/python3.7/dist-packages/openai/api_resources/completion.py\u001b[0m in \u001b[0;36mcreate\u001b[0;34m(cls, *args, **kwargs)\u001b[0m\n\u001b[1;32m 29\u001b[0m \u001b[0;32mwhile\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 30\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 31\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0msuper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcreate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 32\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mTryAgain\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 33\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mtimeout\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mtime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtime\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0mstart\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mtimeout\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;32m/usr/local/lib/python3.7/dist-packages/openai/api_resources/abstract/engine_api_resource.py\u001b[0m in \u001b[0;36mcreate\u001b[0;34m(cls, api_key, api_base, api_type, request_id, api_version, organization, **params)\u001b[0m\n\u001b[1;32m 104\u001b[0m \u001b[0mheaders\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mheaders\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 105\u001b[0m \u001b[0mstream\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mstream\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 106\u001b[0;31m \u001b[0mrequest_id\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mrequest_id\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 107\u001b[0m )\n\u001b[1;32m 108\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;32m/usr/local/lib/python3.7/dist-packages/openai/api_requestor.py\u001b[0m in \u001b[0;36mrequest\u001b[0;34m(self, method, url, params, headers, files, stream, request_id)\u001b[0m\n\u001b[1;32m 118\u001b[0m \u001b[0mfiles\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mfiles\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 119\u001b[0m \u001b[0mstream\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mstream\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 120\u001b[0;31m \u001b[0mrequest_id\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mrequest_id\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 121\u001b[0m )\n\u001b[1;32m 122\u001b[0m \u001b[0mresp\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mgot_stream\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_interpret_response\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mresult\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstream\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;32m/usr/local/lib/python3.7/dist-packages/openai/api_requestor.py\u001b[0m in \u001b[0;36mrequest_raw\u001b[0;34m(self, method, url, params, supplied_headers, files, stream, request_id)\u001b[0m\n\u001b[1;32m 297\u001b[0m \u001b[0mfiles\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mfiles\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 298\u001b[0m \u001b[0mstream\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mstream\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 299\u001b[0;31m \u001b[0mtimeout\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mTIMEOUT_SECS\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 300\u001b[0m )\n\u001b[1;32m 301\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mrequests\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexceptions\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mRequestException\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;32m/usr/local/lib/python3.7/dist-packages/requests/sessions.py\u001b[0m in \u001b[0;36mrequest\u001b[0;34m(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)\u001b[0m\n\u001b[1;32m 585\u001b[0m }\n\u001b[1;32m 586\u001b[0m \u001b[0msend_kwargs\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mupdate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msettings\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 587\u001b[0;31m \u001b[0mresp\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mprep\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0msend_kwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 588\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 589\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mresp\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;32m/usr/local/lib/python3.7/dist-packages/requests/sessions.py\u001b[0m in \u001b[0;36msend\u001b[0;34m(self, request, **kwargs)\u001b[0m\n\u001b[1;32m 699\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 700\u001b[0m \u001b[0;31m# Send the request\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 701\u001b[0;31m \u001b[0mr\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0madapter\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrequest\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 702\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 703\u001b[0m \u001b[0;31m# Total elapsed time of the request (approximately)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;32m/usr/local/lib/python3.7/dist-packages/requests/adapters.py\u001b[0m in \u001b[0;36msend\u001b[0;34m(self, request, stream, timeout, verify, cert, proxies)\u001b[0m\n\u001b[1;32m 497\u001b[0m \u001b[0mdecode_content\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 498\u001b[0m \u001b[0mretries\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmax_retries\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 499\u001b[0;31m \u001b[0mtimeout\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtimeout\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 500\u001b[0m )\n\u001b[1;32m 501\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;32m/usr/local/lib/python3.7/dist-packages/urllib3/connectionpool.py\u001b[0m in \u001b[0;36murlopen\u001b[0;34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, **response_kw)\u001b[0m\n\u001b[1;32m 708\u001b[0m \u001b[0mbody\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mbody\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 709\u001b[0m \u001b[0mheaders\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mheaders\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 710\u001b[0;31m \u001b[0mchunked\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mchunked\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 711\u001b[0m )\n\u001b[1;32m 712\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;32m/usr/local/lib/python3.7/dist-packages/urllib3/connectionpool.py\u001b[0m in \u001b[0;36m_make_request\u001b[0;34m(self, conn, method, url, timeout, chunked, **httplib_request_kw)\u001b[0m\n\u001b[1;32m 447\u001b[0m \u001b[0;31m# Python 3 (including for exceptions like SystemExit).\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 448\u001b[0m \u001b[0;31m# Otherwise it looks like a bug in the code.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 449\u001b[0;31m \u001b[0msix\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mraise_from\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0me\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 450\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mSocketTimeout\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mBaseSSLError\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mSocketError\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 451\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_raise_timeout\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0merr\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0me\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0murl\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0murl\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtimeout_value\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mread_timeout\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;32m/usr/local/lib/python3.7/dist-packages/urllib3/packages/six.py\u001b[0m in \u001b[0;36mraise_from\u001b[0;34m(value, from_value)\u001b[0m\n","\u001b[0;32m/usr/local/lib/python3.7/dist-packages/urllib3/connectionpool.py\u001b[0m in \u001b[0;36m_make_request\u001b[0;34m(self, conn, method, url, timeout, chunked, **httplib_request_kw)\u001b[0m\n\u001b[1;32m 442\u001b[0m \u001b[0;31m# Python 3\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 443\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 444\u001b[0;31m \u001b[0mhttplib_response\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mconn\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgetresponse\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 445\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mBaseException\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 446\u001b[0m \u001b[0;31m# Remove the TypeError from the exception chain in\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;32m/usr/lib/python3.7/http/client.py\u001b[0m in \u001b[0;36mgetresponse\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 1371\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1372\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1373\u001b[0;31m \u001b[0mresponse\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbegin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1374\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mConnectionError\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1375\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mclose\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;32m/usr/lib/python3.7/http/client.py\u001b[0m in \u001b[0;36mbegin\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 317\u001b[0m \u001b[0;31m# read until we get a non-100 response\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 318\u001b[0m \u001b[0;32mwhile\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 319\u001b[0;31m \u001b[0mversion\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstatus\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mreason\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_read_status\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 320\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mstatus\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0mCONTINUE\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 321\u001b[0m \u001b[0;32mbreak\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;32m/usr/lib/python3.7/http/client.py\u001b[0m in \u001b[0;36m_read_status\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 278\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 279\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_read_status\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 280\u001b[0;31m \u001b[0mline\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreadline\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0m_MAXLINE\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"iso-8859-1\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 281\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mline\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0m_MAXLINE\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 282\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mLineTooLong\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"status line\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;32m/usr/lib/python3.7/socket.py\u001b[0m in \u001b[0;36mreadinto\u001b[0;34m(self, b)\u001b[0m\n\u001b[1;32m 587\u001b[0m \u001b[0;32mwhile\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 588\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 589\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_sock\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrecv_into\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mb\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 590\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mtimeout\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 591\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_timeout_occurred\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;32m/usr/lib/python3.7/ssl.py\u001b[0m in \u001b[0;36mrecv_into\u001b[0;34m(self, buffer, nbytes, flags)\u001b[0m\n\u001b[1;32m 1069\u001b[0m \u001b[0;34m\"non-zero flags not allowed in calls to recv_into() on %s\"\u001b[0m \u001b[0;34m%\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1070\u001b[0m self.__class__)\n\u001b[0;32m-> 1071\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnbytes\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbuffer\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1072\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1073\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0msuper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrecv_into\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbuffer\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnbytes\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mflags\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;32m/usr/lib/python3.7/ssl.py\u001b[0m in \u001b[0;36mread\u001b[0;34m(self, len, buffer)\u001b[0m\n\u001b[1;32m 927\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 928\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mbuffer\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 929\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_sslobj\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbuffer\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 930\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 931\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_sslobj\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;31mKeyboardInterrupt\u001b[0m: "]}]},{"cell_type":"code","source":["sentiment_results = TextClassifier.classify_sentiments(classify_dict)"],"metadata":{"id":"lDRMUhJ8pvZ5","executionInfo":{"status":"ok","timestamp":1657267143287,"user_tz":-120,"elapsed":6652,"user":{"displayName":"Marcus Ascard","userId":"03011699740768629907"}}},"execution_count":75,"outputs":[]},{"cell_type":"code","source":["new_data = TextClassifier.analyze_sentiment(classify_dict)"],"metadata":{"id":"xV3AapTKB8TI","executionInfo":{"status":"ok","timestamp":1657267717134,"user_tz":-120,"elapsed":1226,"user":{"displayName":"Marcus Ascard","userId":"03011699740768629907"}}},"execution_count":107,"outputs":[]},{"cell_type":"code","source":["# Insert new predictions in data dictionary\n","for key, value in classify_dict.items():\n"," data_dict[key] = value\n","\n","# We have now made all of our API calls\n","# -> Save updated dict as pkl file\n","os.chdir(\"/content/drive/MyDrive/Softhouse-Twitter-Analyzer/\") \n","a_file = open(\"data_dict.pkl\", \"wb\")\n","pickle.dump(data_dict, a_file)\n","a_file.close()\n","os.chdir(\"/content\")"],"metadata":{"id":"9F5mzXp4px9Q","executionInfo":{"status":"ok","timestamp":1657267720919,"user_tz":-120,"elapsed":239,"user":{"displayName":"Marcus Ascard","userId":"03011699740768629907"}}},"execution_count":108,"outputs":[]},{"cell_type":"code","source":["data_dict"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"uTTc6hrlqD2R","executionInfo":{"status":"ok","timestamp":1657281204293,"user_tz":-120,"elapsed":528,"user":{"displayName":"Marcus Ascard","userId":"03011699740768629907"}},"outputId":"ff2405eb-408a-4157-8b2e-2f63570c8607"},"execution_count":252,"outputs":[{"output_type":"execute_result","data":{"text/plain":["{'Bra att parterna förhandlar. Men om regeringen håller fast vid punkt 44 kommer det leda till marknadshyror. Det blir en förhandling under hot där hyresgästerna förlorar. Det här är oseriöst och politisk teater för att förhala processen. Ta ansvar för landet och stryk punkt 44.': {'hour': '09',\n"," 'nlikes': 6724,\n"," 'nreplies': 643,\n"," 'nretweets': 730,\n"," 'sentiment': 'criticism',\n"," 'target': 'The Swedish government',\n"," 'topic': ['Swedish politics', 'Rental market', 'Government policy']},\n"," 'Centerpartiet har nu deklarerat att de är beredda att släppa kravet på marknadshyror i januariavtalet. Det är ett positivt besked för landets hyresgäster och alla tusentals människor har skrivit på namnlistor, delat flygblad och kampanjat på alla sätt som gått under rådande läge.': {'hour': '14',\n"," 'nlikes': 4231,\n"," 'nreplies': 172,\n"," 'nretweets': 290,\n"," 'sentiment': 'praise',\n"," 'target': 'Centerpartiet',\n"," 'topic': ['Swedish politics', 'Centerpartiet', 'Market rents']},\n"," 'Det finns ingen heder i förtryck. Det är att begå våld på en människas frihet. Alldeles för många tvingas lida under detta förtryck. Det bedrivs inte av en pytteliten minoritet. Straffen för dessa brott måste vara hårda. Skriver med @nikeorbrink. https://t.co/IbuURS0UaP': {'hour': '12',\n"," 'nlikes': 1267,\n"," 'nreplies': 51,\n"," 'nretweets': 112,\n"," 'sentiment': 'criticism',\n"," 'target': 'N/A',\n"," 'topic': ['Crime', 'Human rights', 'Punishment']},\n"," 'Det här handlar om tryggheten för 3 miljoner hyresgäster. Marknadshyror hör inte hemma i Sverige. https://t.co/1SEt9b5JF3': {'hour': '13',\n"," 'nlikes': 556,\n"," 'nreplies': 70,\n"," 'nretweets': 74,\n"," 'sentiment': 'opposition',\n"," 'target': 'marknadshyror',\n"," 'topic': ['Swedish politics', 'Rent control', 'Housing policy']},\n"," 'Det är detta envetna arbete för rätten till bostäder som vanliga löntagare, barnfamiljer, ungdomar och pensionärer har råd med, som burit frukt. Det politiska läget är fortfarande svårt. Men jag är stolt över att ha varit delaktig i att Sveriges hyresgäster fått sin röst hörd.': {'hour': '14',\n"," 'nlikes': 1743,\n"," 'nreplies': 68,\n"," 'nretweets': 89,\n"," 'sentiment': 'proud',\n"," 'target': '\"Sveriges hyresgäster\"',\n"," 'topic': ['Swedish politics', 'Housing', \"Workers' rights\"]},\n"," 'Detta är inget mindre än en skandal. Regeringen måste nu se till att både amerikaner och danskar lägger korten på bordet. https://t.co/aq9DI0DWtE': {'hour': '05',\n"," 'nlikes': 172,\n"," 'nreplies': 20,\n"," 'nretweets': 20,\n"," 'sentiment': 'criticism',\n"," 'target': 'The Swedish government',\n"," 'topic': ['Politics', 'Diplomacy', 'Sweden']},\n"," 'Du ska kunna lita på att du får vård i tid, en trygg ålderdom och att polisen kommer när du ringer. Då måste välfärdens finansiering hålla ihop. Vi föreslår bland annat bidragstak och hembesök hos alla bidragstagare för att bryta långtidsarbetslösheten. https://t.co/qfhllTK4mM': {'hour': '17',\n"," 'nlikes': 1803,\n"," 'nreplies': 191,\n"," 'nretweets': 133,\n"," 'sentiment': 'statements',\n"," 'target': 'N/A',\n"," 'topic': ['Swedish welfare system', 'Funding', 'Unemployment']},\n"," 'En polisman beskjuten till döds i tjänsten. En förfärlig händelse. Något som aldrig någonsin ska få hända. Mina tankar är med familjen och de anhöriga. https://t.co/bZ5ABVj6aW': {'hour': '06',\n"," 'nlikes': 879,\n"," 'nreplies': 75,\n"," 'nretweets': 58,\n"," 'sentiment': 'sadness',\n"," 'target': '\"En polisman beskjuten till döds i tjänsten.\"',\n"," 'topic': ['Crime', 'Violence', 'Death']},\n"," 'Fast jag föddes iofs inte 197 cm lång.': {'hour': '11',\n"," 'nlikes': 191,\n"," 'nreplies': 12,\n"," 'nretweets': 1,\n"," 'sentiment': 'statements',\n"," 'target': '\"iofs\"',\n"," 'topic': ['Birth', 'Height']},\n"," 'Fruktansvärda uppgifter ifrån Örebro idag. Mina tankar är med offrens anhöriga och vänner. En mycket tung dag. https://t.co/NsedZ8iTSc': {'hour': '20',\n"," 'nlikes': 173,\n"," 'nreplies': 8,\n"," 'nretweets': 8,\n"," 'sentiment': 'sadness',\n"," 'target': '\"offrens anhöriga och vänner\"',\n"," 'topic': ['Crime', 'Violence', 'Grief']},\n"," 'Förslaget om marknadshyror skulle vara en katastrof för Sveriges hyresgäster och ett stort systemskifte. Höjda hyror, mer otrygghet. Regeringen kan inte lägga fram förslag om marknadshyror, det har vi sagt från början. Nu måste vi prata med varandra och hitta vägar framåt.': {'hour': '12',\n"," 'nlikes': 889,\n"," 'nreplies': 92,\n"," 'nretweets': 102,\n"," 'sentiment': 'opposition',\n"," 'target': 'The Swedish government',\n"," 'topic': ['Swedish housing', 'Rental prices', 'Government policy']},\n"," 'Glad midsommar! Från V önskar vi att fler partier öppnar för samarbete nu. Vi vill att Stefan Löfven kommer tillbaka, nu när marknadshyrorna är borta, och vi hoppas på samarbete kring budgeten i höst.': {'hour': '12',\n"," 'nlikes': 1967,\n"," 'nreplies': 266,\n"," 'nretweets': 80,\n"," 'sentiment': 'support',\n"," 'target': 'Vänsterpartiet',\n"," 'topic': ['Swedish politics',\n"," 'The Swedish Social Democratic Party',\n"," 'The Swedish Moderate Party']},\n"," 'Glädjande besked. Nu måste humanitärt bistånd sättas in i Gaza omedelbart. Den långsiktiga freden kräver att den israeliska ockupationen upphör och bosättarna drar sig tillbaka. https://t.co/yrgass2jMR': {'hour': '08',\n"," 'nlikes': 356,\n"," 'nreplies': 42,\n"," 'nretweets': 35,\n"," 'sentiment': 'support',\n"," 'target': '\"humanitarian aid in Gaza\"',\n"," 'topic': ['Israel-Palestine conflict',\n"," 'Humanitarian aid',\n"," 'Long-term peace']},\n"," 'Grattis älskade Göteborg som fyller 400 år idag! ❤️ (ThomasO design) https://t.co/94L9t6dWKY': {'hour': '06',\n"," 'nlikes': 322,\n"," 'nreplies': 10,\n"," 'nretweets': 21,\n"," 'sentiment': 'praise',\n"," 'target': 'Göteborg',\n"," 'topic': ['Swedish city of Gothenburg', 'th anniversary', 'ThomasO design']},\n"," 'Håller tummarna för Tusse. Galant genomfört. #Eurovision': {'hour': '21',\n"," 'nlikes': 272,\n"," 'nreplies': 16,\n"," 'nretweets': 8,\n"," 'sentiment': 'praise',\n"," 'target': 'Tusse',\n"," 'topic': ['Music', 'Eurovision', 'Sweden']},\n"," 'Hårddragen rubrik. Om Vänsterpartiets mandat krävs för en budget kräver det självklart förhandling med oss. Det är uteslutet för Vänsterpartiet att rösta på en budget vi inte har förhandlat. https://t.co/RLVUmZe3ZZ': {'hour': '16',\n"," 'nlikes': 659,\n"," 'nreplies': 88,\n"," 'nretweets': 74,\n"," 'sentiment': 'disagreement',\n"," 'target': 'Vänsterpartiet',\n"," 'topic': ['Swedish politics', 'Left party', 'Budget']},\n"," 'Ja se där. Mer än avsiktsförklaringen mellan Sverige, Finland och Turkiet kan ha påverkat detta. https://t.co/wW1ZVe7T8Y': {'hour': '19',\n"," 'nlikes': 52,\n"," 'nreplies': 6,\n"," 'nretweets': 5,\n"," 'sentiment': 'statements',\n"," 'target': 'The tweet is aimed at the Swedish government.',\n"," 'topic': ['Foreign policy', 'Sweden', 'Finland', 'Turkey']},\n"," 'Jag hoppas att de som tidigare låtit prestige och låsningar styra nu är beredda att samtala. Vi vill bidra till att Stefan Löfven fortsätter som statsminister, men det blir utan marknadshyrorna. Vår dörr står öppen.': {'hour': '11',\n"," 'nlikes': 4508,\n"," 'nreplies': 379,\n"," 'nretweets': 282,\n"," 'sentiment': 'support',\n"," 'target': 'Stefan Löfven',\n"," 'topic': ['Swedish politics', 'The Social Democrats', 'Stefan Löfven']},\n"," 'Jag vill bara föra till protokollet att jag nog inte kommer leverera ett mer meme-vänligt ansiktsuttryck under den här mandatperioden. Jag har det helt enkelt inte i mig. Efter valet kanske det kan levereras ett nytt. Tills dess är det denna som gäller. https://t.co/x7HiSGh2Rv': {'hour': '07',\n"," 'nlikes': 5593,\n"," 'nreplies': 250,\n"," 'nretweets': 198,\n"," 'sentiment': 'statements',\n"," 'target': 'N/A',\n"," 'topic': ['Swedish politics', 'Social media', 'Memes']},\n"," 'Marknadshyror skulle få enorm påverkan på hyrorna. Även om reglerna till en början endast gäller nya bostäder. Bara om några år kommer var femte stockholmare att bo i en nyproducerad bostad exempelvis. https://t.co/pFVB30ztO3': {'hour': '05',\n"," 'nlikes': 270,\n"," 'nreplies': 27,\n"," 'nretweets': 52,\n"," 'sentiment': 'predictions',\n"," 'target': 'Stockholm',\n"," 'topic': ['Real estate', 'Rental prices', 'New construction']},\n"," 'Men nu är verkligheten alltså ikapp oss och förnuftet tycks vara på väg tillbaka. Det är med stor glädje jag mottar Vattenfalls besked idag. Det är inte en dag för tidigt som planerna för ny kärnkraft på Ringhals återupptas.': {'hour': '11',\n"," 'nlikes': 57,\n"," 'nreplies': 1,\n"," 'nretweets': 5,\n"," 'sentiment': 'praise',\n"," 'target': 'Vattenfalls',\n"," 'topic': ['Nuclear power', 'Vattenfalls']},\n"," 'Mycket allvarliga uppgifter om att USA har spionerat på svenska politiker och tjänstemän. Regeringen behöver omedelbart kalla till sig USAs ambassad för att klarlägga vad det är som har hänt.': {'hour': '17',\n"," 'nlikes': 583,\n"," 'nreplies': 58,\n"," 'nretweets': 57,\n"," 'sentiment': 'criticism',\n"," 'target': 'USA',\n"," 'topic': ['Espionage', 'Sweden', 'United States']},\n"," 'Nedmonteringen av kärnkraften i södra Sverige som regeringen ägnat sig åt de senaste två mandatperioderna har gett mycket konkreta konsekvenser både för hushållen och industrin. Sverige är i dag uppdelat elektriskt. Systemet är för svagt för att hålla ihop.': {'hour': '11',\n"," 'nlikes': 51,\n"," 'nreplies': 1,\n"," 'nretweets': 8,\n"," 'sentiment': 'criticism',\n"," 'target': 'Regeringen',\n"," 'topic': ['Nuclear power', 'Sweden', 'Electricity']},\n"," 'Nu är det tid att ta ansvar för att Sverige ska kunna regeras.\\xa0Vi är villiga att samtala, förhandla och hitta lösningar med regeringen och C. Ska inte talmansrundorna landa i extraval måste vi sätta oss ner i samma rum och komma överens. Det förväntar sig väljarna av oss nu.': {'hour': '16',\n"," 'nlikes': 1974,\n"," 'nreplies': 164,\n"," 'nretweets': 150,\n"," 'sentiment': 'agreement',\n"," 'target': 'The Swedish people',\n"," 'topic': ['Swedish politics', 'Government formation', 'Extra elections']},\n"," 'Och robothundarna gillar mig. 🐕': {'hour': '15',\n"," 'nlikes': 135,\n"," 'nreplies': 2,\n"," 'nretweets': 2,\n"," 'sentiment': 'praise',\n"," 'target': 'robothundarna',\n"," 'topic': ['Pets', 'Dogs', 'Robots']},\n"," 'Oerhört allvarliga uppgifter om dödsskjutningar. Nu behövs krafttag mot insmugglingen av vapen och narkotika. Men också mot arbetslöshet, bostadsbrist och segregation. Ett jämlikt samhälle är det bästa värnet mot gängbrottslighet.': {'hour': '08',\n"," 'nlikes': 948,\n"," 'nreplies': 107,\n"," 'nretweets': 84,\n"," 'sentiment': 'statements',\n"," 'target': 'The Swedish government',\n"," 'topic': ['Crime', 'Gun violence', 'Drug trafficking']},\n"," 'Orimligt. Börja med att betala tillbaka stödet till skattebetalarna. https://t.co/LvnQ6kz7cf': {'hour': '12',\n"," 'nlikes': 556,\n"," 'nreplies': 34,\n"," 'nretweets': 82,\n"," 'sentiment': 'opinion',\n"," 'target': 'The Swedish government',\n"," 'topic': ['Swedish Politics', 'Taxation', 'Welfare']},\n"," 'Pensionsgruppen krackelerar och pensionerna är idag rekordlåga. Det är en skandal att systemet underfinansierats under så lång tid. Nu får pensionärerna stå för notan. Vill man efter valet ha vårt stöd måste man sätta sig ned och prata med oss om hur vi höjer pensionerna.': {'hour': '19',\n"," 'nlikes': 358,\n"," 'nreplies': 27,\n"," 'nretweets': 51,\n"," 'sentiment': 'criticism',\n"," 'target': 'Pensionsgruppen',\n"," 'topic': ['Pensions', 'Retirement', 'Finances']},\n"," 'Pinsamt. Morgan Johansson måste vara svensk mästare i att skylla ifrån sig. Titta på utvecklingen. Finns det något annat statsråd i modern tid som misslyckats på det sätt han gjort? https://t.co/BrTE5Jv2Xf': {'hour': '16',\n"," 'nlikes': 4777,\n"," 'nreplies': 373,\n"," 'nretweets': 445,\n"," 'sentiment': 'criticism',\n"," 'target': 'N/A',\n"," 'topic': ['Swedish politics',\n"," 'The Swedish Minister for Health and Social Affairs']},\n"," 'Regeringen vill att hyresgästerna snart ska få kraftigt höjda hyror. Samtidigt får marknadshyror ingen effekt på nyproduktionen. Det var viktigt att ge besked om fastighetsskatten. Men något liknande löfte får alltså inte hyresgästerna? https://t.co/maaiEbOo3j': {'hour': '08',\n"," 'nlikes': 259,\n"," 'nreplies': 27,\n"," 'nretweets': 53,\n"," 'sentiment': 'criticism',\n"," 'target': 'The Swedish government',\n"," 'topic': ['Swedish government', 'Housing policy', 'Tax policy']},\n"," 'Som väntat fanns det inget stöd för en högernationalistisk regering. Nu är det dags för det som utgör den socialdemokratiska statsministerns regeringsunderlag att samla sig.': {'hour': '08',\n"," 'nlikes': 1683,\n"," 'nreplies': 205,\n"," 'nretweets': 102,\n"," 'sentiment': 'opposition',\n"," 'target': 'The right-wing nationalist government',\n"," 'topic': ['Swedish politics', 'Left-wing politics', 'Right-wing politics']},\n"," 'Svensk vinst och publikrekord när Sverige efter lite tvekan körde över Brasilien på Friends. Sedan Nato på det. Och besked om ny svensk kärnkraft vid lunch idag. Hårt arbete ger resultat i alla väder.': {'hour': '18',\n"," 'nlikes': 745,\n"," 'nreplies': 21,\n"," 'nretweets': 25,\n"," 'sentiment': 'praise',\n"," 'target': 'Sverige',\n"," 'topic': ['Sports', 'Politics']},\n"," 'Sverige har seglat åt fel håll i åtta år och vi har brottsstatistiken som bevisar det. När skeppet seglar åt fel håll och inte lägger om kursen så är det inte skeppets fel. Då är det kapten och styrman som behöver bytas ut. https://t.co/0XFRsmCxSk': {'hour': '11',\n"," 'nlikes': 2190,\n"," 'nreplies': 158,\n"," 'nretweets': 120,\n"," 'sentiment': 'criticism',\n"," 'target': 'N/A',\n"," 'topic': ['Politics', 'Sweden', 'Crime']},\n"," 'Sveriges försvar behöver stärkas snabbt. När vi nu ska gå med i Nato, spelar vårt lands ambitionsnivå stor betydelse. Vi vill att Sverige når 2 procent av BNP redan 2025. Läs @MikaelOscarsson, med företrädare från M, SD och L. https://t.co/tnoBXAKB8j': {'hour': '11',\n"," 'nlikes': 564,\n"," 'nreplies': 46,\n"," 'nretweets': 27,\n"," 'sentiment': 'opinion',\n"," 'target': 'N/A',\n"," 'topic': ['Swedish defense', 'NATO membership', 'Swedish ambitions']},\n"," 'Tack för allt stöd, det är vi i rörelsen som tillsammans stått upp för hyresgästerna och den svenska modellen. Här kommer sju sorters blommor till huvudkudden! 🌺🌸🌼🌻🌹🌷🥀': {'hour': '12',\n"," 'nlikes': 860,\n"," 'nreplies': 32,\n"," 'nretweets': 18,\n"," 'sentiment': 'praise',\n"," 'target': 'The Swedish Model',\n"," 'topic': ['Swedish politics', 'Housing', 'Flowers']},\n"," 'Tanken som slår mig är att det kanske inte var en slump att ingenjörerna som planerade systemet byggde 12 reaktorer i södra Sverige. Att tro att det inte skulle ge några konsekvenser att minska antalet reaktorer till 6 är hybris på en nivå inte ens Socialdemokraterna brukar visa': {'hour': '11',\n"," 'nlikes': 55,\n"," 'nreplies': 3,\n"," 'nretweets': 8,\n"," 'sentiment': 'criticism',\n"," 'target': '\"att minska antalet reaktorer till 6\"',\n"," 'topic': ['Nuclear power', 'Engineering', 'Sweden']},\n"," 'Totalt mörker att ta del av den ondska som skett i Texas. Ännu en skolmassaker. Ännu en gång barn som mördas just i den miljö de ska kunna vara trygga i. Mina tankar är hos offren och alla anhöriga.': {'hour': '05',\n"," 'nlikes': 1247,\n"," 'nreplies': 58,\n"," 'nretweets': 21,\n"," 'sentiment': 'sadness',\n"," 'target': 'N/A',\n"," 'topic': ['Gun violence', 'School shootings', 'Children']},\n"," 'Tragiskt. Alla tankar till brottsoffret. Ge polisen alla chans att utred detta fruktansvärd brott på bästa sätt.': {'hour': '12',\n"," 'nlikes': 321,\n"," 'nreplies': 7,\n"," 'nretweets': 10,\n"," 'sentiment': 'sadness',\n"," 'target': 'The victim of the crime',\n"," 'topic': ['Crime', 'Victims', 'Police']},\n"," 'Trots att den svenska energipolitiken, regelverken och regeringens styrning av myndigheterna är riggade för att missgynna kärnkraften har alltså verkligheten nu kommit ikapp. Statens eget energibolag tittar seriöst på att bygga nya reaktorer.': {'hour': '11',\n"," 'nlikes': 64,\n"," 'nreplies': 2,\n"," 'nretweets': 8,\n"," 'sentiment': 'statements',\n"," 'target': 'Regeringen',\n"," 'topic': ['Swedish energy policy', 'Nuclear power']},\n"," 'Två unga män ihjälskjutna i Örebro. Samtidigt blir en skjutning i Uppsala knappt en nyhetsnotis. Sverige har akuta problem. Tryggheten är vår tids ödesfråga och regeringen är ytterst ansvarig.': {'hour': '06',\n"," 'nlikes': 3834,\n"," 'nreplies': 211,\n"," 'nretweets': 272,\n"," 'sentiment': 'fear',\n"," 'target': 'N/A',\n"," 'topic': ['Crime', 'Sweden']},\n"," 'Varför regeringskris för det här, Annie Lööf? https://t.co/ZJGzlCDqIn': {'hour': '06',\n"," 'nlikes': 786,\n"," 'nreplies': 56,\n"," 'nretweets': 111,\n"," 'sentiment': 'criticism',\n"," 'target': 'Annie Lööf',\n"," 'topic': ['Swedish politics', 'The Center Party', 'Annie Lööf']},\n"," 'Vattenfall meddelade idag att man arbetar med en förstudie för att bygga nya reaktorer vid Ringhals. Man siktar på små modulära reaktorer som ska kunna stå på plats 2030. https://t.co/rF2hkvQ3Bc': {'hour': '11',\n"," 'nlikes': 336,\n"," 'nreplies': 13,\n"," 'nretweets': 22,\n"," 'sentiment': 'statements',\n"," 'target': 'Vattenfall',\n"," 'topic': ['Nuclear power', 'Sweden', 'Vattenfall']},\n"," 'Vi gör det vi har sagt i två och ett halvt års tid, vi står vid vårt ord. Någon måste stå upp för Sveriges tre miljoner hyresgäster.': {'hour': '10',\n"," 'nlikes': 5345,\n"," 'nreplies': 408,\n"," 'nretweets': 356,\n"," 'sentiment': 'support',\n"," 'target': 'The Swedish Moderate Party',\n"," 'topic': ['Swedish politics', 'Housing', 'Promises']},\n"," 'Vi har förlorat åtta värdefulla år på grund av att S byggt sitt maktinnehav på att samarbeta med ett parti som sätter en avveckling av kärnkraften över både klimatarbetet och människors rätt till fria rika liv. Men nu blickar vi äntligen framåt!': {'hour': '11',\n"," 'nlikes': 315,\n"," 'nreplies': 21,\n"," 'nretweets': 31,\n"," 'sentiment': 'criticism',\n"," 'target': 'The Swedish Social Democratic Party',\n"," 'topic': ['Swedish politics', 'The Green Party', 'Nuclear power']},\n"," 'Vi håller vad vi lovat svenska folket. Vi sviker inte Sveriges hyresgäster. Vi har hela tiden sagt att det inte kan ske förhandlingar utifrån lagförslaget. Låt parterna förhandla utan hot.': {'hour': '09',\n"," 'nlikes': 3530,\n"," 'nreplies': 219,\n"," 'nretweets': 300,\n"," 'sentiment': 'agreement',\n"," 'target': 'The Swedish people',\n"," 'topic': ['Swedish politics',\n"," \"The Swedish government's housing policy\",\n"," \"The Swedish government's promise to not raise rents\"]},\n"," 'Vi minns alla hur S och MP i oktober 2014, så fort de fick chansen, stoppade Vattenfalls då pågående nybyggnadsprojekt som just syftade till att bygga vid Ringhals.': {'hour': '11',\n"," 'nlikes': 105,\n"," 'nreplies': 6,\n"," 'nretweets': 12,\n"," 'sentiment': 'opposition',\n"," 'target': 'The Swedish Social Democratic Party and the Swedish Green Party',\n"," 'topic': ['Swedish politics',\n"," 'The Social Democratic Party',\n"," 'The Moderate Party']},\n"," 'Vi politiker måste nu genast lägga om energipolitiken. Arbetet börjar så snart den liberala borgerliga regeringen tillträder. Kärnkraftsavvecklingen är inställd. Nu fokuserar vi på klimatomställningen och nyindustrialiseringen.': {'hour': '11',\n"," 'nlikes': 105,\n"," 'nreplies': 4,\n"," 'nretweets': 6,\n"," 'sentiment': 'agreement',\n"," 'target': 'politicians',\n"," 'topic': ['Politics', 'Climate change', 'Nuclear power']},\n"," 'Vissa värderingar är inte valbara. https://t.co/NwXRXcAZKi': {'hour': '11',\n"," 'nlikes': 3525,\n"," 'nreplies': 178,\n"," 'nretweets': 246,\n"," 'sentiment': 'statements',\n"," 'target': 'N/A',\n"," 'topic': ['Values', 'Morals', 'Ethics']},\n"," 'Vår statsministerkandidat är Stefan Löfven. Det är naturligt för en statsminister att vilja få igenom sin budget. När Liberalerna nu har lämnat samarbetet är vi beredda att erbjuda oss att ersätta dem i budgetförhandlingarna. Sverige måste kunna regeras till nästa val.': {'hour': '12',\n"," 'nlikes': 1823,\n"," 'nreplies': 127,\n"," 'nretweets': 119,\n"," 'sentiment': 'agreement',\n"," 'target': 'The Swedish people',\n"," 'topic': ['Swedish politics', 'The budget', 'Coalition negotiations']},\n"," 'Ännu en meningslös och vidrig masskjutning. Nu i Köpenhamn. Alla tankar till offren och deras anhöriga. ❤️🇩🇰': {'hour': '19',\n"," 'nlikes': 397,\n"," 'nreplies': 7,\n"," 'nretweets': 12,\n"," 'sentiment': 'sadness',\n"," 'target': 'The victims and their families',\n"," 'topic': ['Mass shooting', 'Copenhagen', 'Victims and families']},\n"," 'Äntligen enighet för att hantera de yttre hot som vårt land står inför. Vad krävs för att Sverige också på allvar ska ta itu med de stora inre hot som vi möter idag? Trots åtta år vid makten är Morgan Johanssons avsaknad av krisinsikt fortsatt total. https://t.co/Qa41q4Ctda': {'hour': '05',\n"," 'nlikes': 1632,\n"," 'nreplies': 150,\n"," 'nretweets': 146,\n"," 'sentiment': 'agreement',\n"," 'target': 'N/A',\n"," 'topic': ['Swedish politics', 'National security', 'Crime']},\n"," 'Är det någon som har sett till Annie Lööf? Är hon så angelägen om att höja hyrorna att hon är beredd att driva fram regeringskris? I politik måste man kunna kompromissa.': {'hour': '09',\n"," 'nlikes': 1642,\n"," 'nreplies': 226,\n"," 'nretweets': 156,\n"," 'sentiment': 'criticism',\n"," 'target': 'Annie Lööf',\n"," 'topic': ['Swedish politics', 'The Center Party', 'Compromise']},\n"," 'Örebro nu. Sänk elskatten. Bygg kärnkraft. Gärna vind också. Men idag blåser det typ noll. Och ger således noll el. Varför gjorde ni ansvariga partier med ”kärnkraftshat” för ögonen så här mot Sverige? Varför struntade ni i klimatet, människor och företag? https://t.co/35LvqR35Nu': {'hour': '07',\n"," 'nlikes': 917,\n"," 'nreplies': 96,\n"," 'nretweets': 100,\n"," 'sentiment': 'criticism',\n"," 'target': 'N/A',\n"," 'topic': ['Swedish politics', 'Renewable energy', 'Nuclear power']}}"]},"metadata":{},"execution_count":252}]},{"cell_type":"code","source":["TextClassifier.print_stats(data_dict)\n","#TextClassifier.print_results(data_dict) "],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"ZB1Bk9z4tmqW","executionInfo":{"status":"ok","timestamp":1657279694139,"user_tz":-120,"elapsed":483,"user":{"displayName":"Marcus Ascard","userId":"03011699740768629907"}},"outputId":"f5278a87-93aa-4bbe-8b8f-3903389e1f22"},"execution_count":248,"outputs":[{"output_type":"stream","name":"stdout","text":["Two targets with a sequence matching > 0.85 were detected: Vattenfalls AND Vattenfall\n","Merging targets...\n","\n","\u001b[1mUSER: \u001b[0m \n","\u001b[1mNBR OF TWEETS SCRAPED: \u001b[0m 53\n","\u001b[1mNBR OF DIFFERENT TOPICS: \u001b[0m 101 \n","\n","\u001b[1mTOPIC TOPIC FREQUENCY AVERAGE NBR OF LIKES AVERAGE NBR OF RETWEETS AVERAGE NBR OF REPLIES REACH AVERAGE\u001b[0m \n","Swedish politics 21 2446.19 183.95 4019 2216.38 \n","Left party 1 659.00 74.00 88 273.67 \n","Budget 1 659.00 74.00 88 273.67 \n","Left-wing politics 1 1683.00 102.00 205 663.33 \n","Right-wing politics 1 1683.00 102.00 205 663.33 \n","Crime 8 1405.50 101.25 767 757.92 \n","Violence 2 526.00 33.00 83 214.00 \n","Death 1 879.00 58.00 75 337.33 \n","The budget 1 1823.00 119.00 127 689.67 \n","Coalition negotiations 1 1823.00 119.00 127 689.67 \n","Government formation 1 1974.00 150.00 164 762.67 \n","Extra elections 1 1974.00 150.00 164 762.67 \n","Housing 3 2649.33 154.33 508 1103.89 \n","Flowers 1 860.00 18.00 32 303.33 \n","The Swedish Social Democratic Party 1 1967.00 80.00 266 771.00 \n","The Swedish Moderate Party 1 1967.00 80.00 266 771.00 \n","Workers' rights 1 1743.00 89.00 68 633.33 \n","Centerpartiet 1 4231.00 290.00 172 1564.33 \n","Market rents 1 4231.00 290.00 172 1564.33 \n","The Social Democrats 1 4508.00 282.00 379 1723.00 \n","Stefan Löfven 1 4508.00 282.00 379 1723.00 \n","The Swedish government's housing policy 1 3530.00 300.00 219 1349.67 \n","The Swedish government's promise to not raise rents 1 3530.00 300.00 219 1349.67 \n","Rental market 1 6724.00 730.00 643 2699.00 \n","Government policy 2 3806.50 416.00 735 1652.50 \n","The Center Party 2 1214.00 133.50 282 543.17 \n","Annie Lööf 1 786.00 111.00 56 317.67 \n","Promises 1 5345.00 356.00 408 2036.33 \n","Compromise 1 1642.00 156.00 226 674.67 \n","Rent control 1 556.00 74.00 70 233.33 \n","Housing policy 2 407.50 63.50 97 189.33 \n","Real estate 1 270.00 52.00 27 116.33 \n","Rental prices 2 579.50 77.00 119 258.50 \n","New construction 1 270.00 52.00 27 116.33 \n","Swedish housing 1 889.00 102.00 92 361.00 \n","Swedish city of Gothenburg 1 322.00 21.00 10 117.67 \n","th anniversary 1 322.00 21.00 10 117.67 \n","ThomasO design 1 322.00 21.00 10 117.67 \n","Swedish Politics 1 556.00 82.00 34 224.00 \n","Taxation 1 556.00 82.00 34 224.00 \n","Welfare 1 556.00 82.00 34 224.00 \n","Politics 4 803.00 42.75 203 349.58 \n","Diplomacy 1 172.00 20.00 20 70.67 \n","Sweden 9 838.33 57.78 486 460.70 \n","Grief 1 173.00 8.00 8 63.00 \n","Espionage 1 583.00 57.00 58 232.67 \n","United States 1 583.00 57.00 58 232.67 \n","Gun violence 2 1097.50 52.50 165 438.33 \n","Drug trafficking 1 948.00 84.00 107 379.67 \n","Pensions 1 358.00 51.00 27 145.33 \n","Retirement 1 358.00 51.00 27 145.33 \n","Finances 1 358.00 51.00 27 145.33 \n","Swedish government 1 259.00 53.00 27 113.00 \n","Tax policy 1 259.00 53.00 27 113.00 \n","Music 1 272.00 8.00 16 98.67 \n","Eurovision 1 272.00 8.00 16 98.67 \n","Israel-Palestine conflict 1 356.00 35.00 42 144.33 \n","Humanitarian aid 1 356.00 35.00 42 144.33 \n","Long-term peace 1 356.00 35.00 42 144.33 \n","Victims 1 321.00 10.00 7 112.67 \n","Police 1 321.00 10.00 7 112.67 \n","Pets 1 135.00 2.00 2 46.33 \n","Dogs 1 135.00 2.00 2 46.33 \n","Robots 1 135.00 2.00 2 46.33 \n","Birth 1 191.00 1.00 12 68.00 \n","Height 1 191.00 1.00 12 68.00 \n","Mass shooting 1 397.00 12.00 7 138.67 \n","Copenhagen 1 397.00 12.00 7 138.67 \n","Victims and families 1 397.00 12.00 7 138.67 \n","Renewable energy 1 917.00 100.00 96 371.00 \n","Nuclear power 8 237.50 23.50 141 134.00 \n","Foreign policy 1 52.00 5.00 6 21.00 \n","Finland 1 52.00 5.00 6 21.00 \n","Turkey 1 52.00 5.00 6 21.00 \n","Sports 1 745.00 25.00 21 263.67 \n","Climate change 1 105.00 6.00 4 38.33 \n","The Green Party 1 315.00 31.00 21 122.33 \n","The Social Democratic Party 1 105.00 12.00 6 41.00 \n","The Moderate Party 1 105.00 12.00 6 41.00 \n","Vattenfalls 1 57.00 5.00 1 21.00 \n","Engineering 1 55.00 8.00 3 22.00 \n","Electricity 1 51.00 8.00 1 20.00 \n","Swedish energy policy 1 64.00 8.00 2 24.67 \n","Vattenfall 1 336.00 22.00 13 123.67 \n","The Swedish Minister for Health and Social Affairs 1 4777.00 445.00 373 1865.00 \n","Values 1 3525.00 246.00 178 1316.33 \n","Morals 1 3525.00 246.00 178 1316.33 \n","Ethics 1 3525.00 246.00 178 1316.33 \n","National security 1 1632.00 146.00 150 642.67 \n","Human rights 1 1267.00 112.00 51 476.67 \n","Punishment 1 1267.00 112.00 51 476.67 \n","School shootings 1 1247.00 21.00 58 442.00 \n","Children 1 1247.00 21.00 58 442.00 \n","Swedish welfare system 1 1803.00 133.00 191 709.00 \n","Funding 1 1803.00 133.00 191 709.00 \n","Unemployment 1 1803.00 133.00 191 709.00 \n","Social media 1 5593.00 198.00 250 2013.67 \n","Memes 1 5593.00 198.00 250 2013.67 \n","Swedish defense 1 564.00 27.00 46 212.33 \n","NATO membership 1 564.00 27.00 46 212.33 \n","Swedish ambitions 1 564.00 27.00 46 212.33 \n","\n","\n","\u001b[1mNBR OF DIFFERENT SENTIMENTS: \u001b[0m 12 \n","\n","\u001b[1mSENTIMENT SENTIMENT FREQUENCY\u001b[0m\n","disagreement 1 \n","opposition 4 \n","sadness 5 \n","agreement 5 \n","praise 7 \n","support 4 \n","proud 1 \n","criticism 14 \n","predictions 1 \n","opinion 2 \n","statements 8 \n","fear 1 \n","\n","\n","\u001b[1mNBR OF DIFFERENT TARGETS: \u001b[0m 33 \n","\n","\u001b[1mTARGET TARGET FREQUENCY\u001b[0m\n","Vänsterpartiet 2 \n","The right-wing nationalist government 1 \n","\"En polisman beskjuten till döds i tjänsten.\" 1 \n","The Swedish people 3 \n","The Swedish Model 1 \n","\"Sveriges hyresgäster\" 1 \n","Centerpartiet 1 \n","Stefan Löfven 1 \n","The Swedish government 6 \n","Annie Lööf 2 \n","The Swedish Moderate Party 1 \n","marknadshyror 1 \n","Stockholm 1 \n","Göteborg 1 \n","\"offrens anhöriga och vänner\" 1 \n","USA 1 \n","Pensionsgruppen 1 \n","Tusse 1 \n","\"humanitarian aid in Gaza\" 1 \n","The victim of the crime 1 \n","robothundarna 1 \n","\"iofs\" 1 \n","The victims and their families 1 \n","N/A 11 \n","The tweet is aimed at the Swedish government. 1 \n","Sverige 1 \n","politicians 1 \n","The Swedish Social Democratic Party 1 \n","The Swedish Social Democratic Party and the Swedish Green Party 1 \n","Vattenfalls 1 \n","\"att minska antalet reaktorer till 6\" 1 \n","Regeringen 2 \n"]}]},{"cell_type":"code","source":["!pip install python-Levenshtein"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"iZ8jFgrp3Zm9","executionInfo":{"status":"ok","timestamp":1657267929633,"user_tz":-120,"elapsed":7273,"user":{"displayName":"Marcus Ascard","userId":"03011699740768629907"}},"outputId":"d1f5cb89-f56e-444e-c175-2f3eb8f989e4"},"execution_count":112,"outputs":[{"output_type":"stream","name":"stdout","text":["Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/\n","Collecting python-Levenshtein\n"," Downloading python-Levenshtein-0.12.2.tar.gz (50 kB)\n","\u001b[K |████████████████████████████████| 50 kB 3.0 MB/s \n","\u001b[?25hRequirement already satisfied: setuptools in /usr/local/lib/python3.7/dist-packages (from python-Levenshtein) (57.4.0)\n","Building wheels for collected packages: python-Levenshtein\n"," Building wheel for python-Levenshtein (setup.py) ... \u001b[?25l\u001b[?25hdone\n"," Created wheel for python-Levenshtein: filename=python_Levenshtein-0.12.2-cp37-cp37m-linux_x86_64.whl size=149863 sha256=4677e4ec35d76f247fe528052ab0a7b97a896b7c9d80d1372581899ed12302e2\n"," Stored in directory: /root/.cache/pip/wheels/05/5f/ca/7c4367734892581bb5ff896f15027a932c551080b2abd3e00d\n","Successfully built python-Levenshtein\n","Installing collected packages: python-Levenshtein\n","Successfully installed python-Levenshtein-0.12.2\n"]}]},{"cell_type":"code","source":["## C\n","\n","import itertools\n","from difflib import SequenceMatcher \n","\n","new_topic_list = [] \n","l = ['Vattenfalls', 'Vatten', 'Eldig själ', 'Vattna']\n","topic = \"Vattenfall\"\n","for s1 in l:\n"," matching_percentage = SequenceMatcher(None, s1, topic).ratio()\n"," print(matching_percentage)\n"," # if matching_percentage > 0.7:\n"," # print(s1 + \": \" + topic)\n"," #print(\"s1 = \" + s1 + \" \" \"s2 = \" + s2)\n"," #print(\"Topics: \" + s1 + \" & \" + s2 + \" \" + str(matching_percentage))\n","\n"," "],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"0dBZaK-h4z11","executionInfo":{"status":"ok","timestamp":1657283131482,"user_tz":-120,"elapsed":264,"user":{"displayName":"Marcus Ascard","userId":"03011699740768629907"}},"outputId":"0d204b18-c7e7-45fb-cb05-ebc21e5cf770"},"execution_count":257,"outputs":[{"output_type":"stream","name":"stdout","text":["0.9523809523809523\n","0.75\n","0.2\n","0.75\n"]}]}]}