<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Assignment 4b-BA
Step3:  Exercise 3
In this exercise, we are going to run VADER on our own tweets and evaluate it against the sentiment labels that we manually annotated for each tweet. We are going to make use of the following two functions
Step4:  Exercise 3a
You will now run VADER on the tweets you've collected. You will process each tweet using the code we have shown you above. The goal is add information about each tweet (i.e. in every iteration of the loop) to each of the three lists listed below. We can use these lists to compare the Vader output to the correct labels you provided. 
tweets
<ASSISTANT_TASK:>
Python Code:
import json
my_tweets = json.load(open('my_tweets.json'))
for id_, tweet_info in my_tweets.items():
    print(id_, tweet_info)
    break
Explanation: Assignment 4b-BA: Sentiment analysis using VADER
Due: Friday October 15, 2021, before 14:30
Please note that this is Assignment 4 for the Bachelor version of the Python course: Introduction to Python for Humanities and Social Sciences (L_AABAALG075)
Please submit your assignment (notebooks of parts 4a + 4b + JSON file) as a single .zip file. 
Please name your zip file with the following naming convention: ASSIGNMENT_4_FIRSTNAME_LASTNAME.zip
Please submit your assignment on Canvas: Assignments --> Assignment 4
If you have questions about this chapter, please contact us at cltl.python.course@gmail.com. Questions and answers will be collected in this Q&A document, so please check if your question has already been answered.
Credits
The notebooks in this block have been originally created by Marten Postma and Isa Maks. Adaptations were made by Filip Ilievski.
Part I: VADER assignments
Preparation (nothing to submit):
To be able to answer the VADER questions you need to know how the tool works. 
* Read more about the VADER tool in this blog.
* VADER provides 4 scores (positive, negative, neutral, compound). Be sure to understand what they mean and how they are calculated.
* VADER uses rules to handle linguistic phenomena such as negation and intensification. Be sure to understand which rules are used, how they work, and why they are important.
* VADER makes use of a sentiment lexicon. Have a look at the lexicon. Be sure to understand which information can be found there (lemma?, wordform?, part-of-speech?, polarity value?, word meaning?) What do all scores mean? You can inspect the README of the VADER system for more information.
Exercise 1
Consider the following sentences and their output as given by VADER. Analyze sentences 1 to 7, and explain the outcome for each sentence. Take into account both the rules applied by VADER and the lexicon that is used. You will find that some of the results are reasonable, but others are not. Explain what is going wrong or not when correct and incorrect results are produced. 
```
INPUT SENTENCE 1 I love apples
VADER OUTPUT {'neg': 0.0, 'neu': 0.192, 'pos': 0.808, 'compound': 0.6369}
INPUT SENTENCE 2 I don't love apples
VADER OUTPUT {'neg': 0.627, 'neu': 0.373, 'pos': 0.0, 'compound': -0.5216}
INPUT SENTENCE 3 I love apples :-)
VADER OUTPUT {'neg': 0.0, 'neu': 0.133, 'pos': 0.867, 'compound': 0.7579}
INPUT SENTENCE 4 These houses are ruins
VADER OUTPUT {'neg': 0.492, 'neu': 0.508, 'pos': 0.0, 'compound': -0.4404}
INPUT SENTENCE 5 These houses are certainly not considered ruins
VADER OUTPUT {'neg': 0.0, 'neu': 0.51, 'pos': 0.49, 'compound': 0.5867}
INPUT SENTENCE 6 He lies in the chair in the garden
VADER OUTPUT {'neg': 0.286, 'neu': 0.714, 'pos': 0.0, 'compound': -0.4215}
INPUT SENTENCE 7 This house is like any house
VADER OUTPUT {'neg': 0.0, 'neu': 0.667, 'pos': 0.333, 'compound': 0.3612}
```
Exercise 2: Collecting 25 tweets for evaluation
Collect 25 tweets. Try to find tweets that are interesting for sentiment analysis, e.g., very positive, neutral, and negative tweets. These could be your own tweets (typed in) or collected from the Twitter stream. You can simply copy-paste tweets into the JSON file. Do not attempt to crawl them!
We will store the tweets in the file my_tweets.json (use a text editor to edit).
For each tweet, you should insert:
sentiment analysis label: negative | neutral | positive (this you determine yourself, this is not done by a computer)
the text of the tweet
the Tweet-URL
from:
"1": {
        "sentiment_label": "",
        "text_of_tweet": "",
        "tweet_url": "",
to:
"1": {
        "sentiment_label": "positive",
        "text_of_tweet": "All across America people chose to get involved, get engaged and stand up. Each of us can make a difference, and all of us ought to try. So go keep changing the world in 2018.",
        "tweet_url" : "https://twitter.com/BarackObama/status/946775615893655552",
    },
You can load your tweets with the sentiment labels you provided in the following way:
End of explanation
def run_vader(nlp,
              textual_unit, 
              lemmatize=False, 
              parts_of_speech_to_consider=set(),
              verbose=0):
    
    Run VADER on a sentence from spacy
    
    :param str textual unit: a textual unit, e.g., sentence, sentences (one string)
    (by looping over doc.sents)
    :param bool lemmatize: If True, provide lemmas to VADER instead of words
    :param set parts_of_speech_to_consider:
    -empty set -> all parts of speech are provided
    -non-empty set: only these parts of speech are considered
    :param int verbose: if set to 1, information is printed
    about input and output
    
    :rtype: dict
    :return: vader output dict
    
    doc = nlp(textual_unit)
        
    input_to_vader = []
    for sent in doc.sents:
        for token in sent:
            
            if verbose >= 2:
                print(token, token.pos_)
            to_add = token.text
            if lemmatize:
                to_add = token.lemma_
                if to_add == '-PRON-': 
                    to_add = token.text
            if parts_of_speech_to_consider:
                if token.pos_ in parts_of_speech_to_consider:
                    input_to_vader.append(to_add) 
            else:
                input_to_vader.append(to_add)
    scores = vader_model.polarity_scores(' '.join(input_to_vader))
    
    if verbose >= 1:
        print()
        print('INPUT SENTENCE', sent)
        print('INPUT TO VADER', input_to_vader)
        print('VADER OUTPUT', scores)
    return scores
def vader_output_to_label(vader_output):
    
    map vader output e.g.,
    {'neg': 0.0, 'neu': 0.0, 'pos': 1.0, 'compound': 0.4215}
    to one of the following values:
    a) positive float -> 'positive'
    b) 0.0 -> 'neutral'
    c) negative float -> 'negative'
    
    :param dict vader_output: output dict from vader
    
    :rtype: str
    :return: 'negative' | 'neutral' | 'positive'
    
    compound = vader_output['compound']
    
    if compound < 0:
        return 'negative'
    elif compound == 0.0:
        return 'neutral'
    elif compound > 0.0:
        return 'positive'
    
assert vader_output_to_label( {'neg': 0.0, 'neu': 0.0, 'pos': 1.0, 'compound': 0.0}) == 'neutral'
assert vader_output_to_label( {'neg': 0.0, 'neu': 0.0, 'pos': 1.0, 'compound': 0.01}) == 'positive'
assert vader_output_to_label( {'neg': 0.0, 'neu': 0.0, 'pos': 1.0, 'compound': -0.01}) == 'negative'
import spacy
! python -m spacy download en_core_web_sm
nlp = spacy.load('en_core_web_sm')
from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer
vader_model = SentimentIntensityAnalyzer()
my_annotation = 'positive' # what you annotate yourself
sentence = "I like Python"
vader_output = run_vader(nlp, sentence)
vader_label = vader_output_to_label(vader_output)
accurate = my_annotation == vader_label
print()
print('SENTENCE', sentence) # the sentence
print('VADER OUTPUT', vader_output) # the VADER output
print('VADER LABEL', vader_label) # the VADER output mapped to a label, in this case 'positive'
print('MY ANNOTATION', my_annotation) # my annotation
print('ACCURACY', accurate) # did VADER predict the same label as my manual annotation?
Explanation: Exercise 3
In this exercise, we are going to run VADER on our own tweets and evaluate it against the sentiment labels that we manually annotated for each tweet. We are going to make use of the following two functions:
End of explanation
import json
my_tweets = json.load(open('my_tweets.json'))
tweets = []
all_vader_output = []
manual_annotation = []
for id_, tweet_info in my_tweets.items():
    the_tweet = tweet_info['text_of_tweet']
    vader_output = ''# run vader
    vader_label = ''# convert vader output to category
    
    tweets.append(the_tweet)
    all_vader_output.append(vader_label)
    manual_annotation.append(tweet_info['sentiment_label'])
Explanation: Exercise 3a
You will now run VADER on the tweets you've collected. You will process each tweet using the code we have shown you above. The goal is add information about each tweet (i.e. in every iteration of the loop) to each of the three lists listed below. We can use these lists to compare the Vader output to the correct labels you provided. 
tweets: append your tweet
all_vader_output: append the vader_label: negative | neutral | positive
manual_annotation: append your annotation: negative | neutral | positive
You can use the code snippet below as a starting point.
End of explanation
<END_TASK>