<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>The Data Sleuth</title>
    <description>An exploratory blog created for practicing techniques in data analysis, machine learning, predictive modeling, and programming langauges</description>
    <link>https://thedatasleuth.github.io/</link>
    <atom:link href="https://thedatasleuth.github.io/sitemap.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Sun, 13 Oct 2019 20:29:40 +0000</pubDate>
    <lastBuildDate>Sun, 13 Oct 2019 20:29:40 +0000</lastBuildDate>
    <generator>Jekyll v3.8.5</generator>
    
      <item>
        <title>Weather Observation Station 18</title>
        <description>&lt;h3 id=&quot;prompt&quot;&gt;Prompt&lt;/h3&gt;

&lt;p&gt;Consider &lt;em&gt;P&lt;sub&gt;1&lt;/sub&gt;(a,b)&lt;/em&gt; and &lt;em&gt;P&lt;sub&gt;2&lt;/sub&gt;(c,d)&lt;/em&gt; to be two points on a 2D plane.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;a&lt;/em&gt; happens to equal the minimum value in Northern Latitude (LAT_N in STATION).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;b&lt;/em&gt; happens to equal the minimum value in Western Longitude (LONG_W in STATION).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;c&lt;/em&gt; happens to equal the maximum value in Northern Latitude (LAT_N in STATION).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;d&lt;/em&gt; happens to equal the maximum value in Western Longitude (LONG_W in STATION).&lt;/p&gt;

&lt;p&gt;Query the &lt;a href=&quot;https://xlinux.nist.gov/dads/HTML/manhattanDistance.html&quot;&gt;Manhattan Distance&lt;/a&gt; between points &lt;em&gt;P&lt;sub&gt;1&lt;/sub&gt;&lt;/em&gt; and &lt;em&gt;P&lt;sub&gt;2&lt;/sub&gt;&lt;/em&gt; and round it to a scale of 4 decimal places.&lt;/p&gt;

&lt;p&gt;The STATION table is described as follows:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Field&lt;/th&gt;
      &lt;th&gt;Type&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;ID&lt;/td&gt;
      &lt;td&gt;NUMBER&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;CITY&lt;/td&gt;
      &lt;td&gt;VARCHAR2(21)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;STATE&lt;/td&gt;
      &lt;td&gt;VARCHAR2(2)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;LAT_N&lt;/td&gt;
      &lt;td&gt;NUMBER&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;LONG_W&lt;/td&gt;
      &lt;td&gt;NUMBER&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;br /&gt;
where LAT_N is the northern latitude and LONG_W is the western longitude.&lt;/p&gt;

&lt;h3 id=&quot;answer&quot;&gt;Answer&lt;/h3&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ROUND&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;ABS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;MIN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LAT_N&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;MAX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LAT_N&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;ABS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;MIN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LONG_W&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;MAX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LONG_W&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;STATION&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Fri, 14 Sep 2018 00:00:00 +0000</pubDate>
        <link>https://thedatasleuth.github.io/tutorial/2018/09/14/Hacker-Rank-Weather-Observation-Station-18.html</link>
        <guid isPermaLink="true">https://thedatasleuth.github.io/tutorial/2018/09/14/Hacker-Rank-Weather-Observation-Station-18.html</guid>
        
        <category>SQL</category>
        
        
        <category>Tutorial</category>
        
      </item>
    
      <item>
        <title>Voter Registration by New York Congressional Districts for 2018 Midterm Elections</title>
        <description>&lt;p&gt;&lt;em&gt;Analysis of Voter Registration for the 27 New York Congressional Districts in anticipation of the 2018 Midterm Elections with interactive Dash charts.&lt;/em&gt;&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;In anticipation of the 2018 mid-term elections, Enigma Public is hosting a data science competition.  Using their new &lt;a href=&quot;https://pypi.org/project/enigma-sdk/&quot;&gt;SDK package&lt;/a&gt; which facilitates API calls on their public database, contestants are encouraged to explore topics that have some explanatory power over the midterm elections.  The competition ends on Friday, September 21, 2018.&lt;/p&gt;

&lt;p&gt;Under their &lt;a href=&quot;https://public.enigma.com/browse/tag/elections/34&quot;&gt;Elections&lt;/a&gt; collection, there are six umbrella datasets: Congressional Candidate Disbursements, Federal Election Commission, New York State Board of Elections, PAC Summary, Presidential Campaign Disbursements, and Tafra.  While there’s definitely something to dig into in each of these datasets, I chose to explore the New York State Board of Elections dataset filled with 5 years of voter registration statistics by Congressional District.&lt;/p&gt;

&lt;p&gt;I initially started off this analysis plotting in Matplotlib but halfway through decided to challenge myself and build out my plots using Dash.  I wanted to do this for several reasons: First, I’ve used &lt;a href=&quot;https://plot.ly/#/&quot;&gt;Plotly&lt;/a&gt; in a &lt;a href=&quot;https://thedatasleuth.github.io/predictive-modeling/2018/05/21/Predicting-Titanic-Survivability-Odds-Using-Machine-Learning.html&quot;&gt;previous project&lt;/a&gt; and was really impressed with the interactive hover-over feature and the crispness of the colors.  With &lt;a href=&quot;https://plot.ly/products/dash/&quot;&gt;Plotly-Dash&lt;/a&gt;, I was able to take the user interaction to the next level by including drop-down menus to facilitate more focused analysis.  Second, I felt like building out interactive plots like the ones below encourage engagement with the data as opposed to just reading someone’s findings.  I can’t think of a better topic than election season to get people engaged with data and thinking about their right to vote.  Also, the kid in me really likes pushing the buttons.&lt;/p&gt;

&lt;p&gt;Have a click through the charts below and feel free to share your own findings in the comments section.&lt;/p&gt;

&lt;h3 id=&quot;voter-registration-across-political-parties-from-2014-2018&quot;&gt;Voter Registration across Political Parties from 2014-2018&lt;/h3&gt;

&lt;p&gt;The chart below displays voter registration numbers for all 27 districts of New York which can be filtered by year using the drop-down menu.  Click on any combination of the boxes in the legend to compare voters across political parties.  Here are a few questions to get you started on your analysis:  Did the Democrats lose any districts to the Republicans?  If so, where and when?  What’s the greatest party affiliation after the Democrats and Republicans?  Does that political affiliation represent opportunity or apathy?  Where does the Independent Party have the most registered voters?  What other trends can you see?&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;iframe src=&quot;https://ny-districts-by-year.herokuapp.com/&quot; width=&quot;620px&quot; height=&quot;520px&quot;&gt;&lt;/iframe&gt;

&lt;h3 id=&quot;percentage-change-of-voter-registration&quot;&gt;Percentage Change of Voter Registration&lt;/h3&gt;

&lt;p&gt;Sometimes it’s not enough to just look at the numbers themselves but to actually calculate how the numbers have changed from year to year.  Using the &lt;code class=&quot;highlighter-rouge&quot;&gt;.pct_change()&lt;/code&gt; in Pandas, I was able to identify the percentage change of voter registration across the political parties.  This analysis produced some interesting results, especially as it relates to the fringe parties of New York, namely, the Women’s Equality Party (WEP) and the Reform Party (REF).&lt;/p&gt;

&lt;p&gt;Founded in 2014, the Women’s Equality Party (WEP) was created by Andrew Cuomo, the current governor of New York.  The party reached full political party status in 2014 during the gubernatorial elections after receiving the requisite 50,000 votes.  While Cuomo is no longer in control of the party on paper, the party remains deeply supportive of the incumbent governor, supporting his most recent re-election bid in 2018.&lt;/p&gt;

&lt;p&gt;The Reform Party (REF), another fringe political party founded in 2014, is a ballot-access qualified party created by &lt;a href=&quot;https://www.nyreformparty.com/endorsements&quot;&gt;Curtis Sliwa&lt;/a&gt;.  Silwa initially founded another group called the Guardian Angels in 1979 and is a regular contributor to several talk radio and television shows, including Fox 5.&lt;/p&gt;

&lt;p&gt;Click through the chart below to see how each district has responded to the introduction of these new parties.  Do you see any patterns emerging across districts that are represented by a Democrat as opposed to a Republican?&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;iframe src=&quot;https://ny-congressional-districts.herokuapp.com/&quot; width=&quot;620px&quot; height=&quot;520px&quot;&gt;&lt;/iframe&gt;

&lt;!-- District 1, located in Eastern Long Island, District 2, located on Southern Long Island, and Districts 23 and 27, both located in Western New York, all of which are represented by a Republican congressman, show a significant percentage change in voter registration for the WEP party in 2016.  Similarly, for Democrat-represented districts like District 3 located in Northern Long Island, District 7, located in Queens, District 18, located in Orange, Putnam, Southern Dutchess, and Northeastern Westchester, District 20, located in Albany and Schenectady, all saw a huge spike in WEP registration in 2016.    

For the REF party, there was some increase in Republican-represented districts like District 19 in the Hudson Valley and District 24 in Cayuga, Onondaga, Wayne counties in 2016 and District 2, located in Southern Long Island and District 23 located in Western New York in 2017.  The REF party increased its voter registration percentage significantly two years in a row in District 22 located in Central New York.

For Democrat-represented districts, the REF party also increased its voter share most significantly in District 18 in Orange, Putnam, Southern Dutchess, and Northeastern Westchester counties in 2016, and in District 3, Northern Long Island and District 4, Central and Southern Nassau County, and to a lesser extent District 5, Queens, and District 10, an amalgamation of the Upper West Side, the Financial District, Greenwich Village, and Borough Park in Brooklyn, District 16, Northern Bronx and Southern Westchester and District 20 Albany and Schenectady in 2017. --&gt;

&lt;h3 id=&quot;active-v-inactive-voters-in-2018&quot;&gt;Active v. Inactive Voters in 2018&lt;/h3&gt;

&lt;p&gt;Counting the number of registered voters, however, does not equate to how many people will actually vote.  In the 2016 Presidential election, for example, &lt;a href=&quot;https://www.pbs.org/newshour/politics/voter-turnout-2016-elections&quot;&gt;58%&lt;/a&gt; of &lt;a href=&quot;https://en.wikipedia.org/wiki/Voter_turnout&quot;&gt;eligible voters&lt;/a&gt; cast a ballot.  So how can you tell if someone will vote or not?  One way to identify potential voter turnout is to take a look at the active and &lt;a href=&quot;http://vote.nyc.ny.us/html/voters/faq.shtml&quot;&gt;inactive voter registration&lt;/a&gt;&lt;sup id=&quot;fnref:1&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.  Voters who are active are more likely to show up to the polls than are inactive voters.&lt;/p&gt;

&lt;p&gt;Click through the chart below to see the breakdown of active and inactive voters across all districts for each party in 2018.  Is there a party that is consistently active across all districts?  Which party is the most inactive?  Who’s more active between the Democrats and Republicans?  Thinking back to the fringe parties percentage change chart, what do you think it means that a newly founded fringe party has inactive voters?&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;iframe src=&quot;https://active-inactive-ny-voters2.herokuapp.com/&quot; width=&quot;620px&quot; height=&quot;520px&quot;&gt;&lt;/iframe&gt;

&lt;h3 id=&quot;final-thoughts&quot;&gt;Final Thoughts&lt;/h3&gt;

&lt;p&gt;The 2018 midterm elections are significant for a number of different reasons.  Republicans retaining control of both the Senate and the House of Representatives means they will be able to continue pushing a more conservative agenda that may include trying to repeal Obamacare again, cutting budgets for social services like welfare, Medicare, and Social Security, and restricting access to abortion.  Moreover, because many gubernatorial and state legislature elections determine how state districts are drawn, whoever is elected will be able to help shape congressional district boundaries in the upcoming 2020 Census, and those boundaries will be in effect for the following ten years.  Here’s an &lt;a href=&quot;https://www.washingtonpost.com/graphics/2018/politics/governors-redistricting/?utm_term=.4dd62658f59e&quot;&gt;interactive map&lt;/a&gt; created by the Washington Post detailing who determines how congressional districts are drawn for each state.&lt;/p&gt;

&lt;p&gt;Many of the 2018 Midterm elections will be held on &lt;strong&gt;Tuesday, November 6, 2018&lt;/strong&gt;.  All 435 seats in the United States House of Representatives and 35 of the 100 seats in the United States Senate will be contested.&lt;sup id=&quot;fnref:2&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;  Vote early and vote often.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class=&quot;footnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot;&gt;
      &lt;p&gt;A voter in inactive status who does not vote in two consecutive Federal Elections is, in the fifth year, removed from the list of the register. The voter must re-register in order to vote. &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:2&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/United_States_elections,_2018&quot;&gt;https://en.wikipedia.org/wiki/United_States_elections,_2018&lt;/a&gt; &lt;a href=&quot;#fnref:2&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Wed, 12 Sep 2018 00:00:00 +0000</pubDate>
        <link>https://thedatasleuth.github.io/python/2018/09/12/2018-Midterm-Election-New-York-Congressional-Districts.html</link>
        <guid isPermaLink="true">https://thedatasleuth.github.io/python/2018/09/12/2018-Midterm-Election-New-York-Congressional-Districts.html</guid>
        
        <category>Python</category>
        
        <category>Plotly-Dash</category>
        
        
        <category>Python</category>
        
      </item>
    
      <item>
        <title>5 Not So Obvious Ways to Get a Job in Data Science</title>
        <description>&lt;p&gt;&lt;em&gt;The search for a job can be exhausting, frustrating, and perplexing, even in a field as hot as data science is right now.  To get some actual traction with employers, don’t do what everyone else does.  Here are five ways to look for a data-oriented job that can actually connect you to a hiring manager.&lt;/em&gt;&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;We’ve all been there before.  You see a job on an aggregator site like Monster, Glassdoor, or Indeed that matches your interests and skillset.  You fill out basic demographic information about yourself and upload your resume.  Maybe you attach a general cover letter, maybe you don’t.  Who even reads those things anymore anyway, you wonder.  You click the “Apply” button at the bottom of the screen and feel temporarily productive about the state of your job search and the acceleration of your career only to never hear back from the company - not even to acknowledge they’ve received your application.  You do this about a hundred more times, expecting different results.&lt;/p&gt;

&lt;p&gt;While unemployment is at &lt;a href=&quot;https://www.nytimes.com/2018/05/04/business/economy/jobs-report.html&quot;&gt;the lowest since the beginning of the century&lt;/a&gt; as of the writing of this post, it still remains difficult to land a good job, even for an industry as hyped as Data Science.  Hundreds, if not thousands, of candidates apply for a single job posting, many of whom have advanced degrees and years of professional and &lt;em&gt;relevant&lt;/em&gt; job experience.&lt;/p&gt;

&lt;p&gt;I used to think landing a job was just a numbers game, and if I only applied to enough postings, statistically speaking, I would eventually get an offer.  During this shot-gun approach, I applied to over 20 jobs that were entry level data science jobs in a single day.  I got exactly zero invitations for a phone screen, let alone an actual in-person interview.  It was then that I decided to switch up my job search strategy because &lt;em&gt;feeling&lt;/em&gt; productive is not always the same thing as actually generating solid leads.  Here’s a few of the strategies that I’ve used in my own job search that have connected me to real human beings who’ve had a genuine interest in speaking to me about a job that actually exists.&lt;/p&gt;

&lt;h3 id=&quot;slack-channels&quot;&gt;Slack Channels&lt;/h3&gt;

&lt;p&gt;Slack is a new platform launched in 2014 to to help facilitate communication among common interest user groups.  For example, companies use Slack in lieu of email to track work projects and provide updates to relevant team members.  I’ve used Slack during my &lt;a href=&quot;https://thedatasleuth.github.io/general-assembly/2018/07/17/General-Assembly-Data-Science-Review.html&quot;&gt;12-week Data Science course at General Assembly&lt;/a&gt; to follow along in lectures and ask questions of my instructor and classmates.  My apartment building even has a Slack channel where residents receive building updates and invitations for get-togethers.  Slack is user-friendly platform for people to connect - which means it can also be a way for job seekers to connect with hiring managers.&lt;/p&gt;

&lt;p&gt;I’ve joined four Slack channels (apart from GA and my apartment building) that are focused exclusively on Data Science topics: two are focused on supporting women in Data Science, one is focused on the tech industry in New York, and the fourth is a private channel for &lt;a href=&quot;https://www.datacamp.com/home&quot;&gt;Data Camp&lt;/a&gt; subscribers.  Here are the Slack channels I’ve joined to stay connected to the Data Science community, and more specifically, to identify job opportunities:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://wimlds.slack.com/&quot;&gt;wimlds&lt;/a&gt; (Women in Machine Learning and Data Science)&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://rladies-community.slack.com/&quot;&gt;R-Ladies Community&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://nyctech.slack.com/&quot;&gt;NYCTech&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://datacamp-usa.slack.com/&quot;&gt;Data Camp USA&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Within each of these channels, there is a sub-channel dedicated to #jobs.  Yes, employers actually post real jobs in these channels and usually include the email handles of hiring managers.  It is not only ok but encouraged to email the poster directly to further inquire about opportunities that interest you.  Congrats, you just connected to a real live human for a real live job.&lt;/p&gt;

&lt;p&gt;My list is by no means an exhaustive one, and &lt;a href=&quot;https://towardsdatascience.com/15-data-science-slack-communities-to-join-8fac301bd6ce&quot;&gt;neither is this one&lt;/a&gt;.  These are just some of the channels that are out there related to data.  I would encourage you to do a little bit of research yourself to find a few Slack channels that would be good fits for you.  When trying to identify Slack channels to join, consider your stack, your location, and your demographic.  Connect with people who are similar to you and/or have similar interests.  Get the emotional buy-in from someone who actually wants to read your cover letter/email instead of a hoping to be discovered.&lt;/p&gt;

&lt;h3 id=&quot;start-a-blog&quot;&gt;Start a Blog&lt;/h3&gt;

&lt;p&gt;Every job hunter has a resume and a LinkedIn profile.  For prospective employers, it can be difficult to actually gauge a candidate’s technical ability based on self-reported bullet points, and &lt;a href=&quot;https://www.theladders.com/career-advice/men-puff-up-success-linkedin-women-undersell&quot;&gt;women in particular underreport their abilities&lt;/a&gt;.  To really give employers a better understanding of your skills, start detailing your analyses in a blog.  This serves the twinned purpose of not only demonstrating your coding ability but also proving that you can actually present your findings in an organized way.  Data Science is a multidisciplinary field in which practitioners can be expected to report their findings to a range of technical and non-technical stakeholders.  Having the skills to communicate efficiently and methodically is just as important as slicing through a dataset with Pythonic prowess.&lt;/p&gt;

&lt;p&gt;Moreover, having a blog demonstrates a deeper level of interest in data than the average applicant.  I’ve even used my blog to supplement my skills pitch during interviews by inviting prospective employers to read through some of my posts to gain a better understanding of my skills and interests.  Multiple employers have actually followed up to tell me they read one of my posts, allowing me to stay connected to them long after I left their office.&lt;/p&gt;

&lt;h3 id=&quot;lunch-clubs&quot;&gt;Lunch Clubs&lt;/h3&gt;

&lt;p&gt;When I think of networking, I imagine a room full of people standing around awkwardly working the crowd to figure out who might be able to help them advance their agendas, whether it’s to find a job, pitch an investor, or meet a potential co-founder.  But without any structure, it can feel like a giant waste of time.  When I meet up with someone in a professional setting, I like for both people to know why they are there and what the goal of the meeting is.&lt;/p&gt;

&lt;p&gt;Lunch clubs like &lt;a href=&quot;https://lunchclub.ai&quot;&gt;Lunchclub.ai&lt;/a&gt; and &lt;a href=&quot;https://letslunch.com/&quot;&gt;LetsLunch&lt;/a&gt; cut through the ambiguity by pairing people up with similar networking intentions.  As a member, you state your role during the initial sign-up period, and upon acceptance to the club, you receive invites to meet up with people who can actually help you.  Job seekers can pair up with prospective employers, start-ups can match with investors, and people who just want to connect with other professionals in their field can meet up one-on-one, too.  And even if it’s a total bust, at least you got to sit down and eat.&lt;/p&gt;

&lt;h3 id=&quot;hackathons&quot;&gt;Hackathons&lt;/h3&gt;

&lt;p&gt;I recently went to a SexTech Hackathon in Brooklyn which focused on leveraging technology to improve the sex lives of 8 billion people.  While I didn’t have specific plans to break into the SexTech industry, it was a really great way to meet people from a variety of different backgrounds.  Teams were self-selected, and I ended up on a team comprised of a “humanitarian” (soft skills), a “hipster” (design), a “hustler” (business savvy), and another “hacker” (coding) besides me.  In just a day and a half, my team built a rudimentary chatbot decision tree in JavaScript (which I had never used before that weekend) designed to improve intimacy between couples.  To me and the other hacker, it mattered not what our inputs were, whether they were NSFW-related or about flowers - the code and the logic was the same.  And while I did go just to improve my coding skills and to do a fun, crazy thing in Brooklyn for a weekend, I actually ended up connecting with the other hacker on my team who ended up referring me for a gig with her part-time employer to tutor Python to kids aged 8-10.  So really, you never know who you’ll meet and how they might help you.  Keep an open mind and sign up for any hackathon that looks like it could be fun.  If nothing else, you’ll have quite the story for Monday.&lt;/p&gt;

&lt;h3 id=&quot;cold-email-companies-you-admire&quot;&gt;Cold email companies you admire&lt;/h3&gt;

&lt;p&gt;Companies post jobs on aggregator sites because they have an immediate need to fill.  Looking at it in the negative, however, just because a company &lt;em&gt;hasn’t&lt;/em&gt; posted a job description that squarely aligns with your skillset doesn’t mean there isn’t a space (or funding) for you.&lt;/p&gt;

&lt;p&gt;In a confusing age of both anonymity and oversharing, it can be difficult for employers (or anyone really) to get a read on someone without meeting them.  Interviews will always be preferable, but second to meeting someone in person is writing them a sincere email.  For companies that interest you, research the management team and identify someone you could write to.  Keep it short and direct - no more than 4-5 sentences - to explain who you are, what about the company interests you, and what specific value you could add.  For illustrative purposes, here’s a sample email intro:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Hi Ms. Employer,&lt;/p&gt;

  &lt;p&gt;My name is Jess Chace, and I writing to you to inquire about a position with Data Science Co.  DS Co. has been on my radar for several years now, and I’ve watched your growth and increasing number of tech solutions with great interest, especially (include specific example here).  Having recently updated my own tech stack, I now feel competitive enough to join your team to help build out (whatever your stack can build here).  Do you have time to meet up for an exploratory interview this week or next?&lt;/p&gt;

  &lt;p&gt;Looking forward to hearing from you,&lt;/p&gt;

  &lt;p&gt;Jess&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, I’m not suggesting you try this technique on someone like Jeff Bezos or Andrew Ng.  This strategy is more geared towards companies that are range from 10 to 1000 employees.  Worst case scenario, you don’t hear back from them.  Best case scenario, you’re invited in for an exploratory interview, bypassing the phone screen and getting straight to that face-to-face.  More likely, however, is that you’ll get a thank you for your interest or maybe even an invitation to check back in 3-6 months.  Take them up on that offer.  Check back in in 3-6 months, update them on what you’ve been up to since you last spoke, whether it’s learning a new language or completing a new project.  Think like a salesperson when it comes to advocating for your career:  great job opportunities are like leads that need to be cultivated through months of check-ins and follow-ups.  Play the long game.&lt;/p&gt;

&lt;h3 id=&quot;final-thoughts&quot;&gt;Final Thoughts&lt;/h3&gt;

&lt;p&gt;No one is going to place a 150k salaried job in your lap because they recognized your technical aptitude and great cultural fit from your LinkedIn profile.  Even if you have a degree from a fancy university with multiple years of professional experience, you are not owed a great job.  You have to fight for it.  When it’s a numbers game like it is with the job search, and especially in a competitive field like Data Science, you have to think of ways to stand out from the crowd, because in reality, there are many candidates with similar qualifications.&lt;/p&gt;

&lt;p&gt;The only way I’ve been able to get around that is to get the emotional buy-in of someone on the inside who can then advocate for you, whether it’s writing an email to them, connecting over a private Slack channel, or meeting up with them individually.  Otherwise, you’re just another bag of words.&lt;/p&gt;

&lt;p&gt;What about you?  Have you had any success with these or other non-traditional job search techniques?  Feel free to share them in the comments below!&lt;/p&gt;
</description>
        <pubDate>Mon, 10 Sep 2018 00:00:00 +0000</pubDate>
        <link>https://thedatasleuth.github.io/opinion/2018/09/10/5-Not-So-Obvious-Ways-to-Get-a-Job-in-Data-Science.html</link>
        <guid isPermaLink="true">https://thedatasleuth.github.io/opinion/2018/09/10/5-Not-So-Obvious-Ways-to-Get-a-Job-in-Data-Science.html</guid>
        
        <category>Job Search</category>
        
        
        <category>Opinion</category>
        
      </item>
    
      <item>
        <title>Hacker Rank</title>
        <description>&lt;p&gt;&lt;em&gt;Answers to Hacker Rank challenges in the SQL module.&lt;/em&gt;&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;Hacker Rank is another great resource to improve programming and analysis skills offering modules like “Problem Solving”, “Language Proficiency”, and “Specialized Skills”.  Within each module there is a topic, so for example, within the Language Proficiency module, there are seven languages to practice, including Python, Java, and Ruby.  Programmers can work through a series of challenges to improve their proficiencies, earning points that eventually accumulate to badges.  Bronze, silver, and gold badges represent what proficiency a programmer has within a given topic.  You may wonder why someone would care about achieving a badge that isn’t seemingly worth anything, but this is actually another great way to showcase coding ability to prospective employers.  Demonstrating that you’ve achieved a gold badge in SQL on Hacker Rank is a quantifiable data point that corroborates bullet points on a resume.&lt;/p&gt;

&lt;p&gt;Within each challenge, there is a discussion section where coders can ask questions and post answers.  I’ve found this particularly helpful when I was stuck on a small aspect of the challenge or to identify alternative methods of approaching the problem.&lt;/p&gt;

&lt;p&gt;Below is a series of posts containing my answers to challenges rated at medium difficulty for the SQL module.&lt;/p&gt;
</description>
        <pubDate>Wed, 22 Aug 2018 00:00:00 +0000</pubDate>
        <link>https://thedatasleuth.github.io/sql/2018/08/22/Hacker-Rank-Answers.html</link>
        <guid isPermaLink="true">https://thedatasleuth.github.io/sql/2018/08/22/Hacker-Rank-Answers.html</guid>
        
        <category>SQL</category>
        
        
        <category>SQL</category>
        
      </item>
    
      <item>
        <title>SQL Zoo</title>
        <description>&lt;p&gt;&lt;em&gt;A complete list of my answers to the SQL Zoo Tutorials.&lt;/em&gt;&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;Lately I’ve been focusing on my Python projects so I thought I’d switch it up and do some SQL practice using &lt;a href=&quot;https://sqlzoo.net/&quot;&gt;SQL Zoo’s&lt;/a&gt; interactive tutorials.  These tutorials are filled with prompts to query databases using SQL.  What’s great about this site is that it shows the results of the query right next to the prompt line, allowing the user to verify that the query pulled the desired results.  SQL Zoo confirms answers with a :)&lt;/p&gt;

&lt;p&gt;Below is a list of posts that contain prompts and answers to each of the chapters in SQL Zoo.&lt;/p&gt;
</description>
        <pubDate>Tue, 21 Aug 2018 00:00:00 +0000</pubDate>
        <link>https://thedatasleuth.github.io/sql/2018/08/21/SQL-Zoology.html</link>
        <guid isPermaLink="true">https://thedatasleuth.github.io/sql/2018/08/21/SQL-Zoology.html</guid>
        
        <category>SQL</category>
        
        
        <category>SQL</category>
        
      </item>
    
      <item>
        <title>SUM and COUNT Tutorial</title>
        <description>&lt;h3 id=&quot;total-world-population&quot;&gt;Total world population&lt;/h3&gt;

&lt;p&gt;Show the total population of the world.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;SUM&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;population&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;list-of-continents&quot;&gt;List of continents&lt;/h3&gt;

&lt;p&gt;List all the continents - just once each.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;DISTINCT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;continent&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;gdp-of-africa&quot;&gt;GDP of Africa&lt;/h3&gt;

&lt;p&gt;Give the total GDP of Africa&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;SUM&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gdp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;continent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Africa'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;count-the-big-countries&quot;&gt;Count the big countries&lt;/h3&gt;

&lt;p&gt;How many countries have an area of at least 1000000&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;COUNT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;area&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;baltic-states-population&quot;&gt;Baltic states population&lt;/h3&gt;

&lt;p&gt;What is the total population of (‘Estonia’, ‘Latvia’, ‘Lithuania’)&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;SUM&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;population&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;IN&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Estonia'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Latvia'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Lithuania'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;counting-the-countries-of-each-continent&quot;&gt;Counting the countries of each continent&lt;/h3&gt;

&lt;p&gt;For each continent show the continent and number of countries.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;continent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;COUNT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;GROUP&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;BY&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;continent&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;counting-big-countries-in-each-continent&quot;&gt;Counting big countries in each continent&lt;/h3&gt;

&lt;p&gt;For each continent show the continent and number of countries with populations of at least 10 million.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;continent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;COUNT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;population&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10000000&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;GROUP&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;BY&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;continent&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;counting-big-continents&quot;&gt;Counting big continents&lt;/h3&gt;

&lt;p&gt;List the continents that have a total population of at least 100 million.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;continent&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;GROUP&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;BY&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;continent&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;HAVING&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;SUM&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;population&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100000000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;
</description>
        <pubDate>Sat, 18 Aug 2018 00:00:00 +0000</pubDate>
        <link>https://thedatasleuth.github.io/2018/08/18/SUM-COUNT.html</link>
        <guid isPermaLink="true">https://thedatasleuth.github.io/2018/08/18/SUM-COUNT.html</guid>
        
        <category>SQL</category>
        
        
      </item>
    
      <item>
        <title>SELECT within SELECT Tutorial</title>
        <description>&lt;h3 id=&quot;bigger-than-russia&quot;&gt;Bigger than Russia&lt;/h3&gt;
&lt;p&gt;List each country name where the population is larger than that of ‘Russia’.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;population&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
     &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;population&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Russia'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;richer-than-uk&quot;&gt;Richer than UK&lt;/h3&gt;
&lt;p&gt;Show the countries in Europe with a per capita GDP greater than ‘United Kingdom’.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;continent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'EUROPE'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;AND&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gdp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;population&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gdp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;population&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'United Kingdom'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;neighbors-of-argentina-and-australia&quot;&gt;Neighbors of Argentina and Australia&lt;/h3&gt;

&lt;p&gt;List the name and continent of countries in the continents containing either Argentina or Australia. Order by name of the country.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;continent&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;continent&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;IN&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'South America'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Oceania'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;ORDER&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;BY&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;between-canada-and-poland&quot;&gt;Between Canada and Poland&lt;/h3&gt;

&lt;p&gt;Which country has a population that is more than Canada but less than Poland? Show the name and the population.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;population&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;population&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;population&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Canada'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;AND&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;population&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;population&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Poland'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;percentages-of-germany&quot;&gt;Percentages of Germany&lt;/h3&gt;

&lt;p&gt;Germany (population 80 million) has the largest population of the countries in Europe. Austria (population 8.5 million) has 11% of the population of Germany.&lt;/p&gt;

&lt;p&gt;Show the name and the population of each country in Europe. Show the population as a percentage of the population of Germany.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CONCAT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ROUND&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;population&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;population&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Germany'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'%'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;continent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Europe'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;bigger-than-every-country-in-europe&quot;&gt;Bigger than every country in Europe&lt;/h3&gt;

&lt;p&gt;Which countries have a GDP greater than every country in Europe? [Give the name only.] (Some countries may have NULL gdp values)&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gdp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;ALL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gdp&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;continent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Europe'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;AND&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gdp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;AND&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;continent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Europe'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;largest-in-each-continent&quot;&gt;Largest in each continent&lt;/h3&gt;

&lt;p&gt;Find the largest country (by area) in each continent, show the continent, the name and the area:&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;continent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;area&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;area&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;ALL&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;area&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;continent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;continent&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;AND&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;area&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;first-country-of-each-continent-alphabetically&quot;&gt;First country of each continent (alphabetically)&lt;/h3&gt;

&lt;p&gt;List each continent and the name of the country that comes first alphabetically.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;continent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;ALL&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;continent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;continent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;difficult-questions-that-utilize-techniques-not-covered-in-prior-sections&quot;&gt;Difficult Questions That Utilize Techniques Not Covered In Prior Sections&lt;/h3&gt;

&lt;p&gt;Find the continents where all countries have a population &amp;lt;= 25000000. Then find the names of the countries associated with these continents. Show name, continent and population.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;continent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;population&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;continent&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;IN&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;continent&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;MAX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;population&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;continent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;continent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;25000000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Some countries have populations more than three times that of any of their neighbors (in the same continent). Give the countries and continents.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;continent&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;population&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;ALL&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;population&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;continent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;continent&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;AND&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;hr /&gt;
</description>
        <pubDate>Fri, 17 Aug 2018 00:00:00 +0000</pubDate>
        <link>https://thedatasleuth.github.io/2018/08/17/Nested-SELECT.html</link>
        <guid isPermaLink="true">https://thedatasleuth.github.io/2018/08/17/Nested-SELECT.html</guid>
        
        <category>SQL</category>
        
        
      </item>
    
      <item>
        <title>SELECT FROM world Tutorial</title>
        <description>&lt;h3 id=&quot;introduction&quot;&gt;Introduction&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://sqlzoo.net/wiki/Read_the_notes_about_this_table.&quot;&gt;Read the notes about this table.&lt;/a&gt; Observe the result of running this SQL command to show the name, continent and population of all countries.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;continent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;population&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;large-countries&quot;&gt;Large Countries&lt;/h3&gt;

&lt;p&gt;How to use WHERE to filter records. Show the name for the countries that have a population of at least 200 million. 200 million is 200000000, there are eight zeros.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;population&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;200000000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;per-capita-gdp&quot;&gt;Per capita GDP&lt;/h3&gt;

&lt;p&gt;Give the name and the per capita GDP for those countries with a population of at least 200 million.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gdp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;population&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;population&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;200000000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;south-america-in-millions&quot;&gt;South America In millions&lt;/h3&gt;

&lt;p&gt;Show the name and population in millions for the countries of the continent ‘South America’. Divide the population by 1000000 to get population in millions.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;population&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1000000&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;continent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'South America'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;france-germany-italy&quot;&gt;France, Germany, Italy&lt;/h3&gt;

&lt;p&gt;Show the name and population for France, Germany, Italy&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;population&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;IN&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'France'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Germany'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Italy'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;united&quot;&gt;United&lt;/h3&gt;

&lt;p&gt;Show the countries which have a name that includes the word ‘United’&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;LIKE&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'%United%'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;two-ways-to-be-big&quot;&gt;Two ways to be big&lt;/h3&gt;

&lt;p&gt;Two ways to be big: A country is big if it has an area of more than 3 million sq km or it has a population of more than 250 million.&lt;/p&gt;

&lt;p&gt;Show the countries that are big by area or big by population. Show name, population and area.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;population&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;area&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;area&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3000000&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;OR&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;population&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;250000000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;one-or-the-other-but-not-both&quot;&gt;One or the other (but not both)&lt;/h3&gt;

&lt;p&gt;Exclusive OR (XOR). Show the countries that are big by area or big by population but not both. Show name, population and area.&lt;/p&gt;

&lt;p&gt;Australia has a big area but a small population, it should be included.
Indonesia has a big population but a small area, it should be included.
China has a big population and big area, it should be excluded.
United Kingdom has a small population and a small area, it should be excluded.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;population&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;area&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;area&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3000000&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XOR&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;population&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;250000000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;rounding&quot;&gt;Rounding&lt;/h3&gt;

&lt;p&gt;Show the name and population in millions and the GDP in billions for the countries of the continent ‘South America’. Use the ROUND function to show the values to two decimal places.&lt;/p&gt;

&lt;p&gt;For South America show population in millions and GDP in billions both to 2 decimal places.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ROUND&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;population&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1000000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ROUND&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gdp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1000000000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;continent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'South America'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;trillion-dollar-economies&quot;&gt;Trillion dollar economies&lt;/h3&gt;

&lt;p&gt;Show the name and per-capita GDP for those countries with a GDP of at least one trillion (1000000000000; that is 12 zeros). Round this value to the nearest 1000.&lt;/p&gt;

&lt;p&gt;Show per-capita GDP for the trillion dollar countries to the nearest $1000.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ROUND&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gdp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;population&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gdp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000000000000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;name-and-capital-have-the-same-length&quot;&gt;Name and capital have the same length&lt;/h3&gt;

&lt;p&gt;Greece has capital Athens.&lt;/p&gt;

&lt;p&gt;Each of the strings ‘Greece’, and ‘Athens’ has 6 characters.&lt;/p&gt;

&lt;p&gt;Show the name and capital where the name and the capital have the same number of characters.&lt;/p&gt;

&lt;p&gt;You can use the LENGTH function to find the number of characters in a string&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;capital&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;LENGTH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;LENGTH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;capital&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;matching-name-and-capital&quot;&gt;Matching name and capital&lt;/h3&gt;

&lt;p&gt;The capital of Sweden is Stockholm. Both words start with the letter ‘S’.&lt;/p&gt;

&lt;p&gt;Show the name and the capital where the first letters of each match. Don’t include countries where the name and the capital are the same word.
You can use the function LEFT to isolate the first character.
You can use &amp;lt;&amp;gt; as the NOT EQUALS operator.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;capital&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;LEFT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;LEFT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;capital&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;AND&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;capital&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;all-the-vowels&quot;&gt;All the vowels&lt;/h3&gt;

&lt;p&gt;Equatorial Guinea and Dominican Republic have all of the vowels (a e i o u) in the name. They don’t count because they have more than one word in the name.&lt;/p&gt;

&lt;p&gt;Find the country that has all the vowels and no spaces in its name.&lt;/p&gt;

&lt;p&gt;You can use the phrase name NOT LIKE ‘%a%’ to exclude characters from your results.
The query shown misses countries like Bahamas and Belarus because they contain at least one ‘a’&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;LIKE&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'%A%'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;AND&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;LIKE&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'%E%'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;AND&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;LIKE&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'%I%'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;AND&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;LIKE&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'%O%'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;AND&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;LIKE&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'%U%'&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;AND&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;LIKE&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'% %'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;hr /&gt;
</description>
        <pubDate>Sat, 11 Aug 2018 00:00:00 +0000</pubDate>
        <link>https://thedatasleuth.github.io/2018/08/11/SELECT-Basics.html</link>
        <guid isPermaLink="true">https://thedatasleuth.github.io/2018/08/11/SELECT-Basics.html</guid>
        
        <category>SQL</category>
        
        
      </item>
    
      <item>
        <title>Review of General Assembly's Data Science Immersive Course</title>
        <description>&lt;p&gt;&lt;em&gt;An honest, post-graduation review of the course’s layout, syllabus, and instructors.&lt;/em&gt;&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;General Assembly bills itself as a leader in Education.  Founded in 2011, GA claims to have “transformed tens of thousands of careers through pioneering, experiential education in today’s most in-demand skills”&lt;sup id=&quot;fnref:1&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; such as data science, web development, and user-experience design.  GA offers a wide range of classes and workshops, from 2-hour info sessions to 3-month, full time immersion courses.&lt;/p&gt;

&lt;p&gt;My first introduction to General Assembly was in early 2017 when I enrolled in their &lt;a href=&quot;https://generalassemb.ly/education/excel-bootcamp/new-york-city&quot;&gt;Excel&lt;/a&gt; and &lt;a href=&quot;https://generalassemb.ly/education/sql-bootcamp-series/new-york-city&quot;&gt;SQL&lt;/a&gt; bootcamps.  These workshops were either one (Excel) or two-day (SQL) accelerated overviews of the respective tools.&lt;/p&gt;

&lt;p&gt;After six hours in the Excel bootcamp, I actually was able to walk away with a much better understanding of conditional statements, formulas, and pivot tables and was able to implement the techniques I learned in the class to my job immediately.  The SQL class also helped, but I wasn’t able to practice writing queries as much after the class.&lt;/p&gt;

&lt;p&gt;But as the months went by, I had a lingering feeling that if I wanted to advance my career in any kind of meaningful way, I needed harder-to-obtain skills than knowing how to write some formulas or manipulate some pivot tables.  In the year prior up to enrolling in GA’s Data Science Immersive course, I kept returning to the curriculum in which GA promised to teach its students the fundamentals of machine learning in 12 weeks.  I was frustrated with how stagnant and limited my skillset was at my current job and concerned with my ability to advance beyond a lower-mid level role.  I wanted to take on more interesting (and analytical) projects but was routinely overlooked in favor of someone with more technical skills.&lt;/p&gt;

&lt;p&gt;For about a year, I kept returning to that curriculum, nervous about how I could possibly swing taking three (plus) months off of work while living in NYC, and more nervous about what would happen if I didn’t.&lt;/p&gt;

&lt;h2 id=&quot;orientation-day&quot;&gt;Orientation Day&lt;/h2&gt;

&lt;p&gt;What GA (and any other bootcamp for that matter) proposes to accomplish is somewhat of an impossible task: Take students from varying backgrounds, skillsets, and aptitudes and teach a wide breadth of new and complicated material in what ends up being a sprint to the finish line every single week.  My cohort was no different.  At one end of the academic spectrum, a student decided to matriculate through the bootcamp in lieu of going to college.  On the other, there was a student who had tripled majored in math, physics, and philosophy at Yale.  There were students who had had professional experience as data analysts and were looking to advance their careers in their established fields and there were those that were looking to transition from completely unrelated industries.  The majority of the class had their Bachelor’s degree, but a healthy amount also had Master’s.  One student had a Ph.D in Statistics.  About half of the class had majored in Math or a hard Science.  This is all to say, while it was a diverse cohort, many of my fellow students were quantitatively inclined.&lt;/p&gt;

&lt;h2 id=&quot;syllabus&quot;&gt;Syllabus&lt;/h2&gt;

&lt;p&gt;The Data Science course is taught simultaneously across the U.S. divided into two sections - East Coast and West Coast using a “connected classroom” format.  Using a video call, a global instructor would teach the lecture material to all five of the East locations (New York, Boston, DC, Atlanta, and Austin) and then turn around and teach the same material to the West Coast cohort.&lt;/p&gt;

&lt;p&gt;Surprisingly, it was fairly easy to engage with the lecturer via a dedicated Slack channel.  During lecture, students would pose questions on Slack, and either the global instructor would answer them on the spot or, more often, lecture would continue while the local instructors, who were in the classroom with us, would answer them via Slack.  If you think this sounds like there was a lot happening all of the time during lecture, you’re right.  There were multiple topic-related side discussions going on at once during lecture that you could choose to follow.  (They were almost always related to a spin-off question posed during lecture.)  This was my first time using Slack, but I soon learned to love it because it allowed me to go back and review a written record of the lecture, and specifically, answers to questions that I may not have fully understood the first time around.&lt;/p&gt;

&lt;p&gt;I included a diagram of the schedule (seen below) from GA’s website because it more or less describes how class was run every day.  (&lt;strong&gt;NB:&lt;/strong&gt; While the course material is the same across the different locations, the overall experience of the course varies slightly based on the local instructor, the makeup of the class, and class-time restrictions mandated at the state level.  Because I am based in New York and took the course in New York, this post only describes my experience in that location.)&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/schedule.png&quot; alt=&quot;schedule.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I would caveat that while the post-lecture reviews are &lt;em&gt;technically&lt;/em&gt; optional, they really aren’t in practice.  This is time that the local instructor uses to go over questions related to the lecture material or work with students individually to answer questions related to labs or projects.  Trust me, you won’t want to skip out on this.  In New York, there wasn’t a “Community Meetup” that I can recall.  We basically just ended lecture around 4 PM, took a ten minute break, and then had our afternoon lab/review time right up until the end of the day at 6 PM when our local instructor congratulated us for surviving another day.&lt;/p&gt;

&lt;p&gt;While I’m sure the material changes slightly with each cohort, this is a summary of the topics we covered each week:&lt;/p&gt;

&lt;p&gt;Week 1: Intro to Python&lt;/p&gt;

&lt;p&gt;Week 2: “Pandas Appreciation Week”, SQL&lt;/p&gt;

&lt;p&gt;Week 3: Linear Regression&lt;/p&gt;

&lt;p&gt;Week 4: Classification&lt;/p&gt;

&lt;p&gt;Week 5: Web-scraping, APIs, Natural Language Processing&lt;/p&gt;

&lt;p&gt;Week 6: Advanced Modeling&lt;/p&gt;

&lt;p&gt;Week 7: Neural Networks&lt;/p&gt;

&lt;p&gt;Week 8: Unsupervised Learning&lt;/p&gt;

&lt;p&gt;Week 9: Bayesian Statistics&lt;/p&gt;

&lt;p&gt;Week 10: Spatio-temporal Modeling&lt;/p&gt;

&lt;p&gt;Week 11: Big Data (AWS, Scala, Spark)&lt;/p&gt;

&lt;p&gt;Week 12: Capstone Project Workshops&lt;/p&gt;

&lt;p&gt;Overall, I was happy with the breadth of topics we covered.  As with any bootcamp, depth is always going to be a challenge given how much material there is to cover within a certain amount of time.  That being said, GA provided many resources to further explore any given topic, and post-course, I have found myself reviewing materials and lesson plans.&lt;/p&gt;

&lt;p&gt;There is, however, one change I would make to the syllabus: Week 9.  We spent a whole week on high-concept Bayesian statistics, and given that I &lt;a href=&quot;https://thedatasleuth.github.io/about/&quot;&gt;majored in Ancient Greek&lt;/a&gt;, this was an uphill battle.  While I do believe that a fundamental grounding in statistical analysis is important to Data Science, I believe our time would have been better spent learning R - another highly sought-after programming skill geared more toward statistical analysis.  When time permits, that will be my next challenge.&lt;/p&gt;

&lt;h2 id=&quot;meet-the-instructors&quot;&gt;Meet the Instructors&lt;/h2&gt;

&lt;p&gt;There were four global instructors, all with impressive credentials in statistics, machine learning, and development.  Three out of the four lecturers were excellent.  They were able to explain difficult concepts in an organized and coherent way, often with supplemental powerpoint materials that enhanced my ability to grasp new concepts, especially ones that were more math and theory-based.  There were also many in-class “code-alongs” during which we practiced actual execution and wrote code in tandem with the instructor to reinforce programming skills.  This technique was particularly useful when we were first learning how to use the neural network libraries, &lt;a href=&quot;https://thedatasleuth.github.io/neural-network/keras/kaggle/2018/06/07/Intro-to-Keras.html&quot;&gt;Keras&lt;/a&gt; and TensorFlow.&lt;/p&gt;

&lt;p&gt;We also had a local instructor and a TA in class with us.  I cannot say enough good things about my local instructor.  He had the impossible task of raising 20 baby Data Scientists and did it with the patience of a demi-god.  He explained and reviewed difficult concepts multiple times until things began to stick.  He debugged coding errors like a ninja.  He supported my ideas for projects and my capstone and he helped me achieve my overall goals for the course.  He was approachable, likable, and compassionate and one of the main reasons I was able to make it through 12 weeks of Data Science.&lt;/p&gt;

&lt;h2 id=&quot;graduation-day&quot;&gt;Graduation Day&lt;/h2&gt;

&lt;p&gt;We also had a weekly Outcomes meeting every Thursday afternoon during which we discussed topics related to our pending job searches.&lt;/p&gt;

&lt;p&gt;In addition to our weekly homework assignments and bi-weekly projects, we were also required to hand-in weekly “Outcomes” assignments, including Brand Statements, updated resumes, LinkedIn profiles, and written responses to questions like, “Tell me about yourself.”&lt;/p&gt;

&lt;h2 id=&quot;a-little-commencement-speech&quot;&gt;A little Commencement Speech&lt;/h2&gt;

&lt;p&gt;Matriculating through this bootcamp was one of the harder things I’ve ever done.  Unlike college where I had at most three one hour long lectures every day, in the bootcamp we consistently had about four hours of lecture followed by about two hours of review, in addition to another two hours or so of workshop time.  In 12 weeks, we had to complete 20 out of 25 (80%) labs in addition to four projects &lt;em&gt;and&lt;/em&gt; a capstone, which averages to about two assignments due per week. It was a pretty grueling pace made more difficult by the fact that these were topics I had never been exposed to before.&lt;/p&gt;

&lt;p&gt;There are also personal and financial considerations.  I don’t think I saw my friends more than once during the entire three months I was in the course because I spent my nights and weekends working on labs and/or projects.  I hired a dog walker to help out with my big girl and ended up enrolling in MealPal because I just didn’t have time to cook.  By Week 8, I was exhausted struggling to keep up with assignments, and looking down the barrel of a whole other month.  In Week 9, my 10-year old computer broke.  (Fortunately, I had my work backed up.)&lt;/p&gt;

&lt;p&gt;With all of that being said though, if you are thinking of enrolling in a bootcamp, I would recommend it.  While I am still learning and improving my Data Science skills everyday, I would absolutely say that the bootcamp gave me a foundation in programming that I previously thought unattainable.  Before GA, I had never coded in my life.  In 12 weeks, I was able to build predictive models, scrape the web, apply natural language processing, analyze complex datasets, and probably most importantly, gain confidence that I &lt;em&gt;could&lt;/em&gt; learn programming techniques.  My unsolicited advice to anyone considering one of these programs is:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Get help&lt;/strong&gt; with the household (kids, dog, cleaning, meal prep) if you swing it/afford it.  Every task taken off of your plate during this time will help relieve pressure.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Prepare financially&lt;/strong&gt; to cover living expenses for the three months while in bootcamp &lt;em&gt;and&lt;/em&gt; the three months after while job searching.  (My experience thus far has been that jobs worth getting move slowly.)  General Assembly (and maybe other bootcamps) offers loans for tuition as well as living expenses, if, like me, you don’t have about 25k cash lying around while living in NYC.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;And finally, &lt;strong&gt;find your grit&lt;/strong&gt;.  Unless you are a data ninja before enrolling in the course (to which I would then wonder why you would feel the need for such a course to being with) it’s going to be hard.  You will feel pressed for time, constantly.  There will be concepts that you will not get right away.  You will get stuck in your code.  You may even fail a quiz, or five.  This is a high-stakes environment given the cost of the class, the pace of the syllabus, the difficulty of the concepts, and the pressure to secure employment after.  Knowing in your gut why you are doing this and what it will mean for you after - higher income, greater job stability, maybe even a better work/life balance - will carry you through.  That, and a healthy supply of snacks.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If I can answer any more questions specifically about my own experience as a now alum of GA’s Data Science Immersive course, feel free to reach out to me via my &lt;a href=&quot;https://thedatasleuth.github.io/contact/&quot;&gt;contact form&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here’s a picture of my cohort on our (very long) last day of class after 20 capstone presentations!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/dsi-pic.jpg&quot; alt=&quot;dsi-pic.jpg&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;
&lt;div class=&quot;footnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://generalassemb.ly/why-ga-is-worth-it&quot;&gt;https://generalassemb.ly/why-ga-is-worth-it&lt;/a&gt; &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Tue, 17 Jul 2018 00:00:00 +0000</pubDate>
        <link>https://thedatasleuth.github.io/general-assembly/2018/07/17/General-Assembly-Data-Science-Review.html</link>
        <guid isPermaLink="true">https://thedatasleuth.github.io/general-assembly/2018/07/17/General-Assembly-Data-Science-Review.html</guid>
        
        <category>General Assembly</category>
        
        <category>Coding Bootcamp</category>
        
        
        <category>General-Assembly</category>
        
      </item>
    
      <item>
        <title>Can SEC Filings Predict Enforcement Actions?</title>
        <description>&lt;p&gt;&lt;em&gt;Complex financial schemes usually involve a lot of documents, but what if machine learning could help financial regulators identify which corporations to investigate?&lt;/em&gt;&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;The FBI and the American Association of Certified Fraud Examiners estimate that white collar crime costs 300 to 600 billion dollars a year.  That’s the equivalent of Warren Buffet’s net worth 3.5 times over, or buying out the debt of New York City’s MTA 9 times over, or purchasing the New York Knicks 90 times over.  It’s incredible amount of money and also a very wide range, suggesting that enforcement agencies don’t actually know the extent of the damage cause by white collar crime.&lt;/p&gt;

&lt;p&gt;And that damage is not just limited to the crime itself - the ripple effects of financial crime are even wider, more opaque, but undoubtedly affect every single one of us.  Companies that are defrauded will raise prices on consumer goods to recoup losses.  Scammed insurance companies will demand higher premiums on their policies. Hedge fund schemes that manipulate equity markets can decrease stock prices. And if the government gets taken for a ride, we all know what happens then - more government taxes.&lt;/p&gt;

&lt;p&gt;Identifying these bad actors is difficult.  Complex financial schemes usually involve a lot of documents, some of which demand law or accounting degrees to truly understand.  Moreover, as with many government agencies, there’s just not enough people to review all of those complex documents.  And the select few who are tasked with reviewing these complex cases are doing it with outdated and insufficient technology.&lt;/p&gt;

&lt;p&gt;Corporations that are listed on any U.S. stock exchange are required to submit financial reports to the Securities and Exchange Commission (SEC) to inform potential investors of the company’s financial health.  There are &lt;a href=&quot;https://en.wikipedia.org/wiki/SEC_filing&quot;&gt;hundreds&lt;/a&gt; of filing types that a corporation can submit, and these filings include information like &lt;a href=&quot;https://www.investopedia.com/terms/1/10q.asp&quot;&gt;quarterly&lt;/a&gt; and &lt;a href=&quot;https://www.investopedia.com/terms/1/10-k.asp&quot;&gt;annual&lt;/a&gt; financial statements, &lt;a href=&quot;https://www.investopedia.com/terms/1/8-k.asp&quot;&gt;major events&lt;/a&gt;, &lt;a href=&quot;https://www.sec.gov/info/edgar/forms/edgform.pdf&quot;&gt;changes to the institution’s organizational structure&lt;/a&gt;, and &lt;a href=&quot;https://www.investopedia.com/terms/s/sec-form-f-1.asp&quot;&gt;foreign investments&lt;/a&gt;, to name a few.  The SEC makes these filings publicly available on their website.&lt;/p&gt;

&lt;p&gt;To that end, I wanted to use data science techniques like web scraping, exploratory data analysis, and machine learning to see whether I could identify ‘bad actor’ corporations by the types of reports they file in concert with other demographic information to help financial regulators like the SEC focus their investigations of white collar crime.&lt;/p&gt;

&lt;h2 id=&quot;identifying-the-target&quot;&gt;Identifying the Target&lt;/h2&gt;

&lt;p&gt;My first task was to identify my targets so I could train my model on what suspicious cases might look like.  I researched SEC indictments reports and found that the SEC releases annual reports of their enforcement cases.  &lt;a href=&quot;https://www.sec.gov/files/2017-03/secstats2016.pdf&quot;&gt;For example&lt;/a&gt;, in these reports I found, there is a list of indictments with information about the defendant (either an individual or a corporation) as well as date information and related charges.  I located reports for the years 2006-2016.  Given that these reports were in pdf format, my first task was to find a way to extract the information I needed into a format that I could eventually feed into my model.  I first tried using a package I found that reads in material from pdfs, but because of the inherent unstable process of extracting text, the formula I wrote to extract the text from the first report did not extract text in the same way as the next.  Because I only had a couple of weeks to complete this project and needed to extract text from eleven reports just to identify my targets, I quickly abandoned this method.  I later found a free website that more accurately (and quickly) converted my reports to excel files.  In data science as in many disciplines, sometimes the simplest tool is the best.&lt;/p&gt;

&lt;p&gt;The next big hurdle to overcome was the fact that names of individuals and corporations are not easily fed into searches.  In a future iteration of this project, I would try to use some of kind fuzzing matching algorithm like the &lt;a href=&quot;https://github.com/seatgeek/fuzzywuzzy&quot;&gt;fuzzy wuzzy&lt;/a&gt; package to feed the names of the defendants into a search box.&lt;/p&gt;

&lt;p&gt;For now, I manually entered the names of the cases into the EDGAR search field to identify their corresponding CIK ID Number.  Because I didn’t want to manually search 5,000 entries, I pared my initial list of defendants down to corporations.  Many of the names of the corporate defendants did not turn up a CIK number.  (For some cases, this makes sense given that these corporations were accused of financial crime and may never have filed the required reports).  From the 1600 or so corporate cases I had, I was able to identify 175 corporates with CIK ID numbers.  I finally had my target set.&lt;/p&gt;

&lt;h2 id=&quot;putting-the-case-together&quot;&gt;Putting the Case Together&lt;/h2&gt;

&lt;p&gt;But what about my Not Indicted class?  If I was going to make predictions, I needed to build out my dataset with values associated with corporations that have not had enforcement action against them, given that that is the overwhelming norm.  Initially, I thought about doing the same process over again with just a random list of companies from the S&amp;amp;P500, but after more research, I found a &lt;a href=&quot;http://api.corpwatch.org/&quot;&gt;similar project&lt;/a&gt; that had already done some of the work that I wanted to.  Given my time constraints, I decided to download their datasets, which also identifies corporations by the Central Index Key (CIK).  These datasets contained the types of data points I was looking for, namely, locations and years active.  I suspected that the 175 target corporations I had previously identified were somewhere in the 65,000 rows of corporates, so I subset my target data set out of the much larger dataset.  When I compared the shapes of the prior set to the new set, sure enough, 175 rows were dropped.  I created a new column within my new dataset called ‘Indicted’ and set it to ‘0’.  Then, I concatenated my target dataset on the 0 axis with its corresponding ‘Indicted’ column and set it to 1, meaning, positive for having been indicted.&lt;/p&gt;

&lt;p&gt;With the CIK ID numbers for both of my Indicted and Not Indicted classes, I was able to scrape the SEC website for their filings using a nested for loop with the requests and Beautiful soup libraries.  Having saved all of my filings in a list for each of my 65,000 rows, I then transformed those individual filings into their own unique dummy columns and filled each column with the value counts of the filing.  With this final transformation, I had a working dataset that I could analyze and subsequently feed into a model.&lt;/p&gt;

&lt;h2 id=&quot;witness-selection&quot;&gt;Witness Selection&lt;/h2&gt;

&lt;p&gt;I knew that I was likely going to use some ‘blackbox’ models that would limit my ability to interpret what weights were given to which features in predicting the Indicted class.  So, I decided to use a tool that does allow for interpretability of what factors are most predictive of the minority class.  &lt;a href=&quot;http://scikit-learn.org/stable/modules/generated/sklearn.feature_selection.SelectKBest.html&quot;&gt;SelectKBest&lt;/a&gt;, identified features that were most predictive of my Indicted class.  One of the top ten features identified was the number of years a corporation was active.  As visualized in the plot below, half of the Indicted class was active for less than a year, whereas there is more of a normal distribution among the Not Indicted class.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/Years_Active.png&quot; alt=&quot;Years_Active.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In addition to the number of years a corporation has been active, SelectKBest also identified several filing types that were highly predictive of the minority class, including the ‘2-A’, a report of sales and uses of proceeds,&lt;sup id=&quot;fnref:2&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;, the ‘ADV-H-T’, an application for temporary hardship,&lt;sup id=&quot;fnref:3&quot;&gt;&lt;a href=&quot;#fn:3&quot; class=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; the ‘DEFR14C’, a filing that discloses pertinent information that is required to be disclosed to shareholders but does not required a shareholder vote for approval,&lt;sup id=&quot;fnref:4&quot;&gt;&lt;a href=&quot;#fn:4&quot; class=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; and the ‘SC 14F1/A’, a filing disclosing a majority change in a corporation’s directors.&lt;sup id=&quot;fnref:6&quot;&gt;&lt;a href=&quot;#fn:6&quot; class=&quot;footnote&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;The Indicted class filed these types of filings with slightly more frequently than did the Not Indicted class, as illustrated in the plot below.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/filings-updated.png&quot; alt=&quot;filings-updated.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In analyzing the purpose of these filings, I posited that some corporations might be “hiding” pertinent information that in fact should be voted on by shareholders, or, in the case of the ‘SC 14F1/A’ registering the corporation with a ‘straw owner’ to give an air of legitimacy before the “real” directors take over to pursue potentially criminal activities.&lt;/p&gt;

&lt;h2 id=&quot;balancing-the-scales&quot;&gt;Balancing the Scales&lt;/h2&gt;

&lt;p&gt;My baseline accuracy for this project was 99.7%.  This means that if you guessed that a corporation was not indicted (0 in the target column), you would be right 99.7% of the time.  With my majority and minority classes so imbalanced, it is difficult for the machine to pick up on the (very subtle) signals that the minority class is sending out.  To counter-act this imbalance, I used several different class balancing techniques to amplify the minority class’s signals.&lt;/p&gt;

&lt;p&gt;First, I used a resampling technique called downsampling from scikit-learn’s utils package.  This technique allowed me to reduce the majority population to try to “quiet” the amount of signals the majority class sends out.  I chose to downsample my majority class from 65,324 down to 10,000 and assumed that 10,000 samples of the majority class would have enough variety to represent the full 65,324 set.&lt;/p&gt;

&lt;p&gt;With my majority class muffled a little bit, I then used another sampling tool called SMOTEENN to try to amplify the signals of my minority class (the Indicted class).  Imblearn’s &lt;a href=&quot;http://contrib.scikit-learn.org/imbalanced-learn/stable/generated/imblearn.combine.SMOTEENN.html&quot;&gt;SMOTEENN&lt;/a&gt; is a slight variation of &lt;a href=&quot;http://contrib.scikit-learn.org/imbalanced-learn/stable/generated/imblearn.over_sampling.SMOTE.html&quot;&gt;SMOTE&lt;/a&gt; (Synthetic Minority Oversampling TEchnique which randomly selects data points in the minority class and creates copies of them that mimic the characteristics of the minority class based on a k nearest neighbors distance calculation.  SMOTEENN differs slightly from SMOTE by additionally using Edited Nearest Neighbors (ENN), which in essence “cleans” the data set of points that are not strong representatives of their class.  Put another way, it reduces noise within the data set for both classes.  I verified that the were properly balanced by checking their shapes.  In fact, both had 10,892 rows of data.&lt;/p&gt;

&lt;p&gt;I then performed two train-test-splits on the dataset - the first set would be used to initially train my models on my X_train and y_train.  Within this first set, I would conduct another train-test-split on my X_train and y_train which would be split into my cross-validation set (X_train_val, y_train_val, X_test_val, y_test_val).  Cross validating my models on a dataset that the model hasn’t been trained on guards against overfitting my models to any one particular dataset.  If and when I was satisfied with the results of my models and satisfied with how my parameters were tuned, I would then predict on the X_test from the initial train-test-split - another dataset that the models have not yet seen.&lt;/p&gt;

&lt;h2 id=&quot;reaching-a-verdict&quot;&gt;Reaching a Verdict&lt;/h2&gt;

&lt;p&gt;When running my models, I decided to score on precision because I was most concerned with reducing false positives while also trying to increase the number of true positives as much as possible.  The equation for precision, seen below, calculates the positive predictive value but penalizes the score by how many positive values were predicted incorrectly.  In my project, a false positive would be a corporate that was predicted to be indicted but should not have been.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;Precision = \frac{True Positive}{True Positive + False Positive}&lt;/script&gt;

&lt;p&gt;In a slightly different metric, recall measures the true positive rate by penalizing the score with false negatives (seen below).  In this project, a false negative would be a corporate that should have been indicted but wasn’t.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;Recall = \frac{True Positive}{True Positive + False Negative}&lt;/script&gt;

&lt;p&gt;In sum, both precision and recall are measures of truthiness but with slightly different perspectives.  Because it is a much more serious thing to indict a corporation that is innocent (both in terms of potential monetary penalties when the corporation turns around and sues the government as well as lost faith in the justice system) than to not indict a potentially guilty corporation, I decided that precision was the most important measure of success.&lt;/p&gt;

&lt;p&gt;To visualize this decision, I plotted two confusion matrices of the models I ran to represent the cross-validation run (left) and the test run (right).  Despite the name, a confusion matrix is actually quite a simple tool to interpret.  Simply, it is a matrix of four values: true positives (values that were predicted positive and supposed to be positive), false positives (values that were predicted positive but supposed to be negative), true negatives (values that were predicted negative and supposed to be negative), and false negatives (values that were predicted negative but supposed to be positive) to compare the number of false positives, true positives, and false negatives.  In the cross-validation run, both the Decision Tree and XGBoost Classifiers kept the false positives to 0 while predicting 14 true positives.  They both left 19 false negatives on the table (corporations that should have been indicted but weren’t).  The Random Forest and Balanced Bagging Classifiers both predicted more true positives (18 and 21, respectively) but they also predicted more false positives (5 and 17, respectively).  In my mind, the benefit of indicting 4 to 7 more corporations does not outweigh the cost of inappropriately accusing 5 to 17 corporations (and the attendant damage caused to the company for being embroiled in litigation).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/confusion-matrix.png&quot; alt=&quot;confusion-matrix.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;To focus in on the Indicted class even more, I also plotted the classification reports of each the models.  Similar to a confusion matrix, a classification report is another tool that can be used to evaluate model performance other than accuracy.  Some of the outputs of a classification report are: precision, recall, and an f1-score (a weighted average of the precision and recall metrics). Because the Decision Tree and XGBoost Classifiers both reduced false positives to 0, they have perfect precision scores of 1.0.  However, because they both left corporations “on the table”, their recall scores are not as great.  Because the goal of this project was to identify as many corporations as possible to further investigate without investigating a corporation that should not be, I considered these metrics a success.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/classification-report.png&quot; alt=&quot;classification-report&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;areas-of-further-research&quot;&gt;Areas of Further Research&lt;/h2&gt;

&lt;p&gt;While this was a toy project based on a handful of inputs related to corporate demographics and filing types, I think it demonstrates the point that machine learning techniques can help financial regulatory agencies identify potential targets for further investigation.  If I were to continue researching this topic, I would be interested in pulling in more data to feed the model, such as the names of the directors as well as any associated negative news.  I would also be interested in “reading” the filings themselves using natural language processing, and specifically, a Term Frequency - Inverse Document Frequency (TF-IDF) analysis to identify any rare terminology that might signal unusual behavior.&lt;/p&gt;

&lt;p&gt;To see all of the code associated with this project, head on over to the related &lt;a href=&quot;https://github.com/jesster413/SEC-Filings&quot;&gt;GitHub repo&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class=&quot;footnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:2&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://www.investopedia.com/terms/s/sec-form-2-a.asp&quot;&gt;https://www.investopedia.com/terms/s/sec-form-2-a.asp&lt;/a&gt; &lt;a href=&quot;#fnref:2&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:3&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://www.iard.com/support_hardship&quot;&gt;https://www.iard.com/support_hardship&lt;/a&gt; &lt;a href=&quot;#fnref:3&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:4&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://www.investopedia.com/terms/s/sec-form-defr14c.asp&quot;&gt;https://www.investopedia.com/terms/s/sec-form-defr14c.asp&lt;/a&gt; &lt;a href=&quot;#fnref:4&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:6&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://www.sec.gov/info/edgar/forms/edgform.pdf&quot;&gt;https://www.sec.gov/info/edgar/forms/edgform.pdf&lt;/a&gt; &lt;a href=&quot;#fnref:6&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Fri, 06 Jul 2018 00:00:00 +0000</pubDate>
        <link>https://thedatasleuth.github.io/predictive-modeling/web-scraping/2018/07/06/Can-SEC-Filings-Predict-Enforcement-Actions.html</link>
        <guid isPermaLink="true">https://thedatasleuth.github.io/predictive-modeling/web-scraping/2018/07/06/Can-SEC-Filings-Predict-Enforcement-Actions.html</guid>
        
        <category>Balanced Classes</category>
        
        <category>Web Scraping</category>
        
        <category>XGBoost</category>
        
        <category>Random Forest</category>
        
        <category>Python</category>
        
        <category>Beautiful Soup</category>
        
        
        <category>Predictive-Modeling</category>
        
        <category>Web-scraping</category>
        
      </item>
    
      <item>
        <title>Predicting West Nile Virus in Chicago Using Advanced Modeling Techniques</title>
        <description>&lt;p&gt;&lt;em&gt;In June 2015, the City of Chicago released data to Kaggle and asked competitors to predict which areas of the city would be more prone to West Nile Virus outbreaks.&lt;/em&gt;&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;West Nile Virus (WNV) was first discovered in Uganda in 1937 and persists through the present day in many disparate parts of the world, spreading primarily through female mosquitoes and affecting several types of bird species, as well as other mammals like horses and humans.  Infected victims can either be asymptomatic (75% of cases) or display symptoms like fever, rash, vomiting (20% of cases), encephalitis/meningitis (1% of cases), and in rare instances death (1 out of 1500).&lt;sup id=&quot;fnref:1&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;  While the first case of WNV in the US was reported in Queens, NYC in 1999, Chicago has been particularly plagued by the disease since it was first reported in the Windy City in 2001.  As of 2017, Chicago has reported 90 cases of WNV, eight of which resulted in death.&lt;sup id=&quot;fnref:2&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;Since 2004, Chicago has had set up a surveillance system of mosquito traps designed to monitor which areas of the city were positive for WNV which remains in effect today.  Every week from late spring through the fall, mosquitos in traps across the city are tested for the virus. The results of these tests influence when and where the city will spray airborne pesticides to control adult mosquito populations.&lt;/p&gt;

&lt;p&gt;In June 2015, the City of Chicago &lt;a href=&quot;https://www.kaggle.com/c/predict-west-nile-virus&quot;&gt;released their data&lt;/a&gt; to Kaggle in the form of a competition, asking competitors to analyze their datasets and predict which areas of the city would be more prone to WNV outbreaks, thereby allowing the City and Chicago Department of Public Health (CPHD) to allocate resources more efficiently.  The prize, $40,000.&lt;/p&gt;

&lt;p&gt;While I was a little late to the competition, this dataset remains one of the more popular sets to analyze, given its depth, complexity, and uniquely inherent challenges.  Below, I identify the challenges that came up for me when analyzing this dataset as well as the techniques I used to resolve them.&lt;/p&gt;

&lt;h2 id=&quot;going-in-for-a-check-up&quot;&gt;Going in for a check-up&lt;/h2&gt;

&lt;p&gt;As with many projects, the raw data was split across a several different dataframes, including a train.csv, a test.csv, a weather.csv, and a spray.csv.  The spray.csv was a collection of locations and timestamps where pesticides were sprayed - I initially set this aside given that it was not immediately obvious to me how I could incorporate it into my model.&lt;/p&gt;

&lt;p&gt;There was also a file filled with location points that represented the city of Chicago.  I used this file to identify the traps where WNV was present.  These traps are represented by red ‘x’ marks in the map below.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/wnv-map.png&quot; alt=&quot;wnv-map.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;For the weather.csv, I decided to drop the ‘Water1’, ‘Depart’, and ‘Depth’ columns given that volume of values that were missing.  I also decided to drop the CodeSum category.  There were also some columns with strange values like ‘  T’ which I decided to replace with 0 instead.  Finally, I noticed that weather data was collected by two weather stations and seemed largely duplicative.  I decided to slice on station1.&lt;/p&gt;

&lt;p&gt;Initially, my train (and test) sets had 10 columns and 10506 rows.  While there were no null values in the train set, there were values labeled ‘M’ which effectively were nulls.  I decided to fill the ‘M’ values with NaNs that I could drop later.  I then grouped my train dataframe on ‘Species’, ‘Date’, and ‘Trap’ by the mean to mirror how the test set was organized.  I then dropped the ‘Block’, ‘Latitude’,’Longitude’, and ‘AddressAccuracy’ features because I later engineered columns that I thought would be more helpful (and predictive) of WNV.&lt;/p&gt;

&lt;h2 id=&quot;were-going-to-have-to-operate&quot;&gt;We’re going to have to operate&lt;/h2&gt;

&lt;p&gt;I decided to engineer a column called ‘LatLong’ which was a tuple of the ‘Latitude’ and ‘Longitude’ columns zipped together.  I did this because I wanted to calculate the distance of any given point in my train data from ‘hot spots’ I identified through aggregating my WNV column.  The package I used to calculate distances was &lt;a href=&quot;https://pypi.org/project/vincenty/&quot;&gt;vincenty&lt;/a&gt; from geopy.distance and takes two args, both of which need to be tuples.&lt;/p&gt;

&lt;p&gt;For my first arg in the vincenty function, I created two ‘hot spot’ locations of coordinates by identifying which coordinates had the highest mean value of WNV. I did this by grouping the tupled coordinates in the ‘LatLong’ column, slicing on the ‘WNVPresent’ column and sorting the ‘WNVPresent’ values in descending order.  I named the two variables for the top two locations where WNV was present centroid1 (41.974689, -87.890615) and centroid2 (41.673408, -87.599862).&lt;/p&gt;

&lt;p&gt;With my centroids identified, I was able to write a for-loop that calculated the distances in miles for each of the tupled location points from the two centroids and saved the result in a list.  I applied these list to my dataframe in new features called ‘Distances1’ and ‘Distances2’.  I also created another column called ‘Close_to_Centroid2’ which was a lambda function of my ‘Distances2’ feature that binarized whether a point was within five miles of the centroid or not.&lt;/p&gt;

&lt;p&gt;Given that the ‘Species’ and ‘Trap’ features were categorical data, I label encoded them into numerical values for modeling purposes.  I also applied the datetime function within two lambda functions that I mapped to the ‘Date’ feature.  This transformed the one ‘Date’ one column into two - the first date column represented the day of the year (out of 365), and the second column represented the year.  This way, these date features could be fed into the model as numerical values instead of objects.&lt;/p&gt;

&lt;p&gt;Finally, I merged the weather set onto my train set in preparation of modeling.&lt;/p&gt;

&lt;h2 id=&quot;were-going-to-need-to-run-some-tests&quot;&gt;We’re going to need to run some tests&lt;/h2&gt;

&lt;p&gt;One of the most difficult aspects of this project was the fact that the baseline accuracy for the dataset was 95% accuracy.  This meant that if you were to guess that WNV was not present, you would be correct 95 out of 100 times.  While this may not seem like a big deal, it is very costly to the City to A. spray expensive pesticides where WNV is not present and run the risk of unnecessarily exposing residents to the toxins (a false negative) and B. not spray pesticides where WNV is present and run the risk of residents becoming ill with the virus and potentially being sued for negligence (a false positive).&lt;/p&gt;

&lt;p&gt;Keeping this in mind, I installed the &lt;a href=&quot;http://contrib.scikit-learn.org/imbalanced-learn/stable/api.html&quot;&gt;imblearn&lt;/a&gt; package which contains a class balancer, SMOTEENN.  Imblearn’s &lt;a href=&quot;http://contrib.scikit-learn.org/imbalanced-learn/stable/generated/imblearn.combine.SMOTEENN.html&quot;&gt;SMOTEENN&lt;/a&gt; is a slight variation of &lt;a href=&quot;http://contrib.scikit-learn.org/imbalanced-learn/stable/generated/imblearn.over_sampling.SMOTE.html&quot;&gt;SMOTE&lt;/a&gt; (Synthetic Minority Oversampling TEchnique which randomly selects data points in the minority class and creates copies of them that mimic the characteristics of the minority class based on a k nearest neighbors distance calculation.  SMOTEENN differs slightly from SMOTE by additionally using Edited Nearest Neighbors (ENN), which in essence “cleans” the data set of points that are not strong representatives of their class.  This allows the model to learn more deeply about what characteristics are inherent to the target class.&lt;/p&gt;

&lt;p&gt;After balancing the classes, I ran three models: a Random Forest Classifier, &lt;a href=&quot;https://github.com/dmlc/xgboost&quot;&gt;XGBoost&lt;/a&gt;, and a Balanced Bagging Classifier.  I chose these models based on their powerful algorithms to extract information from features and, in the case of XGBoost, learn from mistakes made in the Decision Tree learning process and incorporate that information gain back into training process.&lt;/p&gt;

&lt;h2 id=&quot;whats-the-prognosis&quot;&gt;What’s the prognosis?&lt;/h2&gt;

&lt;p&gt;ROC-AUC is short for Receiver Operating Characteristic - Area Under the Curve.  It is a metric created by plotting the true positive rate against the false positive rate.&lt;/p&gt;

&lt;p&gt;The true positive rate is also known as recall, where true positives are divided by the sum of true positives and false negatives.  The true positive rate is a metric that evaluates the proportion of positive data points that were correctly predicted as positive.  A higher true positive rate means better accuracy with respect to positive data points.&lt;sup id=&quot;fnref:4&quot;&gt;&lt;a href=&quot;#fn:4&quot; class=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;The false positive rate is called the fall-out and is calculated by the number of false positives divided by the sum of false positives and true negatives.  This can be interpreted as the proportion of negative data points that were incorrectly predicted as positive.  A higher false positive rate means more negative data points are classified incorrectly as positive.&lt;sup id=&quot;fnref:5&quot;&gt;&lt;a href=&quot;#fn:5&quot; class=&quot;footnote&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;I plotted the ROC-AUC curves of my three models below.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Random Forest&lt;/th&gt;
      &lt;th&gt;XGBoost&lt;/th&gt;
      &lt;th&gt;Balanced Bagging Classifier&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;img src=&quot;/static/img/rf-rocauc.png&quot; alt=&quot;rf-rocauc.png&quot; /&gt;&lt;/td&gt;
      &lt;td&gt;&lt;img src=&quot;/static/img/xgb-rocauc.png&quot; alt=&quot;xgb-rocauc.png&quot; /&gt;&lt;/td&gt;
      &lt;td&gt;&lt;img src=&quot;/static/img/bbc-rocauc.png&quot; alt=&quot;bbc-rocauc.png&quot; /&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Because the baseline accuracy score was so high already, I wanted to take a closer look at how many positive data points I correctly (and incorrectly) predicted, so I ran a confusion matrix on all three models.  I was mostly concerned with reducing the amount of false positives as much as I could while increasing the true positives.  For example, while the XGBoost model produced 73 true positives, it also predicted 247 false positives.  In comparison, the Balanced Bagging Classifier model only predicted 56 positives correctly, however, it also only incorrectly predicted 202 positives.  The decision of which model’s trade-off to choose depends on the goals of the project.  On the one hand, it might be better to spray pesticides on more areas that were correctly predicted to have WNV.  On the other hand, it also might be more expensive to the City.  For illustrative purposes, I plotted the true positives and false positives of all three models below.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/wnv-confusion.png&quot; alt=&quot;wnv-confusion.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Having tuned my models, I submitted my predictions to Kaggle.  While my best score was only a 0.61 (score on ROC-AUC), this project was well worth my time.  Not only did it allow me to continue learning more about tuning my models and scoring on different metrics, but it also was my first introduction to imbalanced classes.  In the real world, (and especially the industries I’m interested in working in, like financial crime) many datasets are severely imbalanced because there just are not many instances of the minority class because it is a rare event.  However, in order to create a model that can more accurately predict the minority class, it is up to the data scientist to make the model more sensitive to the signals sent out by the minority class.  Knowing how to balance the majority and minority classes allows for better models.&lt;/p&gt;

&lt;p&gt;If you’re interested in seeing the code associated with this project, head on over to the related &lt;a href=&quot;https://github.com/thedatasleuth/West-Nile-Virus&quot;&gt;GitHub repo&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;
&lt;div class=&quot;footnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;http://www.northwestmvcd.org/Northwestmvcd/West_Nile.html&quot;&gt;http://www.northwestmvcd.org/Northwestmvcd/West_Nile.html&lt;/a&gt; &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:2&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;http://chicago.cbslocal.com/2018/05/30/west-nile-virus-reported/&quot;&gt;http://chicago.cbslocal.com/2018/05/30/west-nile-virus-reported/&lt;/a&gt; &lt;a href=&quot;#fnref:2&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:4&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://stats.stackexchange.com/questions/132777/what-does-auc-stand-for-and-what-is-it&quot;&gt;https://stats.stackexchange.com/questions/132777/what-does-auc-stand-for-and-what-is-it&lt;/a&gt; &lt;a href=&quot;#fnref:4&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:5&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://stats.stackexchange.com/questions/132777/what-does-auc-stand-for-and-what-is-it&quot;&gt;https://stats.stackexchange.com/questions/132777/what-does-auc-stand-for-and-what-is-it&lt;/a&gt; &lt;a href=&quot;#fnref:5&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Fri, 15 Jun 2018 00:00:00 +0000</pubDate>
        <link>https://thedatasleuth.github.io/predictive-modeling/2018/06/15/Predicting-West-Nile-Virus-Using-Machine-Learning.html</link>
        <guid isPermaLink="true">https://thedatasleuth.github.io/predictive-modeling/2018/06/15/Predicting-West-Nile-Virus-Using-Machine-Learning.html</guid>
        
        <category>Balanced Classes</category>
        
        <category>Kaggle</category>
        
        <category>XGBoost</category>
        
        <category>Random Forest</category>
        
        <category>Python</category>
        
        
        <category>Predictive-Modeling</category>
        
      </item>
    
      <item>
        <title>The Writing's on the Wall, Part 1 (Introduction to Neural Networks Using Keras)</title>
        <description>&lt;p&gt;&lt;em&gt;Visions of the future are never completely true, but with the right key, some can be more truthful than others.  Here’s an introduction to the neural network library, Keras, which I used to predict handwritten numbers.&lt;/em&gt;&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;When dreaming of the day her husband, Odysseus, would return from war, Penelope describes a vision she had that portends his return.  Having waited twenty years already, she is wary of the dream’s validity, saying:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;em&gt;“Stranger, dreams verily are baffling and unclear of meaning, and in no wise do they find fulfilment in all things for men. For two are the gates of shadowy dreams, and one is fashioned of horn and one of ivory. Those dreams that pass through the gate of sawn ivory deceive men, bringing words that find no fulfilment. But those that come forth through the gate of polished horn bring true issues to pass, when any mortal sees them.” Homer, Odyssey 19. 560–569 ff (Murray translation)&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Penelope describes dreams that pass through the ivory gates as deceitful whereas those that pass through gates of horn can be trusted.  As Arthur Murray notes, the Greek word for horn, κέρας, recalls a similar sounding word κραίνω meaning “fulfill” whereas ἐλέφας, the Greek word for ivory, similarly recalls the word ἐλεφαίρομαι meaning “deceive.”  Finally, &lt;a href=&quot;https://thedatasleuth.github.io/about/&quot;&gt;my degree in Ancient Greek&lt;/a&gt; paid off.&lt;/p&gt;

&lt;p&gt;François Chollet, a Google enigeer, drew inspiration from this imagery which was first referenced in the Odyssey nearly three thousand years ago when naming his popular neural network library, Keras.  Designed explicitly for ease of use and speed, Keras is a deep neural network library that makes use of TensorFlow on the backend.&lt;/p&gt;

&lt;p&gt;For my first neural network project, I applied Keras to the MNIST (“Modified National Institute of Standards and Technology”) handwriting database &lt;a href=&quot;https://www.kaggle.com/c/digit-recognizer/data&quot;&gt;made available by Kaggle&lt;/a&gt; to predict numbers based on their handwritten equivalent.  Below is a walkthrough of the steps I took to make predictions.&lt;/p&gt;

&lt;h2 id=&quot;prepping-the-canvas&quot;&gt;Prepping the Canvas&lt;/h2&gt;

&lt;!-- Neural networks, in a single line, attempt to iteratively train a set (or sets) of weights that, when used together, return the most accurate predictions for a set of inputs. Just like many of our past models, the model is trained using a loss function, which our model will attempt to minimize over iterations. Remember that a loss function is some function that takes in our predictions and the actual values and returns some sort of aggregate value that shows how accurate (or not) we were.

Neural networks do this by establishing sets of neurons (known as hidden layers) that take in some sort of input(s), apply a weight, and pass that output onward. As we feed more data into the network, it adjusts those weights based on the output of the loss function, until we have highly trained and specific weights. --&gt;

&lt;p&gt;To start, I read the training set into pandas, identifying 42,000 rows and 785 columns of data, inclusive of the target column, ‘label.’  With the exception of the target column, all of the rest of the columns were pixel features of the images.&lt;/p&gt;

&lt;!-- Should I maybe talk about how to convert images to pixels here? --&gt;

&lt;p&gt;Because Keras requires a numpy array (as opposed to a pandas dataframe), I transformed the X set into a numpy matrix and then normalized the dataset by dividing each value by the maximum number of pixels (255).  I also transformed the target (y) values into a one-hot encoded matrix given that this dataset is a multi-classification problem.&lt;/p&gt;

&lt;p&gt;Before feeding the data into the neural network model, I train-test-split my data for training purposes.&lt;/p&gt;

&lt;h2 id=&quot;adding-nuance&quot;&gt;Adding Nuance&lt;/h2&gt;

&lt;p&gt;I initialized the model by making it Sequential() and adding layers to it.  Within a neural network, there are different layers that can be added to improve model performance.  First, I added a dense layer which connected all of the neurons.  Then, I added a “hidden” dropout layer.  A hidden layer does not mean that it is not present or isn’t working - it just means that it is not the initial input layer or the final output layer, as seen in the image below.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/neuralnet.png&quot; alt=&quot;neuralnet.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;A neural network can have any number of hidden layers with any number of neurons.  However, within each layer, each neuron will transform the data in different (and difficult to quantify) ways based on the assigned and change in weights within that neuron.&lt;/p&gt;

&lt;p&gt;I decided to set my dropout layer to 0.5, which means that 50% of the neurons would be randomly “turned off” from training.  I did this to prevent the model from being overfit to the training set and to allow for some flexibility when faced with new data.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Sequential&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Dense&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X_train&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input_shape&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;784&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;activation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'relu'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Dropout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;.5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Dense&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y_train&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;activation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'softmax'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Next, I activated the training set with ‘relu’ (Rectified Linear Unit) which only activates neurons whose output will be positive.  For the target, I activated with ‘softmax’ to essentially normalize the inputs within a scale of 0 to 1 to create a probability for an input falling within one of the target classes.&lt;/p&gt;

&lt;h2 id=&quot;knowing-your-audience&quot;&gt;Knowing Your Audience&lt;/h2&gt;

&lt;p&gt;The next step to modeling a neural network is to compile the model.  I chose the ‘adam’ optimizer given its ease of use, computational efficiency, and ability to handle large sets of data.  While there is &lt;a href=&quot;https://arxiv.org/pdf/1412.6980.pdf&quot;&gt;much more complex math&lt;/a&gt; behind how ‘adam’ is derived, essentially it works similar to (but different from) stochastic gradient descent in which the loss function is computed during each epoch and, as a result, neurons are re-weighted until the loss is sufficiently minimized.  ‘Adam’ differs slightly from stochastic gradient descent by incorporating a dynamic and adaptive learning rate determined by the magnitude of change to the gradients.&lt;sup id=&quot;fnref:1&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;Because this was a muticlassification problem, I set the loss metric to ‘categorical_crossentropy’ as suggested by the &lt;a href=&quot;https://keras.io/losses/#categorical_crossentropy&quot;&gt;Keras documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;failing-better&quot;&gt;Failing Better&lt;/h2&gt;

&lt;p&gt;When training the model, a user can specify how many epochs used to train the model.  An epoch is a “roundtrip” for information to be passed forwards and backwards through the network.&lt;/p&gt;

&lt;p&gt;During forward propagation, data is passed from the initial input layer, through the hidden layers, and finally to the output layer during which weights, biases, and activation functions are applied to the neurons.&lt;/p&gt;

&lt;p&gt;During back propagation, the data is then passed back from the output towards the input layer, measuring the loss produced from the weights assigned to the neurons and, using gradient descent, changes the weights accordingly in order to make more accurate predictions over a user-defined number of iterations.  The amount of epochs to use during training can be identified when either the accuracy or the loss of the predictions stabilizes at an acceptable value.&lt;/p&gt;

&lt;p&gt;To illustrate this point, I plotted a summary chart of the four runs I conducted, tweaking the number of epochs and the dropout percentage with each new run.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/keras-summary.png&quot; alt=&quot;keras-summary.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The top left plot shows the loss from both the training and the cross-validation (test) during which I trained 50 epochs without a dropout layer.  Notice how the training loss dramatically reduces within the first ten epochs but continues to improve only slightly as the training continues to the 50th epoch.  The loss from the test set, however, increases with the number of epochs with a wider amount of variance - a clear sign of overfitting.  The top right plot shows a similar training run but with an added dropout layer of 50%.  Both the training and test sets appear to be more stable and the loss from the test set is reduced.  In my third run, illustrated by the bottom left plot, I increased the dropout percentage to 75% while still running 50 epochs.  Again, the test loss amount is reduced.  Finally, in the fourth run, noticing that in the last three runs there was a shift in performance between the tenth and twentieth epoch, I decided to set my training epochs to 15 while keeping the dropout rate at 75%.  In this run, the test set loss hued closely to the loss of the training set.  Now I had a model that was trained up on the dataset while remaining flexible enough to predict on unseen data.  To further illustrate this point, I input the training and test loss values into a table for easier comparison.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Run&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Epochs&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Dropout&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Train Loss&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Test Loss&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;1&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;50&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;0%&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;0.002&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;0.178&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;2&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;50&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;50%&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;0.019&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;0.140&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;3&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;50&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;75%&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;0.073&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;0.117&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;4&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;15&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;75%&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;0.104&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;0.093&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;art-is-a-lie-that-makes-us-realize-truth&quot;&gt;Art is a Lie that makes us Realize Truth&lt;/h2&gt;

&lt;p&gt;As machine learning continues to be integrated into our daily lives, we should be as discerning as Penelope was when determining which visions of the future are true and which are false.&lt;/p&gt;

&lt;p&gt;To see all of the code associated with this post, check out the associated &lt;a href=&quot;https://github.com/thedatasleuth/Digit-Recognizer-Keras&quot;&gt;GitHub repo&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;
&lt;div class=&quot;footnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://machinelearningmastery.com/adam-optimization-algorithm-for-deep-learning/&quot;&gt;https://machinelearningmastery.com/adam-optimization-algorithm-for-deep-learning/&lt;/a&gt; &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Thu, 07 Jun 2018 00:00:00 +0000</pubDate>
        <link>https://thedatasleuth.github.io/neural-network/2018/06/07/Introduction-to-Neural-Networks-Using-Keras.html</link>
        <guid isPermaLink="true">https://thedatasleuth.github.io/neural-network/2018/06/07/Introduction-to-Neural-Networks-Using-Keras.html</guid>
        
        <category>Neural Network</category>
        
        <category>Keras</category>
        
        <category>Python</category>
        
        
        <category>Neural-Network</category>
        
      </item>
    
      <item>
        <title>Salary Predictions Using Only 3 Features and XGBoost</title>
        <description>&lt;p&gt;&lt;em&gt;Sometimes you can’t get everything you want.  Here’s an afternoon hackathon project that challenged me to make the most of what I had.&lt;/em&gt;&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;We’ve all heard it before - you can get something fast and cheap, but it probably won’t be very good; you could get something good and cheap, but it will take a long time; or you can get something good and fast, but it’s going to cost you.  In that vein, I participated in an afternoon hacking challenge that prompted us to predict whether a person’s salary was above $50,000.&lt;/p&gt;

&lt;p&gt;But there was a catch: each of the three teams were handicapped by a constraint.  ‘Team Samples’ was limited to the number of samples they were allowed to train on but could engineer an unlimited amount of features and choose their own models.  ‘Team Features’ was bound to the number of features they could use (engineered or pre-existing) but could train on the full set of data and choose their own model.  ‘Team Algorithm’ was not bound by the number of features or samples but was constrained by the model they were allowed to use.  None of the three teams knew which team they were on until after the class had voted on the parameters of the constraint.  While these constraints were not dealbreakers, they were &lt;em&gt;highly unfavorable&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I was randomly assigned to ‘Team Features’ and constrained to using only three features from the dataset.  In three and a half hours, I worked with my two teammates to build out the best model we could given our project &lt;em&gt;and&lt;/em&gt; time constraints.  Below is a summary of what we did that afternoon.&lt;/p&gt;

&lt;h2 id=&quot;ready-go&quot;&gt;Ready? Go!&lt;/h2&gt;

&lt;p&gt;The dataset had 30,298 rows across 14 columns related to demographic information of workers, such as age, sex, education, marital-status, and occupation, to name a few.  In a separate target set, we were given their corresponding salaries.  Thankfully, there were no null values, which I would have likely dropped given the time constraint of the project.&lt;/p&gt;

&lt;p&gt;There were eight categorical columns and six numerical columns.  I decided to LabelEncode all of the categorical data in order to get the data into a model as quickly as possible.&lt;/p&gt;

&lt;p&gt;With my data in numbers I could model with, I applied SelectKBest to the data and the salaries as my target.  Given that I was constrained by the number of features I could feed into a model, I set my k value to three.  SelectKBest identified that the three most predictive features of a salary were ‘education-num’, ‘relationship’, and ‘capital-gain’.  To be honest, this surprised me, as I was expecting to see ‘sex’ as a major predictor.  From there, I scaled and train-test-split my data before feeding it into a model.  Given that this project was a competition, I wanted to challenge myself to use a new model that I hadn’t yet tried.&lt;/p&gt;

&lt;h2 id=&quot;power-up&quot;&gt;Power Up!&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/mariokart.gif&quot; alt=&quot;mariokart.gif&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/dmlc/xgboost&quot;&gt;XGBoost&lt;/a&gt;, short for eXtreme Gradient Boosting, is a powerful algorithm used in many Kaggle competitions and is known for its performance as well as computational speed.  The XGBoost algorithm is an ensemble model based on a Decision Tree methodology that creates new models based on predictions of errors from prior models and adds them together sequentially to make a final prediction.  To calculate those errors, XGBoost employs the gradient descent algorithm which identifies optimal parameter values that minimize loss.&lt;/p&gt;

&lt;p&gt;More specifically, gradient descent is an iterative method that chooses a random parameter value to optimize from a starting point dictated the user and calculates the loss of the function for that parameter value.  It continues to randomly guess values for parameters until the loss is sufficiently minimized, meaning that the difference of loss function between two iterations of parameters is sufficiently small.  The distance between one guess and the next is determined by the learning rate.  Move too fast, however, and the algorithm might just skip over the best possible value, move too slowly, and the model might never converge.  If the model fails to converge, the learning rate (alpha) will need to be increased.&lt;/p&gt;

&lt;p&gt;To understand this process visually, imagine yourself on a sled at the top of the peak in the graph below.  Gradient descent will pick a random direction and sled down the mountain a little bit, calculate the loss function, and then sled down the mountain some more until it reaches a valley that satisfies the loss threshold, set as one of the parameters within the algorithm.  XGBoost prevents the potential for overfitting by using L1 and L2 regularization penalties.&lt;sup id=&quot;fnref:1&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/gradient-descent.jpg&quot; alt=&quot;gradient-descent.jpg&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;and-the-winner-is&quot;&gt;And the Winner Is…&lt;/h2&gt;

&lt;p&gt;When modeling my data using XGBoost, I also GridSearched across some parameters, namely ‘max_depth’, ‘n_estimators’, ‘learning_rate’ , and ‘booster’ to hypertune the model.  The fitting took about four and a half minutes across 13,500 possible fits and returned the following best parameters:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;‘booster’: ‘gbtree’,&lt;/li&gt;
  &lt;li&gt;‘learning_rate’: 0.7054802310718645,&lt;/li&gt;
  &lt;li&gt;‘max_depth’: 5,&lt;/li&gt;
  &lt;li&gt;‘n_estimators’: 10&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The model scored a 0.847 for the training set and a 0.851 for the test set within the initial train-test-split.&lt;/p&gt;

&lt;p&gt;Having fit the model and verified that it wasn’t overfit, we then applied our fitted XGBoost model to the hold-out test set and waited for our final score - a 0.841!  Not bad for a model with only three features!&lt;/p&gt;

&lt;p&gt;This was a really fun afternoon project and a great introduction to what Data Science might be like in a professional setting - I suspect that as a Data Scientist, I will have to make (and defend) all sorts of decisions when faced with client deadlines, budget constraints, and incomplete or limited datasets.  Plus, it challenged me to learn a new and powerful model that I later applied to larger-scale projects.&lt;/p&gt;

&lt;p&gt;To view the underlying code for this post, check out the corresponding &lt;a href=&quot;https://github.com/thedatasleuth/Fast-Good-Cheap&quot;&gt;GitHub repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/peach.gif&quot; alt=&quot;peach.gif&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;
&lt;div class=&quot;footnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://machinelearningmastery.com/gentle-introduction-xgboost-applied-machine-learning/&quot;&gt;https://machinelearningmastery.com/gentle-introduction-xgboost-applied-machine-learning/&lt;/a&gt; &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Tue, 05 Jun 2018 00:00:00 +0000</pubDate>
        <link>https://thedatasleuth.github.io/predictive-modeling/2018/06/05/Predicting-Salary-Using-Machine-Learning.html</link>
        <guid isPermaLink="true">https://thedatasleuth.github.io/predictive-modeling/2018/06/05/Predicting-Salary-Using-Machine-Learning.html</guid>
        
        <category>XGBoost</category>
        
        <category>Hackathon</category>
        
        <category>Python</category>
        
        
        <category>Predictive-Modeling</category>
        
      </item>
    
      <item>
        <title>How to Be Popular on Reddit</title>
        <description>&lt;p&gt;&lt;em&gt;With an endless supply of things to read on the internet, it seems impossible to write a post that anyone else but your mom will read.  But with a few (hundred) lines of code, even a platform as wild as Reddit can be neatly distilled into a handful of targeted insights.&lt;/em&gt;&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;Reddit claims to be the front page of the internet, and that’s because they are. With an average of 542 million monthly visitors, of which 234 million are unique, Reddit is the third most visited site in the U.S. and ranked sixth in the world. Reddit is subdivided into subreddits, which are themed discussion boards created and populated by Reddit users with links, text, videos and images. These subreddits span an endless array of interests including world news, sports, economics, movies, music, fitness, and more. Reddit members discuss proposed topics in the comments section, and the most popular comments are “up-voted” to the top of the discussion board.  In 2015, Reddit users submitted nearly 75 million posts and followed up with nearly three quarters of a billion comments.  With so many users, submissions, comments, and up-votes, it can seem impossible to craft a post that will ever see the light of day.&lt;/p&gt;

&lt;p&gt;For this project, I was tasked with analyzing a subset of Reddit’s “Hot Posts” section to identify what, if any, features of a post determine its popularity.  Using data science techniques like exploratory data analysis, predictive modeling, and natural language processing allowed me to efficiently search through a sample of 5,000 posts faster than I ever could have if I had just read through the posts manually.&lt;/p&gt;

&lt;p&gt;With an endless supply of things to read on the internet, it seems impossible to write a post that anyone else but your mom will read.  But with a few (hundred) lines of code, even a platform as wild as Reddit can be neatly distilled into a handful of targeted insights.&lt;/p&gt;

&lt;h2 id=&quot;lets-give-em-something-to-talk-about&quot;&gt;Let’s give ‘em something to talk about&lt;/h2&gt;

&lt;p&gt;This was my first project wherein I had to gather my own data (as opposed to downloading a dataset from Kaggle, for example.)  In order to build out my dataset, I scraped 5,000 posts from the “Hot Posts” section of Reddit’s website using the ‘requests’ and ‘Beautiful Soup’ libraries.  Later on in the project, I used Reddit’s popular API wrapper PRAW to grab some comments from my top 50 ‘hot’ posts.  After a few hours (with three second delays in between each set of 25 posts pulled so as not to be black listed by Reddit’s servers), my scrape was complete.&lt;/p&gt;

&lt;p&gt;With any Reddit post, there are upwards of 85 identifying features, and while I did pull all 85 of those features for each of my 5,000 posts, I decided to limit the features that I built into my dataframe to those I thought would be most predictive of popularity.  I pared the 85 features down to 14 and stored them in variables.  The features I chose to use in my model were: ‘author’, ‘title’, ‘subreddit’, ‘subreddit_subscribers’, ‘score’, ‘ups’, ‘downs’, ‘num_comments’, ‘num_crossposts’, ‘selftext’, ‘pinned’, ‘stickied’, ‘wls’, ‘created_utc.’  If a post had actual original text, it was stored in the ‘selftext’ feature, however, when I began to explore my dataset in more depth, I learned that many Reddit posts don’t actually have original content, but rather, are links to a previous post.&lt;/p&gt;

&lt;!-- ![heidi.jpg](/static/img/heidi.jpg) --&gt;

&lt;p&gt;With my dataframe finally built out, I was able to start exploring the posts I pulled.  My un-engineed dataset began with 5000 rows and 17 columns.  When I grouped by ‘subreddit’, I identified 1950 unique subreddits within my dataset.  While it would be too much to name every single subreddit in this blog post, a few of my favorites were: ‘todayilearned’, ‘mildlyinteresting’, and ‘Showerthoughts.’&lt;/p&gt;

&lt;p&gt;In exploring the null values of my ‘Text’ column which corresponded to the ‘selftext’ feature of my scrape from Reddit, only 416 of posts that I pulled had actual text in the post.  The rest were empty and presumably re-posts.  Given this, I decided to fill the missing values with 0 in order to keep track of which rows had actual text.&lt;/p&gt;

&lt;p&gt;With the exception of ‘wls’ which had 684 missing entries, the rest of my dataset was filled with values.  I decided to fill the missing ‘wls’ values with 6 since that was the mode for the column.&lt;/p&gt;

&lt;p&gt;The score stats directly mirrored the ‘ups’ stats with a maximum score of 133,613, a mean score of 1,590 and a minimum score of 25.  There was nothing to be gleaned from the ‘downs’ stats given that all of the data were 0s.&lt;/p&gt;

&lt;p&gt;I also created two boolean columns ‘IsPinned’ and ‘IsStickied’ which I mapped to the ‘pinned’ and ‘stickied’ variables.  I then dropped the original ‘pinned’ and ‘stickied’ object columns for modeling purposes.&lt;/p&gt;

&lt;p&gt;The comments column, however, was the column I was most interested in, since it made sense that a post’s popularity might be greatly correlated with its volume of comments.  For the posts that I pulled, the max number of comments was 20,246, the minimum, 0, the mean, 76, and the median, 16.  While I did pull these posts from the ‘Hot Posts’ section from Reddit to begin with, I was tasked with identifying and mapping posts whose comments were above a certain threshold.  I used a lambda function to create a new column called ‘Hot’ which represented posts 16 comments (50% percentile) and above and another column called ‘Super Hot’ which represented posts with 44 comments (75% percentile) and above.&lt;/p&gt;

&lt;h2 id=&quot;popular-youre-going-to-be-pop-u-lar&quot;&gt;Popular, you’re going to be pop-u-lar&lt;/h2&gt;

&lt;p&gt;I then created a bag of words of all of the words from the ‘Title’ feature using a for-loop running across the rows in the ‘Title feature’.  In total, there were 10,445 unique words not including common ‘stop’ words such as ‘the’, ‘a’, &amp;amp; ‘and.’  I was able to exclude these common ‘stop’ words using the ‘stop_words’ arg in my CountVectorizer, specifying ‘english’ as my language.&lt;/p&gt;

&lt;p&gt;After performing a train-test-split, I then vectorized the top 20 most common ‘Title’ words into a sparse dataframe, which I then concatenated onto my X_train and X_test matrices with the hope that more information would improve my model performance.  After standardizing my dataset with Standard Scaler, I was ready to run my models.&lt;/p&gt;

&lt;p&gt;In total, I gridsearched over six different models, including a LogisticRegression, an SGDClassifier, a KNeighborsClassifier, a BernoulliNB, a DecisionTreeClassifier, and a RandomForestClassifier.  While I remain skeptical of the perfect test scores for the Decision Tree and Random Forest Classifiers, the R2 scores of the other four models seem to make sense.  I summarized the results of the models into a summary bar plot, with the bold lines at the top of each bar representing the mean standard deviation of the cross validation runs.  The red horizontal line represents the baseline accuracy score of 0.42779.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/reddit-models.png&quot; alt=&quot;reddit-models.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Having fit and scored my models, I chose the Random Forest Classifier to run feature importances on to understand which of my 32 features were most predictive of ‘hot’ posts.  Unsurprisingly, ‘num_comments’ was the most predictive feature with a coefficient of 0.761.  The next most predictive columns did not have nearly the same predictive power as num_comments, with ‘score’, ‘ups’, and ‘subreddit_subscribers’ as the next most predictive with coefficients of 0.0863, 0.0725, and 0.0247, respectively.&lt;/p&gt;

&lt;h2 id=&quot;gossip-folks&quot;&gt;Gossip Folks&lt;/h2&gt;

&lt;p&gt;With modeling done, I wanted to continue exploring the text in my posts to see what, if any, themes rose to the top.  Because I had already done a CountVectorizer on the titles of my posts, I wanted to try another natural language processing technique to help me better understand my data.  So, I subset my data to ‘hot’ posts only (posts with 16 or more comments) and ran a for-loop across those rows to create another bag of words - this time, filled with words that were linked to ‘hot’ posts.  I did the same thing again to my ‘super hot’ posts.  With these two bags of words, I then used a word cloud on the data set to visually inspect any themes.  The images below represent the results of this analysis.  Given that one of the most common words in the ‘super hot’ bag of words was ‘need’, I suspect that more than a few people on Reddit are giving some (unsolicited) advice.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;‘Hot’ Posts&lt;/th&gt;
      &lt;th&gt;‘Super Hot’ Posts&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;img src=&quot;/static/img/hot-posts.png&quot; alt=&quot;hot-posts.png&quot; /&gt;&lt;/td&gt;
      &lt;td&gt;&lt;img src=&quot;/static/img/super-hot.png&quot; alt=&quot;super-hot.png&quot; /&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Having analyzed the text of the posts, I then wanted to further explore Reddit’s data by pulling the comments associated with my top 50 most commented on posts.  First, I created a mask for which I sorted the value counts of the ‘num_comments’ feature with ‘ascending’ set to False.  I then sliced on the first fifty rows.&lt;/p&gt;

&lt;p&gt;With my top fifty most commented on posts in hand, I was ready to pull their associated comments.  Because this was my first time using PRAW, I had to sign up for a developer’s account.  With this account, I was given a user-id, an API key and a secret key which allowed me to use PRAW.&lt;/p&gt;

&lt;p&gt;I wanted to pull the associated top comments so I could run a sentiment analysis on the comment’s text and see which posts received positive comments and which received negative comments.  To parse out sentiment, I installed nltk’s &lt;a href=&quot;https://github.com/cjhutto/vaderSentiment&quot;&gt;Vader Sentiment Analyzer&lt;/a&gt; package.&lt;/p&gt;

&lt;p&gt;To calculate the ‘sentiment intensity’ of each comment, I ran a for-loop across each of my fifty rows and stored the scores in a list.  Vader produces four scores when performing its analysis: negative, neutral, positive, and compound.  The negative, positive, and neutral scores are all bound between 0 and 1, whereas the compound score is bound between -1 and 1, to effectively give an overall score.  To illustrate the range of scores my comments received, I plotted them out in Plotly.  The x axis represents the negative score, the y axis, the positive score, and the color shading represents the overall compound score - compound scores that were more positive were closer to the blue spectrum and compound scores that were overall more negative were hued closer to the red spectrum.  This explains why one of the data points is blue despite having greater than a 0 score on the negative x axis.&lt;/p&gt;

&lt;div&gt;
    &lt;a href=&quot;https://plot.ly/~jesster413/875/?share_key=EhaoM19zpKFqUcZ1pguqhr&quot; target=&quot;_blank&quot; title=&quot;plot from API (15)&quot; style=&quot;display: block; text-align: center;&quot;&gt;&lt;img src=&quot;https://plot.ly/~jesster413/875.png?share_key=EhaoM19zpKFqUcZ1pguqhr&quot; alt=&quot;plot from API (15)&quot; style=&quot;max-width: 100%;width: 600px;&quot; width=&quot;600&quot; onerror=&quot;this.onerror=null;this.src='https://plot.ly/404.png';&quot; /&gt;&lt;/a&gt;
    &lt;script data-plotly=&quot;jesster413:875&quot; sharekey-plotly=&quot;EhaoM19zpKFqUcZ1pguqhr&quot; src=&quot;https://plot.ly/embed.js&quot; async=&quot;&quot;&gt;&lt;/script&gt;
&lt;/div&gt;

&lt;p&gt;While I initially thought that having only positive comments was ideal for posts, after reading through some of the comments and their corresponding scores, I realized that everything but super negative scores is &lt;em&gt;usually&lt;/em&gt; fine.  I then joined my compound_scores dataframe with my comments_scores dataframe to more easily visualize which scores lined up with which comments and sliced on individual subreddits to identify which categories would be the least inflammatory and best received for someone interested in pitching an article to Reddit.&lt;/p&gt;

&lt;p&gt;Finally, I wanted to try to create my own machine learning sentences using a Markov chain generator.  In another post, I walk through more in depth what Markov chain’s are and how they work, but for this project, I installed the &lt;a href=&quot;https://pypi.org/project/markovify/&quot;&gt;markovify&lt;/a&gt; package from PyPi and applied it to my ‘hot’ bag of words.  Using a very simple for-loop and limiting my range to one sentence, I used the ‘beginning’ arg of the ‘make_sentence_with_start function to create one-liner sentences starting with words I specified.  The following is the output of that code.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Women need to give me pity cash.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;I will be replaced, and unfortunately, i don’t think Ameer will be stickying this for four days.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;I can’t remember if it was pursuing me.  I glanced up at her, and five days after my hospitalization it started to happen.  I started working here almost two months ago.  We had talked on the couch, took off my sunglasses, and checked my phone.  Still no service.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;Why would someone do this?  There was just going to be literally upside down.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Again, these sentences were created from the corpus of ‘hot’ words I created from text in the posts I pulled from Reddit.&lt;/p&gt;

&lt;p&gt;If you’d like to see all of the code associated with this project, head on over to the corresponding &lt;a href=&quot;https://github.com/jesster413/Reddit-NLP&quot;&gt;GitHub Repo.&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Tue, 05 Jun 2018 00:00:00 +0000</pubDate>
        <link>https://thedatasleuth.github.io/web-scraping/natural-language-processing/2018/06/05/Predicting-Reddit-Hot-Posts-Using-Machine-Learning-and-Natural-Language-Processing.html</link>
        <guid isPermaLink="true">https://thedatasleuth.github.io/web-scraping/natural-language-processing/2018/06/05/Predicting-Reddit-Hot-Posts-Using-Machine-Learning-and-Natural-Language-Processing.html</guid>
        
        <category>Web Scraping</category>
        
        <category>Natural Language Processing</category>
        
        <category>Python</category>
        
        <category>Beautiful Soup</category>
        
        
        <category>Web-scraping</category>
        
        <category>Natural-Language-Processing</category>
        
      </item>
    
      <item>
        <title>How to Predict Housing Prices with Linear Regression</title>
        <description>&lt;p&gt;&lt;em&gt;When buying a new home, everyone wants the most bang for the buck.  To that end, I analyzed homes in Ames, Iowa to identify what features of a house contribute the most to its sale price.&lt;/em&gt;&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;Buying a house is one of life’s most significant milestones, and according to the most recent census report on residential vacancies, around 64% of homes are occupant-owned.&lt;sup id=&quot;fnref:1&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;  But within the homeownership population, there is a wide range of what is considered desirable in a home which is unique to each home buyer.  Some might want more bedrooms to accommodate a larger family.  Others might want more garage space to fit their growing car collection.  And still others might want a wrap-around porch for those hot summer nights.  Regardless of individual preferences, however, it seems safe to assume that everyone wants the most bang for their buck.  To that end, participated in a private Kaggle challenge during which I analyzed a &lt;a href=&quot;https://www.kaggle.com/c/dsi-us-4-project-2-regression-challenge&quot;&gt;dataset&lt;/a&gt; of homes located in Ames, Iowa to identify what features of a house contribute the most to its sale price.&lt;/p&gt;

&lt;h2 id=&quot;building-the-foundation&quot;&gt;Building the Foundation&lt;/h2&gt;

&lt;p&gt;To start, I wanted to get a sense of what the dataset looked like, both externally and internally.  The initial shape of the data consisted of 2051 rows and 234 columns, with both numerical (numbers) and categorical (words) data.  I knew I would need to convert the categorical data into a form that I could later feed into a model, but first, I wanted to see if I had any null values to contend with.  Sure enough, both my numerical and categorical columns had null values, as seen in the plot below.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/null-values.png&quot; alt=&quot;null-values.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Based on the fact that ‘Pool QC’, ‘Misc Feature’, ‘Alley’, and ‘Fence’ all were missing over 80% of their data, I decided to drop those columns entirely, thinking that what few values existed in these columns would not be enough to inform the model one way or another, and would also not be statistically significant from which to impute new data.&lt;/p&gt;

&lt;p&gt;For the rest of the columns, I decided to impute the missing data based on the data I had with the &lt;a href=&quot;https://github.com/iskandr/fancyimpute/tree/master/fancyimpute&quot;&gt;fancyimpute&lt;/a&gt; package which creates values that mimics the characteristics of values similar to them using a k-nearest neighbors distance calculation.  This is similar to another technique related to upsampling the minority class that I’ve used in other projects.&lt;/p&gt;

&lt;p&gt;I first imputed the numerical columns given that the data was already in the correct data type.  I decided to use 3 k-nearest neighbors for calculation purposes and saved the imputed (and existing) data in a dataframe called ‘imputed_numerical’ which I decided to tack on to the initial train dataframe later.&lt;/p&gt;

&lt;p&gt;The categorical columns, however, were not as easy to impute.  Because fancy impute only takes in numbers, I decided to effectively “LabelEncode” my values while simultaneously skipping over the null values (so as not encode them and nullify the imputation exercise) using the following code snippet:&lt;/p&gt;

&lt;p&gt;With my string values encoded with numerical values, I imputed the remaining null values with nine k-nearest neighbors.  Having imputed all of the missing values, I then dropped the columns in the train set with the missing values and concatenated both the imputed_numerical and imputed_categorical onto the train dataframe, effectively replacing the initial columns with the missing values. I dummified the categorical columns that were not missing data to try to maintain as much interpretability as possible by assigning a new column to each unique value in the categorical columns.  Having finished cleaning the data, it was ready to be fed into some models.&lt;/p&gt;

&lt;!-- Next, I dummified all of the object columns in both of the train and test datasets.  While most of those columns were the same, there were some that differed between the train and test datasets.  In this iteration of the project, I &quot;subtracted&quot; the test set columns from the training set columns to identify what columns were present in the training set that were not present in the test set.  I then dropped those extra columns in the training set.

In a future iteration of this project, I would not drop the extra training columns.  Instead, I would train on the full set, even if it meant that my predictions would be less accurate because this is more representative of how data is collected and presented in the real world - you won't always have the benefit of knowing what the test set looks like in advance.  Rather, it may come in later and you will have to apply the model to it regardless.

Maybe talk about data leakage.  This is the first time I came up against this issue.  Maybe talk about data integrity.

With that in mind, I set out to dummify the object columns in my training set and if there were columns in the test set that did not match those in the training set, I created new columns within the test set and set their values to zero. --&gt;

&lt;h2 id=&quot;choosing-the-framework&quot;&gt;Choosing the Framework&lt;/h2&gt;

&lt;p&gt;Because I was most interested in which features contribute the most to a home’s price, I applied SelectKBest to the dataset.  Unsurprisingly, the top ten features that are most predictive of a home’s sale price were: ‘Overall Qual’, ‘Year Built’, ‘1st Flr SF’, ‘Gr Liv Area’, ‘Garage Yr Blt’, ‘Total Bsmt SF’, ‘Garage Area’, ‘Garage Cars’, ‘Bsmt Qual’, and ‘Exter Qual_TA.’  Looking at these features, it makes sense that the overall quality of a home is most predictive of the value of a home, as does the square footage of the first floor, the basement, and garage area.  Visually, we can see that these features are correlated to the sale price by plotting them on a heatmap.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/ames-heatmap.png&quot; alt=&quot;ames-heatmap.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The bottom row on the left hand side of the plot follows the correlations of the SelectKBest features to the ‘SalePrice’ target.  As we can see, Overall Quality is most positively correlated with Sale Price at a 0.8 correlation, followed by ‘Gr Liv Area’ with a score of 0.7, and so on.  This means that when the values of these features increase, so too does the sale price of a home.  Notably, ‘Bsmt Qual’ and ‘Exter Qual_TA’ were highly negatively correlated to ‘SalePrice’ meaning that when their values increase, the sale price decreases.  The ‘BsmtQual’ feature measured the heights of basements, so based on this analysis, homebuyers don’t particularly value basements with high ceilings.  The ‘Exter Qual_TA’ feature tracked homes with an exterior quality rated ‘TA’ - short for Typical/Average.  Based on this finding, it appears that the sale price of a home decreases when its exterior quality is only rated ‘Average’ as opposed to ‘Excellent’ or ‘Good.’&lt;/p&gt;

&lt;p&gt;No matter how complicated a data science project is, I always find it useful to take a step back sometimes and ask myself whether the results make sense.  Machine learning isn’t some magical black box (although sometimes it feels that way) but rather, it’s a tool that extends the human analytical capabilities to crunch numbers faster and across far larger datasets than anyone has time for manually.&lt;/p&gt;

&lt;p&gt;Having checked the top ten features, I then used SelectKBest to identify the top 100 most predictive features of a home’s sale price to feed into the model.  I then polynomialized those features to capture the information gained from the interactions between features.  I limited the features I polynomialized to 100 out of concern for computation issues.&lt;/p&gt;

&lt;p&gt;For illustrative purposes, I plotted the SelectKBest top ten features that I then polynomialized and zipped them to the coefficient values of the linear regression model without regularization.  In the models that I actually ran, I included the top 100 polynomialized features but, because of computation (and space) issues, was not able to plot them in the same manner.  As you can see, the coefficients varied widely and needed to be regularized.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/ames-lrcoefs.png&quot; alt=&quot;ames-lrcoefs.png&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;crunching-the-numbers&quot;&gt;Crunching the Numbers&lt;/h2&gt;

&lt;p&gt;Without regularizing my coefficients, my Linear Regression model scored a -3.154, which isn’t a viable R2 score and suggests that the model was overfit.  To counter this issue, I used several different regularizing techniques, namely, Ridge, Lasso, and Elastic Net to “penalize” oversized coefficients in order to best minimize the loss function during model training.  When loss functions are minimized, optimal coefficient values are revealed.&lt;/p&gt;

&lt;p&gt;Another reason to regularize data is the fact that while features are correlated to the target to varying degrees, they can also be correlated to each other.  Multicollinearity that goes unaddressed can affect the predictions made by the model and can be contingent upon small changes in sample sets that should not affect predictions.  Moreover, variables that are correlated to each other cannot be independently interpreted as to how they contribute to the target, given that a change in one variable conditionally necessitates a change in another.&lt;/p&gt;

&lt;p&gt;The Ridge regularization technique handles multicollinearity by penalizing the coefficients and effectively crunches them down.  Lasso also addresses multicolinearity, but in a different way.  Instead of “crunching” down the coefficients, it “zeroes” out the coefficients that are not statistically significant in predicting the target value.  In effect, Lasso acts as a feature selector by zeroing out redundant or unimportant variables.  The Lasso regularization technique was particularly useful in this dataset given that polynomializing the top 100 features identified by SelectKBest produced 5,050 features all together.  Lasso pared this number down to 75 features, illustrated in the plot below.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/lasso-coefs.png&quot; alt=&quot;lasso-coefs.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;With the exception of dropping the Overall Qual Gr Liv Area polynomialized feature which had a coefficient value of 25000, the remaining 74 features ranged from just above 0 to 5000 (as opposed to -600,000 to over 700,000 in the first linear regression plot of the top ten polynomialized features.)  This model is particularly useful when interpretability (as in the case of buying a house) is important.&lt;/p&gt;

&lt;p&gt;I also ran an Elastic Net regression, which is a combination of both the Ridge and Lasso penalties.&lt;/p&gt;

&lt;h2 id=&quot;evaluating-the-offer&quot;&gt;Evaluating the Offer&lt;/h2&gt;

&lt;p&gt;I ran 10 cross-validation runs across the three regularized regression models as seen in the plot below.  It looks like all three models fared similarly, with the exception of Lasso’s ninth cross-validation run, where it fell down hard - perhaps because of the variation within the sample set it modeled.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/ames-cv.png&quot; alt=&quot;ames-cv.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Put another way, I plotted the mean cross-validation scores of the three models in the bar plot below.  Because of the ninth cross validation run of Lasso, it’s overall mean score was lower than that of the Ridge and Elastic Net models, however, it might still help a buyer choose a home given how interpretable the coefficients are.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/ames-evaluation.png&quot; alt=&quot;ames-evaluation.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Having conducted this analysis, it appears that the overall quality of a house, the amount of space in the living area, the square footage of the basement, whether there is a fireplace, and the year the home was built and/or remodeled all contribute greatly to the sale price of a house.  In a future iteration of this project, I would be interested in analyzing which neighborhoods are considered most desirable based on their predictive values to the home’s sale price.  Already, from the Lasso coefficients, we can see that the No Ridge and Stone Bridge neighbors have large coefficients, suggesting a statistical significance in their ability to predict a home’s sale price.&lt;/p&gt;

&lt;p&gt;To view the code associated with this project, head on over to the corresponding &lt;a href=&quot;https://github.com/thedatasleuth/Ames-Iowa-Housing-Prices/tree/master&quot;&gt;GitHub repo&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;div class=&quot;footnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://www.census.gov/housing/hvs/files/currenthvspress.pdf&quot;&gt;https://www.census.gov/housing/hvs/files/currenthvspress.pdf&lt;/a&gt; &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Wed, 23 May 2018 00:00:00 +0000</pubDate>
        <link>https://thedatasleuth.github.io/predictive-modeling/2018/05/23/Predicting-Ames-Iowa-Housing-Prices-Using-Machine-Learning.html</link>
        <guid isPermaLink="true">https://thedatasleuth.github.io/predictive-modeling/2018/05/23/Predicting-Ames-Iowa-Housing-Prices-Using-Machine-Learning.html</guid>
        
        <category>Linear Regression</category>
        
        <category>Python</category>
        
        
        <category>Predictive-Modeling</category>
        
      </item>
    
      <item>
        <title>Would I Have Survived the Titanic?</title>
        <description>&lt;p&gt;&lt;em&gt;While the infamous shipwreck happened over 100 years ago, its cultural significance is sunk deep into our collective memory as one of the most tragic manifestations of hubris, classism, and dumb luck.  To that end, I analyzed the data provided on Kaggle’s website to determine more specifically how features such as age, gender, class, and wealth predetermined a passenger’s fate on April 15, 1911 aboard the RMS Titanic.&lt;/em&gt;&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;While the infamous shipwreck happened over 100 years ago, its cultural significance is sunk deep into our collective memory as one of the most tragic manifestations of hubris, classism, and dumb luck.  To that end, I analyzed the data provided on Kaggle’s website to determine more specifically how features such as age, gender, class, and wealth predetermined a passenger’s fate on April 15, 1911 aboard the RMS Titanic.&lt;/p&gt;

&lt;h2 id=&quot;where-to-miss&quot;&gt;“Where to, Miss?”&lt;/h2&gt;

&lt;iframe src=&quot;https://giphy.com/embed/ghvWn8S0jiI0M&quot; width=&quot;480&quot; height=&quot;203&quot; frameborder=&quot;0&quot; class=&quot;giphy-embed&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
&lt;p&gt;&lt;a href=&quot;https://giphy.com/gifs/movie-titanic-ghvWn8S0jiI0M&quot;&gt;via GIPHY&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For this project, I wanted to predict a passenger’s fate using machine learning across several different types of models.  I was also interested in identifying which features had the greatest impact on a person’s chances of survival.&lt;/p&gt;

&lt;p&gt;This dataset is neatly packaged in a .csv file that can be downloaded from Kaggle’s &lt;a href=&quot;https://www.kaggle.com/c/titanic/data&quot;&gt;Titanic competition&lt;/a&gt; page.  In some of &lt;a href=&quot;https://thedatasleuth.github.io/category/Web-scraping&quot;&gt;my other projects&lt;/a&gt; where the data is not so readily accessible, I have used research and web-scraping techniques to assemble my datasets.&lt;/p&gt;

&lt;h2 id=&quot;remember-they-love-money-so-pretend-like-you-own-a-gold-mine-and-youre-in-the-club&quot;&gt;“Remember, they love money, so pretend like you own a gold mine and you’re in the club”&lt;/h2&gt;

&lt;p&gt;Whenever I begin with a new dataset, I like to get an understanding of its shape, stats, and potential pitfalls (null values, outliers, categorical data).  I use descriptors like df.info(), df.shape(), df.describe() as well as a mask I wrote to slice on columns that specifically have null values.&lt;/p&gt;

&lt;p&gt;In sum, this dataset has 891 rows across 12 columns, five of which are categorical columns: ‘Name’,	‘Sex’,	‘Ticket’,	‘Cabin’,	‘Embarked’ and seven of which are numerical columns: ‘PassengerId’,	‘Survived’,	‘Pclass’,	‘Age’,	‘SibSp’,	‘Parch’,	‘Fare’.&lt;/p&gt;

&lt;p&gt;Given that the ‘Cabin’ category was missing almost 80% of its data, I decided not to try to impute the missing values and instead relabeled them as “UI” (Unidentified) from which I then stripped just the first letter from all the cabins in order to make a dummy column called Cabin_category.  This column organized the cabins in this neat array: ‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’, ‘G’, ‘T’, ‘U’.  The ‘Age’ feature, however, was only missing about 20% of its data, so it made sense to me to impute the missing values using MICE within the fancyimpute package.  I decided to drop the two rows in the ‘Embarked’ feature entirely.&lt;/p&gt;

&lt;p&gt;For illustrative purposes, I plotted some graphs with Plotly to help visualize the dataset.  In the ‘Age’ plot, we can see that the majority of people who died were in the 20-39 bins, whereas the majority of people who lived were in the 0-9 bin.  It makes sense that children would have been prioritized both in terms of what was considered the moral thing to do as well as how much space they took up on the life rafts.&lt;/p&gt;

&lt;div&gt;
    &lt;a href=&quot;https://plot.ly/~jesster413/787/?share_key=dGWKE4WznFehAsCcV0SKD0&quot; target=&quot;_blank&quot; title=&quot;plot from API (19)&quot; style=&quot;display: block; text-align: center;&quot;&gt;&lt;img src=&quot;https://plot.ly/~jesster413/787.png?share_key=dGWKE4WznFehAsCcV0SKD0&quot; alt=&quot;plot from API (19)&quot; style=&quot;max-width: 100%;width: 600px;&quot; width=&quot;600&quot; onerror=&quot;this.onerror=null;this.src='https://plot.ly/404.png';&quot; /&gt;&lt;/a&gt;
    &lt;script data-plotly=&quot;jesster413:787&quot; sharekey-plotly=&quot;dGWKE4WznFehAsCcV0SKD0&quot; src=&quot;https://plot.ly/embed.js&quot; async=&quot;&quot;&gt;&lt;/script&gt;
&lt;/div&gt;

&lt;p&gt;We can also see in the plot below that analyzes the gender breakdown of the people who died that the majority of those who perished were men - over four times as many as those who survived.  On the other hand, the women who survived outnumbered those who perished by nearly 3:1.&lt;/p&gt;

&lt;div&gt;
    &lt;a href=&quot;https://plot.ly/~jesster413/791/?share_key=HIZYGI52HOgQjqEKizOPPF&quot; target=&quot;_blank&quot; title=&quot;plot from API (21)&quot; style=&quot;display: block; text-align: center;&quot;&gt;&lt;img src=&quot;https://plot.ly/~jesster413/791.png?share_key=HIZYGI52HOgQjqEKizOPPF&quot; alt=&quot;plot from API (21)&quot; style=&quot;max-width: 100%;width: 600px;&quot; width=&quot;600&quot; onerror=&quot;this.onerror=null;this.src='https://plot.ly/404.png';&quot; /&gt;&lt;/a&gt;
    &lt;script data-plotly=&quot;jesster413:791&quot; sharekey-plotly=&quot;HIZYGI52HOgQjqEKizOPPF&quot; src=&quot;https://plot.ly/embed.js&quot; async=&quot;&quot;&gt;&lt;/script&gt;
&lt;/div&gt;

&lt;p&gt;I was also interested in analyzing whether a person’s wealth played a role in their chances of survival, so I plotted a graph that analyzed the price of a passenger’s ticket as well as their class and cabin.  The size of the bubble corresponds to the price of the ticket (the bigger the bubble, the more expensive the ticket.)  From this plot, it looks like the passengers who were located in Passenger Class 1, Cabin B and held an expensive ticket were more likely to survive.&lt;/p&gt;

&lt;div&gt;
    &lt;a href=&quot;https://plot.ly/~jesster413/554/?share_key=uPkCoBfkZF2cpBiDxKE2rj&quot; target=&quot;_blank&quot; title=&quot;plot from API (12)&quot; style=&quot;display: block; text-align: center;&quot;&gt;&lt;img src=&quot;https://plot.ly/~jesster413/554.png?share_key=uPkCoBfkZF2cpBiDxKE2rj&quot; alt=&quot;plot from API (12)&quot; style=&quot;max-width: 100%;width: 600px;&quot; width=&quot;600&quot; onerror=&quot;this.onerror=null;this.src='https://plot.ly/404.png';&quot; /&gt;&lt;/a&gt;
    &lt;script data-plotly=&quot;jesster413:554&quot; sharekey-plotly=&quot;uPkCoBfkZF2cpBiDxKE2rj&quot; src=&quot;https://plot.ly/embed.js&quot; async=&quot;&quot;&gt;&lt;/script&gt;
&lt;/div&gt;

&lt;h2 id=&quot;you-dont-know-what-hand-youre-gonna-get-dealt-next&quot;&gt;“You don’t know what hand you’re gonna get dealt next”&lt;/h2&gt;

&lt;p&gt;Here’s where I engineered my features, whether it was dropping columns entirely or creating new columns.  For this dataset, I decided to drop the PassengerId, Name, and Ticket columns since their values do not contribute to predicting whether someone survived or not.  Whether someone was male or female, however, did so I encoded those columns: 0 for male and 1 for female.  I also dummified the Embarked and Cabin_category columns to determine whether those features played a role in survivability.  Finally, I added columns like ‘IsReverend’ which encoded whether someone was a Reverend or not and ‘FamilyCount’ which combined the values of ‘SibSp’ and ‘Parch’ to give further detail to the model.&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;iframe src=&quot;https://giphy.com/embed/Y4aRyFaavT9ss&quot; width=&quot;460&quot; height=&quot;480&quot; frameborder=&quot;0&quot; class=&quot;giphy-embed&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
&lt;p&gt;&lt;a href=&quot;https://giphy.com/gifs/Y4aRyFaavT9ss&quot;&gt;via GIPHY&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;it-is-a-mathematical-certainty&quot;&gt;“It is a mathematical certainty.”&lt;/h2&gt;

&lt;p&gt;Because this is a binary prediction, I used Classifier models to predict whether a passenger survived or not, specifically, Logistic Regression, an SGD Classifier, a kNN Classifier, a Bernoulli Naive Bayes Classifier, a Random Forest, and XGBoost.&lt;/p&gt;

&lt;p&gt;To more easily compare my R^2 scores, I generated a table to catalogue my training and test scores across all of my models.  As expected, my training scores were higher than my test scores given that I fit my models to my training data.  It looks like the models all fared pretty well, however, it looks like the kNN and Random Forest models were overfit, given the discrepancy between their training and test scores.  Logistic Regression, SGD Classifier, and XGBoost all looked like they performed well in both the training as well as the test sets.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Model&lt;/th&gt;
      &lt;th&gt;Penalty&lt;/th&gt;
      &lt;th&gt;Alpha&lt;/th&gt;
      &lt;th&gt;Train Score&lt;/th&gt;
      &lt;th&gt;Test Score&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;LogReg&lt;/td&gt;
      &lt;td&gt;Lasso&lt;/td&gt;
      &lt;td&gt;0.077&lt;/td&gt;
      &lt;td&gt;0.844&lt;/td&gt;
      &lt;td&gt;0.816&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;SGD&lt;/td&gt;
      &lt;td&gt;N/A&lt;/td&gt;
      &lt;td&gt;N/A&lt;/td&gt;
      &lt;td&gt;0.830&lt;/td&gt;
      &lt;td&gt;0.816&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;kNN&lt;/td&gt;
      &lt;td&gt;N/A&lt;/td&gt;
      &lt;td&gt;N/A&lt;/td&gt;
      &lt;td&gt;1.000&lt;/td&gt;
      &lt;td&gt;0.794&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;BNB&lt;/td&gt;
      &lt;td&gt;N/A&lt;/td&gt;
      &lt;td&gt;N/A&lt;/td&gt;
      &lt;td&gt;0.757&lt;/td&gt;
      &lt;td&gt;0.757&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;RF&lt;/td&gt;
      &lt;td&gt;N/A&lt;/td&gt;
      &lt;td&gt;N/A&lt;/td&gt;
      &lt;td&gt;0.992&lt;/td&gt;
      &lt;td&gt;0.785&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;XGBoost&lt;/td&gt;
      &lt;td&gt;N/A&lt;/td&gt;
      &lt;td&gt;N/A&lt;/td&gt;
      &lt;td&gt;0.830&lt;/td&gt;
      &lt;td&gt;0.821&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;a-womans-heart-is-a-deep-ocean-of-secrets&quot;&gt;“A woman’s heart is a deep ocean of secrets.”&lt;/h2&gt;

&lt;p&gt;Based on the analysis performed in this post, it appears that men between the ages of 20 and 39 were the most likely to die while on board the RMS Titanic.  Women, children, and those with higher priced tickets fared better.  To illustrate this point even further, I applied the &lt;a href=&quot;http://lime-ml.readthedocs.io/en/latest/lime.html&quot;&gt;LIME&lt;/a&gt; package to the XGBoost model predictions to get a statistical likelihood of a passenger’s survivability based on the ‘Age’, ‘Sex’, and ‘Pclass’ features.&lt;/p&gt;

&lt;p&gt;For example, a 28 year old male passenger in third class had an 81% likelihood of dying.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/titanic-lime-dead.png&quot; alt=&quot;titanic-lime-dead.png&quot; /&gt;
&lt;br /&gt;
In contrast, a three year old female in first class had a 75% chance of survival.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/titanic-lime-survived.png&quot; alt=&quot;titanic-lime-survived.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;To see all of the code associated with this project, check out the corresponding &lt;a href=&quot;https://github.com/thedatasleuth/Titanic-Survival-Predictions&quot;&gt;GitHub repo&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Mon, 21 May 2018 00:00:00 +0000</pubDate>
        <link>https://thedatasleuth.github.io/predictive-modeling/2018/05/21/Predicting-Titanic-Survivability-Odds-Using-Machine-Learning.html</link>
        <guid isPermaLink="true">https://thedatasleuth.github.io/predictive-modeling/2018/05/21/Predicting-Titanic-Survivability-Odds-Using-Machine-Learning.html</guid>
        
        <category>Logistic Regression</category>
        
        <category>Random Forest</category>
        
        <category>XGBoost</category>
        
        <category>Python</category>
        
        
        <category>Predictive-Modeling</category>
        
      </item>
    
      <item>
        <title>Why I Decided to Learn Data Science</title>
        <description>&lt;p&gt;&lt;em&gt;On April 23, 2018, I enrolled in General Assembly’s Data Science course, a full-time immersion program designed to teach programming languages, data analysis techniques, and machine learning skills in 12 weeks.&lt;/em&gt;&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;On April 23, 2018, I enrolled in General Assembly’s Data Science course, a full-time immersion program designed to teach programming languages, data analysis techniques, and machine learning skills in 12 weeks.  On the first day, I was writing code in Python, parsing out a dictionary full of Pokemon characteristics, and wondering if I had made a huge mistake.&lt;/p&gt;

&lt;p&gt;I started off my career as a Paralegal for the Violent and Organized Crime Unit of the U.S. Attorney’s Office for the Southern District of New York.  I knew from the first day I stepped inside of that dilapitated office, I had found my people and my purpose.  For the next three and a half years, I worked on a wide range of cases related to gang violence, drug trafficking, human trafficking, and securities fraud, helping Assistant U.S. Attorneys (AUSAs) prepare for trial.  I later left that office to join the New Jersey Attorney General’s Office where I continued my investigative work as a Detective for the Public Corruption Unit.&lt;/p&gt;

&lt;p&gt;The decision to enroll in a data science bootcamp started the year prior when I was working at a consulting firm tasked with the five-year, court-appointed monitorship of HSBC.  I frequently found myself on teams responsible for investigating transaction-monitoring alerts (given my investigations background) but was routinely passed over for more analytics-based projects in favor of someone with more advanced skills.  I knew what I wanted the data to bear out, I just didn’t know how to do it.&lt;/p&gt;

&lt;p&gt;Frustrated with the limitations of my skillset, I initially took one-off Excel courses to boost my understanding of pivot tables and functions but did not feel satisfied with the results.  While Excel is a powerful tool and can be useful in some types of analyses, it cannot compute on datasets larger than a million rows and cannot identify the kind of insights machine learning packages can.  I realized if I wanted to keep moving forward in my career as an investigator, to be able to interrogate large datasets, to identify unprecedented insights, I needed to invest in upping my tech skills.&lt;/p&gt;

&lt;p&gt;And that’s the path that led me to writing for-loops over a dictionary of full of Pokemon names, gym locations, and combat techniques.  Over the course of the next 12 weeks, I would learn even more about data mining, data enrichment, natural language processing, data visualization, and many different machine learning packages.&lt;/p&gt;

&lt;p&gt;This blog, The Data Sleuth, was inspired by my experiences in both investigative work as well as data science.  It is a collection of my work that I began in my course and that I have continued to refine in the following weeks and months post-graduation.  Feel free to read through the blog posts which are usually shorter topical pieces or have a looked at my portfolio in the ‘Projects’ section, where I go more in depth into the methodology I followed for that particular project.  Should you have any questions related to the topics I write about, any code associated with my projects, or just want to chat about my experience in the coding bootcamp, do not hesitate to reach out via email by clicking on the envelope icon on the left.  I look forward to hearing from you!&lt;/p&gt;

&lt;p&gt;Welcome to The Data Sleuth.&lt;/p&gt;
</description>
        <pubDate>Mon, 23 Apr 2018 00:00:00 +0000</pubDate>
        <link>https://thedatasleuth.github.io/general-assembly/2018/04/23/Why-Should-I-Learn-Data-Science.html</link>
        <guid isPermaLink="true">https://thedatasleuth.github.io/general-assembly/2018/04/23/Why-Should-I-Learn-Data-Science.html</guid>
        
        <category>General Assembly</category>
        
        <category>Bootcamp</category>
        
        
        <category>General-Assembly</category>
        
      </item>
    
  </channel>
</rss>
