<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Eugenia </title>
    <description>The latest articles on Forem by Eugenia  (@ugis22).</description>
    <link>https://forem.com/ugis22</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F166594%2F4687a0c2-af4c-4ac1-ae80-d405b456016d.jpeg</url>
      <title>Forem: Eugenia </title>
      <link>https://forem.com/ugis22</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ugis22"/>
    <language>en</language>
    <item>
      <title>Using machine learning to understand customers behavior</title>
      <dc:creator>Eugenia </dc:creator>
      <pubDate>Wed, 29 May 2019 12:01:00 +0000</pubDate>
      <link>https://forem.com/ugis22/using-machine-learning-to-understand-customers-behavior-47po</link>
      <guid>https://forem.com/ugis22/using-machine-learning-to-understand-customers-behavior-47po</guid>
      <description>&lt;p&gt;&lt;a href="https://towardsdatascience.com/using-machine-learning-to-understand-customers-behavior-f41b567d3a50?source=rss-5515433d5913------2"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wuDrLiVt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2500/1%2AROmgayIXEU8QKwtqmSTaFg.jpeg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Not all clients are alike&lt;/p&gt;

&lt;p&gt;&lt;a href="https://towardsdatascience.com/using-machine-learning-to-understand-customers-behavior-f41b567d3a50?source=rss-5515433d5913------2"&gt;Continue reading on Towards Data Science »&lt;/a&gt;&lt;/p&gt;

</description>
      <category>datavisualization</category>
      <category>machinelearning</category>
      <category>tech</category>
      <category>datascience</category>
    </item>
    <item>
      <title>Discovering the essential tools for Named Entities Recognition</title>
      <dc:creator>Eugenia </dc:creator>
      <pubDate>Sat, 11 May 2019 20:06:01 +0000</pubDate>
      <link>https://forem.com/ugis22/discovering-the-essential-tools-for-named-entities-recognition-50ne</link>
      <guid>https://forem.com/ugis22/discovering-the-essential-tools-for-named-entities-recognition-50ne</guid>
      <description>&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*gM1g-IMKeR3yN3KyYcn4wA.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*gM1g-IMKeR3yN3KyYcn4wA.jpeg" alt=""&gt;&lt;/a&gt;Image source: &lt;a href="https://unsplash.com/photos/JChRnikx0tM"&gt;&lt;strong&gt;Unsplash&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  It’s all about the names!
&lt;/h4&gt;

&lt;p&gt;_“The letter is E …. Start!…” — _One of my brothers said.&lt;/p&gt;

&lt;p&gt;We began to crazily write down words that start with E in each category. Everyone wanted to win as many points as possible in that afternoon game.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Stop!!!!!” — _My sister announced suddenly — &lt;/em&gt;“I’m already done with all the categories”_.&lt;/p&gt;

&lt;p&gt;We stared at each other with disbelief.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Ok. Let’s start checking!” &lt;/em&gt;— I said.&lt;/p&gt;

&lt;p&gt;One by one, we start to enumerate the words we have entered under each category: fruits, places, names…&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“What about a color name?”&lt;/em&gt; — My other brother asked at one point.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Emerald…”&lt;/em&gt; — my sister said proudly.&lt;/p&gt;

&lt;p&gt;“&lt;em&gt;Noo! Noo! That’s not a color name!!!&lt;/em&gt;” — My two brothers complained loudly at the same time.&lt;/p&gt;

&lt;p&gt;_“Of course it is! If no one put a color name I get double points!” — _She replied happily.&lt;/p&gt;

&lt;p&gt;Every time we played &lt;a href="https://en.wikipedia.org/wiki/Scattergories"&gt;Scattergories&lt;/a&gt;, or &lt;em&gt;Tutti Frutti&lt;/em&gt; as it is commonly called in Argentina, we had the same discussion. The rules about color names changed every time.&lt;/p&gt;

&lt;p&gt;It all depended on the players of the day. Something happening to a lot of people playing that game as we learned after.&lt;/p&gt;

&lt;p&gt;It is easy for us to put words under categories. We can tell which word is a noun, an adjective or a verb in a text. We can point out the name of a person, an organization or a country.&lt;/p&gt;

&lt;p&gt;This is not an easy task for a machine. However, we have come a long way.&lt;/p&gt;

&lt;p&gt;Now, we don’t need to spend long hours reading long texts anymore. We can use machine learning algorithms to extract useful information from them.&lt;/p&gt;

&lt;p&gt;I remember the first time I read about &lt;em&gt;Natural Language Processing (NLP).&lt;/em&gt; It was hard for me to picture how an algorithm can recognize words. How it was able to identify their meaning. Or select which type of words they were.&lt;/p&gt;

&lt;p&gt;I was even confused about how to start. It was so much information. After going around in circles, I started by asking myself what exactly I had to do with NLP.&lt;/p&gt;

&lt;p&gt;I had several corpora of text coming from different websites I have scraped. My main goal was to extract and classify the names of persons, organizations, and locations, among others.&lt;/p&gt;

&lt;p&gt;What I had between my hands was a _Named Entities Recognition (NER) _task.&lt;/p&gt;

&lt;p&gt;These names, known as entities, are often represented by proper names. They share common semantic properties. And they usually appear in similar contexts.&lt;/p&gt;

&lt;p&gt;Why did I want to extract these entities? Well, there are many reasons for doing it.&lt;/p&gt;

&lt;p&gt;We use words to communicate with each other. We tell stories. We state our thoughts. We communicate our feelings. We claim what we like, dislike or need.&lt;/p&gt;

&lt;p&gt;Nowadays, we mostly deliver things through written text. We tweet. We write in a blog. The news appears on a website. So written words are a powerful tool.&lt;/p&gt;

&lt;p&gt;Let’s imagine that we have the superpower of knowing which people, organizations, companies, brands or locations are mentioned in every news, tweet or post in the web.&lt;/p&gt;

&lt;p&gt;We could detect and assign relevant tags for each article or post. This will help us distribute them in defined categories. We could match them specifically with the people that are interested in reading about that type of entities. So we would act as classifiers.&lt;/p&gt;

&lt;p&gt;We could also do the reverse process. Anyone can ask us a specific question. Using the keywords, we would also be capable of recommending articles, websites or post very efficiently. Sounds familiar?&lt;/p&gt;

&lt;p&gt;We can go even further and recommend products or brands. If someone complains about a particular brand or product, we can easily assign it to the most idoneous department in a matter of seconds. So we are going to be excellent customer support.&lt;/p&gt;

&lt;p&gt;As you can guess, NER is a very useful tool. However, everything comes at a price.&lt;/p&gt;

&lt;p&gt;Before an algorithm can recognize entities in a text, it should be able to classify words in verbs, nouns, adjectives. Together they are referred to as &lt;em&gt;parts of speech&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The task of labeling them is called &lt;em&gt;part-of-speech tagging&lt;/em&gt;, or &lt;strong&gt;POS-tagging&lt;/strong&gt;. The method label a word based on its context and definition.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*zUTAx-w5Gi9ROFq30vfeyw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*zUTAx-w5Gi9ROFq30vfeyw.png" alt=""&gt;&lt;/a&gt;Example of POS-tagging a text.&lt;/p&gt;

&lt;p&gt;Take as an example the sentences: “The new technologies impact all the world” and “In order to reduce global warming impact, we should do something now”. “&lt;em&gt;Impact&lt;/em&gt;” has two different meanings in each sentence.&lt;/p&gt;

&lt;p&gt;There are several supervised learning algorithms that can be picked for this assignment:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Lexical Based Methods.&lt;/em&gt; They assign the most frequently POS co-occurring with a word in the training set.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Probabilistic Methods.&lt;/em&gt; They consider the probability of the occurrence of specific tag sequence and assign it based on that.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Rule-Based Methods.&lt;/em&gt; They create rules to represent the structure of the sequence of words appearing in the training set. The POS is assigned based on these rules.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Deep Learning Methods&lt;/em&gt;. In this case, recurrent neural networks are trained and used for assigning the tags.&lt;/p&gt;

&lt;p&gt;Training a NER algorithm demands suitable and annotated data. This implies that you need different types of data that match the type of data you want to analyze.&lt;/p&gt;

&lt;p&gt;The data should also be provided with annotations. This means that the named entities should be identified and classified for the training set in a reliable way.&lt;/p&gt;

&lt;p&gt;Also, we should pick an algorithm. Train it. Test it. Adjust the model….&lt;/p&gt;

&lt;p&gt;Fortunately, they are several tools in Python that make our job easier. Let’s review two of them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;1&lt;/em&gt; Natural Language Tool Kit (NLTK):&lt;/strong&gt; &lt;a href="http://www.nltk.org/"&gt;NLTK&lt;/a&gt; is the most used platform when working with human language data in Python.&lt;/p&gt;

&lt;p&gt;It provides more than 50 corpora and lexical resources. It also has libraries to classify, tokenize, and tag texts, among other functions.&lt;/p&gt;

&lt;p&gt;For the next part, we will get a bit more technical. Let’s start!&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;In the code, we imported the module ntlk but also the methods word_tokenize and pos_tag.&lt;/p&gt;

&lt;p&gt;The first will help us &lt;em&gt;tokenize&lt;/em&gt; the sentences. This means splitting the sentences into tokens or words.&lt;/p&gt;

&lt;p&gt;You may wonder why we don’t use the Python method .split(). NLTK split a sentence in words and punctuation. So it is more robust.&lt;/p&gt;

&lt;p&gt;The second method will “tag” our tokens into the different parts of speech.&lt;/p&gt;

&lt;p&gt;First, we are going to make use of two other Python module: requests and BeautifulSoup. We’ll use them to scrape Wikipedia website about NLTK. And retrieve its text.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;Now, our text is in the variable wiki_nltk.&lt;/p&gt;

&lt;p&gt;It’s time to see our main methods in action. We’ll create a method that takes the text as an input. It will use word_tokenize to split the text into tokens. Then, it will tag each token with its part of speech using pos_tag.&lt;/p&gt;

&lt;p&gt;The method will return a list of tuples. What each tuple will consist of? Well, a word along with its tag; the part of the speech that it corresponds to.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;After that, we apply the method to our text wiki_nltk. For convenience, we will print only the first 20 tuples; 5 per line.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*t0w4HRVkqhwVnBu-R0N1Lg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*t0w4HRVkqhwVnBu-R0N1Lg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The tags are quite cryptic, right? Let’s decode &lt;a href="https://www.ling.upenn.edu/courses/Fall_2003/ling001/penn_treebank_pos.html"&gt;some of them&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;DT&lt;/em&gt; indicates that the word is a determiner. &lt;em&gt;NN&lt;/em&gt; a Noun, singular. &lt;em&gt;NNP&lt;/em&gt; a proper noun, singular. CC a coordinating conjunction. JJR an adjective, comparative. RB an adverb. IN a preposition.&lt;/p&gt;

&lt;p&gt;How is that pos_tag is able to return all of these tags?&lt;/p&gt;

&lt;p&gt;It uses Probabilistic Methods. Particularly, &lt;em&gt;Conditional Random Fields&lt;/em&gt; (CRF) and &lt;em&gt;Hidden Markov Models.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;First, the model extracts a set of features of each word called &lt;em&gt;State Features&lt;/em&gt;. It bases the decision on characteristics like capitalization of the first letter, presence of numbers or hyphen, suffixes, prefixes, among others.&lt;/p&gt;

&lt;p&gt;The model considers also the label of the previous word in a function called Transition Feature. It will determine the weights of different features functions to maximize the likelihood of the label.&lt;/p&gt;

&lt;p&gt;The next step is to perform entity detection. This task will be carried out using a technique called &lt;strong&gt;&lt;em&gt;chunking&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Tokenization extracts only “tokens” or words. On the other hand, chunking extract phrases that may have an actual meaning in the text.&lt;/p&gt;

&lt;p&gt;Chunking requires that our text is first tokenized and POS tagged. It uses these tags as inputs. It outputs “chunks” that can indicate entities.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*krodfGw3NWjwRKAW6mtL7g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*krodfGw3NWjwRKAW6mtL7g.png" alt=""&gt;&lt;/a&gt;An example of how chunking can be visualized.&lt;/p&gt;

&lt;p&gt;NLTK has several functions that facilitate the process of chunking our text. The mechanism is based on the use of regular expressions to generate the chunks.&lt;/p&gt;

&lt;p&gt;We can first apply noun pronoun chunks or _NP-chunk_s. We’ll look for chunks matching individual noun phrases. For this, we will customize the regular expressions used in the mechanism.&lt;/p&gt;

&lt;p&gt;We first need to define rules. They will indicate how sentences should be chunked.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;Our rule states that our NP chunk should consist of an optional determiner (DT) followed by any number of adjectives (JJ) and then one or more pronoun noun (NNP).&lt;/p&gt;

&lt;p&gt;Now, we create a chunk parser using RegexpParser and this rule. We’ll apply it to our POS-tagged words using chunkParser.parse.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;The result is a tree. In this case, we printed only the chunks. We can also display it graphically.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*OGXkbemhrCSe9lGa3eGWlQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*OGXkbemhrCSe9lGa3eGWlQ.png" alt=""&gt;&lt;/a&gt;Entities recognized in the text.&lt;/p&gt;

&lt;p&gt;NLTK also provides a pre-trained classifier using the function nltk.ne_chunk(). It allows us to recognize named entities in a text. It also works on top of POS-tagged text.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*jRu5akedFIrc3VkhBQlgDg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*jRu5akedFIrc3VkhBQlgDg.png" alt=""&gt;&lt;/a&gt;Entities recognized in the text.&lt;/p&gt;

&lt;p&gt;As we can see, the results are the same using both methods.&lt;/p&gt;

&lt;p&gt;However, the results are not completely satisfying. Another disadvantage of NLTK is that POS tagging supports English and Russian languages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;2&lt;/em&gt;&lt;/strong&gt; &lt;a href="https://github.com/explosion/spaCy"&gt;&lt;strong&gt;SpaCy model&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;:&lt;/strong&gt; An open-source library in Python. It provides an efficient statistical system for NER by labeling groups of contiguous tokens.&lt;/p&gt;

&lt;p&gt;It is able to recognize a wide variety of named or numerical entities. Among them, we can find company-names, locations, product-names, and organizations.&lt;/p&gt;

&lt;p&gt;A huge advantage of Spacy is having pre-trained models in several languages: English, German, French, Spanish, Portuguese, Italian, Dutch, and Greek.&lt;/p&gt;

&lt;p&gt;These models support tagging, parsing and entity recognition. They have been designed and implemented from scratch specifically for spaCy.&lt;/p&gt;

&lt;p&gt;They can be imported as Python libraries.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;And loaded easily using spacy.load(). In our code, we save it in the variable nlp .&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;SpaCy provides a Tokenizer, a POS-tagger and a Named Entity Recognizer. So it’s very easy to use. We just called our model in our text nlp(text). This will tokenize it, tagged it and recognize the entities.&lt;/p&gt;

&lt;p&gt;The attribute .sents will retrieve the tokens. .tag_ the tag for each token. .ents the recognized entities. .label_ the label for each entity. .text just the text for any attribute.&lt;/p&gt;

&lt;p&gt;We define a method for this task as follows.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;Now, we apply the defined method to our original Wikipedia text.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*Zqc2pJve9aOdcWZE8jnZog.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*Zqc2pJve9aOdcWZE8jnZog.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Spacy recognizes not only names but also numbers. Very cool, right?&lt;/p&gt;

&lt;p&gt;One question that probably raises is how SpaCy works.&lt;/p&gt;

&lt;p&gt;Its &lt;a href="https://www.youtube.com/watch?time_continue=2099&amp;amp;v=sqDHBH9IjRU"&gt;architecture&lt;/a&gt; is very rich. This results in a very efficient algorithm. Explaining every component of SpaCy model will require another whole post. Even &lt;a href="https://explosion.ai/blog/how-spacy-works"&gt;tokenization&lt;/a&gt; is done in a very novel way.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;According to Explosion AI, Spacy Named Entity Recognition system features a sophisticated word embedding strategy using subword features, a deep convolutional neural network with residual connections, and a novel &lt;a href="https://arxiv.org/abs/1603.01360"&gt;transition-based approach&lt;/a&gt; to named entity parsing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let’s explain these basic concepts step by step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Word embedding strategy using subword features.&lt;/em&gt;&lt;/strong&gt; Wow! Very long name and a lot of difficult concepts.&lt;/p&gt;

&lt;p&gt;What does this mean? Instead of working with words, we should represent them using multi-dimensional numerical vectors.&lt;/p&gt;

&lt;p&gt;Each dimension captures the different characteristics of the words. This is also referred to as &lt;em&gt;Word embeddings&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The advantage is that working with numbers is easier than working with words. We can make calculations, apply functions, among other things.&lt;/p&gt;

&lt;p&gt;The huge limitation is that these models normally ignore the morphological structure of the words. In order to correct this, the &lt;em&gt;subword feature&lt;/em&gt; is introduced to include the knowledge about morphological structures of the words.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://arxiv.org/abs/1603.01360"&gt;&lt;strong&gt;&lt;em&gt;Convolutional neural network with residual connections&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;&lt;em&gt;.&lt;/em&gt;&lt;/strong&gt; Convolution networks are mainly used in processing images. The convolutional layer multiplies a kernel or filter (a matrix with weights) by a window or portion of the input matrix.&lt;/p&gt;

&lt;p&gt;The structure of the traditional &lt;a href="https://dev.to/ugis22/understanding-neural-networks-what-how-and-why-4g3o-temp-slug-1978506"&gt;neural networks&lt;/a&gt; is that each layer feeds the next layer.&lt;/p&gt;

&lt;p&gt;A neural network with residual blocks splits a big network into small chunks. This chunks of the network are connected through skip functions or shortcut connections.&lt;/p&gt;

&lt;p&gt;The efficiency of a residual network is given by the fact that the activation function has to be applied fewer times.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.semanticscholar.org/paper/A-Dynamic-Oracle-for-Arc-Eager-Dependency-Parsing-Goldberg-Nivre/22697256ec19ecc3e14fcfc63624a44cf9c22df4"&gt;&lt;strong&gt;&lt;em&gt;Transition-based&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt; &lt;a href="https://explosion.ai/blog/parsing-english-in-python"&gt;&lt;strong&gt;&lt;em&gt;approach&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;.&lt;/strong&gt; This strategy uses sequential steps to add one label or change the state until it reaches the most likely tag.&lt;/p&gt;

&lt;p&gt;Lastly, Spacy provides a function to display a beautiful visualization of the Named Entity annotated sentences: displacy.&lt;/p&gt;

&lt;p&gt;Let’s use it!&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*F0cja04vgCHom6Sp6QOjJA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*F0cja04vgCHom6Sp6QOjJA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;… Wrapping up!&lt;/p&gt;

&lt;p&gt;Named Entities Recognition is an on-going developing tool. A lot has been done regarding this topic. However, there is still room for improvement.&lt;/p&gt;

&lt;p&gt;Natural Language Processing Toolkit — It is a very powerful tool. Widely used. It provides many algorithms to choose from for the same task. However, it only supports 2 languages. And it requires more tunning. It does not support word vectors.&lt;/p&gt;

&lt;p&gt;SpaCy — It is a very advanced tool. It supports 7 languages as well as multilanguage. It is more efficient. It’s object-oriented. However, the algorithms behind are complex. Only keeps the best algorithm for a task. It has support for word vectors.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Anyhow, Just go ahead and try an approach! You will have fun!&lt;/em&gt;&lt;/p&gt;




</description>
      <category>tech</category>
      <category>machinelearning</category>
      <category>datascience</category>
      <category>namedentityrecogni</category>
    </item>
    <item>
      <title>Visualizing Twitter interactions with NetworkX</title>
      <dc:creator>Eugenia </dc:creator>
      <pubDate>Fri, 19 Apr 2019 22:42:13 +0000</pubDate>
      <link>https://forem.com/ugis22/visualizing-twitter-interactions-with-networkx-53n</link>
      <guid>https://forem.com/ugis22/visualizing-twitter-interactions-with-networkx-53n</guid>
      <description>&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*FEGgjav1t5p1rC16qxoogQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*FEGgjav1t5p1rC16qxoogQ.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Connections, connections, and connections…
&lt;/h4&gt;

&lt;p&gt;Social media is used every day for many purposes: expressing opinions about different topics such as products and movies, advertising an event, a service or a conference, among other things. But what is most interesting about social media, and particularly for this post, about Twitter, is that it creates connections; networks that can be studied to understand how people interact or how news and opinions get spread.&lt;/p&gt;

&lt;p&gt;Previously, we have used Twitter API to &lt;a href="https://dev.to/ugis22/how-to-build-a-postgresql-database-to-store-tweets-37oj-temp-slug-1890626"&gt;store tweets&lt;/a&gt; to afterward performed a &lt;a href="https://dev.to/ugis22/learning-how-to-perform-twitter-sentiment-analysis-402i-temp-slug-2003818"&gt;sentiment analysis&lt;/a&gt; and elucidate the public opinion about avengers. Let’s review the steps needed to stream tweets: First of all, we should go to the &lt;a href="https://developer.twitter.com/en.html"&gt;Twitter developer website&lt;/a&gt;, log-in with the twitter account and ask for approval as a developer. After receiving the approval, we go on and create a new app filling out the details, and lastly, we create the access tokens keeping them in a safe place. In a Jupyter notebook, we can use the &lt;a href="http://www.tweepy.org/"&gt;Tweepy&lt;/a&gt; Python library to connect with our Twitter credentials and stream real-time tweets related to a term of interest and then, save them into a .txt file.&lt;/p&gt;

&lt;p&gt;Now, we are going to read all the data we gathered into a pandas DataFrame.&lt;/p&gt;

&lt;p&gt;We will use this information to graph how the people that tweet about Avengers interact with each other. There are three types of interactions between two Twitter users that we are interested in: retweets, replies, and mentions. According to &lt;a href="https://developer.twitter.com/en/docs/tweets/data-dictionary/overview/intro-to-tweet-json#tweetobject"&gt;Twitter documentation&lt;/a&gt;, the JSON file retrieved representing the Tweet object will include a &lt;em&gt;User&lt;/em&gt; object that describes the author of the Tweet, an &lt;a href="https://developer.twitter.com/en/docs/tweets/data-dictionary/overview/entities-object"&gt;&lt;em&gt;entities&lt;/em&gt; object&lt;/a&gt; that includes arrays of hashtags and user mentions, among others.&lt;/p&gt;

&lt;p&gt;Let’s take a look at the columns of our DataFrame so we can check how the information was read:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*zT0WXnTO6IyYXKPKAh1uxA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*zT0WXnTO6IyYXKPKAh1uxA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the displayed columns, we are interested in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Author of the Tweet: Name(screen_name) and Id(id ) inside user.&lt;/li&gt;
&lt;li&gt;Twitter users mention in the text of the Tweet: Name and Id can be found as screen_name and id in user_mentions inside entities.&lt;/li&gt;
&lt;li&gt;Account taking the retweet action: screen_name and id inside user object of the retweet_status.&lt;/li&gt;
&lt;li&gt;User to which the tweet replies to: in_reply_to_screen_name and in_reply_to_id&lt;/li&gt;
&lt;li&gt;Tweet to which the tweet replies to: in_reply_to_status_id&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You may be wondering how the details collected will help us build a network representing the interactions between Twitter users. In order to answer that, we will need to take a glimpse at Graph Data Structure.&lt;/p&gt;

&lt;p&gt;Let’s start with the basic concepts. What is a Graph? Graph is a data structure used to represent and analyze connections between elements. Its two main elements are nodes or vertices, and edges or lines that connect two nodes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/445/1*dRDV6eAolRyZuLAf-Y681w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/445/1*dRDV6eAolRyZuLAf-Y681w.png" alt=""&gt;&lt;/a&gt;Representation of a Graph structure&lt;/p&gt;

&lt;p&gt;Even though two nodes could not be directly connected to each other, there is a sequence of edges or path that can be followed to go from one node to the other. The possibility of finding one node by following paths is what makes Graph so powerful to represent different structures or networks. When there are a few nodes such that there is no path you can take to reach them, then we are in the presence of a disconnected graph or isolated nodes.&lt;/p&gt;

&lt;p&gt;Graph can also be classified as directed when the edges have a specific orientation (normally representing by an arrow to indicate direction) or undirected when the edges don’t follow any orientation.&lt;/p&gt;

&lt;p&gt;In our analysis, users represent the nodes of our Graph or Network. If we find any type of interaction (&lt;em&gt;retweet, reply or mention&lt;/em&gt;) between them, an edge will be created to connect both nodes. We can work with direct Graph if we are interested in knowing which user retweets another user. Because we only want to describe the interaction present between two users without caring about its orientation, then we are going to use an Undirected Graph.&lt;/p&gt;

&lt;p&gt;The next question is which tool can be used in our analysis. We will take advantage of &lt;a href="https://networkx.github.io/"&gt;NetworkX&lt;/a&gt;, a Python package for the creation and study of the structure of complex networks, such as a social network.&lt;/p&gt;

&lt;p&gt;First of all, we’ll define a function that will allow us to get a list of the interactions between users. We will iterate over the DataFrame, obtain the user_id and screen_name of the user that the author of that specific tweet mention, reply or retweet. The function will return the user of the specific tweet together with a list of the users with whom the user interacted. We need to be careful to discard any None value that may be raised if the user doesn't have any interactions in the three categories mentioned before.&lt;/p&gt;

&lt;p&gt;Now, it’s time to initialize the Graph. We can do this by calling the function .Graph() of NetworkX.&lt;/p&gt;

&lt;p&gt;There are two other important functions to create a Graph. The first one is add_node()and the second one, add_edge both with a very descriptive name. Let’s pay attention to the syntax of &lt;a href="https://networkx.github.io/documentation/stable/reference/classes/generated/networkx.Graph.add_edge.html"&gt;add_edge&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Graph.add_edge(&lt;/strong&gt;&lt;strong&gt;&lt;em&gt;u_of_edge&lt;/em&gt; **&lt;/strong&gt;,**  &lt;strong&gt;&lt;em&gt;v_of_edge&lt;/em&gt;&lt;/strong&gt;** , **** &lt;em&gt;**attr&lt;/em&gt;*&lt;em&gt;**)&lt;/em&gt;*&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;where u, v are the nodes, and attr are keyword arguments that characterize the edge data such as weight, capacity, length, etc.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If we add an edge that already exists, the edge data will get updated. Also, if we are an edge between two nodes that are still not in the Graph, the nodes will be created in the process.&lt;/p&gt;

&lt;p&gt;We are going to populate the Graph by calling the function get_interactions that we defined earlier. With this information, we apply the function add_edge to every tuple consisting of the tweet’s user_id and the user_id of the user mentioned, replied to or retweeted, creating the nodes and the edges connecting them. Also, the tweet id will be added as edge data.&lt;/p&gt;

&lt;p&gt;Now that we have the node and edge of the Graph created, let’s see the number of nodes and edges present:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*EKDFhzk-gK3jCnvep_vsNA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*EKDFhzk-gK3jCnvep_vsNA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s explore now some other characteristic of a Graph. The &lt;strong&gt;degree&lt;/strong&gt; of a node u, denoted as &lt;em&gt;deg(u),&lt;/em&gt; is the number of edges that occur to that node. In simpler words, the number of connections a particular node has. The &lt;strong&gt;maximum degree&lt;/strong&gt; of a graph and the &lt;strong&gt;minimum degree&lt;/strong&gt; of a graph are the maximum and minimum degree of its nodes, respectively.&lt;/p&gt;

&lt;p&gt;In our case, we can obtain the degrees of the Graph:&lt;/p&gt;

&lt;p&gt;and the maximum and minimum degree:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*n8iHnuxTtkwa2iFb0ZAG6A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*n8iHnuxTtkwa2iFb0ZAG6A.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can also obtain the average degree and the most frequent degree of the nodes in the Graph:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*L7DXzOkQgKjqJ3oNnYCEow.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*L7DXzOkQgKjqJ3oNnYCEow.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An undirected graph is connected if, for every pair of nodes, there is a path between them. For that to happen, most of the nodes should have at least a degree of two, except for those denominated leaves which have a degree of 1. From the characteristics of the Graph, we can suspect that the graph is not connected. In order to confirm these, we can use nx.is_connected:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*okGtj_9BP7_l8RuRdAYn6g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*okGtj_9BP7_l8RuRdAYn6g.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Components of a graph are the distinct maximally connected subgraphs. Now, that we confirm that our Graph is not connected, we can check how many connected components it has:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*tEn7gG836ysMYOjCobIr1g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*tEn7gG836ysMYOjCobIr1g.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For this analysis, we are going to work with the largest connected component. Fortunately, NetworkX gives us an easy way to obtain that component by using nx.connected_component_subgraphs that generates graphs, one for each connected component of our original graph, and max function that will help us retrieve the largest component:&lt;/p&gt;

&lt;p&gt;Now, we can obtain the characteristics of this new graph:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*db4cahRQnb_Qh6tCNdkfpw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*db4cahRQnb_Qh6tCNdkfpw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And if we use the function nx.is_connected we’ll observe that the subgraph is connected as it should be.&lt;/p&gt;

&lt;p&gt;Clustering and transitivity measure the tendency for nodes to cluster together or for edges to form triangles. In our context, they are measures of the extent to which the users interacting with one particular user tend to interact with each other as well. The difference is that transitivity weights nodes with a large degree higher.&lt;/p&gt;

&lt;p&gt;The clustering coefficient, a measure of the number of triangles in a graph, is calculated as the &lt;em&gt;number of triangles connected to node i&lt;/em&gt; divided by the &lt;em&gt;number of sets of two edges connected to node i (Triple nodes).&lt;/em&gt; While the transitivity coefficient is calculated as &lt;em&gt;3&lt;/em&gt; multiply by &lt;em&gt;the number of triangles in the network&lt;/em&gt; divided by the &lt;em&gt;number of connected triples of nodes in the network&lt;/em&gt;. These two parameters are very important when analyzing social networks because it gives us an insight into how users tend to create tightly knot groups characterized by relatively high-dense ties.&lt;/p&gt;

&lt;p&gt;Let’s take a look at what is happening in our analysis using the functions average_clustering and transitivity:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*2FkCS750MtZYc7LqpTU2lA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*2FkCS750MtZYc7LqpTU2lA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It appears that in our graph, the users do not tend to form close clusterings.&lt;/p&gt;

&lt;p&gt;After that, we’ll investigate some summary statistics, particularly related to distance, or how far away one node is from another random node. &lt;strong&gt;Diameter&lt;/strong&gt; represents the maximum distance between any pair of nodes while the &lt;strong&gt;average distance&lt;/strong&gt; tells us the average distance between any two nodes in the network. NetworkX facilitates the functions diameter and average_shortest_path_length to obtain these parameters:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*VhnBLWi_d4_teTDlZ70Z6A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*VhnBLWi_d4_teTDlZ70Z6A.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, we are going to focus on &lt;strong&gt;network centrality&lt;/strong&gt; which captures the importance of a node’s position in the network considering: &lt;em&gt;degree&lt;/em&gt; on the assumption that an important node will have many connections_, closeness_ on the assumption that important nodes are close to other nodes_, and finally, betweenness_ on the assumption that important nodes are well situated and connect other nodes. For this, we are going to use the following functions degree_centrality, closenness_centrality and betwenness_centrality, all which return a list of each node and its centrality score. We will particularly capture the node with the best score in each one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*ALI_b_fSEnVGlnsmVnemlw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*ALI_b_fSEnVGlnsmVnemlw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we can see not always the same node shows the maximum in all the centrality measures. However, the node with id &lt;em&gt;393852070&lt;/em&gt; seems to be the one with more connection that is well situated connecting other nodes. On the other hand, the node with id &lt;em&gt;2896294831&lt;/em&gt; is closest to other nodes.&lt;/p&gt;

&lt;p&gt;Now, we can get to see how the Graph looks like. For that, we will use nx.drawing.layout to apply node positioning algorithms for the graph drawing. Specifically, we will use spring_layout that uses &lt;a href="https://en.wikipedia.org/wiki/Force-directed_graph_drawing"&gt;&lt;em&gt;force-directed graph drawing&lt;/em&gt;&lt;/a&gt; which purpose is to position the nodes in two-dimensional space so that all the edges are of equal length and there are as few crossing edges as possible. It achieves this by assigning forces among the set of edges and nodes based on their relative positions and then uses this to simulate the motion of the edges and nodes. One of the parameters that we can adjust is &lt;em&gt;k&lt;/em&gt;, the optimal distance between nodes; as we increase the value, the nodes will farther apart. Once, that we got the positions, we are also going to create a special list so that we can draw the two nodes with higher centrality that we found in different colors to highlight them.&lt;/p&gt;

&lt;p&gt;After all that calculation, we’ll use the functions draw_networkx_nodes() and draw().&lt;/p&gt;

&lt;p&gt;And finally, we have the drawing of the largest connected component of our original Graph:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*llI2SfgDVHPVjk6PXNh3GQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*llI2SfgDVHPVjk6PXNh3GQ.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you want to get to know the entire code for this project, check out my&lt;/em&gt; &lt;a href="https://github.com/ugis22/analysing_twitter"&gt;&lt;em&gt;GitHub Repository&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;




</description>
      <category>datascience</category>
      <category>twitter</category>
      <category>networkanalysis</category>
      <category>networkx</category>
    </item>
    <item>
      <title>Learning how to perform Twitter Sentiment Analysis</title>
      <dc:creator>Eugenia </dc:creator>
      <pubDate>Thu, 31 Jan 2019 18:35:16 +0000</pubDate>
      <link>https://forem.com/ugis22/learning-how-to-perform-twitter-sentiment-analysis-53ba</link>
      <guid>https://forem.com/ugis22/learning-how-to-perform-twitter-sentiment-analysis-53ba</guid>
      <description>&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1004/1*ex3gjAfvaV3Ub9Me7kYPXQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1004/1*ex3gjAfvaV3Ub9Me7kYPXQ.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Keras challenges the Avengers
&lt;/h4&gt;

&lt;p&gt;Sentiment Analysis, also called Opinion Mining, is a useful tool within natural language processing that allow us to identify, quantify, and study subjective information. Due to the fact that quintillion of bytes of data is produced every day, this technique gives us the possibility to extract attributes of this data such as negative or positive opinion about a subject, also information about which subject is being talked about and what characteristics hold the persons or entities expressing that opinion.&lt;/p&gt;

&lt;p&gt;Twitter has been growing in popularity and nowadays, it is used every day by people to express opinions about different topics, such as products, movies, music, politicians, events, social events, among others. A lot of movies are released every year, but if you are a Marvel’s fan like I am, you’d probably be impatient to finally watch the new Avengers movie. Personally, I want to know how the people is feeling about this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/ugis22/how-to-build-a-postgresql-database-to-store-tweets-37oj-temp-slug-1890626"&gt;Previously&lt;/a&gt;, we have discussed how we can use the Twitter API to stream tweets and store them in a relational database. Now, we will use that information to perform sentiment analysis. But before that, we should take into consideration some things. First of all, we have streamed our tweets using the term ‘Avengers’ but without any extra consideration. It is highly likely that we have thousands of repeated tweets. In terms of sentiment analysis, processing them will not add any extra value and contrary, it will be computationally expensive. So, we need to access the database and delete duplicated tweets keeping the first occurrence. Second, we have an unlabeled database. For the model to learn during training, we should state if the tweets are positive or negative. The ideal solution would be to manually label the dataset, which is very accurate but requires a lot of time. However, there are &lt;a href="https://www.altexsoft.com/blog/datascience/how-to-organize-data-labeling-for-machine-learning-approaches-and-tools/"&gt;several alternatives&lt;/a&gt; such as using an open-source dataset labeling tool such as &lt;a href="https://stanfordnlp.github.io/CoreNLP/#human-languages-supported"&gt;&lt;em&gt;Stanford CoreNLP&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;There are a high number of frameworks that can be used for machine learning tasks, however, we are going to use &lt;a href="https://keras.io/"&gt;&lt;strong&gt;&lt;em&gt;Keras&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt; because it offers consistent and simple APIs, minimizes the number of user actions required and more importantly, it is easy to learn and use. We will also make use of the &lt;a href="https://www.nltk.org/"&gt;&lt;strong&gt;&lt;em&gt;Natural Language Toolkit&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt; (NLTK), that provides many corpora and lexical resources that will come in handy for tagging, parsing, and semantic reasoning, and &lt;a href="https://scikit-learn.org/stable/"&gt;&lt;strong&gt;&lt;em&gt;Scikit-learn&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt;, that provides useful tools for data mining and data analysis.&lt;/p&gt;

&lt;p&gt;Ready to start? Let’s see what Keras can learn about Avengers.&lt;/p&gt;

&lt;p&gt;First of all, we need to retrieve the tweets that we have previously store in our PostgreSQL database. For that aim, we are going to take advantage of &lt;a href="https://www.sqlalchemy.org/"&gt;sqlalchemy&lt;/a&gt;, a Python SQL toolkit and Object Relational Mapper that will allow us to connect and query the database in an easy way. One of the characteristics of sqlalchemy is that includes dialect (the system that it uses to communicate with databases) implementations for the most common database, such as MySQL, SQLite, and PostgreSQL, among others. We’ll use the create_engine() function that produces an Engine object based on a given database URL which typical form is as follows: dialect+driver://username:password &lt;strong&gt;@host&lt;/strong&gt; :port/database. In our case, the dialect is PostgreSQL while the driver is psycopg2. After creating the engine object, we’ll use the function read_sql_query from pandas module to query the database to obtain all the data stored in our tweet table (‘select * from tweet_table’) and gather the information retrieved in a DataFrame:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;Before we dig into analyzing the public opinion on ‘Avengers’, there is an important step that we need to take: preprocessing the tweet text. But what does this mean? Text preprocessing includes a basic text cleaning following a set of simple rules commonly used but also, advanced techniques that take into account syntactic and lexical information. In the case of our project, we are going to perform the following steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Convert tweets to lowercase using **&lt;/strong&gt;.lower() function**, in order to bring all tweets to a consistent form. By performing this, we can assure that further transformations and classification tasks will not suffer from non-consistency or case sensitive issues in our data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remove&lt;/strong&gt;  &lt;strong&gt;‘RT’&lt;/strong&gt; , &lt;strong&gt;UserMentions&lt;/strong&gt; and &lt;strong&gt;links:&lt;/strong&gt; In the tweet text, we can usually see that every sentence contains a reference that is is a retweet (‘RT’), a User mention or a URL. Because it is repeated through a lot of tweets and it doesn’t give us any useful information about sentiment, we can remove them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remove numbers:&lt;/strong&gt; Likewise, numbers do not contain any sentiment, so it is also common practice to remove them from the tweet text.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remove punctuation marks and special characters:&lt;/strong&gt; Because this will generate tokens with a high frequency that will cloud our analysis, it is important to remove them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Replace elongated words:&lt;/strong&gt; an elongated word is defined as a word that contains a repeating character more than two times, for example, &lt;em&gt;‘Awesoooome’.&lt;/em&gt; Replacing those words is very important since the classifier will treat them as different words from the source words lowering their frequency. Though, there are some English words that contain repeated characters, mostly consonants, so we will use the wordnet from NLTK to compare to the English lexicon.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Removing stopwords&lt;/strong&gt; : Stopwords are function words that are high frequently present across all tweets. There is no need for analyzing them because they do not provide useful information. We can obtain a list of these words from NLTK stopwords function.&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.jcomputers.us/vol12/jcp1205-11.pdf"&gt;&lt;strong&gt;Handling negation with antonyms&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;:&lt;/strong&gt; One of the problems that come out when analyzing sentiment is handling negation and its effect on subsequent words. Let’s take an example: Say that we find the tweet “I didn’t like the movie” and we discard the stopwords, we will get rid of “I” and “didn’t” words. So finally, we will get the tokens “like” and “movie”, which is the opposite sense that the original tweet had. There are several ways of handling negation, and also there is a lot of &lt;a href="http://www.jcomputers.us/vol12/jcp1205-11.pdf"&gt;research going on about this&lt;/a&gt;; however, for this project, in particular, we are going to scan our tweets and replace with an antonym (that we’ll get from lemmas in wordnet) of the noun, verb or adjective following our negation word.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After we have cleaned our data but before we start building our model for sentiment analysis, we can perform an exploratory data analysis to see what are the most frequent words that appear in our ‘Avengers’ tweets. For this part, we will show graphs regarding tweets labeled as positive separated from those labeled as negative.&lt;/p&gt;

&lt;p&gt;We will start by using WordCloud to represent the word usage across all tweets by resizing every word proportionally to its frequency. Even though it would seem not the most appropriated for different reasons, this graph provides a textual analysis and a general idea of which type of words are present more frequently in our tweets. Python has a &lt;a href="http://amueller.github.io/word_cloud/"&gt;WordCloud&lt;/a&gt; library that allows us to apply a mask using an image that we upload from our hard drive, select the background, the word colormap, the maximum words, font size, among other characteristics of the graph.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;WordCloud for positive tweets:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*z2jnwPAOCVhpubNyWDHjYg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*z2jnwPAOCVhpubNyWDHjYg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;WordCloud for negative tweets:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*kxSkKv-0uMzOO0hL1E-53w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*kxSkKv-0uMzOO0hL1E-53w.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When we observed the WordCloud for positive tweets, some of the words that appear in a bigger size do not have a particular connotation and can be interpreted as neutral, such as “Captain Marvel”, “infinity war”. On the other hand, other words, even though some of smaller size, could be explained to be in tweets with a positive sense, such as “good”, ”great”, ”best” and “liked”. On the contrary, WordCloud for negative tweets showed mostly neutral words such as “movie”, “endgame” and very small words with a negative connotation, for example, “never”, and “fuck”.&lt;/p&gt;

&lt;p&gt;Afterward, we can present in a graph the 50 most frequent words in co-occurrence with ‘Avengers’ term for positive and negative tweets. We’ll start by using the function CountVectorizer from sklearn which will convert the collection of tweets into a matrix of token counts producing a sparse representation of the counts. Then, we sum all counts for each token and obtain the frequency and store them as a DataFrame.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;We can now plot these values in a barplot by using matplotlib function bar.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*sfkh5vOUPFOu35a4iadGhQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*sfkh5vOUPFOu35a4iadGhQ.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*JrULxd1gs8T3J4LKmwdaCg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*JrULxd1gs8T3J4LKmwdaCg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see that the first frequent words are common for positive and negative tweets: “marvel”, “endgame” and moreover, most of the words have a neutral connotation, except for words like “good”, “great”, “love”, “favorite” and “best” in the positive tweets.&lt;/p&gt;

&lt;p&gt;We can finally check if there is any correlation between the frequency of the words that appear in the positive and negative tweets. We’ll concatenate both word frequency DataFrames and after that, we’ll use the seaborn regplot graph:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/876/1*EurGOPDo69mdC2lCV4ssDQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/876/1*EurGOPDo69mdC2lCV4ssDQ.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Apart from one or two points that seem related, no meaningful association can be derived from the graph above between words appearing in positive and negative tweets.&lt;/p&gt;

&lt;p&gt;After visualizing our data, the next step is to split our dataset into training and test sets. For doing so, we’ll take advantage of the train_test_split functionality of sklearn package. We will take 20% of the dataset for testing following the 20–80% rule. From the remaining 80% used for the training set, we’ll save a part for validation of our model.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;We also need to convert our sentiment column into categories that our model can understand. We’ll use then 0 for negative, 1 for neutral and 2 for positive tweets.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;Finally, we need to process our input tweet column using TfidfVectorizer that will convert the collection of tweets to a matrix of Term Frequency/Invert document frequency (TF-IDF) features. What is very crucial about this function is that it will return normalized frequencies; feature normalization is a key step in building a machine learning algorithm. After several tries, 3500 was the number of maximum features returned that worked best with our model.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;Now, it’s time to build our model: &lt;em&gt;a neural network&lt;/em&gt;. If you are not familiar with how neural networks work, you can check &lt;a href="https://dev.to/ugis22/understanding-neural-networks-what-how-and-why-4g3o-temp-slug-1978506"&gt;my previous post&lt;/a&gt;. Fortunately, Keras makes building a neural network very simple and easy in a few lines of code.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;Let’s dissect our model: Sequential() is a type of network composed of layers that are stacked and executed in the order presented. So, which type of layers do we have? We observe that we have added Dense layers for our three layers (input, hidden and output layer), meaning that every node in a layer receives input from all nodes in the previous layer implementing the following operation: &lt;a href="https://www.tensorflow.org/api_docs/python/tf/keras/layers/Dense"&gt;output = activation(dot(input, weights) + bias)&lt;/a&gt;. Between them, we have used the Dropout method, which takes a float between 0 and 1 (that we’ll pass as drop and adjust later) representing the fraction of the neurons that will be randomly dropped during training to prevent overfitting. The key layers are the input and the output because they will determine the shape of our network and it is important to correctly know what we expect. Because we’ll use 3500 as the maximum features returned in the vectorization process, we need to use this exact number as the size of the input shape. We’ll also include how many outputs will come out of the first layer (pass as layer1), a parameter that we‘ll modify later in order to make the layer simpler or more complex. In this case, we’ll choose relu as our activation function, which has several benefits over others such as reducing the likelihood of vanishing gradient. For the last layer, we’ll choose three nodes corresponding to the three different outputs and because we want to obtain categorical distributions, we’ll use softmax as an activation function. For the hidden layer, we’ll also pass the size as layer2 that normally is half layer1 and because it's a classification problem, we'll use sigmoid activation (if you want to know more about which activation functions to use, check this &lt;a href="https://www.youtube.com/watch?v=-7scQpJT7uo"&gt;video&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;After that, the optimizer to be used and its parameters should be stated. We’ll use AdamOptimizer with fixed decay and betas, but later we’ll adjust the learning rate and epsilon value. &lt;a href="https://arxiv.org/abs/1412.6980v8"&gt;Adam&lt;/a&gt; is a stochastic optimization which has several advantages such as being straightforward to implement, being computationally efficient, having little memory requirements, being invariant to diagonal rescaling of the gradients, and being well suited for problems that are large in terms of data and/or parameters.&lt;/p&gt;

&lt;p&gt;One of the last steps before training is to compile the network clarifying the loss we want. In this case, we’ll use sparse_categorical_crossentropy due to the fact that we have categories represented as numbers. We’ll also need to clarify the optimizer, and the metrics to be evaluated (for us, it’ll be accuracy). Moreover, we need to fit the model stating the set for X and Y values, the batch size (number of samples propagated through the network), epochs (how many times we’ll scan through all the data, parameter that we’ll also adjust), the validation split (which percentage will be saved to validate our results) and if we are going to present the data every time in the same way or, we are going to shuffle it (shuffle).&lt;/p&gt;

&lt;p&gt;After trying several parameters for dropout, features, shuffle, learning rate, layer size, epsilon, validation_split, epochs, we’d finally arrived at the following model:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*8sRJoax8gKK7hOfZFgA5GQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*8sRJoax8gKK7hOfZFgA5GQ.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see that our final validation accuracy was 71.91 seen for epoch 1 improving to 76.54% for epoch 5. Furthermore, increasing, even more, the epochs improved the training accuracy but decreased the validation accuracy.&lt;/p&gt;

&lt;p&gt;Even though we always want to have higher accuracy, we can now go on and try to identify what the opinion is in a new dataset that we have created just like the one we used for training and validation.&lt;/p&gt;

&lt;p&gt;For that, we are going to query our new database, performed the same text preprocessing step, tokenize our tweets and use our trained model to predict the sentiment on ‘Avengers’ using model.predict(). If we want to make it easier for human readability, we can convert the numeric prediction to our categorical labels ‘positive, neutral and, negative’.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;Now the time of the truth! We can plot how many of our tweets are including in each sentiment category using a pie chart:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/814/1*JhGdi93ybbDmbSkGeQDSzg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/814/1*JhGdi93ybbDmbSkGeQDSzg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see 53.1% of the tweets have a positive connotation about ‘Avengers’ while the remaining 46.9% are neutral or have a negative connotation. If I was to tweet about this subject I should be included on the positive side, or a least I can be 76% confident I would. &lt;em&gt;What about you?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Next, we are going to use Tweets information to &lt;a href="https://medium.com/@meinzaugarat/visualizing-twitter-interactions-with-networkx-a391da239af5"&gt;visualize user interactions on Twitter by using NetworkX&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you want to get to know the entire code for this project, check out my&lt;/em&gt; &lt;a href="https://github.com/ugis22/analysing_twitter"&gt;&lt;em&gt;GitHub Repository&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;




</description>
      <category>nlp</category>
      <category>datascience</category>
      <category>sentimentanalysis</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>How to build a PostgreSQL database to store tweets</title>
      <dc:creator>Eugenia </dc:creator>
      <pubDate>Thu, 27 Dec 2018 15:56:16 +0000</pubDate>
      <link>https://forem.com/ugis22/how-to-build-a-postgresql-database-to-store-tweets-5cm8</link>
      <guid>https://forem.com/ugis22/how-to-build-a-postgresql-database-to-store-tweets-5cm8</guid>
      <description>&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*-_6kuOWGogsZw9Vnr5JTeQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*-_6kuOWGogsZw9Vnr5JTeQ.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Learning how to stream from Twitter API
&lt;/h4&gt;

&lt;p&gt;Twitter is used every day by people to express their feelings or thoughts, especially about something that it is happening at the moment or has just occurred; by companies to promote products or services; by journalists to comment on events or write news, and the list can go on. There is no doubt that analyzing Twitter and tweets is a powerful tool that can give us a sense on the public opinion about a topic that we are interested in.&lt;/p&gt;

&lt;p&gt;But how do we perform this type of analysis? Fortunately, Twitter provides us with an API (that stands for ‘&lt;em&gt;Application Programming Interface&lt;/em&gt;’) which we can interact with creating an app and in that way, access and filter public tweets.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;first step&lt;/em&gt; is to register our app; for that, we need to go to &lt;a href="https://developer.twitter.com/en.html"&gt;Twitter developer website&lt;/a&gt;, log-in with our twitter account and ask Twitter for approval as developers (&lt;em&gt;As from July 2018, Twitter changed their policies and anyone that want to access Twitter API and create an app need to apply for a developer account, provide detailed information on how they intend to use it and wait for the application to be approved&lt;/em&gt;). After we received the approval, we can go on and create a new app filling out the details: &lt;strong&gt;&lt;em&gt;Name&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;(unique name that no one else has used as their Twitter app)&lt;/em&gt;, &lt;strong&gt;&lt;em&gt;Description&lt;/em&gt;&lt;/strong&gt; , and &lt;strong&gt;&lt;em&gt;Website&lt;/em&gt;&lt;/strong&gt; (It should be the app’s home page but we can also put our personal website or a GitHub repository URL.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*RGtIAT2HYgyrBigzkCjjiA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*RGtIAT2HYgyrBigzkCjjiA.png" alt=""&gt;&lt;/a&gt;Creating an app in Twitter Developer account&lt;/p&gt;

&lt;p&gt;After that, we need to create our access tokens. The access tokens will allow our Twitter app to read Twitter information, such as tweets, mentions, friends, and more:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*LBZQmC3Qh7xqVXoAbFQAdg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*LBZQmC3Qh7xqVXoAbFQAdg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the whole analysis, we are going to work with &lt;a href="https://jupyterlab.readthedocs.io/en/stable/getting_started/installation.html"&gt;JupyterLab&lt;/a&gt; and Python. Because anyone having this information can use it to authorize the app to connect to Twitter, we are going to create a python file (.py) where we can store the &lt;em&gt;Consumer Key&lt;/em&gt;, &lt;em&gt;Consumer Secret&lt;/em&gt;, &lt;em&gt;OAuth Access Token&lt;/em&gt;, &lt;em&gt;OAuth Access Token Secret&lt;/em&gt; and then call it in our main Jupyter Notebook file.&lt;/p&gt;

&lt;p&gt;Now that we have registered our app, got our tokens/keys and stored them in a separated file, the &lt;em&gt;second step&lt;/em&gt; is to decide where we are going to store our tweets once we got them. Should we store them in a file, in a &lt;a href="https://www.sisense.com/blog/postgres-vs-mongodb-for-storing-json-data/"&gt;NoSQL-type database or in a relational database&lt;/a&gt;? In order to answer this question, we need to understand how the information that we get from twitter app is given to us and what we want to do with it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.twitter.com/en/docs/tweets/data-dictionary/overview/intro-to-tweet-json"&gt;Twitter APIs&lt;/a&gt; always return tweets encoded using &lt;em&gt;JavaScript Object Notation&lt;/em&gt; (JSON), an unstructured and flexible type which is based on key-value pairs with attributes and associated values that describe objects. Each tweet contains an author, message, unique ID, a timestamp and creation date when it was posted, among others; each user has a name, id, and the number of followers. Because of this, we will immediately think of storing tweets in a built database management systems (DBMS), like MongoDB, an open source database conceived as a native JSON database. The advantages of this type of database are that they are designed to be agile and scalable while using dynamic schemas without defining the structure first.&lt;/p&gt;

&lt;p&gt;On the other hand, relational databases are more related to standards compliance and extensibility and consequently, do not give us freedom over how to store the data. They use dynamic and static schemas which help us to link data when they are relational. On the contrary, because of the unstructured approach, we can not perform this in MongoDB. Some other advantages of using a relational database are that we need only to change data in one of the tables and then it will update itself ( &lt;strong&gt;&lt;em&gt;data integrity&lt;/em&gt;&lt;/strong&gt; ), and they ensure that no attributes are repeated ( &lt;strong&gt;&lt;em&gt;data redundancy&lt;/em&gt;&lt;/strong&gt; ). As we said before, relational databases are structured in columns and rows in a way that we can link information from different tables through the use of keys that uniquely identified any piece of data within the table and are used by other tables to point to them.&lt;/p&gt;

&lt;p&gt;Even though MongoDB has been designed to be fast and has great performance with unstructured data, relational databases such as PostgreSQL has a great performance handling JSON. This fact together with the possibilities that structuring the data give us lead us to use a relational database and specifically, &lt;a href="https://www.postgresql.org/"&gt;&lt;strong&gt;PostgreSQL 10&lt;/strong&gt;&lt;/a&gt; (mention usually just as Postgres) because it is a free, reliable and efficient SQL database that most importantly, has a very powerful and useful python API, called &lt;a href="http://initd.org/psycopg/"&gt;&lt;strong&gt;psycopg2&lt;/strong&gt;&lt;/a&gt;. In order to administer our database in a more friendly way, we will also use &lt;a href="https://dev.to/scottw/pgadmin---postgresql-tools-5ejk"&gt;&lt;strong&gt;pgadmin&lt;/strong&gt;&lt;/a&gt; that will allow us to create a database with a user and password to protect our information. Again, we are going to store these credentials in another python file so we keep them secret once we push the main file to our git repository.&lt;/p&gt;

&lt;p&gt;The last components that we need to bring into our analysis are &lt;a href="http://www.tweepy.org/"&gt;&lt;strong&gt;Tweepy&lt;/strong&gt;&lt;/a&gt;, a python library that will become the main player in our code and will help us to access the Twitter API, handle the authorization request, capture and stream tweets among others, and &lt;strong&gt;json&lt;/strong&gt; which will manage the JSON files obtained from the API.&lt;/p&gt;

&lt;p&gt;So, the first thing that we need to do in our code is to import all the libraries and files that we’ve created:&lt;/p&gt;

&lt;p&gt;After that, we will define a function that will authorize our app to connect to Twitter API. OAuth is an open standard for access mainly used by internet users to grant applications or websites access to their information on other websites without providing them the passwords and instead, allowing approved access tokens to access protected resources hosted by the resource server. In the case of Twitter, we already requested the tokens and keys so, we will use Tweepy that makes OAuth authorization easy for us handling it with the &lt;strong&gt;&lt;em&gt;tweepy.OAuthHandler&lt;/em&gt;&lt;/strong&gt; class. So, first, we pass to this function the consumer key and the consumer secret and then, we set the access tokens to be our access token and our access token secret that we got from Twitter.&lt;/p&gt;

&lt;p&gt;As we have discussed before, relational databases store information in structured tables, so the next step is to decide the schema of our database. There is a very important concept that we need to consider here: &lt;strong&gt;&lt;em&gt;Normalization.&lt;/em&gt;&lt;/strong&gt; Normalizing a database requires a process that structures a relational database according to certain normal forms which follow the goal of reducing data redundancy and improving data integrity. A normalized database is one such as the relationship among the tables matches the relationship that is really there among the data. In simple terms, the rules state that unique keys and events in the rows should say something about it, facts that do not relate to the key belongs into different tables, and the tables should not imply relationships that do not exist.&lt;/p&gt;

&lt;p&gt;In our case, we are going to create two tables: the first one will contain information about the Twitter users: user id, that will be our PRIMARY KEY (a key that is unique for each record), and user name. On the other hand, we will create a second table that will store information about the tweets: creation date, text (the tweet itself), user id, that will be our FOREIGN KEY (a key that uniquely identifies a primary key of another table) relating this table with our user table, and the retweet count.&lt;/p&gt;

&lt;p&gt;We will define a function that once called will connect to our database with the credentials (using the command pyscopg2.connect) and create a table containing the name of the term we want to search for. For this last step, Postgres give us the possibility of setting up a &lt;strong&gt;&lt;em&gt;cursor&lt;/em&gt;&lt;/strong&gt; that encapsulates the query and reads its results a few rows at a time instead of executing a whole query at once. So, we will take advantage of that, create a cursor (using &lt;em&gt;database.cursor()&lt;/em&gt;) and then execute our query to create the user table and then the tweets-containing table. We need to consider some points here: it is important to use the IF NOT EXISTS command when we perform the query to CREATE TABLE, otherwise, Postgres can rise the error that the table is already created and will stop the code execution; we need to clarify which type of variable each column contains (VARCHAR, TIMESTAMP, etc.), which column is the primary and foreign key, and in this last case, which column REFERENCES to; after we have executed the queries is important to commit this (&lt;em&gt;database.commit()&lt;/em&gt;), otherwise, no changes will be persisted, and close the connection to the cursor and the database.&lt;/p&gt;

&lt;p&gt;Afterward, we need to define a function that will help us store the tweets. This function will follow the same logic that we use to create the table(connect to the database, create a cursor, execute the query, commit query, close connection), but instead, we will use the &lt;a href="https://www.postgresql.org/docs/10/sql-insert.html"&gt;INSERT INTO&lt;/a&gt; command. When creating the user table, we declared that user id will be our primary key. So, when we store the tweets we need to be careful how we insert this in the table. If the same user has two tweets, the second time the function is executed, it will raise an error because it detects that particular user id to already be in the table, as primary keys have to be unique. So, we can use here the &lt;a href="https://www.postgresql.org/docs/10/sql-insert.html"&gt;ON CONFLICT&lt;/a&gt; command to tell postgres that if the user id is already in the table, it doesn’t have to insert it again. On the contrary, the tweet will be inserted into the tweets table and will be referenced to that user id in the user table.&lt;/p&gt;

&lt;p&gt;There are two ways to capture tweets with Tweepy. The first one is using the REST search API, &lt;em&gt;tweepy.API,&lt;/em&gt; which searches against a sampling of recent public tweets published in the past 7 days. The second one is streaming real-time tweets by using the &lt;em&gt;Twitter streaming api&lt;/em&gt; that differs from the REST api in the way that this one pulls data from Twitter while the streaming api pushes messages to a persistent session.&lt;/p&gt;

&lt;p&gt;In order to stream tweets in Tweepy, an instance of the class &lt;a href="https://tweepy.readthedocs.io/en/3.7.0/streaming_how_to.html#summary"&gt;&lt;strong&gt;&lt;em&gt;tweepy.Stream&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt; establishes a streaming session and sends messages to an instance of &lt;strong&gt;&lt;em&gt;StreamListener&lt;/em&gt;&lt;/strong&gt; class. Inside of this class, there are several methods that handle tweets. Depending on what type of information we want to obtain, we need to override the different methods: if we want only the status, we will then overload &lt;strong&gt;&lt;em&gt;on_status&lt;/em&gt;&lt;/strong&gt; method. Because we want detailed information about the tweet (creation date, user id, user name, retweet count), we will overload the &lt;strong&gt;on_data&lt;/strong&gt; method that is in charge of receiving all messages and calling functions according to the type of the message.&lt;/p&gt;

&lt;p&gt;Consequently, we will create the class &lt;strong&gt;MyStreamListener&lt;/strong&gt; which will inherit from &lt;strong&gt;&lt;em&gt;tweepy.StreamListener&lt;/em&gt;&lt;/strong&gt; class and we will override &lt;strong&gt;on_data&lt;/strong&gt; method. We will obtain the json file containing the tweet (&lt;em&gt;json.load(raw_data)&lt;/em&gt;) and parse it to store the values in different variables (as an example: user_id = data[‘user’][‘id_str’]) to then pass them to the function to store tweets that we have created before.&lt;/p&gt;

&lt;p&gt;It is important to be careful about error or exceptions that could occur at this point. For this, we will surround the code by a try/except block so in case an exception happens, it will be printed and we can be aware of what is happening. Also, there is a limit number of attempts to connect to the streaming API and this will show an error 420. We can handle this error by overloading the &lt;strong&gt;on_error&lt;/strong&gt; method and disconnect the API in case this error shows up.&lt;/p&gt;

&lt;p&gt;So, what is left? We need to create an api (&lt;em&gt;tweepy.API()&lt;/em&gt;) and after that, create our stream object (&lt;em&gt;tweepy.stream()&lt;/em&gt;) passing the authorization and the listener that we have created. We will use the &lt;strong&gt;&lt;em&gt;filter&lt;/em&gt;&lt;/strong&gt; function to stream all tweets containing a word of interested (&lt;em&gt;track = [‘word’]&lt;/em&gt;) and being written in English (&lt;em&gt;languages = [‘en]&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;Now, it’s time to start streaming the tweets!! I’m particularly interested in knowing what people are feeling about &lt;strong&gt;the Avengers&lt;/strong&gt;. So I will use “avengers” as my term of interest and start capturing real-time tweets to create a nice database that will help my later sentiment analysis that you can read &lt;a href="https://towardsdatascience.com/keras-challenges-the-avengers-541346acb804"&gt;here&lt;/a&gt; as well as to visualize Twitter interactions with Networkx that you can find &lt;a href="https://medium.com/@meinzaugarat/visualizing-twitter-interactions-with-networkx-a391da239af5"&gt;here&lt;/a&gt;. &lt;em&gt;What are you interested in?&lt;/em&gt;&lt;/p&gt;




</description>
      <category>postgres</category>
      <category>twitter</category>
      <category>datascience</category>
      <category>database</category>
    </item>
    <item>
      <title>Understanding Neural Networks: What, How and Why?</title>
      <dc:creator>Eugenia </dc:creator>
      <pubDate>Tue, 30 Oct 2018 22:09:26 +0000</pubDate>
      <link>https://forem.com/ugis22/understanding-neural-networks-what-how-and-why-4ab4</link>
      <guid>https://forem.com/ugis22/understanding-neural-networks-what-how-and-why-4ab4</guid>
      <description>&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*J4WR2GliSeq5C2YdPKAkAQ.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*J4WR2GliSeq5C2YdPKAkAQ.jpeg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Unraveling the &lt;em&gt;black box&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;Neural networks is one of the most powerful and widely used algorithms when it comes to the subfield of machine learning called deep learning. At first look, neural networks may seem a &lt;em&gt;black box&lt;/em&gt;; an input layer gets the data into the “&lt;em&gt;hidden layers&lt;/em&gt;” and after a magic trick we can see the information provided by the &lt;em&gt;output layer&lt;/em&gt;. However, understanding what the hidden layers are doing is the key step to neural network implementation and optimization.&lt;/p&gt;

&lt;p&gt;In our path to understand neural networks, we are going to answer three questions: &lt;em&gt;What&lt;/em&gt;, &lt;em&gt;How&lt;/em&gt; and &lt;em&gt;Why&lt;/em&gt;?&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;WHAT is a Neural Network?&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;The neural networks that we are going to considered are strictly called artificial neural networks, and as the name suggests, are based on what science knows about the human brain’s structure and function.&lt;/p&gt;

&lt;p&gt;Briefly, a neural network is defined as a computing system that consist of a number of simple but highly interconnected elements or nodes, called ‘neurons’, which are organized in layers which process information using dynamic state responses to external inputs. This algorithm is extremely useful, as we will explain later, in finding patterns that are too complex for being manually extracted and taught to recognize to the machine. In the context of this structure, patterns are introduced to the neural network by the &lt;em&gt;input&lt;/em&gt; &lt;em&gt;layer&lt;/em&gt; that has one neuron for each component present in the input data and is communicated to one or more &lt;em&gt;hidden layers&lt;/em&gt; present in the network; called ‘hidden’ only due to the fact that they do not constitute the input or output layer. It is in the hidden layers where all the processing actually happens through a system of connections characterized by &lt;strong&gt;&lt;em&gt;weights and biases&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;(commonly referred as W and b)&lt;/em&gt; &lt;strong&gt;&lt;em&gt;:&lt;/em&gt;&lt;/strong&gt; the input is received, the neuron calculate a weighted sum adding also the bias and according to the result and a pre-set &lt;strong&gt;activation function&lt;/strong&gt; (most common one is sigmoid, &lt;em&gt;σ,&lt;/em&gt; even though it almost not used anymore and there are better ones like ReLu_)&lt;em&gt;, it decides whether it should be ‘fired’ or activated. Afterwards, the neuron transmit the information downstream to other connected neurons in a process called ‘_forward pass&lt;/em&gt;’. At the end of this process, the last hidden layer is linked to the &lt;em&gt;output layer&lt;/em&gt; which has one neuron for each possible desired output.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*pbk9xtz7WbBwYPVATdl9Vw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*pbk9xtz7WbBwYPVATdl9Vw.png" alt=""&gt;&lt;/a&gt;Basic structure of a 2-layer Neural Network. Wi: Weight of the corresponding connection. Note: The input layer is not included when counting the number of layers present in the network.&lt;/p&gt;

&lt;h4&gt;
  
  
  HOW does a Neural Network work?
&lt;/h4&gt;

&lt;p&gt;Now that we have an idea on how the basic structure of a Neural Network look likes, we will go ahead and explain how it works. In order to do so, we need to explain the different type of neurons that we can include in our network.&lt;/p&gt;

&lt;p&gt;The first type of neuron that we are going to explain is &lt;strong&gt;&lt;em&gt;Perceptron&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;.&lt;/em&gt; Even though its use has decayed today, understanding how they work will give us a good clue about how more modern neurons function.&lt;/p&gt;

&lt;p&gt;A perceptron uses a function to learn a binary classifier by mapping a vector of binary variables to a single binary output and it can also be used in supervised learning. In this context, the perceptron follows these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Multiply all the inputs by their weights &lt;strong&gt;&lt;em&gt;w&lt;/em&gt;&lt;/strong&gt; , real numbers that express how important the corresponding inputs are to the output,&lt;/li&gt;
&lt;li&gt;Add them together referred as &lt;strong&gt;&lt;em&gt;weighted sum: ∑ wj xj&lt;/em&gt;&lt;/strong&gt; ,&lt;/li&gt;
&lt;li&gt;Apply the &lt;strong&gt;&lt;em&gt;activation function&lt;/em&gt;&lt;/strong&gt; , in other words, determine whether the weighted sum is greater than a &lt;em&gt;threshold value,&lt;/em&gt; where -threshold is equivalent to &lt;em&gt;bias,&lt;/em&gt; and assign 1 or less and assign 0 as an output_._&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We can also write the perceptron function in the following terms:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/464/1*7y_U0_xQv5e5EUzDUJGvtw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/464/1*7y_U0_xQv5e5EUzDUJGvtw.png" alt=""&gt;&lt;/a&gt;Notes: b is the bias and is equivalent to -threshold, w.x is the dot product of w, a vector which component is the weights, and x, a vector consisting of the inputs.&lt;/p&gt;

&lt;p&gt;One of the strongest point in this algorithm is that we can vary the weights and the bias to obtain distinct models of decision-making. We can assign more weight to those inputs so that if they are positive, it will favor our desired output. Also, because the bias can be understood as a measure of how difficult or easy is to output 1, we can drop or raise its value if we want to make more or less likely the desired output to happen. If we pay attention to the formula, we can observe that a big positive bias will make it very easy to output 1; however a very negative bias will make the task of output 1 very unlikely.&lt;/p&gt;

&lt;p&gt;In consequence, a perceptron can analyze different evidence or data and make a decision according to the set preferences. It is possible, in fact, to create more complex networks including more layers of perceptrons where every layer takes the output of the previous one and weights it and make a more and more complex decisions.&lt;/p&gt;

&lt;p&gt;What wait a minute: If perceptrons can do a good job in making complex decisions, why do we need other type of neuron? One of the disadvantages about a network containing perceptrons is that small changes in weights or bias, even in only one perceptron, can severely change our output going from 0 to 1 or vice versa. What we really want is to be able to gradually change the behaviour of our network by introducing small modifications in the weights or bias. Here is where a more modern type of neuron come in handy (Nowadays its use has been replaced by other types like Tanh and lately, by ReLu): &lt;strong&gt;&lt;em&gt;Sigmoid neurons.&lt;/em&gt;&lt;/strong&gt; The main difference between a sigmoid neuron and a perceptron is that the input and the output can be any continuous value between 0 and 1. The output is obtained after applying the &lt;strong&gt;&lt;em&gt;sigmoid function&lt;/em&gt;&lt;/strong&gt; to the inputs considering the weights, w, and the bias, b. To visualize it better, we can write the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/359/1*INRzr1dj-X3d0N-x7XRSpQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/359/1*INRzr1dj-X3d0N-x7XRSpQ.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, the formula of the output is:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/237/1*OWFmaKDixkpbeAP-1hOe2Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/237/1*OWFmaKDixkpbeAP-1hOe2Q.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we perform a mathematical analysis of this function, we can make a graph of our function _σ _, shown below, and conclude that when z is large and positive the function reaches its maximum asymptotic value of 1; however, if z is large and negative, the function reaches its minimum asymptotic value of 0. Here is where the sigmoid function becomes very interesting because it is with moderate values of z that the function takes a smooth and close to linear shape. In this interval, small changes in weights (Δwj) or in bias (Δbj) will generate small changes in the output; the desired behaviour that we were looking for as an improvement from a perceptron.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;We know that the derivative of a function is the measure of the rate at which the value y changes with respect to the change of the variable x. In this case, the variable y is our output and the variable x is a function of the weights and the bias. We can take advantage of this and calculate the change in the output using the derivatives, and particularly, the partial derivatives (with respect to w and with respect to b). You can read &lt;a href="https://theclevermachine.wordpress.com/2014/09/08/derivation-derivatives-for-common-neural-network-activation-functions/"&gt;this post&lt;/a&gt; to follow the calculations but in the case of sigmoid function, the derivative will be reduce to calculate: f(z)*(1-f(z)).&lt;/p&gt;

&lt;p&gt;Here it’s a simple code that can be used to model a sigmoid function:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;We have just explain the functioning of every neuron in our network, but now, we can examine how the rest of the it works. A neural networks in which the output from one layer is used as the input of the next layer is called &lt;em&gt;feedforward&lt;/em&gt;, particularly because there is no loops involved and the information is only pass forward and never back.&lt;/p&gt;

&lt;p&gt;Suppose that we have a training set and we want to use a 3-layer neural network, in which we also use the sigmoid neuron we saw above, to predict a certain feature. Taking what we explain about the structure of a neural network, weights and bias need to be first assigned to the connections between neurons in one layer and the next layer. Normally, the biases and weights are all initialized randomly in a synapsis matrix. If we are coding the neural network in python, we can use the Numpy function np.random.random generating a Gaussian distributions (where mean is equal to 0 and standard deviation to 1) to have a place to start learning.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;After that, we will build the neural network starting with the &lt;strong&gt;&lt;em&gt;Feedforward&lt;/em&gt;&lt;/strong&gt; step to calculate the predicted output; in other words, we just need to build the different layers involved in the network:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;layer0 is the input layer; our training set read as a matrix (We can called it X)&lt;/li&gt;
&lt;li&gt;layer1 is obtained by apply the activation function a’ = σ(w.X+b), in our case, performing the dot multiplication between input layer0 and the synapsis matrix syn0&lt;/li&gt;
&lt;li&gt;layer2is the output layer obtained by the dot multiplication between layer1 and its synapsis syn1&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We will also need to iterate over the training set to let the network learn (we will see this later). In order to do so, we will add a &lt;em&gt;for&lt;/em&gt; ** ** loop.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;Until now, we have create the basic structure of the neural network: the different layers, the weights and bias of the connection between the neurons, and the sigmoid function. But none of this explains how the neural network can do such a good job in predicting patterns in a dataset. And this is what will take us to our last question.&lt;/p&gt;

&lt;h4&gt;
  
  
  WHY Neural Networks are able to learn?
&lt;/h4&gt;

&lt;p&gt;The main strength of machine learning algorithms is their ability to learn and improve every time in predicting an output. But what does it mean that they can learn? In the context of neural networks, it implies that the weights and biases that define the connection between neurons become more precise; this is, eventually, the weights and biases are selected such as the output from the network approximates the real value y(x) for all the training inputs.&lt;/p&gt;

&lt;p&gt;So, how do we quantify how far our prediction is from our real value in order for us to know if we need to keep searching for more precise parameters? For this aim, we need to calculate an error or in other words, define a &lt;strong&gt;&lt;em&gt;cost function&lt;/em&gt;&lt;/strong&gt; (Cost function is not other thing that the error in predicting the correct output that our network has; in other terms, it is the difference between the expected and the predicted output). In neural networks, the most commonly used one is the quadratic cost function, also called mean squared error, defined by the formula:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/434/1*mlXjgbRMYFcBdW5qW0NvlQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/434/1*mlXjgbRMYFcBdW5qW0NvlQ.png" alt=""&gt;&lt;/a&gt;w and b referred to all the weights and biases in the network, respectively. n is the total number of training inputs. a is the outputs when x is the input. ∑ is the sum over all training inputs.&lt;/p&gt;

&lt;p&gt;This function is preferred over the linear error due to the fact that in neural networks small changes in weights and biases do not produces any change in the number of correct outputs; so using a quadratic function where big differences have more effect on the cost function than small ones help figuring out how to modify these parameters.&lt;/p&gt;

&lt;p&gt;On the other hand, we can see that our cost function become smaller as the output is closer to the real value &lt;em&gt;y&lt;/em&gt;, for all training inputs. The main goal of our algorithm is to minimize this cost function by finding a set of weights and biases to make it as small as possible. And the main tool to achieve this goal is an algorithm called &lt;strong&gt;&lt;em&gt;Gradient Descent&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Then, the next question that we should answer is how we can minimize the cost function. From calculus, we know that a function can have global maximum and/or minimum, that is, where the function achieves the maximum or minimum value that it can have. We also know that one way to obtained that point is calculating derivatives. However, it is easy to calculate when we have a function with two variables but in the case of neural network, they include a lot of variables which make this computation quite impossible to make.&lt;/p&gt;

&lt;p&gt;Instead, let’s take a look at the graph below of a random function:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*ARnEDAhm5BAKQdqeehS7NA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*ARnEDAhm5BAKQdqeehS7NA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see that this function has a global minimum. We could, as we said before, compute the derivatives to calculate where the minimum is located or we could take another approach. We can start in a random point and try to make a small move in the direction of the arrow, we would mathematically speaking, move Δx in the direction x and Δy in the direction of y, and calculate the change in our function ΔC. Because the rate of change in a direction is the derivative of a function, we could express the change in the function as:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/371/1*diN96kF8ptDZOwk7Tld7Mg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/371/1*diN96kF8ptDZOwk7Tld7Mg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here, we will take the definition from calculus of the gradient of a function:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/280/1*i0viu5q_L_uA62NeQHiOtA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/280/1*i0viu5q_L_uA62NeQHiOtA.png" alt=""&gt;&lt;/a&gt;Gradient of a function: Vector with partial derivatives&lt;/p&gt;

&lt;p&gt;Now, we can rewrite the change in our function as:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/302/1*hBpXuOx111_cjNt_ISe9GQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/302/1*hBpXuOx111_cjNt_ISe9GQ.png" alt=""&gt;&lt;/a&gt;Gradient of C relates the change in function C to changes in (x,y)&lt;/p&gt;

&lt;p&gt;So now, we can see what happens with cost function when we choose a certain change in our parameters. The amount that we choose to move in any direction is called &lt;em&gt;learning rate&lt;/em&gt;, and it is what define how fast we move towards the global minimum. If we choose a very small number, we will need to make a too many moves to reach this point; however, if we choose a very big number, we are at risk of passing the point and never be able to reach it. So the challenge is to choose the learning rate small enough. After choosing the learning rate, we can update our weights and biases and make another move; process that we repeat in each iteration.&lt;/p&gt;

&lt;p&gt;So, in few words, the gradient descent works by computing the gradient ∇C repeatedly, and then updating the weights and biases, and trying to find the correct values that minimize, in that way, the cost of function. And this is how the neural network learns.&lt;/p&gt;

&lt;p&gt;Sometimes, calculating the gradient can be very complex. There is, however, a way to speed up this calculations called &lt;em&gt;stochastic gradient descent.&lt;/em&gt; This works by estimating the gradient ∇C by computing instead the gradient for a small sample of randomly chosen training inputs. Then, this small samples are average to get a good estimate of the true gradient, speeding up gradient descent, and thus learning faster.&lt;/p&gt;

&lt;p&gt;But wait a second? How do we compute the gradient of the cost function? Here is where another algorithm makes an entry: &lt;strong&gt;&lt;em&gt;Backpropagation&lt;/em&gt;&lt;/strong&gt;. The goal of this algorithm is to compute the partial derivatives of the cost function with respect to any weight &lt;em&gt;w&lt;/em&gt; and any bias &lt;em&gt;b;&lt;/em&gt; in practice, this means calculating the error vectors starting from the final layer and then, propagating this back to update the weights and biases. The reason why we need to go back is that the cost is a function of the output of our network. There are several calculations and errors that we need to compute whose formula are given by the backpropagation algorithm: 1) Output error (δL) related to the element wise (⦿) product of the gradient (▽C) by the derivative of activation function (σ′(z)), 2) error of one layer (ẟl) in terms of the error in the next layer related to the transpose matrix of the weights (Wl+1) multiplied by the error of the next layer (ẟl+1) and the element wise multiplication of the derivative of activation function, 3) rate of change of the cost with respect to any bias in the network: this means that the partial derivative of C with respect to any bias (∂C/∂bj) is equal to the error ẟl, 4) rate of change of the cost with respect to any weight in the network: meaning that the partial derivative of C with respect to any weight (∂C/∂wj) is equal to the error (ẟl) multiplied by activation of the neuron input. These last two calculation constitute the gradient of the cost function. Here, we can observe the formulas.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/375/1*8_a2jP209g6ypHF4EMBD1A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/375/1*8_a2jP209g6ypHF4EMBD1A.png" alt=""&gt;&lt;/a&gt;Four essential formulas given by backpropagation algorithms that are useful to implement neural networks&lt;/p&gt;

&lt;p&gt;The backpropagation algorithm calculates the gradient of the cost function for only one single training example. As a consequence, we need to combine backpropagation with a learning algorithm, for instance stochastic gradient descent, in order to compute the gradient for all the training set.&lt;/p&gt;

&lt;p&gt;Now, how do we apply this to our neural network in python?. Here, we can see step by step the calculations:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;h4&gt;
  
  
  Let’s wrap up everything…
&lt;/h4&gt;

&lt;p&gt;Now we can put all of these formulas and concepts that we have seen in terms of an algorithm to see how we can implement this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;INPUT&lt;/strong&gt; : We input a set of training examples and we set the activation &lt;em&gt;a&lt;/em&gt; that correspond for the input layer_._&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FEEDFORWARD&lt;/strong&gt; : For each layer, we compute the function z = w . a + b, being a = σ(z)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OUTPUT ERROR&lt;/strong&gt; : We compute the output error by using the formula #1 cited above.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BACKPROPAGATION&lt;/strong&gt; : Now we backpropagate the error; for each layer, we compute the formula #2 cited above.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OUTPUT&lt;/strong&gt; : We calculate the gradient descent with respect to any weight and bias by using the formulas #3 and #4.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Of course, that there are more concepts, implementations and improvements that can be done to neural networks, which can become more and more widely used and powerful through the last years. But I hope this information can give you a hint on what a neural network is, how it works and learns using gradient descent and backpropagation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://neuralnetworksanddeeplearning.com/"&gt;Neural Networks and Deep Learning&lt;/a&gt;. Michael Nielsen&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=h3l4qz76JhQ"&gt;Build a Neural Network in 4 minutes&lt;/a&gt;. Siraj Raval&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>datascience</category>
      <category>neuralnetworks</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>Linear and Bayesian modeling in R: Predicting movie popularity</title>
      <dc:creator>Eugenia </dc:creator>
      <pubDate>Fri, 31 Aug 2018 13:01:27 +0000</pubDate>
      <link>https://forem.com/ugis22/linear-and-bayesian-modeling-in-r-predicting-movie-popularity-2j2f</link>
      <guid>https://forem.com/ugis22/linear-and-bayesian-modeling-in-r-predicting-movie-popularity-2j2f</guid>
      <description>&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*tvhwsNMZ-MgfEIol59yxPw.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*tvhwsNMZ-MgfEIol59yxPw.jpeg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Which movie should I choose?
&lt;/h4&gt;

&lt;p&gt;Let’s imagine a rainy day. You look outside through the window and everything is grey and cold. You grab your blanket and sit in your favourite couch; it is very cozy and comfy and you just decided it’s a perfect day to watch a movie. You want to watch a good one, or something at least that it is popular. You have several options, but some of them are not even rated in the typical movie websites! Wouldn’t be nice to be able to predict what people think of those movies? Well, maybe there is a solution for that. What about predicting a movie popularity according to some characteristics? We just need a dataset with movies, some statistical tools and R studio.&lt;/p&gt;

&lt;p&gt;In our dataset, there is 651 &lt;strong&gt;&lt;em&gt;randomly sampled&lt;/em&gt;&lt;/strong&gt; movies which were released in United States movie theaters in the period of 1970–2016. The data was obtained from &lt;a href="https://www.rottentomatoes.com/"&gt;Rotten Tomatoes&lt;/a&gt; and &lt;a href="https://www.imdb.com/"&gt;IMDB&lt;/a&gt;. The dataset contains 32 features of each movie, including genre, MPAA rating, production studio, and whether they received &lt;em&gt;Oscar&lt;/em&gt; nominations, among other characteristics. So now, we can ask ourselves:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Can the popularity of a movie be predicted by considering certain of its characteristics such as type, genre, MPAA rating, number of IMDb votes, and whether it has won an award?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Before going on developing any model, we need to answer two questions: &lt;em&gt;Can our results be generalised?&lt;/em&gt; &lt;em&gt;Which type of inference can be do with the present dataset?.&lt;/em&gt; For the first question, we can notice that the movies included in this dataset were randomly sampled from the above two mentioned sources and no bias was created by the sampling method, as a consequence, we can assume that the results obtained can be &lt;strong&gt;&lt;em&gt;generalised&lt;/em&gt;&lt;/strong&gt;  &lt;strong&gt;&lt;em&gt;to all U.S movies released between 1970 and 2016&lt;/em&gt;&lt;/strong&gt;. On the other hand, this is an &lt;em&gt;observational study&lt;/em&gt;, so the relationships that could be found from this data indicate &lt;strong&gt;&lt;em&gt;association&lt;/em&gt;&lt;/strong&gt; , but &lt;em&gt;not causation&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Ready to start? Wait a second. What do we understand as “popularity” of a movie? Our dataset includes movies sample from two different sources and we have two variables that could potentially be used as &lt;em&gt;popularity&lt;/em&gt;: audience_score(Audience score on Rotten Tomatoes) and imdb_rating(Rating on IMDB). So let’s go ahead and analyse a little more these two variables. First of all, we will check whether these variables show a correlation between them. For doing this, we will plot both variables in a scatter plot:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/480/1*JKeCABBDA7JAJ3_3OEpsWA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/480/1*JKeCABBDA7JAJ3_3OEpsWA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see that the plot shows a possible positive correlation between the two variables. We will confirm this by using the function cor to numerically calculate the correlation:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;As we can observed, there is a high correlation between both variables. If we are going to include one of the variables as response, it is better to not include the other one as independent variable. So we need to decide which one to select as response variable. We can analyse their distribution by making use of histogram and summary statistics to make a wise choice. Let’s start by imbd_rating:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/480/1*GwKjZ-aSVsprqKpDafRhOg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/480/1*GwKjZ-aSVsprqKpDafRhOg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/321/1*ys4QKn6SXC5Umf7NmMGe1g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/321/1*ys4QKn6SXC5Umf7NmMGe1g.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, we can do the same for audience_score:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/480/1*wFY_H0tBeqcGGMVO9tKNWg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/480/1*wFY_H0tBeqcGGMVO9tKNWg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/346/1*90dVUkDcgQ6QV1NugwWcSg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/346/1*90dVUkDcgQ6QV1NugwWcSg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see that the variable imbd_rating shows a distribution close to normal with a slightly left skew with a mean of 6.493 and a median of 6.00. On the other hand, the variable audience_score shows a more uniform distribution with a mean of 62.36 and a median of 65.00. Because of its distribution, we will choose to considered only imdb_rating.&lt;/p&gt;

&lt;p&gt;After deciding which variable we will consider as our response variable, we need to &lt;em&gt;explore our explanatory variables&lt;/em&gt;. We can analyse the distribution of the variables that we are interested in including in our model by plotting a histogram for each of the variables and obtaining summary descriptive tables. For those variables that are &lt;strong&gt;categorical&lt;/strong&gt; , we can create a proportion table by using the build-in function table. On the other hand, we can create a data frame for &lt;strong&gt;continuous variables&lt;/strong&gt; and apply the function summary. I will not show the entire code here, but for example, in our dataset, the analysis showed that the distribution of the number of votes was right skew. In order to adjust this, we can apply a log-transformation to the values (log_votes).&lt;/p&gt;

&lt;p&gt;After that, we can analyse the interaction between our exploratory variables and the response variable. For this task, we can plot boxplot or scatter plots according to whether the exploratory variable is numerical o categorical. I will only show the significant findings.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/672/1*x0_f8oGfkNRTzoztaLobPg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/672/1*x0_f8oGfkNRTzoztaLobPg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the plots and the summary descriptive obtained, it can be seen that, in our dataset, those movies that won an &lt;em&gt;Oscar&lt;/em&gt; or the director ever won an &lt;em&gt;Oscar&lt;/em&gt; appear to have a sightly higher rating. Moreover, the number of votes given show a weak positive association with the IMDB rating. Last, the variables best_actor_win and best_actress_win appear to have the same distribution and a similar association with imdb_rating, so we will combine these two variables in a new one called main_oscar_win.&lt;/p&gt;

&lt;p&gt;Now, we have a good idea of what our response variable looks like and also a hint on which variables could be important to predict the popularity of a movie. &lt;em&gt;It’s time to start building a model!&lt;/em&gt;. We will take two approaches here: first, we will do a multiple linear regression and then, we will develop a Bayesian model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multiple linear regression model&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Multiple linear regression seek to model the relationship between two or more independent or explanatory variables and the response variable by fitting a linear equation to the data.&lt;/p&gt;

&lt;p&gt;Our goal is to reach a &lt;strong&gt;parsimonious model&lt;/strong&gt; , this is the simpler model with great explanatory predictive power. In order to do this, we have two options for model selection: Forward selection and backwards elimination. In the first case, we start with an empty model and we add one predictor at a time. We will choose the second option: Backwards elimination implies starting with a model comprising all candidates and dropping one predictor at a time until the parsimonious model is reached. In our case, our first full model will include six variables that we find before that could be important for predicting movie popularity: genre, best_pic_win, best_dir_win, main_oscar_win, log_votes and mpaa_rating. In R, we can use the function lm to build a linear model:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/553/1*N0wbQeA_wZ4aemM0LibpeQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/553/1*N0wbQeA_wZ4aemM0LibpeQ.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that we have the full model, there are several criteria that we can use in order to drop variables: p-value and adjusted R². We will choose p-value as elimination criteria due to the fact that in this case, the aim is to create a model that shows the highest predictive value using only variables with significance.&lt;/p&gt;

&lt;p&gt;After running the full model with all the variables involved, we have obtained an adjusted R² of 0.3582, which means that we can still improve the model. In order to do so, we can start by removing the variable which has the highest p-value each time, until all the variables remaining in the model are significant. So the variable that has the highest p-value in our model is main_oscar_win.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/546/1*TSuArh0W0JQ4Q3NC5KZjBQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/546/1*TSuArh0W0JQ4Q3NC5KZjBQ.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After running again our simpler model, we can see that now our adjusted R² is 0.3594. We can try to improve our model more by eliminating again the variable with the highest p-value. In this case, it will be best_pic_win.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/550/1*9_jhT4Hexo-3JKneHg_YgQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/550/1*9_jhT4Hexo-3JKneHg_YgQ.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We now see that the adjusted R² is 0.3595, not different from our previous model in step1, but with the difference that this time all variables involved are significant. I will not show it here for practical sake, but removal of any of other variables will decrease the adjusted R². So we considered this our final model.&lt;/p&gt;

&lt;p&gt;There is a very important concept to have in mind for linear regression: &lt;strong&gt;Collinearity.&lt;/strong&gt; Two variables are considered to be collinear when they are highly correlated with each other. The inclusion of collinear predictors complicates the model estimation.&lt;/p&gt;

&lt;p&gt;So at this point, we can look into our variables and see if the variables we are interested in show some degree of collinearity. In our dataset, we have mixed variables, this is we have some variables that are categorical and some that are continuous, so in this case, a way to measure collinearity is using the &lt;strong&gt;&lt;em&gt;variance inflation factor&lt;/em&gt; (VIF)&lt;em&gt;.&lt;/em&gt;&lt;/strong&gt; The VIF, that quantifies the extent of multicollinearity in an ordinary linear regression, is calculated as the ratio between the variance of the model with multiple terms and the variance of the model with one term alone. In simple words, it tells us how much the variance of a regression coefficient increases due to collinearity existent in the model. So, let’s go ahead and calculate this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/329/1*Wac5uF9_OOXsIGKVp3-Rjg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/329/1*Wac5uF9_OOXsIGKVp3-Rjg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;None of our predictors has a high VIF, so we can assume that multicollinearity is not playing a role in our model.&lt;/p&gt;

&lt;p&gt;Now, it’s time to run some diagnostic in our model. The multiple regression model depends on the following four assumptions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Each numerical explanatory variable is linearly related to the response variable&lt;/li&gt;
&lt;li&gt;Residuals are distributed nearly normal with a mean of 0&lt;/li&gt;
&lt;li&gt;Variability of residuals is nearly constant&lt;/li&gt;
&lt;li&gt;The residuals are independant&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We will test one-by-one the assumptions in the context of our model:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The only numerical variable that we have in our model is log_values. So we can explore the first assumption by checking the residual plots.&lt;/li&gt;
&lt;/ol&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/480/1*F7dayZPxnB1upwvajzGq_Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/480/1*F7dayZPxnB1upwvajzGq_Q.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The plot shows that the residuals are random scatter around 0, which indicates a linear relationship between the numerical exploratory variable and the response variable.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;To check this condition, we will perform first the histogram of the residuals and then a residuals Q-Q plot.&lt;/li&gt;
&lt;/ol&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/621/1*dEWQE6ZoNK-tDtuH8RCsQw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/621/1*dEWQE6ZoNK-tDtuH8RCsQw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we can see above, the distribution histogram and the residuals Q-Q plot show a close to normal distribution, and also mimics the left-hand skew that was observed in the original imdb rating variable.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Now, we need to check that the residuals are equally variable for low and high values of the predicted response variable. Then, we will check the plot of residuals vs. predicted.&lt;/li&gt;
&lt;/ol&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/480/1*H_SczBlKX2SGySGCC4KMgA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/480/1*H_SczBlKX2SGySGCC4KMgA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The residuals are randomly scattered in a band with a constant width around 0.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Lastly, we will check for the independency of the residuals:&lt;/li&gt;
&lt;/ol&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/480/1*ytJNSpK6v3xsf0bUiMDG4w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/480/1*ytJNSpK6v3xsf0bUiMDG4w.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The plot above does not display any particulat pattern, so it is possible to assume that the residuals and as a consequence, the observations are independant.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bayesian model&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Usually, we are taught traditional frequentist statistics to solve a problem. However, there is another approach which it is sometimes undermine for being subjective, but which is more intuitive or close to how we think about probability in everyday life and yet is a very powerful tool: &lt;strong&gt;Bayesian statistics&lt;/strong&gt;. There are some key concept on which this theory relies: &lt;em&gt;Conditional probability&lt;/em&gt; and &lt;em&gt;Bayes theorem.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Conditional probability i_s the probability that an event will happen given that another event took place. If the event B is known or assumed to have taken place, then the conditional probability of our event of interest A given B is written as _P&lt;/em&gt;(A|B).&lt;/p&gt;

&lt;p&gt;When two events are independent, meaning that A happening is not affecting B to happen, the &lt;em&gt;conjunction probability of A and B&lt;/em&gt; (in other words, the probability of both events being true) is written as &lt;em&gt;P&lt;/em&gt;(&lt;em&gt;A and B&lt;/em&gt;)= P(A) P(B). But this is not the case if A conditions B to happen, where the conjunction probability is &lt;em&gt;p&lt;/em&gt;(&lt;em&gt;A&lt;/em&gt; &lt;em&gt;and&lt;/em&gt; &lt;em&gt;B&lt;/em&gt;) = &lt;em&gt;p&lt;/em&gt;(&lt;em&gt;A&lt;/em&gt;) &lt;em&gt;p&lt;/em&gt;(&lt;em&gt;B&lt;/em&gt;|&lt;em&gt;A&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;Here, after some mathematical calculations, the &lt;em&gt;Bayes theorem&lt;/em&gt; can be derived and it is presented as follows:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;p&lt;/em&gt;(&lt;em&gt;A&lt;/em&gt;|&lt;em&gt;B&lt;/em&gt;) = &lt;em&gt;p&lt;/em&gt;(&lt;em&gt;A&lt;/em&gt;) &lt;em&gt;p&lt;/em&gt;(&lt;em&gt;B&lt;/em&gt;|&lt;em&gt;A&lt;/em&gt;) / &lt;em&gt;p&lt;/em&gt;(&lt;em&gt;B&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;To put this on words: the probability of A given that B have occurred is calculated as the unconditioned probability of A occurring multiplied by the probability of B occurring if A happened, divided by the unconditioned probability of B.&lt;/p&gt;

&lt;p&gt;There is a powerful interpretation of this theorem called &lt;strong&gt;diachronic interpretation&lt;/strong&gt; , meaning that something is happening over time, and it gives a tool to update the probability of a hypothesis provided new data. In this interpretation, the terms in our equations implies some other concepts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;p&lt;/em&gt;(&lt;em&gt;A&lt;/em&gt;) is the probability of the hypothesis before we see the data, called the prior probability, or just  &lt;strong&gt;prior&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;p&lt;/em&gt;(A|B) is our goal, this is the probability of the hypothesis after we see the data, called the &lt;strong&gt;posterior&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;p&lt;/em&gt;(&lt;em&gt;B&lt;/em&gt;|A) is the probability of the data under the hypothesis, called the &lt;strong&gt;likelihood&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;p&lt;/em&gt;(&lt;em&gt;B&lt;/em&gt;) is the probability of the data under any hypothesis, called the &lt;strong&gt;normalizing constant&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is an element which is key when we want to build a model under Bayesian approach: the &lt;strong&gt;Bayes factor.&lt;/strong&gt; The &lt;em&gt;Bayes factor&lt;/em&gt; is the ratio of the likelihood probability of two competing hypotheses (usually null and alternative hypothesis) and it helps us to quantify the support of a model over another one. In Bayesian modelling, the choice of prior distribution is a key component of the analysis and can modify our results; however, the prior starts to lose weight when we add more data. Non informative priors are convenient when the analyst does not have much prior information.&lt;/p&gt;

&lt;p&gt;In R, we can conduct Bayesian regression using the BAS package. We will use Bayesian Model Averaging ( &lt;strong&gt;BMA&lt;/strong&gt; ), that provides a mechanism for accounting for model uncertainty, and we need to indicate the function some parameters:&lt;/p&gt;

&lt;p&gt;Prior: &lt;strong&gt;Zellner-Siow Cauchy&lt;/strong&gt; (Uses a &lt;a href="https://en.wikipedia.org/wiki/Cauchy_distribution"&gt;Cauchy distribution&lt;/a&gt; that is extended for multivariate cases)&lt;/p&gt;

&lt;p&gt;Model prior: Uniform (assign equal probabilities to all models)&lt;/p&gt;

&lt;p&gt;Method: &lt;a href="https://en.wikipedia.org/wiki/Markov_chain_Monte_Carlo"&gt;Markov chain Monte Carlo&lt;/a&gt; ( &lt;strong&gt;MCMC&lt;/strong&gt; )( improves the model search efficiency)&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;We will now print the marginal inclusion probabilities obtained for the model:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/773/1*zvaGvmJpHpNbI7JyFpzdzg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/773/1*zvaGvmJpHpNbI7JyFpzdzg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that, we can use the function summary to see the top 5 models with the zero-one indicators for variable inclusion.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/681/1*2pubkrh_OQAQ-ssSRLFHSw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/681/1*2pubkrh_OQAQ-ssSRLFHSw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is also displayed a column with the Bayes factor (&lt;em&gt;BF&lt;/em&gt;) for each model to the highest probability model, the posterior probabilities of the models (&lt;em&gt;PostProbs&lt;/em&gt;), the R² of the models, the dimension of the models (&lt;em&gt;dim&lt;/em&gt;) and the log marginal likelihood (&lt;em&gt;logmarg&lt;/em&gt;) under the selected prior distribution.&lt;/p&gt;

&lt;p&gt;Last, we can make use of the function image to visualize the Log Posterior Odds and Model Rank.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/606/1*0LNC2BXgzZCb8QIX-LXZEg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/606/1*0LNC2BXgzZCb8QIX-LXZEg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the picture above, each row correspond to each variable included in the full model as well as one extra row for the intercept. In each column, we can see all possible models (2¹⁶ because we have 16 variables included) sorted by their posterior probability from the best to worst rank on the top (from left to right).&lt;/p&gt;

&lt;p&gt;From the model and the image above, we can see that:&lt;br&gt;&lt;br&gt;
&amp;gt; feature_film has a marginal probability of 0.999, and appears in all five top models&lt;br&gt;&lt;br&gt;
&amp;gt; critics_score has a marginal probability of 0.999 and also appears in all five top models&lt;br&gt;&lt;br&gt;
&amp;gt; runtime has a marginal probability of 0.98 and appears in all five top models&lt;br&gt;&lt;br&gt;
&amp;gt; drama has a marginal probability of 0.57 and appears in three of the five top models&lt;br&gt;&lt;br&gt;
&amp;gt; imbd_num_votes has a marginal probability of 0.99 and appears in three of the five top models&lt;br&gt;&lt;br&gt;
&amp;gt; the &lt;em&gt;intercept&lt;/em&gt; also has a marginal probability of 1, and appears in all five top models  &lt;/p&gt;

&lt;p&gt;According to this, the best model includes the intercept, feature_film, critics_score, drama, imbd_num_votes and runtime&lt;/p&gt;

&lt;p&gt;We can now obtain the coefficients estimates and standard deviations under BMA in order to be able to examine the marginal distributions for the important variables coefficients. To do so, we will use the function coef and plot them using plot&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/752/1*X0Fk4d61HQmp00-VdN4sSw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/752/1*X0Fk4d61HQmp00-VdN4sSw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The vertical line corresponds to the posterior probability that the coefficient equals to 0. On the other hand, the shaped curve shows the density of posiible values where the coefficient is non-zero. It is worthy to mention that the height of the line is scaled to its probability. This implies that intercept and feature_film, critics_score, imbd_num_votes and runtime show no line denoting non-zero probability.&lt;/p&gt;

&lt;p&gt;Last, we can obtain 95% credible intervals (The probability that the true mean is contained within a given interval is 0.95) for coefficients using confint method.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/510/1*cza2QRuEfoWZ4rpFT-5feA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/510/1*cza2QRuEfoWZ4rpFT-5feA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;BAS package provides us with an easy way to get graphical summaries for our model just using the function plot and the which option.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Residual vs. fitted plot&lt;/li&gt;
&lt;/ol&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/629/1*xZ0NYcew6mRRqQ_drGSs7g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/629/1*xZ0NYcew6mRRqQ_drGSs7g.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ideally, we will expect to not see outliers or non-constant variance. However, in this case we can see that there is a constant spread over the prediction but there are two outliers.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Model probabilities&lt;/li&gt;
&lt;/ol&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/619/1*6sP1XKw7Dypca8MqI7aHzA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/619/1*6sP1XKw7Dypca8MqI7aHzA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This plot displays the cumulative probability of the models in the order that they are sampled. This plot shows that the cumulative probability starts to level off after 300 model trials as each additional model adds only a small increment to the cumulative probability. The model search stops at ~1400 instead of enumerations of 2¹⁵ combinations.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Model complexity&lt;/li&gt;
&lt;/ol&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/618/1*4_jy_Cf2WLXaORbg_2CX5g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/618/1*4_jy_Cf2WLXaORbg_2CX5g.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This plot shows the dimension of each model, that is the number of regression coefficients including the intercept versus the log of the marginal likelihood of the model. In this case, we can see that highest log marginal can be reached from 5 to 12 dimensions.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Marginal inclusion probabilities&lt;/li&gt;
&lt;/ol&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/628/1*8JCs9WAhUkNm5LN5XDvGMA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/628/1*8JCs9WAhUkNm5LN5XDvGMA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this case, we can observe the marginal posterior inclusion probabilities for each of the covariates, with marginal posterior inclusion probabilities that are greater than 0.5 shown in red (important variables for explaining the data and prediction). In the graph, we can see what it was show already before about which variables contribute to the final scores.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PREDICTION&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Now it’s time to test the predictive capability of&lt;/em&gt; &lt;em&gt;our two models&lt;/em&gt;! We will use the movie “&lt;em&gt;Zootropolis&lt;/em&gt;” released in 2016. The corresponding information was obtained from the &lt;a href="https://www.imdb.com/title/tt2948356/?ref_=nv_sr_1"&gt;IMDB website&lt;/a&gt; and &lt;a href="https://www.rottentomatoes.com/m/zootopia"&gt;RottenTomatoes&lt;/a&gt; to be consistent with the analysis data.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/728/1*5vfOEBYrhqFtCkqxXHAmfg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/728/1*5vfOEBYrhqFtCkqxXHAmfg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/544/1*oy8ztgSP_yEJMwfrBYQuMA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/544/1*oy8ztgSP_yEJMwfrBYQuMA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we saw above, the true imdb_rating is 8, which is pretty close to what our Bayesian model predicted.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;So what can we conclude?&lt;/em&gt; From the linear regression and the Bayesian model we learnt that in fact the popularity of a movie can be predicted by considering characteristic data of each movie.&lt;/p&gt;

&lt;p&gt;In the linear regression analysis, it was possible to build a parsimonious, multivariable, linear model that is able to some extend to predict the movie popularity, understood as IMDb rating, with the four statistically significant predictors chosen. However, it is important to remember that the adjusted R² of our final model is only 0.3595, so this means that 35.95% of the variability is explained by the model. In the Bayesian model, we finally got a parsimonious model that also fullfilled the Bayesian assumptions.&lt;br&gt;&lt;br&gt;
From both models, we can see that the Bayesian model is the one which prediction was close to the real IMDb rating.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;References:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Peng Roger D. (2016) _Exploratory Data Analysis with R. _&lt;a href="https://leanpub.com/exdata"&gt;LeanPub&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Downey Allen B. (2012) &lt;em&gt;Think Bayes. Bayesian Statistics in Python.&lt;/em&gt; &lt;a href="http://greenteapress.com/wp/think-bayes/"&gt;Green Tea Press&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>datascience</category>
      <category>bayesianstatistics</category>
      <category>statistics</category>
      <category>linearregression</category>
    </item>
    <item>
      <title>Predicting Survival in Patients: Prediction</title>
      <dc:creator>Eugenia </dc:creator>
      <pubDate>Fri, 10 Aug 2018 14:57:15 +0000</pubDate>
      <link>https://forem.com/ugis22/predicting-survival-in-patients-prediction-2kl7</link>
      <guid>https://forem.com/ugis22/predicting-survival-in-patients-prediction-2kl7</guid>
      <description>&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*vpaLyTILKqRSQXqIu6BT7w.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*vpaLyTILKqRSQXqIu6BT7w.jpeg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Building my first Data Science project
&lt;/h4&gt;

&lt;p&gt;After getting the data, it’s very tempting to jump immediately into trying to fit several models and evaluate their performance. However, the first thing that has to be done is an exploratory data analysis (EDA), which allows us to explore the structure of our data and to understand the relationships governing the variables. Any EDA should involve creating and analysing several plots and creating summary statistics to considered the patterns present in our dataset.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you want to see, how I performed EDA for this particular project, you can read this&lt;/em&gt; &lt;a href="https://dev.to/ugis22/predicting-survival-in-patients-exploratory-analysis-3k77-temp-slug-5133306"&gt;&lt;em&gt;previous post&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;From the EDA on this project, we have learnt some important features about our dataset. First of all, it doesn’t suffer from &lt;strong&gt;&lt;em&gt;class imbalance&lt;/em&gt;&lt;/strong&gt; , that occurs when the total number of observations in one class is significantly lower that the observations in the other class. Also, some of our variables showed skewness that was fixed after log-transforming them and that no variable&lt;br&gt;&lt;br&gt;
showed a perfect linear relationship with the other, though in some of them we could observe a trend to an interaction.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Machine learning predictions&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;One of the main decisions to make when performing machine learning is choosing the appropriate algorithm that fits the current problem we are dealing with.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Supervised learning&lt;/strong&gt; refers to the task of inferring a function from a labeled training dataset. We fit the model to the labeled training set with the main goal of finding the optimal parameters that will predict unknown labels of new examples included in the test dataset. There are two main types of supervised learning: regression, in which we want to predict a label that is a real number, and classification, in which we want to predict a categorical label.&lt;br&gt;&lt;br&gt;
In our case, we have a labeled dataset and we want to use a classification algorithm to find the label in the categorical values: 0 and 1.&lt;/p&gt;

&lt;p&gt;We can find many classification supervised learning algorithms, some simple but efficient, such as linear classifier or logistic regression, and another ones more complex but powerful such as decision trees and k-means.&lt;/p&gt;

&lt;p&gt;In this case, we will choose &lt;strong&gt;Random Forest&lt;/strong&gt; algorithm. Random forest is one of the most used machine learning algorithm due to the fact that it is very simple, flexible and easy to use but produces reliable results.&lt;/p&gt;

&lt;p&gt;Briefly, random forest creates ‘&lt;em&gt;a forest&lt;/em&gt;’ of multiple decision trees and ensemble them in order to obtain a more accurate prediction. The advantages of random forest over decision trees are that the combination of the individual models improves the overall result and also, that prevents overfitting by creating smaller trees from random subsets of the features.&lt;/p&gt;

&lt;p&gt;So we will first load the packages from scikit-learn that we need to perform Random Forest and also to evaluate afterwards the model. We will also replace the categorical values with 0 or 1 or NaN as well as transform all variables to float and log-transform the variables to fix skewness, like we did in the EDA. We will again check the total number of missing values in each variable:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;In the EDA, we dropped all NaN values. Here, we need to evaluate what is the best method to handle them.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;&lt;em&gt;There are several ways to deal with missing data&lt;/em&gt;&lt;/strong&gt; but none of them is perfect. The first step is to understand why data went missing. In our case, we can guess that the values missing in the categorical variables could be due to the absence of the feature that instead of being imputed as no was left blank or that it was not tested. Also, missing values in continuous variables could be explained by the lack of biochemical studies performed in that particular patient or because the parameters were within normal range and it was not written down.&lt;/p&gt;

&lt;p&gt;In both cases, we could be in the presence of &lt;strong&gt;Missing at Random&lt;/strong&gt; value (The fact that the value is missing has nothing to do with the hypothetical value) or &lt;strong&gt;Missing not at Random&lt;/strong&gt; value (The missing value depends on the hypothetical value). If it was the first one, we could drop the NaN value safely, while in the last case it would not be safe to drop it because this missing value tell us something about the hypothetical value. So in our case, we will impute the values of the missing value once we are about to train our model.&lt;/p&gt;

&lt;p&gt;Feature scaling or data normalization, a method used to standardize the range of independent variables, is also a very important step before training many classifiers. Some models can perform very poorly if the data is not within the same range. Another advantage of random forest is that does not requiere this step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Splitting the dataset into training and test datasets&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In order to train and test our model, we need to split our dataset into to subdatasets, &lt;strong&gt;&lt;em&gt;the training and the test dataset&lt;/em&gt;&lt;/strong&gt;. The model will learn from the training dataset to generalize to other data; the test dataset will be used to “test” what the model learnt in the training and fitting step.&lt;br&gt;&lt;br&gt;
It is common to use the rule of &lt;strong&gt;80%-20%&lt;/strong&gt; to split the original dataset. It is important to use a reliable method to split the dataset to avoid data leakage; this is the presence in the test set of examples that were also in the training set and can cause overfitting.&lt;/p&gt;

&lt;p&gt;First, we will assign all the columns except our dependant variable (“Class”) to the variable X and the column “Class” to the variable Y.&lt;br&gt;&lt;br&gt;
And then we will train_test_split from the scikit-learn library to split them into X_train, X_test, Y_train and Y_test. It is important to add random_state because this will allow us to have the same results every time we run the code.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; Train/Test splitting has some disadvantages due to the fact that some models require to tune hyperparameters, that in this context, is done also in the train set. One way to avoid this is to create a Train/Validation/Test dataset with the rule 60/20/20%. There are several effective methods to do this that we will see below.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Training Random Forest&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It is very easy now to impute missing values (using Imputer), create and train the basic random forest model using the package Scikit-learn. We will start by apply .ravel() to the &lt;strong&gt;&lt;em&gt;Y_train&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;Y_test&lt;/em&gt;&lt;/strong&gt; to flatten our array as not doing so will rise warnings from our model.&lt;/p&gt;

&lt;p&gt;Then, we will impute our missing values using the function Imputer and the strategy most_frequent that will replace the missing values for the most frequent value in the column (axis = 0). It is worthy to notice that doing so can introduce errors and bias, but of course as we state before there is no perfect way to handle missing data.&lt;/p&gt;

&lt;p&gt;Our basic model has now been trained and has learnt the relationship between our independent variables and the target variable. Now, we can check how good our model is by making predictions on the test set. We can then compare the prediction with our known labels.&lt;/p&gt;

&lt;p&gt;We will again impute the missing values in our test set and use the function predict and the metrics accuracy_score to evaluate the performance of our model.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;As we can observe above, our basic model has an accuracy of 74.19% which tell us that it has to be further improved.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hyperparameters tuning&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are several ways to improve our model: gather more data, tune the hyperparameters of the model or choose other models. We will choose the second one, we will now tune the hyperparameters of our random forest classifier.&lt;/p&gt;

&lt;p&gt;Model parameters are normally learned during training; however hyperparameters must be set manually before training. In the case of random forest, hyperparameters include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;n_estimators: number of trees in the forest&lt;/li&gt;
&lt;li&gt;max_features: maximum number of features in each tree&lt;/li&gt;
&lt;li&gt;max_depth: maximum splits for all trees&lt;/li&gt;
&lt;li&gt;bootstrap: whether to implement bootstrap or not to build trees&lt;/li&gt;
&lt;li&gt;criterion: assess stopping criteria for decision trees&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Of course, when we implement basic random forest, Scikit-learn implements a set of default hyperparameters, but we are not sure if those parameters are the optimal for our particular problem.&lt;/p&gt;

&lt;p&gt;In this point is when we need to considered two concepts: underfitting and overfitting. &lt;strong&gt;&lt;em&gt;Underfitting&lt;/em&gt;&lt;/strong&gt; occurs when the model is too simple and it doesn’t fit the data well: it has low variance but high bias. On the other hand, &lt;strong&gt;&lt;em&gt;Overfitting&lt;/em&gt;&lt;/strong&gt; occurs when the model adjust too well to the training set and performs poorly in new examples. If we tune the hyperparameters in the training dataset, we would then be prone to overfit our random forest classifier. So instead, we will go back to what was mentioned before: the &lt;strong&gt;&lt;em&gt;cross validation&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;There are a many cross validation methods, the best known are: &lt;strong&gt;K-Folds Cross Validation&lt;/strong&gt; and &lt;strong&gt;Leave One Out Cross Validation.&lt;/strong&gt; In our case, we will use the first one: we will split our data into K different subsets using k-1 subsets as our training set and the last as our test data. In order to tune our hyperparameters, we will perform many iterations on the K-subset cross validation but using different model settings each time. Afterwards, we compare all models and select the best one; then, we will train the best model in the full training set and evaluate it on the testing set. We will take advantage of &lt;em&gt;GridSearchCV&lt;/em&gt; package in Scikit-learn to perform this task.&lt;/p&gt;

&lt;p&gt;We will determine the parameters and values that we want to optimize and then we will performed the GridSearchCV and set the best parameters obtained to our model.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;As we can see above our GridSearchCV improve our accuracy from 74 to 77%. Even though that it’s not a great improvement, it has been reported that with this dataset other studies reached only an accuracy of 80%. So considering this and the fact that the dataset has many missing data and it’s not big (only 155 samples) we can go on and analyse other model metrics.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test set metrics&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now that we have optimized our hyperparameters, we will proceed to evaluate our model. First of all, we will create a confusion matrixthat will tell us the True Negative, False positive, False negative and True Positive values according to our predicted values and plot it using seaborn heatmap:&lt;/p&gt;

&lt;p&gt;True Negative (TN)| False positive(FP)&lt;br&gt;&lt;br&gt;
 — — — — — — — — — — — — — — — —&lt;br&gt;&lt;br&gt;
False negative (FN)| True positive (TP)&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;Analysing the confusion matrix, we can expect that our model shows a higher recall (TP/TP+FN) than precision (TP/TP+FP) but both parameters will be higher than the accuracy(TP+TN)/Total. These three parameters can be taken into consideration according to what we consider our model needs to solve. We will come back to these afterwards.&lt;/p&gt;

&lt;p&gt;We can further investigate the False positive rates and true positive rates using ROC Curve and calculating the area under the curve that it is also a metric of the prediction power of our model (if the value is closer to 1 means that our model does a good job in differentiating a random sample into the two classes).&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;From the ROC curve, we learned that our model does not do a good job in distinguishing between both classes as the &lt;strong&gt;auc&lt;/strong&gt; is 0.60. We could improve this issue by collecting and adding more data to the model.&lt;/p&gt;

&lt;p&gt;Last, we can analyse the precision-recall curve:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;We can observe that the precision-recall relationship is quite constant for the different values, indicating that our model has a good precision and recall. This is due to the fact that the True Positive values are quite high compared to the true negative, false positive and false negative. It is important to remember that because of the formula of recall and precision, when one is high the other one is low pushing us to find a balance where both are high enough for our model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Interpreting the results&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The last thing that we could do before finishing our project is to evaluate the variable importance, that is to quantify how useful every variable is for our model.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;We can observe that age, protime, alk_phosphate, bilirubin, malaise, ascites are some of the most important variables for our model. This reflects what we have seen previously in our EDA and reinforces the importance of performing this exploratory analysis before starting the machine learning algorithm.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So after applying random forest to our dataset, we can conclude that our best model was able to predict survival from patients with hepatitis with an accuracy of 77% and a precision and recall of around 80%. This is not the best situacion since we want our model to perform better, specially in this case that involves survival of patients. However, the moderate good results could be due to the small database and the large number of missing values.&lt;/p&gt;




</description>
      <category>randomforest</category>
      <category>predictions</category>
      <category>machinelearning</category>
      <category>datascience</category>
    </item>
    <item>
      <title>Predicting Survival in Patients: Exploratory Analysis</title>
      <dc:creator>Eugenia </dc:creator>
      <pubDate>Fri, 22 Jun 2018 07:50:06 +0000</pubDate>
      <link>https://forem.com/ugis22/predicting-survival-in-patients-exploratory-analysis-5aj2</link>
      <guid>https://forem.com/ugis22/predicting-survival-in-patients-exploratory-analysis-5aj2</guid>
      <description>&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*4qCvEGLb6Iqt5ECJvBAwtA.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*4qCvEGLb6Iqt5ECJvBAwtA.jpeg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Building my first Data Science project
&lt;/h4&gt;

&lt;p&gt;I discovered soon enough that figuring out that I wanted to work towards a future in data science by taking classes and finishing specialisations was the easy part of my journey.&lt;/p&gt;

&lt;p&gt;One of the things you must do if you want to work in data science is to build &lt;em&gt;your portfolio&lt;/em&gt;. At the beginning, I struggled for days trying to find a good topic for a project, thinking on how to do it, what I should look into; many times I thought about something and soon dropped it because it was not exactly what I wanted to do. I felt I could not get it started. But it was then when I realised that building a project started much earlier than when you type the first lines of code. In fact, thinking on how to design it is one of the essential parts of any data science project.&lt;/p&gt;

&lt;p&gt;Because of my PhD and postdoctoral research work, I knew that liver disease has become one of the most common causes of death around the world. Due to the fact that ending stages can be different from patient to patient, establishing a method to assess the prognosis of a particular patient with liver disease still remains a challenge. So, I decided the purpose of my project to be the analysis of a dataset containing information about liver disease patients and the creation of a model to predict their survival.&lt;/p&gt;

&lt;p&gt;I chose a dataset from &lt;a href="https://archive.ics.uci.edu/ml/datasets/hepatitis"&gt;UCI Machine Learning Repository&lt;/a&gt; which CSV file was downloaded from &lt;a href="https://www.openml.org/d/55"&gt;Open ML website&lt;/a&gt;. It comprises an observational study where data was collected regarding 19 different features and an extra class (DIE or LIVE) from 155 patients with chronic liver disease.&lt;/p&gt;

&lt;p&gt;I decided to use Python 3 in Jupyter Notebook. Python has a set of packages, such as Numpy, Pandas, Matplotlib, Scikit-learn, that are very powerful for data analysis and visualization.&lt;/p&gt;

&lt;p&gt;First of all, it is important to use the command &lt;strong&gt;%matplotlib notebook&lt;/strong&gt; in order to interactively plot the figures. We need to load the modules to our python environment using the command &lt;strong&gt;import&lt;/strong&gt;. Because the dataset was downloaded as a CSV file, We will use the &lt;strong&gt;Pandas&lt;/strong&gt; command &lt;strong&gt;read_csv&lt;/strong&gt; that automatically reads the file into a &lt;strong&gt;DataFrame&lt;/strong&gt;. We can check the &lt;strong&gt;shape&lt;/strong&gt; of our DataFrame to match the specifications provided for our dataset: 155 patients(rows), 19 features+1 class (columns).&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Exploratory Data Analysis&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;An important part of doing predictions with Machine Learning techniques is to perform Exploratory Data Analysis (EDA). This is useful for getting to know your data, looking at it from different perspectives, describing and summarizing it without making any assumption in order to detect any potential problems.&lt;/p&gt;

&lt;p&gt;First, we can inspect our data to see if we need to clean it. We will start by using the &lt;strong&gt;head&lt;/strong&gt; command that will show us the first 5 rows of our DataFrame. As we can see below, there are missing values identified with the ? symbol. Knowing the data types of the variables included in our dataset is a good piece of information. We can check this by using dtypesfunction.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;As we can see above, 19 of our 20 variable appear as object type. Some of these variables are categorical (with ‘no’, ‘yes’ levels) and some of them should be numerical with int or float type.&lt;/p&gt;

&lt;p&gt;Because for machine learning algorithms, it is required to have numerical data, we need to convert categorical data that has values ‘no’, ‘yes’ to 0 and 1 respectively. Another important point to consider is to convert the binary survival variable ( Class) encoded now as ‘DIE’, ‘LIVE’ levels to numerical categories (0 and 1, respectively). We will use for this task, the function &lt;strong&gt;replace&lt;/strong&gt;. Lastly, we will convert all of our columns in the dataset to &lt;strong&gt;float&lt;/strong&gt;  type.&lt;/p&gt;

&lt;p&gt;Machine learning algorithms perform well when the number of observations in each class is similar but when there is a high class imbalance, problems arise leading to misclassification. &lt;strong&gt;&lt;em&gt;Class imbalance&lt;/em&gt;&lt;/strong&gt; occurs when the total number of observations in one class is significantly lower than the observations in the other class. Typically, if a data set contains 90% in one class, and 10% in the other class, then it suffers from class imbalance. In order to check this point, we can calculate what percentage of the data belongs to each category.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;We can observe above that even though our dataset is not perfectly balanced (79.35% of patients is contained inLIVE class while only 20.65% is in DIE class), it does not suffer from high class imbalance allowing us to continue with our analysis.&lt;/p&gt;

&lt;p&gt;The first step in EDA is to generate descriptive statistics summarizing the central tendency, dispersion and shape of our dataset’s distribution. We will do that using the function &lt;strong&gt;describe&lt;/strong&gt; from &lt;strong&gt;Pandas&lt;/strong&gt;. It is important to highlight here that this function excludes the NaN values present in our dataset. Because many of our variables are discrete, it does not make sense to get central tendency parameters for them. So, we will only include the numerical variables in this case. On the other hand, we will use the function &lt;strong&gt;apply&lt;/strong&gt; and &lt;strong&gt;value_counts&lt;/strong&gt; to get the counts in every level (0 or 1 that corresponded to ‘no’ and ‘yes’) for each discrete variable in our dataset.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;We can observe in the first table that the patients belong to an age bracket of 7–78 years, with a mean of 41.2 and a median of 39. There are missing values in most of the variables but in particular in PROTIME where we only have 88 observations. If we pay attention to the means of the different variables, it is interesting to note that they display a moderate variance; the range goes from 1.42 (BILIRUBIN) to 105.35 (ALK_PHOSPHATE). Also, the variables SGOT and ALK_PHOSPHATE show a high standard deviation and their distribution could be right skewed due to the fact that the mean is higher than the median. The rest of the variables appear to be normally distributed (mean ~ median). The distribution of our variables is important to considered because they could affect lately our machine learning algorithm due to the fact that many of them make assumptions about the shape of data, particularly about how the residuals are distributed. So we could evaluate to perform a transformation to fix the skewness observed.&lt;/p&gt;

&lt;p&gt;In the case of the categorical variables, there is a marked predominance of observations belonging to level 0 in the variable SEX which means that the dataset include more female than male patients. Likewise, there are more observations in the the class 0 than in the class 1 in the variables ANOREXIA, ASCITES and VARICES. This could point out that these features are differentially present in the patients and might be interesting variables influencing their survival.&lt;/p&gt;

&lt;p&gt;The next step is to create some visuals in order to understand further our dataset by exploring relationships existent in it. For this task, it is very useful to use the &lt;strong&gt;seaborn&lt;/strong&gt; library which facilitates strong attractive statistical graphics that are easy to code.&lt;/p&gt;

&lt;p&gt;We will here take some seconds to evaluate the variables included in our dataset, in particular, some that are interesting regarding liver disease. Elevated levels of Alkaline phosphatase (ALK_PHOSPHATE), Aspartate Aminotransferase (SGOT), bilirubin (BILIRUBIN), albumin (ALK_PHOSPHATE) as well as Prothrombin time (PROTIME) indicate a malfunctioning liver. The presence of anorexia (ANOREXIA) and ascites (ASCITES) appeared later in patients with liver disease and normally, indicates a poor prognosis. Because all of these mentioned variable are indicators of a more or less severe liver damage, we wold evaluate them to see their relationship and explore if they could be important for our predictive model.&lt;/p&gt;

&lt;p&gt;As we already observed, our dataset contains a lot of NaN values. How to handle missing values is an extensive topic that we will not address here, but it is important to notice that there are several ways to overcome this issue and the best way to do it has to be evaluated for each situation. In our case, we are going to drop them by using the Pandas function &lt;strong&gt;.dropna()&lt;/strong&gt;. We will create a new data frame by selecting only the interesting value that we mentioned above.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;We will continue plotting histograms from our numerical variables to visualize and confirm their distribution. In the seaborn library, the function &lt;strong&gt;displot&lt;/strong&gt; allow as to plot a univariate distribution of observations. It is possible to plot both histograms side by side by using the function &lt;strong&gt;subplot&lt;/strong&gt; of matplotlib.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;We can observed in the histograms that in fact several of our variables, including ALK_PHOSPHATE and SGOT that we had detected in the summary statistics, show a degree of skewness. There are several transformation that can be applied in order to fix that. We will use the &lt;strong&gt;Pandas&lt;/strong&gt; function &lt;strong&gt;applymap&lt;/strong&gt; and the &lt;strong&gt;Numpy&lt;/strong&gt; function &lt;strong&gt;np.log&lt;/strong&gt; to log-transform the columns corresponding to those skewed variables in our dataframe.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;Then, we can make use of the &lt;strong&gt;pairplot&lt;/strong&gt; function to visualize the relationship between the different numerical variables. One nice feature about seaborn is that we can use the parameter &lt;strong&gt;hue&lt;/strong&gt; to show with different color in the plot, the different levels of a categorical variable. In our case, we are interesting in identifying the patients in &lt;em&gt;Class 0&lt;/em&gt; and_ 1_.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;Observing the plots, we can highlight several things:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;From the histograms, we learn that the skewness present in our data was mainly fixed
&lt;/li&gt;
&lt;li&gt;We can observed that patients tend to differentiate according to whether they belong to Class 0 or Class 1 in some of our variables; however this distinction is not completely clear.
&lt;/li&gt;
&lt;li&gt;It appears that there is not a perfect linear relationship between the variables plotted, though in some of them we can observed a trend to an interaction ( SGOT and ALK_PHOSPHATE, SGOT and BILIRUBIN, PROTIME and ALBUMIN, BILIRUBIN and ALK_PHOSPHATE)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then, we can analyse the relationship between our categorical variables and our numerical variables. For this part, we will take advantage of &lt;strong&gt;PairGrid&lt;/strong&gt; of seaborn that allows us to plot with a little more freedom to choose the x and y variables. In this case, we will use the graph &lt;strong&gt;swarmplot&lt;/strong&gt; , a particular case of scatterplot which do not overlap the points.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;It is possible to observe that there is no difference in the variables plotted regarding the ANOREXIA status. This can be evidenced by the fact that not only patients from both levels of Class are distributed homogeneously but also there is not difference in the expression of the variables analysed regarding the levels of ANOREXIA. On the other hand, we can see a trend that patients with Class 0 tend to have ascites. However, there is no differences in how the variables are expressed regarding ASCITES status.&lt;/p&gt;

&lt;p&gt;The last thing that we will deepen our analysis to see if there is any strong correlation between all our parameters. The importance of performing correlation analysis in our dataset lies on the fact that highly correlated variables can hurt some models or in other cases, could provide little extra information and considering them can be computational expensive without any real benefit. Also, knowing if our variables display a linear relationship can help us choose which machine learning algorithm is more suitable for our data.&lt;/p&gt;

&lt;p&gt;For this task, we will use the Pearson correlation coefficient because it is a good parameter to evaluate the strength of the linear relationship between two variables. In order to perform the correlation analysis with all our variables, we first need to apply the function &lt;strong&gt;factorize&lt;/strong&gt; to the columns containing categorical variables contained in the dataset in order to obtain a numeric representation of them. We will now make use of the function &lt;strong&gt;corr&lt;/strong&gt; and plot the resulting array using &lt;strong&gt;heatmap&lt;/strong&gt; that will allow us to visualise the correlation coefficient by the intensity of the colours.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;We can observe in the &lt;em&gt;heatmap&lt;/em&gt; that some of the variables show a coefficient of ~0.6 or -0.4, but most of them display a very low correlation coefficient. So we can conclude that there is no strong linear correlation between our variables.&lt;/p&gt;

&lt;p&gt;We have finished the EDA of our dataset. We got to know our data and have now a feeling of it that will become very valuable when choosing the right machine learning algorithm for our case.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you want to keep going on how to perform prediction for this project, you can read&lt;/em&gt; &lt;a href="https://medium.com/@meinzaugarat/building-my-first-data-science-project-part-2-prediction-cc4d971aa17a"&gt;&lt;em&gt;my next post&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;References&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Dua, D. and Karra Taniskidou, E. (2017).&lt;a href="http://archive.ics.uci.edu/ml"&gt;UCI Machine Learning Repository&lt;/a&gt;. Irvine, CA: University of California, School of Information and Computer Science.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>exploratorydataana</category>
      <category>datascience</category>
    </item>
    <item>
      <title>Transitioning to Data Science — My journey so far</title>
      <dc:creator>Eugenia </dc:creator>
      <pubDate>Wed, 06 Jun 2018 18:18:49 +0000</pubDate>
      <link>https://forem.com/ugis22/transitioning-to-data-science-my-journey-so-far-5dd4</link>
      <guid>https://forem.com/ugis22/transitioning-to-data-science-my-journey-so-far-5dd4</guid>
      <description>&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1024/1*o_TwhpYzY99wL2mmyOt05w.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1024/1*o_TwhpYzY99wL2mmyOt05w.jpeg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since you’re little, you are constantly asked the question: “What do you want to be when you’re a grown up?”. I remember changing my mind through the years, listing a lot of different professions. But all of them had one thing in common: they all involved answering questions. I always loved trying to find answers to how things worked, or how two things that I saw were connected. I became interested in biology when I was 16, due to a very good teacher I had in high school, and soon after, I decided to study biological sciences to become eventually a full-time researcher.&lt;/p&gt;

&lt;p&gt;Through my PhD, I encounter wonderful things: trying to dissect a complicated phenomenon by understanding it and converting it into simpler questions, gather information about it to establish a background, planning and performing experiments to answer those questions, and finally interpreting and communicating our results in research papers, or orally at several national and international conferences were things fulfilling the reason why I wanted to be a biologist in the first place. As well, the possibility of doing an internship in US allowed me to meet an amazing research group that help me shape my character as a researcher and also as a person. However, everything was not bright and I also encounter plenty tough times and a lot of disappointment that dampened my enthusiasm over academia.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;All of the professions I could think of when I was growing up involved one thing: Answering questions about how things worked or were connected&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;By the time I defended my dissertation, all the certainties with which I had started were gone. I was beginning to wonder if academia was the right setting in which I wanted to develop my career in a way that there was a balance between personal life and work. I knew I was not alone. I had long talk with colleagues and friends who were going through the same issue. Nevertheless, I decided to go to on with a postdoctoral position while I figured out where in the system I fitted in. I received later an job offer from a US colleague that was moving back to Germany, which I took still exploring the future direction of my career.&lt;/p&gt;

&lt;p&gt;As a postdoc, I really enjoyed managing projects as well as mentoring and supervising students; it’s something which I personally find rewarding for getting not only to teach what I know, but also to learn from the different experiences and people. However, the lack of collaborative spirit to carry out a mutual objective or the absence of rigurosity to work along with the publish or perish culture pushed me further away from academia.&lt;/p&gt;

&lt;p&gt;In the search for the biggest answer I had to dealt with till then, &lt;em&gt;“Do I want this for myself?”,&lt;/em&gt; I started reading about bioinformatics and big data. I liked very much the concept of it being an interdisciplinary field so out of curiosity, I enrolled in “&lt;a href="https://www.coursera.org/learn/dna-analysis"&gt;Finding Hidden Messages in DNA&lt;/a&gt;” course in Coursera, part of a Bioinformatics Specialization offer by University of California San Diego. It’s a well organised course were you can opt whether you want to go for the coding track or stay with theoretical knowledge about the algorithms. I chose the first one. Due to my background, the biological concepts involved were familiar to me. The coding was another story! It was my first approach to Python and I was already struggling with slicing a string, let alone defining a function! Anyway, I was able to finish the course and to my surprise I discovered something: I loved coding in Python!! I enrolled in the next course &lt;a href="https://www.coursera.org/learn/genome-sequencing"&gt;Genome Sequencing&lt;/a&gt;. I slowly improved my skills in Python but by the end of the course, the algorithms were overwhelming and I realised that my trial-error strategy with coding will not work for long.&lt;/p&gt;

&lt;p&gt;I decided then to take a step back and learn some basic concepts enrolling in &lt;a href="https://www.coursera.org/specializations/genomic-data-science"&gt;Genomics Data Science specialization&lt;/a&gt;, offered by John Hopkins University and designed to take the students from introducing basic concepts to applying statistics and algorithms, while learning python, the R package &lt;a href="https://www.bioconductor.org/"&gt;Bioconductor&lt;/a&gt; and command line tools as well as &lt;a href="https://usegalaxy.org/"&gt;Galaxy&lt;/a&gt; software. Once I was done with this, I returned to complete the &lt;a href="https://www.coursera.org/specializations/bioinformatics"&gt;Bioinformatic Specialization&lt;/a&gt;, which provided me with a variety of innovative concepts and gave me tools to understand how complex algorithms work and how they can be applied to biological questions.&lt;/p&gt;

&lt;p&gt;Though I enjoyed learning how to code and I had strengthened my python skills, I was still not completely able to separate myself from academia. Maybe because it was my comfort zone; perhaps due to the fact that it is easy to apply bioinformatics to research. However, there was still something unsettling about the idea of me staying. It was not until I completely immerse myself into investigating the applications of big data and bioinformatics, that I discovered the unlimited potential of data science_._ The more I read, the more I became interested in that field. I started to read every blog I could find concerning its applications, the skills involved as well as the experiences of people working in it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The more I read about the data science field, the more I became interested. I started to read every blog that I could find related to its applications and the experience of people working in it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I decided to start building my future towards that direction, working in projects and doing courses in the evenings and weekends. I enrolled in &lt;a href="https://www.coursera.org/specializations/data-science-python"&gt;Applied Data Science with Python&lt;/a&gt; (offered by University of Michigan) as well as in &lt;a href="https://www.coursera.org/specializations/statistics"&gt;Statistics with R&lt;/a&gt; (offered by Duke University) specializations. The first one, it is a very useful and comprehensive five-courses specialization, where you can have an overview and a first approach to working with &lt;em&gt;pandas&lt;/em&gt;, &lt;em&gt;matplotlib&lt;/em&gt;, &lt;em&gt;scikit-learn&lt;/em&gt; as well as to machine learning and text mining basic concepts. The second one covers from basic to Bayesian statistics while doing exercise and peer-review projects in R, and it is completely worth taking as the teacher is amazingly clear in explaining all the theory. I also enrolled in Andrew Ng’s &lt;a href="https://www.coursera.org/learn/machine-learning"&gt;machine learning&lt;/a&gt; course, which as almost every post or blog that I found commented, it is a must!&lt;/p&gt;

&lt;p&gt;Something very useful for me was listening to the first &lt;a href="https://www.kaggle.com/careercon/2018"&gt;KaggleConf&lt;/a&gt; that took place in March 2018 aimed to people searching their first job in data science. The talks and discussion gave tips about creating a compelling portfolio to show your &lt;a href="https://github.com/ugis22"&gt;projects&lt;/a&gt;, tailoring your &lt;a href="https://www.linkedin.com/in/meinzaugarat/"&gt;CV&lt;/a&gt;, finding opportunities and preparing for a potential interview.&lt;/p&gt;

&lt;p&gt;So, I finally made up my mind: I’m leaving academia and most importantly, I found out that data science might be the right setting to apply my skills, which I’m trying to enhance, in a way that better satisfy my vision on life and work.&lt;/p&gt;

&lt;p&gt;The next step after taking this decision and finishing online specializations was to start my own data science projects that you can read about it &lt;a href="https://medium.com/@meinzaugarat/building-my-first-data-science-project-part-1-exploratory-analysis-9112684badcd"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>academia</category>
      <category>transitioning</category>
      <category>datascience</category>
    </item>
  </channel>
</rss>
