<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Keith Brooks on Medium]]></title>
        <description><![CDATA[Stories by Keith Brooks on Medium]]></description>
        <link>https://medium.com/@kbrook10?source=rss-b76e61029f27------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*X3D8ei8E4Td60KAa4HrVxg.jpeg</url>
            <title>Stories by Keith Brooks on Medium</title>
            <link>https://medium.com/@kbrook10?source=rss-b76e61029f27------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 05:37:35 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@kbrook10/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Day (5) — Web Scraping — Using Regular Expressions]]></title>
            <link>https://medium.com/@kbrook10/day-5-web-scraping-using-regular-expressions-50e991bfc547?source=rss-b76e61029f27------2</link>
            <guid isPermaLink="false">https://medium.com/p/50e991bfc547</guid>
            <category><![CDATA[regex]]></category>
            <category><![CDATA[web-scraping]]></category>
            <category><![CDATA[python]]></category>
            <dc:creator><![CDATA[Keith Brooks]]></dc:creator>
            <pubDate>Thu, 28 Mar 2019 02:24:42 GMT</pubDate>
            <atom:updated>2019-03-28T02:24:42.378Z</atom:updated>
            <content:encoded><![CDATA[<h3>Day (5) — Web Scraping — Using Regular Expressions</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*_RW9u8q1ObVi7uMO" /><figcaption>Photo by <a href="https://unsplash.com/@ryanmfranco?utm_source=medium&amp;utm_medium=referral">Ryan Franco</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><h3>What are Regular Expressions:</h3><p>Yep, when your pattern is not working right, it can make you feel like the baby above. However, that is not what we are talking about here. Focusing back on web scraping… Everything can be thought of as a character. By writing patterns to match a sequence of characters, we are creating a regular expression. Based on wikipedia, <a href="https://en.wikipedia.org/wiki/Regular_expression">regular expressions</a> “is a sequence of characters that define a search pattern. Usually this pattern is used by string searching algorithms for “find” or “find and replace” operations on strings, or for input validation. It is a technique that developed in theoretical computer science and formal language theory. “</p><p>During the first initial chapters on the web scraping book I obtained (i.e. <a href="https://github.com/REMitchell/python-scraping"><em>Web Scraping Book with Python — Ryan Mitchell</em></a>), I started noticing multiple instances of regular expressions (i.e. regex). These seemed like a flexible and scalable way to filter information. After the last entry, I felt it was time to brush up on my skills.</p><p><strong>Step 1:</strong><br><em>~ Find a resource to quickly learn the basics.</em></p><p>After a quick google search, I came across <a href="https://regexone.com/">RegexOne</a>. This is a great site that incorporates quick, short lessons to practice what you are learning. After a few examples, I started feeling better and understanding the flow more. Now it was time to practice what was preached on a live site.</p><h3>What are possible Use Cases:</h3><p>~ Filtering text in resume<br>~ Searching for specific entries in medical notes<br>~ Web scraping<br>~ etc.</p><p>Below is a four step process I used to target a id tag within a &lt;div&gt;, on the NPR site.</p><h3>Process to creating your First Regular Expression:</h3><p><strong><em>Step 1</em></strong><em> — Review the </em><a href="https://www.npr.org/robots.txt"><em>https://www.npr.org/robots.txt</em></a><em> file for NPR</em></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0c80faca82e4d2ec849088d8c0fdb7be/href">https://medium.com/media/0c80faca82e4d2ec849088d8c0fdb7be/href</a></iframe><p><strong><em>Step 2</em></strong><em> — Navigate to the desired page and inspect for respective div tag</em></p><p>Here, I am focused on targeting the &lt;div&gt; tag with id “storytext”. Once that has been located, the goal is to print the first paragraph starting with “The Medicaid expansion…”.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fZgH5EJfjXZVX6i65vRVEg.png" /></figure><p><strong><em>Step 3</em></strong><em> — Take the id and paste into regex platform to try patterns to match sequence</em></p><p>Here, I tested out various patterns to get the test string to highlight all of the characters. Is this the best pattern every created…No…Could this capture other sequence of characters…Yes…However, for the html being reviewed this pattern avoids these pitfalls.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rQfkT51jAdzHwfzo7NLsWA.png" /></figure><p><strong><em>Step 4</em></strong><em> — Add to program</em><br>Here we run the program with our regular expression in step 2.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*aqZETHfq7AKsBPHtOgDK-w.gif" /></figure><h3>Code:</h3><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2d3b68408faa6b2e241a316e48d973ba/href">https://medium.com/media/2d3b68408faa6b2e241a316e48d973ba/href</a></iframe><p>On line 15 we see the re.compile with the pattern created to find “storytext”.</p><p>~ ^[s]+ -&gt; finds a string that begins with the character ‘s’, matching at least once.</p><p>~ [t]+ -&gt; adds to that string the character ‘t’, matching at least once.</p><p>~ [a-z]{1,7} -&gt; adds to the string any character within the range of a to z, matching a repetition of a minimum of no less than 1 and a maximum of no more than 7.</p><p>~ $ -&gt; suggests the end of the pattern.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/17ef6e7573cb2ea7e0c73b73c72f2a8d/href">https://medium.com/media/17ef6e7573cb2ea7e0c73b73c72f2a8d/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7f65430d3152e1c6c9d95f4342ae19fb/href">https://medium.com/media/7f65430d3152e1c6c9d95f4342ae19fb/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f12e2653560b0e4f458064e621102a3e/href">https://medium.com/media/f12e2653560b0e4f458064e621102a3e/href</a></iframe><p><strong>Lessons Learned:</strong><br><em>~ Find the tag in the html that needs to be selected<br>~ Practice regex prior to adding to code to test<br>~ Insert regex into code<br>~ Repeat</em></p><p><strong>Next Steps:</strong><br><em>~ It would be nice to learn more about logging errors, instead of using the print() method.</em></p><p><strong>Food For Thought:</strong><br>~ (<a href="http://rick.measham.id.au/paste/explain.pl">Plain English</a> Explanation of Regex — Just Paste) -&gt; Highly Recommend!</p><blockquote><em>“Wherever there is a human being, there is an opportunity for a kindness.”</em></blockquote><blockquote><em>— Seneca</em></blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=50e991bfc547" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Day (4) — Web Scraping — Crawling the Internet]]></title>
            <link>https://medium.com/@kbrook10/day-4-web-scraping-crawling-the-internet-a108d556674?source=rss-b76e61029f27------2</link>
            <guid isPermaLink="false">https://medium.com/p/a108d556674</guid>
            <category><![CDATA[beautifulsoup]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[web-scraping]]></category>
            <dc:creator><![CDATA[Keith Brooks]]></dc:creator>
            <pubDate>Tue, 26 Mar 2019 23:10:15 GMT</pubDate>
            <atom:updated>2019-03-26T23:23:20.514Z</atom:updated>
            <content:encoded><![CDATA[<h3>Day (4) — Web Scraping — Crawling the Internet</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*DGmc5d2Bowan757f" /><figcaption>Photo by <a href="https://unsplash.com/@picsea?utm_source=medium&amp;utm_medium=referral">Picsea</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><h3>The baby search engine…</h3><p>Cute picture, but we are not talking about that type of crawling. At a high level, a search engine can be thought of in two parts. Part A, concerns multiple data warehouses to store all the data collected. Part B, is the crawler to scrape the internet. However, what we see in our preferred browser is not all of the internet. Apparently, there is a thing called the <a href="https://www.dictionary.com/e/dark-web/">deep web and then another called the dark net</a>. The deep web includes any part of the web that is not indexed by search engines, which is a good bit. Some suggest this makes of 90% of the internet. The Dark web is intentionally hidden from search engines using <a href="https://lifehacker.com/what-is-tor-and-should-i-use-it-1527891029">Tor</a> and other elements. This deep web may have a great deal of information, but it could be difficult finding without a web scraper. But, first things first…Let’s figure out how to create a crawler to jump from one external link to another.</p><p><strong><em>[Caution: Building web crawlers that are not contained within a page, may quickly lead to Non-PG material. So, be careful when creating.]</em></strong></p><p>As with most things, a little planning never hurts in the long run. Below are a few questions to reference below plugging away at your code.</p><h3>Before you start scraping, ask the following:</h3><p><strong><em>~</em></strong><em> What information do I need to gather and why?<br></em><strong><em>a)</em></strong><em> Are there pre-defined websites that hold this data?<br></em><strong><em>b)</em></strong><em> Will this crawler need to discover new sites or not?</em></p><p><strong><em>~</em></strong><em> Does the crawler reach a website and drill down into the various pages or does it quickly follow the next outbound link?</em></p><p><strong><em>~</em></strong><em> What are specific websites that should not be scraped (i.e. those depending on local languages)?</em></p><p><strong><em>~</em></strong><em> What are the legal implications if my crawler draws the attention of a webmaster?</em></p><p>In the below example, we are crawling the web with no specific target in mind at this time. The bot will need to discover new sites and will use <a href="https://docs.python.org/2/library/sets.html">set()</a> method to hold an unordered collections of unique urls. At this time, we have no limits on the bot regarding specific websites. And lastly, we have reviewed the <a href="https://hbr.org/robots.txt">https://hbr.org/robots.txt</a> and should be ok. However, I did see a <a href="http://www.botreports.com/user-agent/008.shtml">User-Agent: 008</a> had a disallow rule. So, it is always worth notifying the webmaster just in case.</p><p>Below is one example of how to use a bot to crawl from one external link to another.</p><h3>(5) Step Process:</h3><ul><li><em>Step 1 — Import Libraries</em></li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2ddcfb1f9689aa392c96515d6015b76d/href">https://medium.com/media/2ddcfb1f9689aa392c96515d6015b76d/href</a></iframe><ul><li><em>Step 2 &amp; 3 — Set variable to unique links and randomizer to randomly select links</em></li></ul><p>This uses the current time of the device to set the initial value to generate a random value, in step 3.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/040512bf1d5953a1eef5e9f590716434/href">https://medium.com/media/040512bf1d5953a1eef5e9f590716434/href</a></iframe><ul><li><em>Step 4 — Retrieve list of Links</em></li></ul><p>The try/ except section uses the urlparse() method to break up the url. Below is taken from the documentation. In our case, the conditional finds internal links by using the pattern that they begin with ‘/’ and consist of the current domain network location.</p><pre>&gt;&gt;&gt; from urlparse import urlparse<br>&gt;&gt;&gt; o = urlparse(&#39;http://www.cwi.nl:80/%7Eguido/Python.html&#39;)<br>&gt;&gt;&gt; o   # doctest: +NORMALIZE_WHITESPACE<br>ParseResult(scheme=&#39;http&#39;, netloc=&#39;www.cwi.nl:80&#39;, path=&#39;/%7Eguido/Python.html&#39;,<br>            params=&#39;&#39;, query=&#39;&#39;, fragment=&#39;&#39;)</pre><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a1852ecf5a5c71b661ce786a3b7cc882/href">https://medium.com/media/a1852ecf5a5c71b661ce786a3b7cc882/href</a></iframe><p>This stores our external links in a python list. The regex searches for &lt;a&gt; tags that begin with either http or www; however, it excludes internal network locations. If it finds an external link it adds it to the external links list.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ed7820fa7e1dd6f411561369079f1505/href">https://medium.com/media/ed7820fa7e1dd6f411561369079f1505/href</a></iframe><p>This part focuses on finding if any external links already exist within the page with the conditional “if len(external_links) ==0” section. If none found, the bot proceeds to look within the current domain until one is found. If there exists an external link, it follows that trail.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/546ed2442f0a19a3630ab1de1a74f8d1/href">https://medium.com/media/546ed2442f0a19a3630ab1de1a74f8d1/href</a></iframe><p>This takes the initial site and calls the function to retrieve the file and parse the information using BeautifulSoup, prints a random external link that has been scraped and then searches for the next in the list of external links.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/625f1b15ea7303c15c5e47c7d90a7387/href">https://medium.com/media/625f1b15ea7303c15c5e47c7d90a7387/href</a></iframe><ul><li><em>Step 5 — Trigger Program</em></li></ul><p>This triggers the program to start at the Harvard Business Review website.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/592c5a2fdfca9317d6b71f19abc13070/href">https://medium.com/media/592c5a2fdfca9317d6b71f19abc13070/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KJ3erGyP4rzZpNwcx09Itg.gif" /></figure><p>Well it appears that I have hit a HTTP 403 — Forbidden Error…</p><p>A great tip when planning the initial phase is to draw out a flow diagram as well, like below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*OrQbJ8NZBQzu2ZigtQdEGw.jpeg" /></figure><h3>Lessons Learned:</h3><p><em>~ </em><a href="https://docs.python.org/2/library/random.html"><em>.random()</em></a><em> -&gt; Pseudo-random number generator.<br>~ </em><a href="https://stackoverflow.com/questions/22639587/random-seed-what-does-it-do"><em>.seed()</em></a><em> -&gt; Seeding a pseudo-random number generator gives it its first “previous” value to perform some operation on.<br>~ </em><a href="https://docs.python.org/2/library/datetime.html"><em>.datetime()</em></a><em> -&gt; Provides the ability to manipulate dates and times in both simple and complex ways<br>~ </em><a href="https://docs.python.org/2/library/urlparse.html"><em>urlparse()</em></a><em> -&gt; Breaks URL strings up in components (addressing scheme, network location, path etc.), to then combine back into a URL string later.<br>~ .robots.txt -&gt; Examples below<br>a) </em><a href="https://www.google.com/robots.txt"><em>https://www.google.com/robots.txt</em></a><em> -&gt; there are a lot here<br>b) </em><a href="https://www.yahoo.com/robots.txt"><em>https://www.yahoo.com/robots.txt</em></a><em><br>c) </em><a href="https://www.bloomberg.com/robots.txt"><em>https://www.bloomberg.com/robots.txt</em></a><em> -&gt; Found a nice apply here message with this one.</em></p><h3>Next Steps:</h3><p><em>~ Regular expressions -&gt; Still struggling to consistently make my own regex from scratch. Need more practice.</em></p><h3>Food for Thought:</h3><p>~ <a href="https://en.wikipedia.org/wiki/Exception_handling#Exception_support_in_programming_languages">Exception Handling</a>: <br>~ Always draw out the Flow of Program<br>~ <a href="https://blog.scrapinghub.com/2016/08/25/how-to-crawl-the-web-politely-with-scrapy">Polite Web Crawler Article</a><br>~ Disallow Bots: (Example: <a href="https://hbr.org/robots.txt">https://hbr.org/robots.txt</a>)</p><blockquote>It’s time you realized that you have something in you more powerful and miraculous than the things that affect you and make you dance like a puppet.— <a href="http://www.dailystoic.com/Marcus-Aurelius/">Marcus Aurelius</a></blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a108d556674" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Day (3) — Web Scraping — Online Course Scraping]]></title>
            <link>https://medium.com/@kbrook10/day-3-web-scraping-online-course-scraping-f16989b5811?source=rss-b76e61029f27------2</link>
            <guid isPermaLink="false">https://medium.com/p/f16989b5811</guid>
            <category><![CDATA[python]]></category>
            <category><![CDATA[beautifulsoup]]></category>
            <category><![CDATA[web-scraping]]></category>
            <dc:creator><![CDATA[Keith Brooks]]></dc:creator>
            <pubDate>Tue, 26 Mar 2019 02:34:28 GMT</pubDate>
            <atom:updated>2019-03-26T20:23:33.463Z</atom:updated>
            <content:encoded><![CDATA[<h3>Day (3) — Web Scraping — Online Course Scraping</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*x1Iq3Tdx2vYHPGA5" /><figcaption>Photo by <a href="https://unsplash.com/@aaronburden?utm_source=medium&amp;utm_medium=referral">Aaron Burden</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>For some students, being called on is a thrill and a privilege. For others…Not so much. This is the time to prove that all the teacher has been instructing has not gone in one ear and out the other. Well, after writing my first scraper I thought it would be good to find another website to test. So, in the words of <a href="https://www.franklincovey.com/the-7-habits.html">Stephen Covey</a>, let us start with the begin in mind. Let us build a scraper to find online courses from one of the many education platforms.</p><p><strong>Options:</strong><br><em>~ </em><a href="https://www.udemy.com/"><em>Udemy</em></a><em><br>~ </em><a href="https://www.coursera.org/courses"><em>Coursera</em></a><em><br>~ </em><a href="https://www.udacity.com/courses/all"><em>Udacity</em></a></p><p><strong>Goal:</strong><br><em>1) Create a web scraper to pull online course titles and their rankings from three websites.<br> a) Udemy<br> b) Coursera<br> c) Udacity</em></p><h3>I’m not afraid of Errors…</h3><p>After successfully completing the first program, the second should be easier. Well, that is what I thought. First I ran into errors, specifically “<a href="https://www.w3.org/Protocols/HTTP/HTRESP.html">HTTP Error 403: Unauthorized</a>”. In the back of my mind the <a href="https://www.youtube.com/watch?v=Fe93CLbHjxQ">Ghostbuster’s song</a> came to mind “I ain’t afraid of no ghost”. Or better yet, I am not afraid of a little error. After a google search, I learned that this error pertains to something that is forbidden and authorization will not help. That was enough for me to stay away. However, without “<a href="https://www.programiz.com/python-programming/exception-handling">handling exceptions</a>” I would have never known that was tripping up the program. So on to the next site. Using coursera, I was able to avoid the HTTP errors and access the html. I was off to the races, woot woot! Using a combination of .find(), .find_all(), and html tags, I was able to navigate to the title and ratings. Below is an easy five step process to create your own scraper.</p><p><strong>The Setup:</strong><br>* The example uses <a href="https://www.python.org/downloads/">Python 3.6</a> within <a href="https://jupyterlab.readthedocs.io/en/stable/getting_started/installation.html">Jupyter lab</a> with the below dependencies<br>~ <a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/">BeautifulSoup</a></p><p><strong>Warning:</strong><br><em>* Feel free to review the docs for additional arguments for the methods.<br>* Or pick up these books for additional details on the math behind these topics:<br>~ </em><a href="https://github.com/REMitchell/python-scraping"><em>Web Scraping Book with Python — Ryan Mitchell</em></a></p><p><strong>(5) Step Process:</strong><br><em>~ Step 1 — Import libraries<br>~ Step 2 — Create Generic URL retrieval function<br>~ Step 3 — Assign variable to Generic URL<br>~ Step 4 — Navigate to list of courses<br>~ Step 5 — Print data</em></p><p><em>Step 1 — Import libraries</em></p><p>This is the basic setup where urlopen allows us to retrieve a specific url from the server. HTTPError allows for us to handle potential errors during the process of obtaining the web file from the server. BeautifulSoup allows us to parse the data for insights.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3a1206b5afb3872ae71ce6e46cd43dfa/href">https://medium.com/media/3a1206b5afb3872ae71ce6e46cd43dfa/href</a></iframe><p><em>Step 2 — Create Generic URL retrieval function</em></p><p>It is important to use handling exceptions here to alert of potential issues.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d4f505b004e73698cc23967910222f42/href">https://medium.com/media/d4f505b004e73698cc23967910222f42/href</a></iframe><p><em>Step 3 — Assign variable to Generic URL</em></p><p>During the troubleshooting phase, I used page_content.prettify() to initially try and see if the content would display. This I switched over and added a try/ except to this section to better understand the error being received.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/718132241fe5bf6ec0474be3e205e1ff/href">https://medium.com/media/718132241fe5bf6ec0474be3e205e1ff/href</a></iframe><p><em>Step 4 — Navigate to list of courses</em></p><p>Here we use the .find() method from BeautifulSoup to navigate to the specific section where the course list is located.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/191b75cf396330d1d96dd26ca071ba13/href">https://medium.com/media/191b75cf396330d1d96dd26ca071ba13/href</a></iframe><p><em>Step 5 — Print data</em></p><p>Here we loop over the list of &lt;li&gt; tags that contain the course specifics and extract the title and current rating.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/843bc514e84989098be87d8583e0d83b/href">https://medium.com/media/843bc514e84989098be87d8583e0d83b/href</a></iframe><h3>Lessons Learned:</h3><p>The use of exception handling was a big advantage to understand what was going on during the initial steps of the program. Once I understood the error, it was easier to identify the next steps to take. Breaking out the code with multiple exceptions made the process of finding out where specifically the error occurred. Next, the .find() and .find_all() are very useful methods that have been great for me as a beginner. And finally, f-strings make reading the final result easier on the eyes.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RGN2pPH3x8Uo_vAXtvn6AA.png" /></figure><h3>Next Step:</h3><p>Regular expressions may have more flexibility than the current method, so that would be interesting to add to future projects. Also, I was at a <a href="https://www.meetup.com/indypy/">local meetup</a> and they mentioned using <a href="https://www.digitalocean.com/community/tutorials/how-to-use-logging-in-python-3">logging</a> instead of the print() method. I will need to dig more into this.</p><h3>Resources:</h3><p>~ <a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/">BeautifulSoup</a><br>~ <a href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html">HTTP Status Codes</a><br>~ <a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/#calling-a-tag-is-like-calling-find-all">Calling Tags</a></p><blockquote>“Difficulties strengthen the mind, as labor does the body.” — Lucius Annaeus Seneca</blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f16989b5811" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Day (2) — Advanced HTML Parsing]]></title>
            <link>https://medium.com/@kbrook10/day-2-advanced-html-parsing-a717ccc1b61f?source=rss-b76e61029f27------2</link>
            <guid isPermaLink="false">https://medium.com/p/a717ccc1b61f</guid>
            <category><![CDATA[beautifulsoup]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[web-scraping]]></category>
            <category><![CDATA[regular-expressions]]></category>
            <dc:creator><![CDATA[Keith Brooks]]></dc:creator>
            <pubDate>Fri, 22 Mar 2019 17:26:22 GMT</pubDate>
            <atom:updated>2019-03-25T19:45:29.151Z</atom:updated>
            <content:encoded><![CDATA[<h3>Day (2) — Web Scraping — Advanced HTML Parsing</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*sllySPxyR_dp_1Ia" /><figcaption>Photo by <a href="https://unsplash.com/@sortino?utm_source=medium&amp;utm_medium=referral">Joshua Sortino</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>Note: The information below is based on the book, “<a href="https://www.amazon.com/Web-Scraping-Python-Collecting-Modern/dp/1491985577">Web Scraping with Python</a>” by Ryan Mitchell. This blog is a way for me to refer back to my notes and assist with my learning.</p><p>When you have a hammer, sometimes everything looks like a nail. Einstein once suggested, <em>“Everything should be made as simple as possible, but not simpler.”</em> This is all to say layering techniques may be a way to impress others or a way that leads to <strong>fragile code</strong> that is hard to debug. Below are five steps to assist.</p><p><strong>(5) Ways to Avoid Advanced HTML Parsing:</strong></p><p><em>1) When code heavily relies on the structure of a website, this may lead to vulnerabilities if the site ever changes.<br>2) There may be some sites that have a “Print this Page” option that has a cleaner HTML format.<br>3) Depending on the comfort level with Javascript, there may be ways to find hidden dictionaries with tons of information.<br>4) Depending on the development, useful information may be contained in the url of the page.<br>5) If the content desired is not unique to a specific page, feel free to investigate other sources that may be easier to access.</em></p><p>Assuming all of the above has been exhausted, there are times when Advanced HTML parsing is helpful (i.e. lets get out our small hammer).</p><p><strong>Topics:</strong><br><em>~ Creative Ways to Select Content</em><br>1) BeautifulSoup options<br>2) Regular Expressions: Define; Common Symbols; ID things about tag; sites;<br><em>~ Use cases<br>~ Anatomy of Creative Scraper</em><br># Step 1 — Import libraries<br># Step 2 — Create Generic URL retrieval function<br># Step 3 — Assign variable to Generic URL<br># Step 4 — Parse Data</p><p><strong>The Setup:</strong><br><em>* The example uses Python 3.6(</em><a href="https://www.python.org/downloads/"><em>https://www.python.org/downloads/</em></a><em>) within Jupyter notebook(</em><a href="http://jupyter.org/"><em>http://jupyter.org/</em></a><em>) with the below dependencies<br>~ </em><a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/"><em>BeautifulSoup</em></a></p><p><strong>Warning:</strong><br><em>* Feel free to review the docs for additional arguments for the methods.<br>* Or pick up these books for additional details on the math behind these topics:<br>~ (</em><a href="https://github.com/REMitchell/python-scraping"><em>Author of Web Scraping Book</em></a><em>)</em></p><h3>Creative Ways to select content:</h3><p>A quick review of the <a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/">BeautifulSoup website</a> and it is clear that there are many ways filter content. We could use the .find_all() method and iterate through the list we retrieve back. We could pass in a parameter to the .find_all() method of limit, to limit the amount of items we retrieve in our list. We could use the .find() method, to search for the first instance of a tag, attribute, position or content. The possibilities feel like that are endless. Below are a few methods from BeautifulSoup.</p><p><a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/#calling-a-tag-is-like-calling-find-all"><strong>Calling Tags</strong></a><strong>: </strong><br><em>1) </em><a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/#find"><em>.find()</em></a><em> -&gt; returns list containing single result; If it can’t find anything it returns None.<br>2) </em><a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/#find-all"><em>.find_all()</em></a><em> -&gt; scans an entire document for results; If it can’t find anything it returns an empty list.<br>3) </em><a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/#find-next-siblings-and-find-next-sibling"><em>.find_next_siblings()</em></a><em> -&gt; this iterates over the element’s siblings in a navigation tree and returns all matches</em></p><h3>Regular Expressions:</h3><p>What is a regular expression? They are a sequence of characters that define a search pattern…Or think of them as tools to identify regular strings which can be generated by a series of linear rules. An example would be a program that validates/ matches an email, telephone number, etc. If trying to target unique image tags, this would be a great resource. See example below in step four.</p><h3>Anatomy of Creative Scraper of Item Page and Price:</h3><p>Below is a process to scrape the information from a Craigslist page.</p><p>Step 1 covers importing the necessary libraries for requesting urls from the server, handling exceptions regarding server errors or page errors, using beautifulsoup to parse the html and using regular expressions to filter the content.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/894d92591e8b18faf314abfed060d6a7/href">https://medium.com/media/894d92591e8b18faf314abfed060d6a7/href</a></iframe><p>Step 2 covers creating a generate function to retrieve the desired url and find the unordered list tag within the html. This focuses on just the items for sale on the craigslist page.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/46f9a8a817cfac7d863f0beba2fa627b/href">https://medium.com/media/46f9a8a817cfac7d863f0beba2fa627b/href</a></iframe><p>Step 3 defines the url we wish to scrape and assigns a variable to the generic site file function.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/54943875a484547b279beac6581e537c/href">https://medium.com/media/54943875a484547b279beac6581e537c/href</a></iframe><p>Step 4 uses regular expression to target only a tags with a class of “result-image” and then proceeds to locate the item page link and the cost of the item. F-strings are used to make the content look better.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/064c29e0dc966aa49ef61048b23300fe/href">https://medium.com/media/064c29e0dc966aa49ef61048b23300fe/href</a></iframe><p>Below is the finished result.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9YOJQzwae4vHfD34h2H3Iw.png" /></figure><p>Well, that is all for today.</p><p>Quote:</p><blockquote>“Luck is what happens when preparation meets opportunity.” — Seneca</blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a717ccc1b61f" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Day (1) — Building a Basic Web Scraper]]></title>
            <link>https://medium.com/@kbrook10/day-1-building-a-basic-web-scraper-f1caaff82166?source=rss-b76e61029f27------2</link>
            <guid isPermaLink="false">https://medium.com/p/f1caaff82166</guid>
            <category><![CDATA[python]]></category>
            <category><![CDATA[beautifulsoup]]></category>
            <category><![CDATA[html]]></category>
            <category><![CDATA[web-scraping]]></category>
            <dc:creator><![CDATA[Keith Brooks]]></dc:creator>
            <pubDate>Tue, 19 Mar 2019 22:43:58 GMT</pubDate>
            <atom:updated>2019-03-23T12:13:37.585Z</atom:updated>
            <content:encoded><![CDATA[<h3>Day (1) — Web Scraping — Building a Basic Web Scraper</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*kGHw-sOIpog4Pmc4" /><figcaption>Photo by <a href="https://unsplash.com/@ahmad_kanbar?utm_source=medium&amp;utm_medium=referral">ahmad kanbar</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p><em>Note: The information below is based on the book, “</em><a href="https://www.amazon.com/Web-Scraping-Python-Collecting-Modern/dp/1491985577"><em>Web Scraping with Python</em></a><em>” by Ryan Mitchell. </em><strong><em>This blog is a way for me to refer back to my notes and assist with my learning</em></strong><em>.</em></p><h3>What is the End Goal of this Journey?</h3><p>Stephen Covey always started “<a href="https://www.franklincovey.com/the-7-habits.html">Begin with the End in Mind</a>”, regarding one of the 7 Habits. A while ago, I completed a course on <a href="https://www.udemy.com/python-for-data-science-and-machine-learning-bootcamp/">Data Science with Python</a>. It was exciting to learn the new tools, but everywhere I turned I kept hearing “You need to access messy data”. As my interest are focused on data engineering and data science, I quickly learned it is critical to have clean data. The whole concept, “Trash in Trash out” is real. I thought…What better way to obtain messy data than to go to the internet. However, there was a problem. I knew nothing about this thing called Web Scraping. The end goal is to learn more about this technique and find what works best for me. Below are a few of the elements that will be covered along the adventure.</p><p><em>1) Databases<br>2) Web Servers<br>3) HTTP<br>4) HTML<br>5) Internet Security<br>6) Image Processing<br>7) And a little Data Science</em></p><p><strong>Topics:</strong><br><em>~ What is Web Scraping<br>~ What are Use Cases<br>~ Anatomy of a Basic Web Scraper<br>1) Import Libraries<br>2) Create generic function<br>3) Assign variable <br>4) Handle Exceptions</em></p><h3>What is web scraping?:</h3><p>Is it a tool construction workers give to the intern and say, “Class is now in session, Wax On…Scrape Off”? Is it a device required to tear up the bathroom floor for remodeling? Well, those are all good guesses, but we are discussing something else. We are referring to the process of aggregating data by means other than having a program interact with an API (i.e. <a href="https://en.wikipedia.org/wiki/Application_programming_interface">application programming interface</a>). At a high level, a web scraper does the following.</p><p><em>1) Queries a web server automatically<br>2) Sends request for data<br>3) Extracts information by parsing data</em></p><h3>What are some use Cases?</h3><p>Have you ever had a project where large quantities of data needed to be gathered and processed quickly? The recommended way would normally be to access an API; however, sometimes that will not work due to certain limitations. Enter stage left Web Scraping with a few, yet not all, use cases below.</p><p><em>1) Machine Learning Training Data<br>2) Medical Diagnostics<br>3) Forecasting</em></p><h3>Anatomy of Basic Web Scraper:</h3><p>A web scraper may consist of, Step (1), importing Libraries to allow for sending requests to the server, handling server and page errors as well as formatting of HTML content. Step (2) Consists of creating a generic function to retrieve a file, given a url. During this phase, we will need to account for page, server and/ or missing tag errors. Step (3) assigns the variable to the object created from the previous function to allow for further parsing. Step (4) allows for parsing the data to extract useful information.</p><p><strong>The Setup:</strong><br>* The example uses <a href="https://www.python.org/downloads/">Python 3.6</a> within <a href="https://jupyterlab.readthedocs.io/en/stable/getting_started/overview.html">Jupyter lab</a> with the below dependencies.<br>~ <a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/">BeautifulSoup</a></p><p><strong>Warning:</strong><br><em>* Feel free to review the docs for additional arguments for the methods.<br>* Or pick up these books for additional details on the math behind these topics:<br>~ (Author of Web Scraping Book) </em><a href="https://github.com/REMitchell/python-scraping"><em>https://github.com/REMitchell/python-scraping</em></a></p><p><strong>1) Import Libraries</strong></p><p>The urllib is a standard Python library that allows for us to request urls from the server for scraping. There are numerous errors to account for; however, HTTPError allows for checking if a page is not found on a server. While, URLError validates that the server is found. BeautifulSoup is a none standard library that helps organizing messy data from the internet.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UTT51ASFTE6y6b3K4wHt4A.png" /></figure><p><strong>2) Generic URL Retrieval Function</strong></p><p>Handling exceptions allows for us to check for potential errors that may negatively affect our program.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*A6C0vu_McmDOayZps4P5HQ.png" /></figure><p><strong>3) Assign variable</strong></p><p>This variable is assigned to the function that will target the python.org events page for data retrieval.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jjLytR8QBLl5lnvjw2RLYg.png" /></figure><p><strong>4) Handle Exceptions</strong></p><p>If there are errors we will receive the “Sorry the file…” message. However, if we are successful there will be a list of events. The for loop takes the BeautifulSoup object we created and drills down the page to the &lt;ul&gt; tag, specifically with the class ‘list-recent-events’. We quickly reviewed the structure of the site’s HTML to identify this was where the information was located. The .find_all() function allows us to target only the &lt;li&gt; tags. Once we have focused on this area we create variables for the event name and date to print.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*49hK0IMDQ9ZcWsKlOQhf3g.png" /></figure><p>Congratulations, we have a list of events.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*aCHASlsGIKwSCLvenn-TVQ.png" /></figure><p>Well, that is our first web scraper! Next we get to play with a Web Crawler.</p><p><em>“Think of the life you have lived until now as over and, as a dead man, see what’s left as a bonus and live it according to Nature. Love the hand that fate deals you and play it as your own, for what could be more fitting?” — </em><a href="http://www.dailystoic.com/Marcus-Aurelius/"><em>Marcus Aurelius</em></a></p><p><strong>Resources:<br></strong>~ (Documentation on urllib) <a href="https://docs.python.org/3/library/urllib.html">https://docs.python.org/3/library/urllib.html</a><br>~ (BeautifulSoup) <a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/#">https://www.crummy.com/software/BeautifulSoup/bs4/doc/#</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f1caaff82166" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[(Day 2) — Data Engineering — Where to Start]]></title>
            <link>https://medium.com/@kbrook10/day-2-data-engineering-where-to-start-358a388fc2ff?source=rss-b76e61029f27------2</link>
            <guid isPermaLink="false">https://medium.com/p/358a388fc2ff</guid>
            <category><![CDATA[studying]]></category>
            <category><![CDATA[learning]]></category>
            <dc:creator><![CDATA[Keith Brooks]]></dc:creator>
            <pubDate>Fri, 29 Jun 2018 03:33:00 GMT</pubDate>
            <atom:updated>2018-06-29T03:33:00.239Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*kzFi4dDJvzhlR_4A" /><figcaption>Photo by <a href="https://unsplash.com/@gitfo?utm_source=medium&amp;utm_medium=referral">Gerrie van der Walt</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>With any new venture, it feels like the hardest thing to do is start. Questions float around like…What should be learned first? Where is the best value training? What platform offers the best value? And many more…So, what is one option to start learning Data Engineering? Having struggled with other skills, reinforcements were needed this time.</p><p><strong><em>Agenda:</em></strong><br><em>~ How to Learn fast<br>~ Rapid Skill Acquisition<br>~ (10) Principles of Rapid Skill Acquisition<br>~ (10) Principles of Effective Learning</em></p><p><strong><em>Warning:</em></strong><br><em>* This is just one path and there are many ways to attain a desired skill.</em></p><p><strong>Learning Fast:</strong></p><p>To organize this initial process, there is a very <a href="https://www.amazon.com/First-20-Hours-Learn-Anything/dp/1591846943/ref=sr_1_1?">helpful book</a> by Josh Kaufman titled “The First 20 Hours, How to Learn Anything Fast”. In a way the secret sauce can be thought of as follows…</p><p><strong><em>Recipe:</em></strong></p><p><em>1) Know what you are getting into</em></p><ul><li>Focus on desconstructing the skill into the smallest possible subskills.</li></ul><p><em>2) Learn the fundamentals</em></p><ul><li>Learn about the most important subskills to ensure practice is conducted intelligently and there is a self-correct element during the progression. The goal is to be able to be self-aware and adapt quickly if something is not working.</li></ul><p><em>3) Remove Obstacles</em></p><ul><li>Learn to remove physical, mental and emotional barriers.</li></ul><p><em>4) Identify a Consistent Practice routine</em></p><ul><li>Dedicate self to practicing subskills for at least 20 hours before deciding to move on to another venture, if the skill is no longer interesting.</li></ul><p><strong>Rapid Skill Acquisition:</strong></p><p>The book focuses on Rapid Skill Acquisition, which is the process of breaking a skill down into the smallest possible parts, by identifying the most important areas of the skill and practicing these first. This allows for creativity, flexibility and freedom to experiment during the experience. The process typically passes through three stages to achieve skill acquisition.</p><p><strong><em>(3) Stages -&gt; Using infants’ walking experience as example…</em></strong></p><p><em>1) Cognitive (Early) Stage</em></p><ul><li>Think of an infant watching toddlers walking and beginning their first steps to do the same thing.</li></ul><p><em>2) Associative (Intermediate) Stage</em></p><ul><li>Think of this as an infant discovering their balance and coordination, by taking the first few steps unassisted.</li></ul><p><em>3) Autonomous (Late) Stage</em></p><ul><li>Finally think of this as freedom, or the time to child proof additional areas of the house. Quick…Baby on the run!</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*0wPPqjRQVWPJrlxE" /><figcaption>Photo by <a href="https://unsplash.com/@phammi?utm_source=medium&amp;utm_medium=referral">MI PHAM</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>This is nice and all, but how can it be used to help learn Data Engineering? Enter the 10 principles of Rapid Skill Acquisition. This is the what to do.</p><p><strong>10 Principles of Rapid Skill Acquisition:</strong></p><p>These will be our roadmap to successfully acquiring our intended skills.</p><p><strong><em>(10) Principles:</em></strong></p><ol><li><em>Choose a lovable project</em><br>~ By putting all focus on the prime skill, we should be able to acquire it in less time.</li><li><em>Focus your energy on </em><strong><em>ONE</em></strong><em> skill at a time</em><br>~ This is like the dog being distracted by the squirrel…Stop That! Creating a “Someday/ Maybe” list is very helpful to log things of interest to be reviewed at a later date.</li><li><em>Define target performance level</em><br>~ Take the time to write a brief statement of what the end looks like. What does it look like when the skill has been obtained to the desired level? A good reference is Steven Covey’s 7 Habits of Highly Effective People (i.e. Begin with the end in mind).</li><li><em>Deconstruct skill into subskills (Very Important)</em><br>~ Learning to Snowboarding Example<br>Lock boots into bindings<br>Stand up<br>Practice falling<br>Leaf down the slopes<br>Practice front side and then back side</li><li><em>Obtain critical tools</em><br>~ Finding these prior to starting practice is critical.</li><li><em>Eliminate barriers to practice</em><br>~ The key is to alter the environment as much as possible to make it easy to initiate practice.</li><li><em>Make dedicated time for practice</em><br>~ Dedicate at least 90 minutes/ day to practice<br>~ Pre-commit to at least 20 hours of practice before stopping the skill acquisition</li><li><em>Create Fast Feedback loops</em><br>~ Create opportunities to get feedback on performance as quickly as possible. Possibly from friends, family, industry experts or others who are knowledgeable.</li><li><a href="https://www.nngroup.com/articles/power-law-learning/"><strong><em>Practice</em></strong></a><em> by the clock in short bursts</em><br>~ Use phone timer, or alternate device, to practice for 20 minutes sessions at a time.<br>~ Break practice sessions into smaller chunks with 3 to 5 per day</li><li><em>Emphasize quantity and speed</em><br>~ It is critical to focus on practicing as much as possible, as quickly as possible in the beginning. Be sure the practice is not sloppy however.</li></ol><p>Think or these elements as a <strong>checklist to get started</strong>. Now we need to learn the how to do. Enter 10 Principles of Effective Learning.</p><p><strong>10 Principles of Effective Learning:</strong></p><blockquote>“No problem can withstand the assault of sustained thinking.” ~ Voltaire</blockquote><ol><li><em>Research Skill and related topics</em><br>~ Spend 20 minutes, or more, to find resources on the skill.<br>~ Find at least 3 references (i.e. books, dvds, course material, etc.).<br>~ Identify trends and patterns regarding the most important subskills.<br>~ Skimming is fine.</li><li><em>Jump in over your head</em><br>~ Move forward, even though the content may be confusing (i.e. this is going to be hard for some).<br>~ Strive for an intimidating learning pace.</li><li><em>Identify mental models and mental hooks</em><br>~ Mental Models -&gt; This is like putting labels on things that come up over and over again in the reviewing of reference materials.<br>~ Mental Hooks -&gt; This is using analogies and metaphors to remember new concepts. Think of how a wonderful Librarian assists users to resources the same way a server helps users to a website of interest.</li><li><em>Imagine opposite of what you want</em><br>~ Think about the worst possible result, from the experience.<br>~ Ask…What if everything goes wrong? What is the worst possible outcome?<br>~ This should help to point out the most important skills to acquire.</li><li><em>Talk to practitioners to get expectations</em><br>~ Ask what does reasonable performance look like for a beginner?<br>~ This should help prevent discouragement, or at least limit the instances.</li><li><em>Eliminate distractions in your environment</em><br>~ Off with the digital devices…<br>~ Find a quiet space from friends and family…And even enemies.</li><li><em>Use spaced repetition and reinforcement for memorization concepts</em><br>~ Ideas that are harder to remember are reviewed often, while easier ones are reviewed less often.<br>~ Try using flash cards.</li><li><em>Create scaffolding and checklists</em><br>~ Checklists -&gt; Helps to remember the setup for every practice<br>~ Scaffolding -&gt; Structured approach to practicing skill…Think about how players set up to conduct free throws in basketball. Yes, even Shaq probably had some process. : )</li><li><em>Make and test predictions</em><br>~ Try new things and see what works…Be the mad scientist…<br>~ Try to guest the outcome for the experiment is started…<br><em>(4) Steps</em><br>~ a) Observations — What currently observing?<br>~ b) Knowns — What known about topic?<br>~ c) Hypothesis — What will improve performance?<br>~ d) Tests — What to do next?<br>~ Record the experiments for future reference.</li><li><em>Honor your biology</em><br>~ Break up study sessions to prevent burn-out.</li></ol><p>Again, these are just <strong>helpful checklists</strong> to stay focused on the task at had and provide a <strong>structured process</strong> for learning.</p><p>Well, time to start building that road map.</p><blockquote>“A problem well stated is a problem half-solved.” — Charles Kettering</blockquote><p>Potential Food for Thought (Books):<br>~ <a href="https://www.amazon.com/Mindset-Psychology-Carol-S-Dweck/dp/0345472322">Mindset: The New Psychology of Success</a> (Dr. Dweck) <br>~ <a href="https://www.amazon.com/First-20-Hours-Learn-Anything/dp/1591846943/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1530206615&amp;sr=1-1&amp;keywords=the+first+20+hours+how+to+learn+anything...+fast">The First 20 Hours</a> (Josh Kaufman) <br>~ <a href="https://www.amazon.com/7-Habits-Highly-Effective-People/dp/0935721800/ref=asap_bc?ie=UTF8">7 Habits</a> (Stephen Covey)</p><p>Until next time…</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=358a388fc2ff" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[(Day 1) — Data Engineering Journey]]></title>
            <link>https://medium.com/@kbrook10/day-1-data-engineering-journey-d854c1e9b34a?source=rss-b76e61029f27------2</link>
            <guid isPermaLink="false">https://medium.com/p/d854c1e9b34a</guid>
            <category><![CDATA[blog]]></category>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[journal]]></category>
            <category><![CDATA[data-engineering]]></category>
            <dc:creator><![CDATA[Keith Brooks]]></dc:creator>
            <pubDate>Wed, 27 Jun 2018 13:00:06 GMT</pubDate>
            <atom:updated>2018-06-27T13:00:06.314Z</atom:updated>
            <content:encoded><![CDATA[<p>After completing a course on Udemy for Data Science, I felt it was important to learn more about Data Engineering. Why you ask? Because like anything in the wild, very little is clean and ready to work with for a project. There are steps prior to conducting analysis and doing cool machine learning and deep learning techniques to gain insights.</p><p>This is where Data Engineering comes into play. Well, this is the start! Let’s see what happens.</p><p>Disclaimer: I took a front-end engineering course at a bootcamp in 2016. Since then, the majority of my training has been through online courses, youtube and reading various industry books. This is my personal journey, which may be different for you. However, I am sure there will be some great lessons along the way.</p><p>“Get busy living, or get busy dying” ~ Andy Dufresne…</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d854c1e9b34a" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Day (11) — Machine Learning — Using KNN (K Nearest Neighbors) with scikit-learn]]></title>
            <link>https://medium.com/@kbrook10/day-11-machine-learning-using-knn-k-nearest-neighbors-with-scikit-learn-350c3a1402e6?source=rss-b76e61029f27------2</link>
            <guid isPermaLink="false">https://medium.com/p/350c3a1402e6</guid>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[pandas]]></category>
            <category><![CDATA[scikit-learn]]></category>
            <category><![CDATA[numpy]]></category>
            <dc:creator><![CDATA[Keith Brooks]]></dc:creator>
            <pubDate>Wed, 04 Apr 2018 16:13:37 GMT</pubDate>
            <atom:updated>2019-01-03T19:43:16.597Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*ZZPsimpdrTbOO7FV." /><figcaption>“A man wears a hat that reads &quot;Love Your Neighbour&quot; on crowded Rheinpromenade” by <a href="https://unsplash.com/@ninastrehl?utm_source=medium&amp;utm_medium=referral">Nina Strehl</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>This article covers work from the <a href="https://www.udemy.com/python-for-data-science-and-machine-learning-bootcamp">Python for Data Science and Machine Learning Bootcamp course</a> on Udemy by Jose Portilla and helpful tips along the way. This course was very helpful in gaining a base understanding of the topic.</p><p><strong>What is this KNN (K Nearest Neighbors) all about?:</strong><br>Who is KNN? Is it some underground band that is bringing a <a href="https://www.youtube.com/watch?v=ZyHipL45pwM">new sound</a> with the banjo that lives next door? Steve Martin, watch out now. What is it? Does it make a pie better than Patti LaBelle’s <a href="https://www.youtube.com/watch?v=eQRwFn7WPk8">sweet potato pie</a>? Well, no. KNN is a classification algorithm. It uses the k value and distance metric(<a href="https://en.wikipedia.org/wiki/Euclidean_distance">Euclidean distance</a>) to measure the distance of new points to nearest neighbors. The pros include that it is: simple to implement, training is easier and it has few parameters. The cons include: high prediction cost, doesn’t play well with numerous features and doesn’t like categorical features. Sorry qualitative features, only quantitative welcome here. The figure below displays a new point — identified by the star — that we want to classify. If we use a k value of 3, we would classify the new point with the gray elements. However, if we use a k value of 10, we would then classify the new point with the orange elements. The smaller the k value the greater the noise with the data; however, we can smooth this out by increasing the value of k.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/544/1*DiDliGvrwvoheDCvgzX7vw.png" /></figure><p><strong>What are some use Cases?:</strong><br>There are times where data may be given that is anonymized and the goal is to attempt to classify it, without really knowing the context of the data. Think group customer personalities to recommend certain products. Some of the ‘use cases’ of this are for the following:</p><ul><li>Recommender Systems</li><li>Theft prevention in the modern retail business</li><li>Detect patterns in credit card usage and much more</li></ul><p><strong>Topics:</strong><br><em>~ What is KNN<br>~ How do we use it<br>1) Import Libraries<br>2) Read in Dataset<br>3) Standardize scale to prep for KNN Algorithm<br>4) Split data into training and test sets<br>5) Create and Train the Model<br>6) Make predictions with the Model <br>7) Evaluate the predictions<br>8) Evaluate alternative K-values for better predictions<br>9) Plot Error Rate<br>10) Adjust K value per error rate evaluations</em></p><p><strong>The Setup:</strong><br>* The example uses <a href="https://www.python.org/downloads/">Python 3.6</a>within <a href="http://jupyter.org/">Jupyter notebook</a> with the below dependencies<br><a href="https://matplotlib.org/users/installing.html#installing">Matplotlib 2.1.2</a> <br><a href="https://www.scipy.org/scipylib/download.html">Numpy 1.14.1</a> <br><a href="https://pandas.pydata.org/">Pandas 0.20.3</a><br><a href="https://seaborn.pydata.org/installing.html">Seaborn 0.7.1</a> <br><a href="http://scikit-learn.org/stable/install.html">Scikit Learn 0.19.1</a></p><p><strong>Warning:</strong><br>* Feel free to review the docs for additional arguments for the methods.<br>* Books for additional details on the math behind these topics:<br>~ Book (<a href="http://www-bcf.usc.edu/~gareth/ISL/">An Introduction to Statistical Learning — The Math</a>)<br>~ Book (<a href="https://web.stanford.edu/~hastie/Papers/ESLII.pdf">The Elements of Statistical Learning</a>)</p><p><strong>Step 1: Import the necessary Libraries</strong><br>Similar to previous discussions, we will need to import libraries that allow for data analysis and data visualization to get acclimated to the dataset. We will be using pandas, numpy, matplotlib and seaborn to conduct this.</p><p>Data Exploration libraries</p><pre>import pandas as pd<br>import numpy as np</pre><p>Data Visualization libraries</p><pre>import matplotlib.pyplot as plt<br>import seaborn as sns<br>%matplotlib inline</pre><p><strong>Step 2: Read in the dataset</strong><br>We will use the pandas .read_csv() method to read in the <a href="https://raw.githubusercontent.com/kbrook10/bootcamp_python_for_data_science_and_machine_learning/master/support_files/Machine%20Learning%20Sections/K-Nearest-Neighbors/Classified%20Data">dataset</a>. Then we will use the .head() method to observe the first few rows of the data, to understand the information better. In our case, the feature(column) headers tell us pretty little. This is fine because we are merely trying to gain insight via classifying new data points by referencing it’s neighboring elements.</p><pre># Use pandas .read_csv() method to read in classified dataset<br># index_col -&gt; argument assigns the index to a particular column</pre><pre>df = pd.read_csv(&#39;Classified Data&#39;, index_col=0)</pre><pre># Use the .head() method to display the first few rows<br>df.head()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xbBPBnIQSpmVHgDs-0emHQ.png" /></figure><p><strong>Step 3: Standardize (normalize) the data scale to prep for KNN algorithm</strong><br>Because the distance between pairs of points plays a critical part on the classification, it is necessary to normalize the data to minimize this(<a href="https://stats.stackexchange.com/questions/287425/why-do-you-need-to-scale-data-in-knn">helpful link</a>). This will generate an array of values. Again, KNN depends on the distance between each feature.</p><pre># Import module to standardize the scale<br>from sklearn.preprocessing import StandardScaler</pre><pre># Create instance (i.e. object) of the standard scaler<br>scaler = StandardScaler()</pre><pre># Fit the object to all the data except the Target Class<br># use the .drop() method to gather all features except Target Class<br># axis -&gt; argument refers to columns; a 0 would represent rows<br>scaler.fit(df.drop(&#39;TARGET CLASS&#39;, axis=1))</pre><p>We should obtain the following confirmation below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/976/1*ZysnlVZvo-6er1sW0M_fBw.png" /></figure><pre># Use scaler object to conduct a transforms<br>scaled_features = scaler.transform(df.drop(&#39;TARGET CLASS&#39;,axis=1))</pre><pre># Review the array of values generated from the scaled features process<br>scaled_features</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*sgdxlzWaW4BUtX600jM6sQ.png" /></figure><p>Here we have the normalized dataset, minus the target column</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*s1NegNNfgxZdO5wrgkrNgA.png" /></figure><p><strong>Step 4: Split the normalized data into training and test sets</strong><br>This step is required to prepare us for the fitting (i.e. training) the model later. The “X” variable is a collection of all the features. The “y” variable is the target label which specifies the classification of 1 or 0 based. Our goal will be to identify which category the new data point should fall into.</p><pre># Import module to split the data<br>from sklearn.model_selection import train_test_split</pre><pre># Set the X and ys<br>X = df_feat<br>y = df[&#39;TARGET CLASS&#39;]</pre><pre># Use the train_test_split() method to split the data into respective sets<br># test_size -&gt; argument refers to the size of the test subset<br># random_state -&gt; argument ensures guarantee that the output of Run <br># 1 will be equal to the output of Run 2, i.e. your split will be always the same</pre><pre>X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=101)</pre><p>This allows for use to train our model on the training set and evaluate the built model against the test set to identify errors.</p><p><strong>Step 5: Create and Train the Model</strong><br>Here we create a KNN Object and use the .fit() method to train the model. Upon completion of the model we should receive confirmation that the training has been completed.</p><pre># Import module for KNN<br>from sklearn.neighbors import KNeighborsClassifier</pre><pre># Create KNN instance<br># n_neighbors -&gt; argument identifies the amount of neighbors used to ID classification<br>knn = KNeighborsClassifier(n_neighbors=1)</pre><pre># Fit (i.e. traing) the model<br>knn.fit(X_train, y_train)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1PHBPi3GKArs8mylm7JHow.png" /></figure><p><strong>Step 6: Make Predictions</strong><br>Here we review where our model was accurate and where it misclassified elements.</p><pre># Use the .predict() method to make predictions from the X_test subset<br>pred = knn.predict(X_test)</pre><pre># Review the predictions<br>pred</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JejF0_1OVYz9DGBVBwqKGA.png" /></figure><p><strong>Step 7: Evaluate the predictions</strong><br>Evaluate the Model by reviewing the classification report or confusion matrix. By reviewing these tables, we are able to evaluate how accurate our model is with new values.</p><pre># Import classification report and confusion matrix to evaluate predictions<br>from sklearn.metrics import classification_report, confusion_matrix</pre><p><em>Classification Report -&gt; This tells us our model was 92% accurate…</em></p><pre># Print out classification report and confusion matrix<br>print(classification_report(y_test, pred))</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/922/1*tvqe2-lhfHwcbqdc-lbxpw.png" /></figure><p><em>Confusion Matrix</em></p><pre># Print out confusion matrix<br>cmat = confusion_matrix(y_test, pred)</pre><pre>#print(cmat)<br>print(&#39;TP - True Negative {}&#39;.format(cmat[0,0]))<br>print(&#39;FP - False Positive {}&#39;.format(cmat[0,1]))<br>print(&#39;FN - False Negative {}&#39;.format(cmat[1,0]))<br>print(&#39;TP - True Positive {}&#39;.format(cmat[1,1]))<br>print(&#39;Accuracy Rate: {}&#39;.format(np.divide(np.sum([cmat[0,0],cmat[1,1]]),np.sum(cmat))))<br>print(&#39;Misclassification Rate: {}&#39;.format(np.divide(np.sum([cmat[0,1],cmat[1,0]]),np.sum(cmat))))</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/756/1*NzWF0ghKbSiolsYtoR3Yiw.png" /></figure><p><strong>Step 8: Evaluate alternative K-values for better predictions</strong><br>To simplify the process of evaluating multiple cases of k-values, we create a function to derive the error using the average where our predictions were not equal to the test values.</p><pre># Generate function to add error rates of KNN with various k-values<br># error_rate -&gt; empty list to gather error rates at various k-values<br># for loop -&gt; loops through k values 1 to 39<br># knn -&gt; creates instance of KNeighborsClassifier with various k<br># knn.fit -&gt; trains the model<br># pred_i -&gt; conducts predictions from model on test subset<br># error_rate.append -&gt; adds error rate of model with various k-value, using the average where prediction not<br># equal to the test values</pre><pre>error_rate = []</pre><pre>for i in range(1,40):<br>    <br>    knn = KNeighborsClassifier(n_neighbors=i)<br>    knn.fit(X_train, y_train)<br>    pred_i = knn.predict(X_test)<br>    error_rate.append(np.mean(pred_i != y_test))</pre><p><strong>Step 9: Plot Error Rate</strong></p><pre># Configure and plot error rate over k values</pre><pre>plt.figure(figsize=(10,4))<br>plt.plot(range(1,40), error_rate, color=&#39;blue&#39;, linestyle=&#39;dashed&#39;, marker=&#39;o&#39;, markerfacecolor=&#39;red&#39;, markersize=10)<br>plt.title(&#39;Error Rate vs. K-Values&#39;)<br>plt.xlabel(&#39;K-Values&#39;)<br>plt.ylabel(&#39;Error Rate&#39;)</pre><p>Here we see that the error rate continues to decrease as we increase the k-value. A picture tells a thousand words. Or at least here, we are able to understand what value of k leads to an optimal model. The k-value of 17 seems to give a decent error rate without too much noise, as we see with k-values of 28 and larger.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*o9Y24C_yJYXkTkhHwx54Sg.png" /></figure><p><strong>10) Adjust K value per error rate evaluations</strong><br>This is just fine tuning our model to increase accuracy. We will need to retrain our model with the new k-value.</p><pre># Retrain model using optimal k-value</pre><pre>knn = KNeighborsClassifier(n_neighbors=17)<br>knn.fit(X_train, y_train)<br>pred = knn.predict(X_test)</pre><p><em>Classification Report -&gt; This tells us our model was 95% accurate…</em></p><pre># Print out classification report and confusion matrix<br>print(classification_report(y_test, pred))</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/932/1*rTFdYUtg8ddu2kawOH-Ffw.png" /></figure><p><em>Confusion Matrix</em></p><pre># Print out confusion matrix<br>cmat = confusion_matrix(y_test, pred)</pre><pre>#print(cmat)<br>print(&#39;TP - True Negative {}&#39;.format(cmat[0,0]))<br>print(&#39;FP - False Positive {}&#39;.format(cmat[0,1]))<br>print(&#39;FN - False Negative {}&#39;.format(cmat[1,0]))<br>print(&#39;TP - True Positive {}&#39;.format(cmat[1,1]))<br>print(&#39;Accuracy Rate: {}&#39;.format(np.divide(np.sum([cmat[0,0],cmat[1,1]]),np.sum(cmat))))<br>print(&#39;Misclassification Rate: {}&#39;.format(np.divide(np.sum([cmat[0,1],cmat[1,0]]),np.sum(cmat))))</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*08GC4zW7A5c__FcG3AMCtA.png" /></figure><p>Well, until next time. Still trying to find a better way to consolidate the information as I learn new content. The goal is to get back to publishing a post a day, per each new machine learning algorithm studied.</p><p>Tips:</p><p>~ Currently reading <a href="https://www.amazon.com/Naked-Statistics-Stripping-Dread-Data/dp/1480590185"><em>Naked Statistics</em></a> by Charles Wheelan. Great perspective on statistics and how it is used in everyday life. If you hated your undergrad courses because you saw know purpose, this is the book for you.</p><blockquote>Quote<br>It’s easy to lie with statistics, but it’s hard to tell the truth without them. ~ Andrejs Dunkels</blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=350c3a1402e6" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Day (10) — Machine Learning — Using LogisticRegression with scikit-learn]]></title>
            <link>https://medium.com/@kbrook10/day-10-machine-learning-using-logisticregression-with-scikit-learn-99316e6589cd?source=rss-b76e61029f27------2</link>
            <guid isPermaLink="false">https://medium.com/p/99316e6589cd</guid>
            <category><![CDATA[pandas]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[data-visualization]]></category>
            <category><![CDATA[scikit-learn]]></category>
            <category><![CDATA[python]]></category>
            <dc:creator><![CDATA[Keith Brooks]]></dc:creator>
            <pubDate>Mon, 26 Mar 2018 20:01:01 GMT</pubDate>
            <atom:updated>2019-01-03T19:42:48.149Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*jmlY84yRrTgPji-H." /><figcaption>Photo by <a href="https://unsplash.com/@cdr6934?utm_source=medium&amp;utm_medium=referral">Chris Ried</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>This article covers work from the <a href="https://www.udemy.com/python-for-data-science-and-machine-learning-bootcamp">Python for Data Science and Machine Learning Bootcamp course</a> on Udemy by Jose Portilla and helpful tips along the way. This course was very helpful in gaining a base understanding of the topic.</p><p><strong>What is Logistic Regression:</strong><br>Unlike the discussion on <a href="https://medium.com/@kbrook10/day-9-machine-learning-using-linearregression-with-scikit-learn-f27ad23fe986">linear regression</a>, not all problems in the world are continuous. There are times when the solution to our problems is of a binary state. This model helps with classifying a new data point and by specifying which category it most closing aligns. These categories can be thought of as qualitative elements. To predict qualitative responses, we use <a href="http://www.cs.cmu.edu/afs/cs/usr/kdeng/www/thesis/logistic.pdf">classification</a>. This is different from linear regression, as linear regression is concerned with the prediction of continuous values. <a href="http://www-bcf.usc.edu/~gareth/ISL/getbook.html">Logistic regression models</a> the probability that a response falls into a specific category. Once trained we may use the confusion matrix to evaluate the classification. The four values are true positive (predicted yes and actually was yes), true negative (predict no and actually was no), false positive (predicted yes and actually was no) and false negative (predicted no and actually was yes).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JasUenDUYp2-sm8ww6Nq9g.jpeg" /></figure><p>False Positives(FP) are type I errors (i.e. think or these as doctor informing a man he is pregnant). False Negatives(FN) are type II errors (i.e. think of a doctor telling a pregnant women that she is not indeed pregnant).</p><p><strong>What are some use Cases?:</strong><br>A <a href="https://en.wikipedia.org/wiki/Logistic_regression">logistic regression</a> model helps us solve, via the Sigmoid function, for situations where the output can take but only two values, 1 or 0. This process can be used to identify spam email vs. non-spam emails, whether or not that loan offer approves an application or the diagnosis of a particular disease.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UCLF7o-kDrYA7ey2tY4fjg.jpeg" /></figure><p><strong>We will be working with the </strong><a href="https://www.kaggle.com/c/titanic"><strong>Titanic Dataset</strong></a><strong>:</strong><br>To learn about logistic regression, we will be working with the Titanic dataset from <a href="https://www.kaggle.com/">Kaggle</a>.</p><p><strong>Topics:</strong><br><em>~ What is Logistic Regression*<br>~ What are use cases for Logistic Regression*<br>~ Example with Titanic Dataset<br>a) Exploratory Data Analysis<br>b) Cleaning Data to handle missing and categorical data<br>c) Training the Logistic Regression Model</em></p><p><strong>The Setup:</strong><br>* The example uses <a href="https://www.python.org/downloads/">Python 3.6</a>within <a href="http://jupyter.org/">Jupyter notebook</a> with the below dependencies<br><a href="https://matplotlib.org/users/installing.html#installing">Matplotlib 2.1.2</a> <br><a href="https://www.scipy.org/scipylib/download.html">Numpy 1.14.1</a> <br><a href="https://pandas.pydata.org/">Pandas 0.20.3</a><br><a href="https://seaborn.pydata.org/installing.html">Seaborn 0.7.1</a> <br><a href="http://scikit-learn.org/stable/install.html">Scikit Learn 0.19.1</a></p><p><strong>Warning:</strong><br>* Feel free to review the docs for additional arguments for the methods.<br>* Books for additional details on the math behind these topics:<br>~ Book (<a href="http://www-bcf.usc.edu/~gareth/ISL/">An Introduction to Statistical Learning — The Math</a>)<br>~ Book (<a href="https://web.stanford.edu/~hastie/Papers/ESLII.pdf">The Elements of Statistical Learning</a>)</p><p><strong>Exploratory Analysis:</strong><br>It is always beneficial to get to know your data before jumping too far into analysis. It has been stated many times before, using the .info() and .describe() methods are great tools to quickly get a feel for your data. Please refer to images below after the dataset has been loaded in via .read_csv() method.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/684/1*1FzV78KuuY4CuQsmrN4sNQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*G0kCvpv4fHjpW1-EYJXD8A.png" /></figure><p>They can tell you the data types for your features, if any features are missing information, what the total rows and columns may be and so much more. Planning ahead saves significant time down the road.</p><p>Step 1 — Import data analysis and visualization libraries</p><pre># Import data analysis modules<br>import numpy as np<br>import pandas as pd</pre><pre># Import visualization modules</pre><pre>import matplotlib.pyplot as plt<br>import seaborn as sns<br>%matplotlib inline</pre><p>Step 2 — Load dataset in with pandas</p><pre># Use pandas to read in csv file<br>train = pd.read_csv(‘titanic_train.csv’)<br>train.head()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3dGD6mYXFko-N1yyyW3zWw.png" /></figure><p>Step 3 — Data Analysis</p><pre># Use the .isnull() method to locate missing data<br>missing_values = train.isnull()<br>missing_values</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mFv3CpuTzecEfCl3nm9Xhw.png" /></figure><p>We use seaborn to conduct heatmap to identify missing data, via the isnull() method on the dataset. The yellow dashes suggest the data is missing.</p><pre># Use seaborn to conduct heatmap to identify missing data<br># data -&gt; argument refers to the data to creat heatmap<br># yticklabels -&gt; argument avoids plotting the column names<br># cbar -&gt; argument identifies if a colorbar is required or not<br># cmap -&gt; argument identifies the color of the heatmap</pre><pre>sns.heatmap(data = missing_values, yticklabels=False, cbar=False, cmap=’viridis’)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/948/1*gA0HIc3l_VU_SMsxYJp8EQ.png" /></figure><p>When reviewing the dataset, it is helpful to use a .countplot() on the target label to get a quick reference of the ratios. Then we can begin assessing relationships with the target label and the various features in the dataset. The value of 0 are individuals who did not survive.</p><pre># Use the countplot() method to identify ratio of who survived vs. not<br># (Tip) very helpful to get a visualization of the target label<br># x -&gt; argument referes to column of interest<br># data -&gt; argument refers to dataset</pre><pre>sns.countplot(x=&#39;Survived&#39;, data=train)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/928/1*pidbe70jdCAUsEGsiWOvsA.png" /></figure><pre># Use the countplot() method to identify ratio of who survived vs. not with interest in Passenger class<br># x -&gt; argument referes to column of interest<br># data -&gt; argument refers to dataset<br># hue -&gt; allows another level to subdivide data<br># palette -&gt; argument refers to plot color</pre><pre>sns.countplot(x=&#39;Survived&#39;, data=train, hue=&#39;Pclass&#39;)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/936/1*P1AVpcBa0xkipK92FiODJQ.png" /></figure><p>To provide for even more engagement, we can use <a href="https://medium.com/@kbrook10/day-7-data-visualization-how-to-use-plotly-and-cufflinks-for-interactive-data-visualizations-3a4b85fdd999">plot.ly</a> to create interactive figures.</p><p><strong>Cleaning Data: (Most of the time is spent here*)</strong></p><p>Step 1 — Assess missing values to impute<br>There are times when data is missing, but we can impute (i.e. fill in) the values based on the existing content available. To investigate this concept we will use the .boxplot() on the ‘Pclass’ and ‘Age’ features to identify the average age per passenger class level.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*yaOeJyEfoRJslOdN_EUi0w.png" /></figure><p>Step 2 — Create function to update missing values<br>Defining a function using if statements allows for us to iterate over the data and update cells that contain missing values. Upon completion we are able to use the .heatmap() method to visualize our efforts to clean up the information.</p><pre># Create function to impute the age value if it is null</pre><pre>def impute_age(cols):<br>    Age = cols[0]<br>    Pclass = cols[1]<br>    <br>    if pd.isnull(Age):<br>        <br>        if Pclass == 1:<br>            return 37<br>        elif Pclass == 2:<br>            return 29<br>        else:<br>            return 24<br>    else:<br>        return Age</pre><pre># Apply function to impute the age for missing values<br># The age column is at position 0<br># The pclass column is at position 1<br># axis -&gt; argument refers to columns instead of rows to apply the impute_age function</pre><pre>train[&#39;Age&#39;] = train[[&#39;Age&#39;, &#39;Pclass&#39;]].apply(impute_age, axis=1)</pre><p><em>Heatmap</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Q6MDHQhIrosfXpHowCNokQ.png" /></figure><p>Step 3 — Drop features that are missing too much information or insignificant rows</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*uB4m3I2J4Pg2lKpV5bX9BA.png" /></figure><p>Step 4 — Convert Categorical features with Dummy variables<br>(Critical) -&gt; Ensure avoidance of multicollinearity issue by passing in the argument ‘drop_first’. This issue may undermine the statistical significance of an independent variable.</p><pre># Use the .get_dummies() method to convert categorical data into dummy values<br># train[&#39;Sex&#39;] refers to the column we want to convert<br># drop_first -&gt; argument avoids the multicollinearity problem, which can undermines<br># the statistical significance of an independent variable.</pre><pre>sex = pd.get_dummies(train[&#39;Sex&#39;], drop_first=True)<br>embark = pd.get_dummies(train[&#39;Embarked&#39;], drop_first=True)</pre><pre># Use  .concat() method to merge the series data into one dataframe</pre><pre>train = pd.concat([train, sex, embark], axis=1)</pre><p>Step 5 — Drop any further insignificant features from the dataset</p><pre># Drop columns with categorical data</pre><pre>train.drop([&#39;Sex&#39;,&#39;Embarked&#39;,&#39;Ticket&#39;,&#39;Name&#39;,&#39;PassengerId&#39;], axis=1, inplace=True)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/822/1*cdT_DTtxUt_S00RAAM9PKw.png" /></figure><p><strong>Training the Logistic Regression Model:</strong></p><p>Step 1 — Split dataset into “X” features and “y” labels<br>This step is required to prepare us for the fitting (i.e. training) the model later. The “X” variable is a collection of all the features. Think of this as ‘Pclass’, ‘Sex’, ‘Age’, etc.. The “y” variable is the target label which specifies whether the individual survives or not. Our goal will be to identify which category the data point should fall into.</p><pre># Split data into &#39;X&#39; features and &#39;y&#39; target label sets</pre><pre>X = train[[&#39;Pclass&#39;, &#39;Age&#39;, &#39;SibSp&#39;, &#39;Parch&#39;, &#39;Fare&#39;, &#39;male&#39;, &#39;Q&#39;,<br>       &#39;S&#39;]]<br>y = train[&#39;Survived&#39;]</pre><p>Step 2 — Split the data into a training and test set<br>This allows for use to train our model on the training set and evaluate the built model against the test set to identify errors.</p><pre># Import module to split dataset<br>from sklearn.model_selection import train_test_split</pre><pre># Split data set into training and test sets</pre><pre>X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=101)</pre><p>Step 3 — Create and Train the Model<br>Here we create a LogisticRegression Object and use the .fit() method to finally train the model. Upon completion of the model we should receive confirmation that the training has been completed.</p><pre># Import module for fitting<br>from sklearn.linear_model import LogisticRegression</pre><pre># Create instance (i.e. object) of LogisticRegression<br>logmodel = LogisticRegression()</pre><pre># Fit the model using the training data<br># X_train -&gt; parameter supplies the data features<br># y_train -&gt; parameter supplies the target labels<br>logmodel.fit(X_train, y_train)</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*f3cSMeMvOneMS7jiQNA9bg.png" /></figure><p>Step 4 — Evaluate the Model by reviewing the classification report or confusion matrix. By reviewing these tables, we are able to evaluate the model. Below we are able to identify that the model has a precision of 81% accuracy. To improve this we could gather more data, conduct further feature engineering and more to continue to adjust.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/910/1*UmnLVG9PVxRt_bAQhAU70Q.png" /></figure><p>Well, until next time…</p><blockquote>We are more often frightened than hurt; and we suffer more from imagination than from reality. ~ <em>Seneca the Younger</em></blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=99316e6589cd" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Day (9) — Machine Learning — Using LinearRegression with scikit-learn]]></title>
            <link>https://medium.com/@kbrook10/day-9-machine-learning-using-linearregression-with-scikit-learn-f27ad23fe986?source=rss-b76e61029f27------2</link>
            <guid isPermaLink="false">https://medium.com/p/f27ad23fe986</guid>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[python-pandas]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[scikit-learn]]></category>
            <category><![CDATA[linear-regression]]></category>
            <dc:creator><![CDATA[Keith Brooks]]></dc:creator>
            <pubDate>Wed, 21 Mar 2018 02:11:08 GMT</pubDate>
            <atom:updated>2019-01-03T19:42:31.324Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*lU5OpqS5upNGHfCH." /><figcaption>“A person reading a book with a magnifying glass and a pen in hand” by <a href="https://unsplash.com/@joaosilas?utm_source=medium&amp;utm_medium=referral">João Silas</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>This article covers work from the <a href="https://www.udemy.com/python-for-data-science-and-machine-learning-bootcamp">Python for Data Science and Machine Learning Bootcamp course</a> on Udemy by Jose Portilla and helpful tips along the way. This course was very helpful in gaining a base understanding of the topic.</p><p>We’re Back!!! But, this will not be a <a href="https://www.youtube.com/watch?v=XOLcsnqBJjI">dinosaur story</a>. We left off with learning how to use <a href="https://medium.com/@kbrook10/day-8-data-visualization-how-to-use-choropleth-maps-63c0fedfd5e7">choropleth maps</a> with <a href="https://plot.ly/python/getting-started/">plotly</a>. It is time to get our hands dirty with this thing called <a href="https://en.wikipedia.org/wiki/Machine_learning">machine learning</a>. One way to view machine learning is as a method that allows computers to discover insights regarding a topic without being explicitly programmed. It is a method of data analysis that automates analytical model building. Some of the ‘use cases’ of this are for the following:</p><ul><li>Fraud detection</li><li>Equipment failure prediction</li><li>Sentiment analysis</li><li>Image recognition and much more.</li></ul><p><strong>Overview of Machine Learning Process:</strong><br>This process may be split up into five phases. The first is the acquisition of data. Think of the old saying “Trash in, Trash out”.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*KcH1dJIAL58wyIxm." /><figcaption>Photo by <a href="https://unsplash.com/@hermez777?utm_source=medium&amp;utm_medium=referral">Hermes Rivera</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>There are free and paid services that offer <a href="https://en.wikipedia.org/wiki/List_of_datasets_for_machine_learning_research">datasets</a>. <a href="https://www.kaggle.com/">Kaggle</a> has some great datasets to get started and competitions to obtain great hands-on learning. The next step is data cleaning. Here we can use skills from <a href="https://pandas.pydata.org/pandas-docs/stable/install.html">pandas</a>, <a href="https://www.scipy.org/scipylib/download.html">numpy</a> and others to prepare the data for training. Once the data has been cleaned we can split it into a training and a test data set. We then proceed to fit (i.e. train) the model on the training data set portion. Once the model has been trained we use the test data set to evaluate the model and iterate over the process until the desired results are achieved. At the completion of a satisfactory model, we deploy it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*732uXLpvsuM5JhlpAIjksQ.png" /></figure><p><strong>Main types of Machine Learning:</strong><br>These include supervised, unsupervised and reinforcement learning. Supervised consists of having labeled data to train and trying to predict a label from known features. The algorithm learns by comparing actual output with the correct outputs to identify errors. Some methods are classification, regression and prediction. Use cases are where historical data predicts a future event (i.e. stock prices). Unsupervised is having unlabeled data and trying to group similar data points together to gain insights. Here the the right answer is not provided. The main purpose is to explore the data and find attributes that separate segments. Typical techniques include self-organizing maps, nearest neighbor mapping and single value decomposition (i.e. think if one guy with red shirt bought this, maybe another will also — very simple example I know…). While Reinforcement is where an algorithm learns an action from experience (i.e. practice). This is used for robotics, gaming and navigation. The algorithm discovers which actions yield the best results through trial and error.</p><p><strong>Linear Regression:</strong><br>The purpose of regression is to draft a line that is as close as possible to every data point. The residual is the difference between the data point (i.e. observation) and the line of best fit.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/892/1*BJ_yp7n_czoJLN_Dtlv5VQ.png" /></figure><p><strong>Topics:</strong><br>* How to conduct Data Exploration <br>* How to training our model using linear regression</p><p><strong>The Setup:</strong><br>* The example uses <a href="https://www.python.org/downloads/">Python 3.6</a>within <a href="http://jupyter.org/">Jupyter notebook</a> with the below dependencies<br><a href="https://matplotlib.org/users/installing.html#installing">Matplotlib 2.1.2</a> <br><a href="https://www.scipy.org/scipylib/download.html">Numpy 1.14.1</a> <br><a href="https://pandas.pydata.org/">Pandas 0.20.3</a><br><a href="https://seaborn.pydata.org/installing.html">Seaborn 0.7.1</a> <br><a href="http://scikit-learn.org/stable/install.html">Scikit Learn 0.19.1</a></p><p><strong>Warning:</strong><br>* Feel free to review the docs for additional arguments for the methods.</p><p><strong>How to conduct Data Exploration:</strong><br>Before we start splitting data and training models we will need to do a little data exploration to understand the information that we have. Obtaining a clear understanding of the data we are working with provides a better foundation to analyze and apply machine learning techniques later.</p><p><strong><em>Step 1 — Conduct Imports:</em></strong><br>To begin we must conduct the necessary imports. We will use pandas and numpy for data manipulation and apply aggregate methods. We will use seaborn and matplotlib for data visualization.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/494/1*Imle7ErlspRK9wruJghWew.png" /></figure><p><strong><em>Step 2 — Obtaining Data</em></strong><br>We will use the pandas method .read_csv() to read in the data. This data resides in the same directory as my working jupyter notebook.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6ZFSQLDbypc1CMKOXpeCBw.png" /></figure><p><strong><em>Step 3 — Investigating Data</em></strong><br>To investigate we will use the .info() method to identify the rows and column details. The .describe() method provides statistical insights on the dataset. While the .columns method returns a list of all the column names.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/760/1*Hv00FVtR9hyDZTHaHai3kw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*hGvMAA5HEKOsVWt5huv6Dg.png" /></figure><p><strong><em>Step 4 — Visualize the Data</em></strong><br>Seaborn’s .pairplot() method is used to display the numeric correlations of the data from a quick high level point. The seaborn .distplot() method displays the distribution of a desired feature (i.e. column). While the seaborn .heatmap() method provides a clearer picture of feature correlations.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/658/1*t3GW7HvOyyeZ8a5txf6_rQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/658/1*0xce08ZYJkA-0fB2HhqWdA.png" /></figure><p><strong>How to training our model using linear regression:</strong></p><p><strong><em>Step 1 — Split dataset into “X” features and “y” labels:</em></strong><br>This step is required to prepare us for the fitting (i.e. training) the model later. The “X” variable is a collection of all the features. Think of this as a house’s age, number of bedrooms, number of rooms and etc. The “y” variable is the target label which specifies the price. Our goal will be to identify the best value to set a feature to obtain the maximum price.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4KY3vjF97TEG0hAkCHGDLA.png" /></figure><p><strong><em>Step 2 — Split the data into a training and test set:</em></strong><br>This allows for use to train our model on the training set and evaluate the built model against the test set to identify errors. Still trying to fully understand the random_state argument, but here is some help(<a href="https://stackoverflow.com/questions/45089858/what-does-the-random-state-parameter-do-in-sklearns-parametersampler">https://stackoverflow.com/questions/45089858/what-does-the-random-state-parameter-do-in-sklearns-parametersampler</a>).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*G8Tz6XAzBbbzrtX_LiN2fg.png" /></figure><p><strong><em>Step 3 — Create and Train the Model:</em></strong><br>Here we create a LinearRegression Object and use the .fit() method to finally train the model. Upon completion of the model we should receive confirmation that the training has been completed.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*s4S-leBScdBPRRjiQxa4DQ.png" /></figure><p><strong><em>Step 4 — Evaluate the Model by reviewing the coefficients:</em></strong><br>By reviewing the coefficients, we are able to evaluate the model. The Avg. Area Income element in the figure below could be translated as for every 1 unit that that feature increases, the price of the house increases as well by 21.53. Obviously, this is a test dataset and these do not pass the real world test. However, there are others out there to <a href="http://archive.ics.uci.edu/ml/index.php">gain practice</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*77aFwAB5zy6r23o_ueHh-A.png" /></figure><p><strong><em>Tips, Tricks and Lessons Learned:</em></strong><br>- Web scraping — Great for creating your own custom datasets…<br>- (Book) <a href="http://www-bcf.usc.edu/~gareth/ISL/">An Introduction to Statistical Learning — The Math</a> — great for understanding the math behind the algorithms <br>- (Book) <a href="https://web.stanford.edu/~hastie/Papers/ESLII.pdf">The Elements of Statistical Learning</a> <br>- (Data Exploration Tools) Using the .info() method to investigate data<br>- (Data Exploration Tools)Using the .describe() method to investigate data<br>- (Data Exploration Tools)Using Distribution Plots<br>- (Data Exploration Tools)Using pairplot() method for correlations<br>- (Data Exploration Tools)Using heatmaps() method for correlations<br><strong><em>~ Guilty Pleasures</em></strong><br>a) <a href="https://www.youtube.com/watch?v=t6kqaip7WS4">Transcending Time</a> <br>b) <a href="https://www.youtube.com/watch?v=zyP_Mx-SJlU">Easy Listening</a></p><p>Well, until next time…</p><blockquote><em>It’s not because things are difficult that we dare not venture. It’s because we dare not venture that they are difficult. ~ </em>Seneca the Younger</blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f27ad23fe986" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>