<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Anthony Agnone</title>
    <description>The latest articles on DEV Community by Anthony Agnone (@aagnone3).</description>
    <link>https://dev.to/aagnone3</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F193444%2F1cf4536b-0944-40af-8b8d-6f11e3216a2e.png</url>
      <title>DEV Community: Anthony Agnone</title>
      <link>https://dev.to/aagnone3</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aagnone3"/>
    <language>en</language>
    <item>
      <title>Advent of Code -- Your New Holiday Season Routine!</title>
      <dc:creator>Anthony Agnone</dc:creator>
      <pubDate>Tue, 26 Nov 2019 22:47:00 +0000</pubDate>
      <link>https://dev.to/aagnone3/advent-of-code-your-new-holiday-season-routine-2n2h</link>
      <guid>https://dev.to/aagnone3/advent-of-code-your-new-holiday-season-routine-2n2h</guid>
      <description>&lt;h3&gt;
  
  
  &lt;em&gt;Harden up your problem solving and coding proficiency while celebrating the holidays&lt;/em&gt;
&lt;/h3&gt;

&lt;h1&gt;
  
  
  The Gist
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;Man, I really need to brush up on &amp;lt;language/skill&amp;gt;.&lt;/p&gt;

&lt;p&gt;I should check out &amp;lt;language/skill&amp;gt;. I'm seeing it appear more and more, and it will become important for me to be proficient in.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;How many times have you recently had some of these conversations with yourself? Chances are, you have at least a few times, and most of us will also readily admit that we also haven't done much of anything about it. Well, here's a fun holiday season routine for you that can help you out: &lt;a href="https://adventofcode.com/2019/about"&gt;Advent of Code&lt;/a&gt;!&lt;/p&gt;




&lt;h1&gt;
  
  
  What it is
&lt;/h1&gt;

&lt;p&gt;Advent of Code is an annual series of daily coding challenges that happens during the year-end holiday season. &lt;br&gt;
While its name alludes to Christian traditions, it is a simple pun choice meant to convey the 25-day nature of the series (come one, come all!). &lt;br&gt;
Each day, between the 1st and 25th of December, a new puzzle is published. The puzzles usually string along a wonderfully-constructed storyline, keeping you entertained as you are challenged. &lt;br&gt;
Here's an example from last year:&lt;/p&gt;

&lt;h2&gt;
  
  
  Example Puzzle (Day 1 2018)
&lt;/h2&gt;

&lt;p&gt;After feeling like you've been falling for a few minutes, you look at the device's tiny screen. "Error: Device must be calibrated before first use. Frequency drift detected. Cannot maintain destination lock." Below the message, the device shows a sequence of changes in frequency (your puzzle input). A value like +6 means the current frequency increases by 6; a value like -3 means the current frequency decreases by 3.&lt;/p&gt;

&lt;p&gt;For example, if the device displays frequency changes of +1, -2, +3, +1, then starting from a frequency of zero, the following changes would occur:&lt;/p&gt;

&lt;p&gt;Current frequency  0, change of +1; resulting frequency  1.&lt;br&gt;
Current frequency  1, change of -2; resulting frequency -1.&lt;br&gt;
Current frequency -1, change of +3; resulting frequency  2.&lt;br&gt;
Current frequency  2, change of +1; resulting frequency  3.&lt;br&gt;
In this example, the resulting frequency is 3.&lt;/p&gt;

&lt;p&gt;Here are other example situations:&lt;/p&gt;

&lt;p&gt;+1, +1, +1 results in  3&lt;br&gt;
+1, +1, -2 results in  0&lt;br&gt;
-1, -2, -3 results in -6&lt;/p&gt;

&lt;h2&gt;
  
  
  Starting with a frequency of zero, what is the resulting frequency after all of the changes in frequency have been applied?
&lt;/h2&gt;

&lt;p&gt;At this point, a link is available on the page for you to obtain the full input sequence (about a thousand inputs) as a text file. &lt;br&gt;
This is where the rubber meets the road between your problem solving skills and software implementation know-how. &lt;/p&gt;

&lt;p&gt;Be careful! Most people will happily &lt;em&gt;nose dive&lt;/em&gt; into regurgitating code that reads the input, and then face-plant when they realize it's time to implement the core algorithm. &lt;br&gt;
Take the time first to make sure you fully understand the problem at hand, and (at least mentally) form the algorithmic solution before rushing to the I/O code.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why you should do it
&lt;/h1&gt;

&lt;p&gt;You need not use any sort of significant computing hardware to participate in these challenges -- feel free to leave your cloud-computing mindset to the side, and get yourself back into the single machine, single problem mindset of your first data structures and algorithms endeavor 😉. &lt;br&gt;
The puzzles, designed personally by &lt;a href="http://was.tl/"&gt;Eric&lt;/a&gt; 👏, are designed such that solving the problem in brute-force fashion will take entirely too long, but solving in a more intelligent fashion will solve the puzzle in at most 15 seconds on commodity hardware. &lt;/p&gt;

&lt;p&gt;You need not use any sort of super duper optimized programming language, either. Note that, since the correct approach to the puzzle will give you the answer in seconds, the true differentiator in solutions is &lt;em&gt;development time&lt;/em&gt;. &lt;br&gt;
Thus, an appropriate approach in an interpreted language (Python, R, etc) will prevail over a naive approach written in a compiled language (C, Rust, Go, etc). &lt;br&gt;
I love this aspect. Some folks love to gripe about how  is the best because you can always optimize it to run faster and closer to the bare metal etc etc etc. &lt;br&gt;
However, how fast your algorithm runs on hardware is usually not the bottleneck in your end system:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The more expensive factors of an algorithmic solution tend to be things like developer time-to-solution, lack of parallelism, or I/O congestion, as opposed to compiler-enabled program optimization.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When was the last time you were in an interview for an established software company, and they constrained you to a language of choice? &lt;sup id="fnref1"&gt;1&lt;/sup&gt; &lt;br&gt;
Usually, you were instead constrained to (either explicitly, or implicitly via a failed interview!) providing a solution that was modular, efficient, and scalable. &lt;br&gt;
All of these things are capable in any Turing-complete language. So forget about language wars for this series, and focus on the real intellectual meat of the problem.&lt;/p&gt;

&lt;p&gt;Indeed, many dispose of competition altogether here, and use Advent of Code as an opportunity to learn a new language. &lt;br&gt;
Personally, I plan to do my first pass in Python, and then follow up in either Go or Javascript (gotta stay future-proof 🧐). &lt;br&gt;
Whether you are looking for intense competition, a learning opportunity, or a chance to establish a good habit this holiday season, consider finding it in Advent of Code!&lt;/p&gt;




&lt;h1&gt;
  
  
  Ready to Go?
&lt;/h1&gt;

&lt;p&gt;Start by reviewing some puzzles from &lt;a href="https://adventofcode.com/2019/events"&gt;past years&lt;/a&gt;.&lt;br&gt;
Feeling your more competitive side? Join the private leaderboard &lt;a href="https://adventofcode.com/2019/leaderboard/private"&gt;here&lt;/a&gt; with code &lt;code&gt;498713-51f0c909&lt;/code&gt; to see how you match up with other participants. &lt;/p&gt;




&lt;h1&gt;
  
  
  Share your opinion
&lt;/h1&gt;

&lt;p&gt;Why are you planning or not planning to participate in this? If you are not, what would change your mind?&lt;/p&gt;

&lt;p&gt;Do you have tried-and-tested ways to ensure the habit of completing daily tasks like this for extended periods of time?&lt;/p&gt;

&lt;p&gt;What else would you like to share?&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;I hope there aren't too many of you that have been a part of such an interview 😬. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>algorithms</category>
      <category>opensource</category>
      <category>productivity</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Another One in the Books 2019/11/23</title>
      <dc:creator>Anthony Agnone</dc:creator>
      <pubDate>Sat, 23 Nov 2019 19:12:04 +0000</pubDate>
      <link>https://dev.to/aagnone3/another-one-in-the-books-2019-11-23-1g4a</link>
      <guid>https://dev.to/aagnone3/another-one-in-the-books-2019-11-23-1g4a</guid>
      <description>&lt;h1&gt;
  
  
  WAYR (What Are You Reading)
&lt;/h1&gt;

&lt;p&gt;In my latest read, I've finally started a formal plunge into the world of micro-service software architectures by diving into &lt;em&gt;&lt;a href="https://amzn.to/2XKhp39"&gt;Building Microservices: Designing Fine-Grained Systems&lt;/a&gt;&lt;/em&gt; by Sam Newman.&lt;br&gt;
Since seeing this architecture appear at my place of work, I've become very curious and interested in what this means for effective integration of machine learning algorithms into standard product offerings. When you take away all the details of service communications and data storage, this really just smells like more concrete ways of modularizing and encapsulating distinct functionalities in a product.&lt;/p&gt;

&lt;p&gt;That being said, there is still slightly more to it than this -- boundaries between these fine-grained services can often be defined more based on business-level logic boundaries, rather than more traditional software-level or data-level boundaries.&lt;br&gt;
I'm about halfway through this one, and am still fully enthralled; Sam has done much more than "fill in the gaps" of architecture details. He has consistently connected theoretical choices to practical implications, so that you can feel much more confident when approaching the development of your first micro-service application.&lt;/p&gt;

&lt;p&gt;I definitely recommend this one. He's already underway working on &lt;a href="https://amzn.to/37vKKmz"&gt;the next version&lt;/a&gt;, but it doesn't appear to be coming for at least another year. Go ahead with the current version!&lt;/p&gt;




&lt;h1&gt;
  
  
  Learning
&lt;/h1&gt;

&lt;p&gt;As mentioned above, I've become interested in analyzing the interplay of micro-service architectures with the current state of machine learning deployment technologies. &lt;br&gt;
It's certainly not expected that every research scientist in industry need understand all of the DevOps, service design, testing considerations, etc that goes into proper micro-service systems. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;However, a lot companies are currently struggling at marrying long-standing notions of a proper software life-cycle with more recent developments of what a proper machine learning model life-cycle is. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I'll give you a hint: they are not the same 😬.&lt;/p&gt;

&lt;p&gt;I can already tell you that I will be making future dedicated posts both about theory and applications of micro-services with machine learning solutions, so I don't want to delve into it too much here. However, please reach out if you have shared interest in this area!&lt;/p&gt;




&lt;h1&gt;
  
  
  Tools
&lt;/h1&gt;

&lt;p&gt;I hate paper.&lt;/p&gt;

&lt;p&gt;You won't find me hugging any trees, but it's just so wasteful amongst all the technology we have now. What do we use paper for? For the most part, it's just a historical form of sharing information, right? &lt;br&gt;
So...now that we have things like quasi-ubiquitous internet and data storage, why do we still have so much paper?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We still have so much paper mainly due to a transition period, in which companies and individuals change their habits of communicating information.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the meantime, however, the &lt;a href="https://amzn.to/2K0dOZh"&gt;Doxie Go SE&lt;/a&gt; scanner I just got is a fantastic way to move my life more towards fully paper-less. I've never had so much fun using a paper-related device (read: printers suck).&lt;/p&gt;

&lt;p&gt;Ok, so what's so good about it?&lt;/p&gt;

&lt;h3&gt;
  
  
  Portability
&lt;/h3&gt;

&lt;p&gt;This thing is &lt;em&gt;compact&lt;/em&gt;. I won't throw any decimal points at you -- it's the length of a standard sheet of paper, and about the width and height of your pinky finger. &lt;br&gt;
You can charge it with a standard micro USB cable, and then take it with you across the room or the world. &lt;/p&gt;

&lt;h3&gt;
  
  
  Ease Of Use
&lt;/h3&gt;

&lt;p&gt;It just works. And that's saying a lot, since office appliances are usually miserable to deal with. &lt;br&gt;
This is my first Doxie product, but they definitely have my attention now moving forward. &lt;/p&gt;

&lt;p&gt;Two buttons: power and WiFi. Can you guess what each does? &lt;/p&gt;

&lt;p&gt;It's easy to connect to a new network: you can first connect to &lt;em&gt;the device itself&lt;/em&gt; from your computer, and then use its web interface to connect it to the desired network.&lt;/p&gt;

&lt;p&gt;Once it's connected to your network, you can view your recent scans, group them to your liking, and then send them to your folder/cloud/destination of choice. I bet they have yours covered!&lt;/p&gt;




&lt;h3&gt;
  
  
  OCR (Optical Character Recognition)
&lt;/h3&gt;

&lt;p&gt;This mouthful of an acronym for the auto-magical process of converting a picture/scan of something with text to a digital document that "knows" what the text is in the image. &lt;br&gt;
Besides being impressed and saying "man, that's cool", there is a massive benefit that this provides over the more traditional paper filing system of previous centuries:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;With OCR scanners, we now have immediate access to a searchable repository of every piece of paper we've processed with them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let me bring this point home with my current favorite workflow with this: my growing dinner recipe book!&lt;/p&gt;

&lt;p&gt;My wife and I recently got settled into our new home. Amongst all the various projects and errands we are both doing, routinely making a nice meal has become more difficult. &lt;br&gt;
We have recently started using a service that sends us (weekly) a few meal-ready sets of ingredients, with recipe sheets for how to prepare them. &lt;/p&gt;

&lt;p&gt;At this point in the process, our parents and grandparents now air-drop into the conversation with a three-hole punch and binder to help us make our very own recipe book. &lt;br&gt;
While this is thoughtful, how about a digital recipe book that is basically impossible to become damaged, lost, or otherwise unwieldy? I'm picking the latter 😁. &lt;/p&gt;

&lt;p&gt;Every time we finish a meal, I pop the recipe card through the scanner and send it to my Google Drive. Now, whenever one of us is feeling , all we need to do is go into Google Drive and search for  and voila! All recipes matching your search auto-magically appear for you. &lt;br&gt;
This isn't your hot-shot machine learning solution, but I had this process up and running within 30 minutes of receiving the scanner.&lt;/p&gt;




&lt;h1&gt;
  
  
  My two cents
&lt;/h1&gt;

&lt;p&gt;In a recent NFL game, defensive end Myles Garrett &lt;a href="https://youtu.be/_PMHlURlxus?t=22"&gt;smashed his helmet&lt;/a&gt; onto the head of QB Mason Rudolph during a scuffle, leading us to &lt;a href="https://www.si.com/nfl/2019/11/15/myles-garrett-suspension-violence"&gt;related incidents&lt;/a&gt; like this in the NFL, and how much of a media ruckus was made with them. &lt;br&gt;
The angle I want to take here is to step back and claim how ridiculous all of this is.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Consider how much human effort went into the media coverage, NFL penalty determination, and fan conversation about this. Is it all &lt;em&gt;worth it&lt;/em&gt; that much, compared to the rest of our lives?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Two grown boys, getting paid millions of dollars, got in a schoolyard brawl in front of a physical-and-digital audience of millions of people.&lt;br&gt;
Then, thousands, if not millions of people spend their time and effort to get paid to do their job in the next few days, which in some part related to this event. &lt;/p&gt;

&lt;p&gt;If you pool together the collective attention and brain power of all of these people, is this really the best use of us?&lt;/p&gt;




&lt;h1&gt;
  
  
  Share your opinion
&lt;/h1&gt;

&lt;p&gt;What are your thoughts on this incident with Myles Garrett, and how the media played a part in the aftermath?&lt;/p&gt;

&lt;p&gt;Do you have any experience with micro-services and/or machine learning deployment?&lt;/p&gt;

&lt;p&gt;Do you have additional ideas about the implications of OCR and traditional paper processes?&lt;/p&gt;

&lt;p&gt;What else would you like to share?&lt;/p&gt;

</description>
      <category>wayr</category>
      <category>learning</category>
      <category>mytwocents</category>
      <category>tools</category>
    </item>
    <item>
      <title>OpenAI's Hide-and-Seek Findings, the Systems Perspective</title>
      <dc:creator>Anthony Agnone</dc:creator>
      <pubDate>Sat, 21 Sep 2019 16:53:48 +0000</pubDate>
      <link>https://dev.to/aagnone3/openai-s-hide-and-seek-findings-the-systems-perspective-2197</link>
      <guid>https://dev.to/aagnone3/openai-s-hide-and-seek-findings-the-systems-perspective-2197</guid>
      <description>&lt;h3&gt;
  
  
  &lt;em&gt;Yes, the agents cheated, but what does that mean for the system?&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;OpenAI released a &lt;a href="https://openai.com/blog/emergent-tool-use/" rel="noopener noreferrer"&gt;fantastic piece&lt;/a&gt; on some results obtained in a multi-agent hide-and-seek simulation, in which multiple hiders and multiple seekers play the popular children's game.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanthonyagnone.com%2Fimg%2Fopenai-hide-and-seek.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanthonyagnone.com%2Fimg%2Fopenai-hide-and-seek.gif" alt="Environment demo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The simulation had some interesting aspects to it, such as tools (boxes, ramps, walls) that the agents could use to aid them in achieving their objective of effective hiding/seeking.&lt;br&gt;
However, the more notable result is that extended simulation of the environment led to &lt;em&gt;emergent behavior&lt;/em&gt;; that is, behavior that is fundamentally unplanned or unexpected.&lt;/p&gt;

&lt;p&gt;For example, some of the expected behavior is that the hiders would eventually learn to build an enclosure with the walls and/or boxes that hides the ramps from the seekers.&lt;br&gt;
This way, the ramps cannot be used to go over the walls and into the built enclosure from above.&lt;br&gt;
Now, what the environment designers did not expect (the emergent behavior) is that the seekers would learn that they could use the ramp to get on top of a box, and then use a running motion to essentially "surf" the box anywhere they pleased!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanthonyagnone.com%2Fimg%2Fopenai-box-surfing.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanthonyagnone.com%2Fimg%2Fopenai-box-surfing.png" alt="Box surfing"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using this method, the seekers found a way to access the hider-built enclosures from above that was not intended by the designers of the system!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The seekers had gamed the system.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, what do you think the hiders did in response to this behavior? Some of you may think that, since the seekers had learned, to some extent, undefined behavior of the system, that the hiders might respond with some ridiculous action, since the system was now in a state of disarray.&lt;/p&gt;

&lt;p&gt;But think about it. The system was not in any sort of unknown state.&lt;/p&gt;

&lt;p&gt;While it may be in a state that the designers did not explicitly intend to create, the agents were continuing to operate in a manner in which they saw as optimal for their desired outcomes.&lt;/p&gt;

&lt;p&gt;Thus, the hiders learned to paralyze the seekers' ability to surf boxes!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanthonyagnone.com%2Fimg%2Fopenai-surf-defense.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fanthonyagnone.com%2Fimg%2Fopenai-surf-defense.png" alt="Surf defense"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;They did this by using the pre-allocated initial time in which the seekers are frozen to &lt;em&gt;lock all of the boxes and ramps&lt;/em&gt;.&lt;br&gt;
Then, they use any time left to construct a quick enclosure with the movable walls and then lock the walls.&lt;br&gt;
This way, the seekers now, once again, have no way to get inside the enclosure (at least, that's the thought...).&lt;br&gt;
Well played, guys.&lt;/p&gt;

&lt;p&gt;I think that is fascinating, but on a different level than most of OpenAI's analysis focuses on. &lt;br&gt;
They do mention that the agents find out how to game their way to a system:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"[...] agents build [...] strategies and counterstrategies, some of which we did not know our environment supported"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;However, they then dive into detail only about the scenarios that the agents learned, and completely ignored the environmental design flaws themselves. I think the latter is the more interesting phenomenon!&lt;br&gt;
I'd like to turn the analysis on its head -- let's now hold the agent designs constant, and vary the environment's state structure and reward system.&lt;br&gt;
Analyze how different incentive/response systems &lt;em&gt;induce&lt;/em&gt; different agent strategies.&lt;br&gt;
The field of reinforcement learning is progressing wonderfully, especially in recent years. We've gone from checkers solvers to a Go champion in just a few decades -- our &lt;em&gt;agent modeling&lt;/em&gt; is getting pretty dang good.&lt;br&gt;
Now, how about our &lt;em&gt;multi-agent environment modeling?&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Multi-Agent Environment Design
&lt;/h1&gt;

&lt;p&gt;OpenAI has certainly thought about it. Per their final paragraph,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Building environments is not easy and it is quite often the case that agents find a way to exploit the environment you build or the physics engine in an unintended way.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A great &lt;a href="https://medium.com/@BonsaiAI/deep-reinforcement-learning-models-tips-tricks-for-writing-reward-functions-a84fe525e8e0" rel="noopener noreferrer"&gt;article on reward function design&lt;/a&gt; written by &lt;a href="https://medium.com/@BonsaiAI" rel="noopener noreferrer"&gt;@BonsaiAI&lt;/a&gt; on Medium mentions that "you get what you incentivize, not [necessarily] what you intend."&lt;br&gt;
That beautifully summarizes the inherent dilemma in designing a reward system for a certain outcome.&lt;br&gt;
You certainly have your mental picture of how your system of incentives will lead to the system as a whole reaching the desired state(s), but have you considered all of the minute ways in which your system may have some "cracks" in it?&lt;br&gt;
Obviously, this is easier said than done. This divergence of "intent vs outcome" is readily seen in our daily lives, whether professionally or not:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;software engineers intend to turn documented specifications into functional software that is a faithful rendition of the documented change.&lt;/li&gt;
&lt;li&gt;company executives intend to compensate employees appropriately, based on how much value they provide to the company as a whole.&lt;/li&gt;
&lt;li&gt;sports team managers intend to apply game plans and player lineups that will bring victory over each successive opposing team.&lt;/li&gt;
&lt;li&gt;etc...&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;The unwavering and succinct truth for all of these situations is that the system behaves &lt;em&gt;exactly&lt;/em&gt; as it is designed; there are not &lt;em&gt;undesigned&lt;/em&gt; consequences, only &lt;em&gt;unintended&lt;/em&gt; ones.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To make this idea clear, let's take the compensation scenario a little further.&lt;br&gt;
Say there are employees near the middle of the corporate hierarchy who are unhappy with their compensation, and are taking issue&lt;br&gt;
with the overall design of the compensation structure (assume the structure is readily known across the organization).&lt;br&gt;
Statements these employees may make will go along the lines of "this system is broken" or "what's happening here is &lt;em&gt;wrong&lt;/em&gt;".&lt;br&gt;
However, what cannot be said in these circumstances (assuming a compassionate and fair designer) is "this system is not doing what it is designed to."&lt;/p&gt;

&lt;p&gt;Of course it is! It is doing exactly what it is instructed to do!&lt;br&gt;
If it should be doing something different than what it is now, then it should be changed as such.&lt;br&gt;
Now, we may have &lt;em&gt;intended&lt;/em&gt; for the system to be doing one thing, but that may or may not actually be the final design.&lt;br&gt;
However, regardless of intent, what is happening is a &lt;em&gt;perfect rendition of the system that was chosen&lt;/em&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  A New Frontier
&lt;/h1&gt;

&lt;p&gt;I'm excited to see more theory develop around effective design of environmental incentive systems, especially in multi-agent scenarios.&lt;br&gt;
The applications for theory like this are littered in our daily lives, and are even among the most important questions we seek to answer with regard to living amongst each other.&lt;br&gt;
Here are some examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what's the best way for us to govern ourselves and others? &lt;sup id="fnref1"&gt;1&lt;/sup&gt;
&lt;/li&gt;
&lt;li&gt;what's the best way to organize how we define and exchange value between each other?&lt;/li&gt;
&lt;li&gt;what's the best way to collaborate with each other towards a common end product or creation?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It should only take one or two of those examples to get you sufficiently motivated for this. And that's great...because this area of research is just getting started in some respects.&lt;br&gt;
For example, I imagine there is a plethora of historical publication on system-level analysis of things like governments, economic systems, and managerial hierarchies.&lt;br&gt;
However, all of this precedence is going to soon be married with the recent advances in multi-agent RL.&lt;br&gt;
The important similarities and differences between these theory families has the potential to lead to an explosion of knowledge and application in topics of human systems and computer-agent systems alike.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Systems will always be gamed, whether the agents are human or digital.&lt;/p&gt;

&lt;p&gt;What are your thoughts on effective ways to prevent/detect/fight the exploitation of incentive systems?&lt;/p&gt;

&lt;p&gt;What are some interesting "timeless" academic works you know of, which analyze human/agent systems at large?&lt;/p&gt;

&lt;p&gt;How about the same for reward design in multi-agent RL?&lt;/p&gt;

&lt;p&gt;What other applications do you see here that I didn't touch on?&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;I'm looking forward to the day where an electoral candiate's proposed policies can be evaluated by simulation, rendering the circus of televised debates useless ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>Reproducible Data Processing with Make + Docker</title>
      <dc:creator>Anthony Agnone</dc:creator>
      <pubDate>Tue, 06 Aug 2019 02:07:39 +0000</pubDate>
      <link>https://dev.to/aagnone3/reproducible-data-processing-with-make-docker-4a28</link>
      <guid>https://dev.to/aagnone3/reproducible-data-processing-with-make-docker-4a28</guid>
      <description>&lt;h3&gt;
  
  
  &lt;em&gt;Avoiding reproducibility hell with dependency management and containerization&lt;/em&gt;
&lt;/h3&gt;

&lt;h2&gt;
  
  
  Motivation
&lt;/h2&gt;

&lt;p&gt;When performing experiments in data science and machine learning, two main blockers of initial progress are delays building/using “base code” and lack of reproducibility.&lt;br&gt;
Thanks to some great open source tools, you don’t have to be a software guru to circumvent these obstacles and get meaning from your data in a much smoother process.&lt;/p&gt;

&lt;p class="has-medium-font-size"&gt;
  “Hey there, I got this error when I ran your code…can you help me?”
&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dWkT3cpK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://anthonyagnone.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-18-at-6.37.49-PM-1024x254.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dWkT3cpK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://anthonyagnone.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-18-at-6.37.49-PM-1024x254.png" alt="" class="wp-image-89"&gt;&lt;/a&gt;oh yeah, that file…&lt;/p&gt;

&lt;p&gt;…and it’s something facepalm-worthy. Here you are, trying to hit the ground running with a friend or colleague on an interesting idea, and you’re now side-tracked debugging a file-not-found error. Welcome back to your intro programming course!&lt;/p&gt;

&lt;p&gt;I’m sure the owner of the code also loves nothing more than to spend a bunch of time helping someone step through these issues at a snail’s pace. The sheer euphoria you two have just shared over the promise of recent experimental results has now morphed into unspoken embarrassment and frustration that the demonstration has failed before showing any worth, whatsoever.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--otEDM--l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://anthonyagnone.com/wp-content/uploads/2019/07/over.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--otEDM--l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://anthonyagnone.com/wp-content/uploads/2019/07/over.jpg" alt="" class="wp-image-121"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But it’s fine. It’s fine! Your buddy knows just where to find that missing file. You’re told that you will have it within minutes, and then you will be on your way!&lt;/p&gt;

&lt;p class="has-medium-font-size"&gt;
  “Alright, download that file — I just emailed it to you. Then run train.py, you should get 98% accuracy in 20 epochs.”
&lt;/p&gt;

&lt;p&gt;Aha! This is it! The time has come to join the ranks of esteemed data magicians, casting one keyboard spell after another, watching your data baby’s brain get progressively more advanced as it beckons for a role in a new Terminator movie! Let’s see what we get!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--V5Zk81mM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://anthonyagnone.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-18-at-6.46.42-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--V5Zk81mM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://anthonyagnone.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-18-at-6.46.42-PM.png" alt="" class="wp-image-90"&gt;&lt;/a&gt;but I did what you said 🙁&lt;/p&gt;

&lt;p&gt;…yeah, we’ve all been there.&lt;/p&gt;

&lt;p&gt;What could it be? Well, maybe it’s something obvious. I know python, and I know what your code should be doing. I’ll just pop open your &lt;code&gt;train.py&lt;/code&gt; to poke around and…NOPE.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TlNQaCec--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.chzbgr.com/full/6157943808/h9C44E570/" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TlNQaCec--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.chzbgr.com/full/6157943808/h9C44E570/" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Don’t worry, this isn’t going to be a pinky-waving article about how to always write a software masterpiece and scoff at anything you deem insubordinate. That’s a sticky subject in general, as it’s wrought with subjectivity and competing standards. These examples aim to just emphasize how there are a myriad of ways in which we would &lt;span&gt;not&lt;/span&gt; prefer for new experiments to start.&lt;/p&gt;

&lt;p&gt;We’re interested in &lt;em&gt;re-producing&lt;/em&gt; and &lt;em&gt;improving&lt;/em&gt; on results in a &lt;em&gt;convenient&lt;/em&gt; fashion, not stumbling to re-create past achievements. With that in mind, let’s have a look at some popular tools that can be used to streamline the start of any new ML software project: &lt;a href="https://www.docker.com/"&gt;Docker&lt;/a&gt; and &lt;a href="https://www.gnu.org/software/make/"&gt;Make&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Docker
&lt;/h2&gt;

&lt;p&gt;The python ecosystem has some great features for dealing with dependencies, such as &lt;a href="https://realpython.com/what-is-pip/"&gt;pip&lt;/a&gt; and &lt;a href="https://docs.python-guide.org/dev/virtualenvs/"&gt;virtualenv&lt;/a&gt;. These tools allow for one to easily get up and running according to some specification of what needs to be installed to proceed with running some code.&lt;/p&gt;

&lt;p&gt;For example, say you have just come across the &lt;a href="https://scikit-learn.org"&gt;scikit-learn&lt;/a&gt; library (and it’s love at first sight, of course). You are particularly drawn to one of its demo examples, but would like to re-produce it with the data housed in a &lt;a href="https://pandas.pydata.org/"&gt;pandas&lt;/a&gt; DataFrame. Furthermore, another project you are working on requires an ancient version of pandas, but you would like to use features available only in a newer version. With pip and virtualenv, you have nothing to fear (…but fear itself).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# create and activate environment&lt;/span&gt;
virtualenv pandas_like_ml
&lt;span class="nb"&gt;source &lt;/span&gt;pandas_like_ml/bin/activate

&lt;span class="c"&gt;# install your desired libraries&lt;/span&gt;
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--upgrade&lt;/span&gt; pip
pip &lt;span class="nb"&gt;install &lt;/span&gt;scikit-learn&lt;span class="o"&gt;==&lt;/span&gt;0.21.1
pip &lt;span class="nb"&gt;install &lt;/span&gt;&lt;span class="nv"&gt;pandas&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;0.19.1

&lt;span class="c"&gt;# the main event&lt;/span&gt;
python eigenfaces.py &lt;span class="nt"&gt;-n&lt;/span&gt; 20000

&lt;span class="c"&gt;# we're done here, so exit the environment&lt;/span&gt;
&lt;span class="nb"&gt;source &lt;/span&gt;deactivate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;When you learn this flow for the first time, you feel freed from the hellish existence that is dependency management. You triumphantly declare that you shall never, ever be conquered again by the wrath of a missing package or a bloated monolithic system environment. However, this unfortunately isn’t always enough…&lt;/p&gt;

&lt;blockquote class="wp-block-quote is-style-large"&gt;
  &lt;p&gt;
    Python environment tools fall short when the dependency is not at the language level, but at the system level.
  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example, say you would like to set up your machine learning project with a &lt;a href="https://www.mongodb.com/"&gt;MongoDB&lt;/a&gt; database backend. No problem! &lt;code&gt;pip install pymongo&lt;/code&gt; and then we’re home free! Not so fast…&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LUn7ArRO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://anthonyagnone.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-18-at-7.16.23-PM-1-1024x329.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LUn7ArRO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://anthonyagnone.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-18-at-7.16.23-PM-1-1024x329.png" alt="" class="wp-image-92"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well…that didn’t go as expected. Now, in addition to setting up my library dependencies, we need to also manage a library outside of python? Gah! Further delays! Time to google for the package name for mongoDB…&lt;/p&gt;

&lt;p&gt;What if I don’t even know what operating system my colleague is using? I can’t give him some &lt;code&gt;sudo apt-get install&lt;/code&gt; snippet if he’s on CentOS. Even more to the point, there’s no easy way to &lt;em&gt;automate&lt;/em&gt; this step for future projects. Make me do something once, I’ll do it. Make me do it again…zzzz.&lt;/p&gt;

&lt;p&gt;So, we’re faced with the desire to standardize and automate setting up software libraries and other system dependencies for new data-related endeavors, and sadly our usual python tools have fallen short. Enter Docker: an &lt;a href="https://docs.docker.com/engine/docker-overview/"&gt;engine&lt;/a&gt; for running services on an OS as lightweight virtualization packages called &lt;em&gt;containers&lt;/em&gt;. Docker containers are the realization of the definition of a Docker &lt;em&gt;image&lt;/em&gt;, which is specified by a file called a &lt;code&gt;Dockerfile&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# you can specify a base image as a foundation to build on&lt;/span&gt;
FROM ubuntu:16.04

&lt;span class="c"&gt;# make a partition, and specify the working directory&lt;/span&gt;
VOLUME /opt
WORKDIR /opt

&lt;span class="c"&gt;# install some base system packages&lt;/span&gt;
RUN apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    python3 &lt;span class="se"&gt;\&lt;/span&gt;
    python3-dev &lt;span class="se"&gt;\&lt;/span&gt;
    python3-pip &lt;span class="se"&gt;\&lt;/span&gt;
    python3-setuptools

&lt;span class="c"&gt;# install some python packages&lt;/span&gt;
RUN pip3 &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--upgrade&lt;/span&gt; pip
RUN pip3 &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    scikit-learn&lt;span class="o"&gt;==&lt;/span&gt;0.21.1 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;pandas&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;0.19.1

&lt;span class="c"&gt;# set the container's entry point, just a bash shell for now.&lt;/span&gt;
&lt;span class="c"&gt;# this can also be a single program to run, i.e. a python script.&lt;/span&gt;
ENTRYPOINT &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"/bin/bash"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Think of a Dockerfile as a (detailed) recipe of setup steps we would need to do in order to get the system in the state we would like for the experiment. Examples include things like setting up a database, installing libraries, and initializing a directory structure. If you’ve ever made a nice shell script to do some setup like this for you, you were not far from the typical Docker workflow. There are many benefits that Docker has over a shell script for this, most notably being &lt;em&gt;containerization&lt;/em&gt;: with Docker containers, we are abstracted away from the host system that the container is running on. The virtual system that the container is running in is defined in its own process. Because of this, we can have multiple containers running completely different setups, but on the same host machine. How’s that for some insulation against system dependency hell?&lt;/p&gt;

&lt;p&gt;Additionally, we are further insulated from issues like missing files and differences of system state. We know &lt;em&gt;exactly&lt;/em&gt; what the system state will be when it is run. We know this because we have made it so via the explicit instructions in the Dockerfile.&lt;/p&gt;

&lt;p&gt;To actually build the image, we use a command like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-t&lt;/span&gt; my_first_container &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-f&lt;/span&gt; Dockerfile
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;At this point, we have built the image. With this image, we can repeatedly instantiate it as desired, e.g. to perform multiple experiments.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    my_first_container
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Voila!&lt;/p&gt;

&lt;p&gt;If we left at this point and ran in N directions to do various different experiments, these commands may get rather cumbersome to type…&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--mount&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;bind&lt;/span&gt;,source&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;,target&lt;span class="o"&gt;=&lt;/span&gt;/opt &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--mount&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;bind&lt;/span&gt;,source&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CORPORA_DIR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;,target&lt;span class="o"&gt;=&lt;/span&gt;/corpora &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;JUPYTER_PORT&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;:&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;JUPYTER_PORT&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-ti&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    my_advanced_container &lt;span class="se"&gt;\&lt;/span&gt;
    jupyter-lab &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--allow-root&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--ip&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0.0.0.0 &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;JUPYTER_PORT&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--no-browser&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        2&amp;gt;&amp;amp;1 | &lt;span class="nb"&gt;tee &lt;/span&gt;log.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Don’t worry if your eyes gloss over at this. The point is it’s a lot to keep typing. That’s fine though, we have shell scripts for a reason. With shell scripts, we can encapsulate minute details of making a very specific sequence of commands into something as mindless as &lt;code&gt;bash doit.sh&lt;/code&gt;. However, consider also a scenario in which your Dockerfile definition depends on other files (i.e. a requirements.txt file or a file of environment variables to use). In this case, we also would like to know &lt;em&gt;automatically&lt;/em&gt; when the Docker image needs to be re-created, based on upstream &lt;em&gt;dependencies&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;So what has four letters, saves you from typing long, arduous commands, and automates dependency management?&lt;/p&gt;

&lt;h2&gt;
  
  
  Make
&lt;/h2&gt;

&lt;p&gt;GNU Make is a wonderous tool, gifted to us by the same software movement that has made the digital world what it is today. I’ll save you a more sparkly introduction and jump into the core abstraction of what it is: a &lt;a href="https://en.wikipedia.org/wiki/Directed_acyclic_graph"&gt;DAG&lt;/a&gt;-based approach to intelligently managing dependencies of actions in a process, in order to &lt;em&gt;efficiently&lt;/em&gt; achieve a desired outcome.&lt;/p&gt;

&lt;p&gt;Ok, it’s also a convenient way to compile C code. But focus on the first definition, and think bigger! Re-using the general DAG-based dependency management idea has led to some great tools over the years, like &lt;a href="https://github.com/Factual/drake"&gt;Drake&lt;/a&gt; (not the rapper), &lt;a href="https://github.com/spotify/luigi"&gt;Luigi&lt;/a&gt; (not Mario’s brother), and perhaps most notably &lt;a href="https://airflow.apache.org/"&gt;Airflow&lt;/a&gt; (AirBnB’s baby, but now part of the Apache Foundation).&lt;/p&gt;

&lt;p&gt;Consider the contrived example below. We’d like to make predictions on audio-visual data with a trained model. As a new raw image appears, do we need to re-train the model in order to create a prediction? Setting aside applications such as online learning, we do not. Similarly, say we just updated some parameters of our trained model. Do we need to re-cull the raw images, in order to re-create the &lt;em&gt;same data sample&lt;/em&gt;? Nope.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IGP4r5sy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://anthonyagnone.com/wp-content/uploads/2019/05/graph-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IGP4r5sy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://anthonyagnone.com/wp-content/uploads/2019/05/graph-1.png" alt="" class="wp-image-102"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is where Make comes into play. By specifying a &lt;a href="http://www.cs.colby.edu/maxwell/courses/tutorials/maketutor/"&gt;Makefile&lt;/a&gt; with “targets” that correspond to (one or more) desired outputs in the DAG, invoking that target will automatically provide that outcome for you, while only re-invoking dependency processes that are necessary.&lt;/p&gt;

&lt;p&gt;Make can be used for pretty much anything that involves actions and their dependencies. It’s not always right tool in the shed (see &lt;a href="https://airflow.apache.org/"&gt;Airflow&lt;/a&gt; for this process on distributed applications), but it can get you pretty far. I even used it to generate the image above! Here’s what the Makefile looks like.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# the "graph.png" target specifies "graph.dot" as a dependency&lt;/span&gt;
&lt;span class="c"&gt;# when "graph.png" is invoked, it invokes "graph.dot" only if necessary&lt;/span&gt;

graph.png: graph.dot
    dot graph.dot &lt;span class="nt"&gt;-Tpng&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; graph.png

&lt;span class="c"&gt;# the "graph.dot" target specifies "make_graph.py" as a dependency&lt;/span&gt;
&lt;span class="c"&gt;# so, this command is only re-run when...&lt;/span&gt;
&lt;span class="c"&gt;#   1) make_graph.py changes&lt;/span&gt;
&lt;span class="c"&gt;#   2) graph.dot is not present&lt;/span&gt;
graph.dot: make_graph.py
    python make_graph.py
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Marrying the Two
&lt;/h2&gt;

&lt;p&gt;So we’ve ailed over to struggles of reproducible work and introduced great tools to manage environment encapsulation (Docker) and dependency management (Make). These are two pretty cool cats, we should introduce them to each other!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kzxj5TMx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://anthonyagnone.com/wp-content/uploads/2019/07/product-school-mEpShydwItI-unsplash-1024x683.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kzxj5TMx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://anthonyagnone.com/wp-content/uploads/2019/07/product-school-mEpShydwItI-unsplash-1024x683.jpg" alt="" class="wp-image-116"&gt;&lt;/a&gt;Photo by &lt;a href="https://unsplash.com/@productschool?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Product School&lt;/a&gt; on &lt;a href="https://unsplash.com/search/photos/meet?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;br&gt;&lt;br&gt;
P.S. Which one is Docker, and which is Make? &lt;/p&gt;

&lt;p&gt;Let’s say we’ve just found the &lt;a href="https://magenta.tensorflow.org/"&gt;Magenta&lt;/a&gt; project, and would like to set up an environment to consistently run demos and experiments in, without further regard to what version of &lt;code&gt;this_or_that.py&lt;/code&gt; is running on someone’s computer. After all, on some level, we don’t care what version of &lt;code&gt;this_or_that.py&lt;/code&gt; is running on your machine. What we care is that you are able to experience the same demo/result that the sender has experienced, with minimal effort.&lt;/p&gt;

&lt;p&gt;So, let’s set up a basic &lt;code&gt;Dockerfile&lt;/code&gt; definition that can accomplish this. Thankfully, the Magenta folks have done the due diligence of creating a &lt;a href="https://hub.docker.com/r/tensorflow/magenta/tags"&gt;base Docker image&lt;/a&gt; themselves, to make it &lt;em&gt;trivial&lt;/em&gt; to build from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# base image&lt;/span&gt;
FROM tensorflow/magenta

&lt;span class="c"&gt;# set partition and working directory&lt;/span&gt;
VOLUME /opt
WORKDIR /opt

&lt;span class="c"&gt;# install base system packages&lt;/span&gt;
RUN apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    vim &lt;span class="se"&gt;\&lt;/span&gt;
    portaudio19-dev

&lt;span class="c"&gt;# install python libraries&lt;/span&gt;
COPY requirements.txt /tmp/requirements.txt
RUN pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--upgrade&lt;/span&gt; pip
RUN pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; /tmp/requirements.txt

&lt;span class="c"&gt;# container entry point&lt;/span&gt;
ENTRYPOINT &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"/bin/bash"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;After specifying the base image as Magenta’s, we set a working directory on an &lt;code&gt;/opt&lt;/code&gt; volume, install some system-level and python-level dependencies, and make a simple &lt;code&gt;bash&lt;/code&gt; entry point until we have a working application. A typical &lt;code&gt;requirements.txt&lt;/code&gt; file might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;jupyterlab
seaborn
scikit-learn
matplotlib
pyaudio
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Awesome. So now we have a specification of our desired environment. We can now make a &lt;code&gt;Makefile&lt;/code&gt; which handles some of the dependencies at play:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# use the name of the current directory as the docker image tag&lt;/span&gt;
DOCKERFILE ?&lt;span class="o"&gt;=&lt;/span&gt; Dockerfile
DOCKER_TAG ?&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;shell &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PWD&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; | rev | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;/ &lt;span class="nt"&gt;-f1&lt;/span&gt; | rev&lt;span class="si"&gt;)&lt;/span&gt;
DOCKER_IMAGE &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DOCKER_USERNAME&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DOCKER_REPO&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;:&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DOCKER_TAG&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;

&lt;span class="si"&gt;$(&lt;/span&gt;DOCKERFILE&lt;span class="si"&gt;)&lt;/span&gt;: requirements.txt
    docker build &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DOCKER_IMAGE&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DOCKERFILE&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nb"&gt;.&lt;/span&gt;

.PHONY image
image: &lt;span class="si"&gt;$(&lt;/span&gt;DOCKERFILE&lt;span class="si"&gt;)&lt;/span&gt;

.PHONY: run
run:
     nvidia-docker run &lt;span class="se"&gt;\&lt;/span&gt;
         &lt;span class="nt"&gt;--mount&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;bind&lt;/span&gt;,source&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;shell &lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;,target&lt;span class="o"&gt;=&lt;/span&gt;/opt &lt;span class="se"&gt;\&lt;/span&gt;
         &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
         &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
         &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;DOCKER_IMAGE&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This &lt;code&gt;Makefile&lt;/code&gt; specifies targets for &lt;code&gt;run&lt;/code&gt;, &lt;code&gt;image&lt;/code&gt;, and &lt;code&gt;$(DOCKERFILE)&lt;/code&gt;. The &lt;code&gt;$(DOCKERFILE)&lt;/code&gt; target lists &lt;code&gt;requirements.txt&lt;/code&gt; as a dependency, and thus will trigger a re-build of the Docker image when that file changes. The &lt;code&gt;image&lt;/code&gt; target is a simple alias for the &lt;code&gt;$(DOCKERFILE)&lt;/code&gt; target. Finally, the &lt;code&gt;run&lt;/code&gt; target allows a concise call to execute the desired program in the Docker container, as opposed to typing out the laborious command each time.&lt;/p&gt;

&lt;h2&gt;
  
  
  One Docker to Rule Them All?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--V3zZ_rKq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://anthonyagnone.com/wp-content/uploads/2019/07/docker-docker-docker-docker-docker-docker.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--V3zZ_rKq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://anthonyagnone.com/wp-content/uploads/2019/07/docker-docker-docker-docker-docker-docker.jpg" alt="" class="wp-image-111"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At this point, you may be motivated to go off and define every possible dependency in a &lt;code&gt;Dockerfile&lt;/code&gt;, in order to never again be plagued with the troubles of ensuring an appropriate environment for your next project. For example, Floydhub has an &lt;a href="https://github.com/floydhub/dl-docker"&gt;all-in-one Docker image&lt;/a&gt; for deep learning projects. This image specification includes &lt;em&gt;numerous&lt;/em&gt; deep learning frameworks and supporting python libraries.&lt;/p&gt;

&lt;p&gt;Don’t do that!&lt;/p&gt;

&lt;p&gt;For the sake of argument, let’s take that to the limit. After the next 100 projects that you work on, what will your Docker image look like? And what about after the next 1000 projects? Over time, it will just become as bloated as if you had incrementally changed your main OS in each project. This goes against the containerization philosophy of Docker — your containers should be lightweight while remaining sufficient.&lt;/p&gt;

&lt;p&gt;Furthermore, with all of that bloat you lose the ability to sustain multiple directions of projects that require different versions of dependencies. What if one of your projects requires the latest version of Tensorflow to run, but you don’t want to update the 99 previous projects (and deal with all of the failures the updates bring)?&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this part of the Towards Efficient and Reproducible (TEAR) ML Workflows series, we’ve established the basis for making experiments and applications a relatively painless process. We used containerization via Docker to ensure experiments and applications are &lt;strong&gt;reproducible&lt;/strong&gt; and easy to execute. We then used some automatic dependency management via Make for keeping experiment pipelines &lt;strong&gt;efficient&lt;/strong&gt; and simple to run.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VhNYWfH7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://anthonyagnone.com/wp-content/uploads/2019/07/susan-holt-simpson-2nSdQEd-Exc-unsplash-1024x689.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VhNYWfH7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://anthonyagnone.com/wp-content/uploads/2019/07/susan-holt-simpson-2nSdQEd-Exc-unsplash-1024x689.jpg" alt="" class="wp-image-114"&gt;&lt;/a&gt;Photo by &lt;a href="https://unsplash.com/@shs521?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Susan Holt Simpson&lt;/a&gt; on &lt;a href="https://unsplash.com/collections/4885214/blog-photos?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;It’s worth noting that there are numerous alternative solutions to these two; however, they follow the same general &lt;em&gt;patterns&lt;/em&gt;: containerization gives you reproducibility and automatic dependency management gives you efficiency. From there, the value added in other solutions usually comes down to bells and whistles like cloud integration, scalability, or general ease of use. To each, your own choice of tools.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Visualizing House Price Distributions</title>
      <dc:creator>Anthony Agnone</dc:creator>
      <pubDate>Fri, 19 Jul 2019 18:29:33 +0000</pubDate>
      <link>https://dev.to/aagnone3/visualizing-house-price-distributions-with-zillow-and-python-s-folium-it-s-easier-than-ever-2p93</link>
      <guid>https://dev.to/aagnone3/visualizing-house-price-distributions-with-zillow-and-python-s-folium-it-s-easier-than-ever-2p93</guid>
      <description>&lt;h5&gt;
  
  
  &lt;em&gt;With Zillow and python's Folium, it's easier than ever&lt;/em&gt;
&lt;/h5&gt;

&lt;h3&gt;
  
  
  Wait, but Why?
&lt;/h3&gt;

&lt;p&gt;I’m in the process of closing on my first home in Atlanta, GA, and have been heavily using various real estate websites like Zillow, Redfin, and Trulia. I’ve also been toying with &lt;a href="https://www.zillow.com/howto/api/APIOverview.htm"&gt;Zillow’s API&lt;/a&gt;, although somewhat spotty in functionality and documentation. Despite its shortcomings, I was fully inspired once I read the &lt;a href="https://towardsdatascience.com/rat-city-visualizing-new-york-citys-rat-problem-f7aabd6900b2"&gt;post&lt;/a&gt; by &lt;a href="https://medium.com/u/5164378fc848"&gt;Lukas Frei&lt;/a&gt; on using the &lt;code&gt;folium&lt;/code&gt; library to seamlessly create geography-based visualizations. A few days and some quick fun later, I’ve combined Zillow and Folium to make some cool visualizations of housing prices both within Atlanta and across the U.S.&lt;/p&gt;

&lt;h3&gt;
  
  
  Topics
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;API integration&lt;/li&gt;
&lt;li&gt;Graph traversal&lt;/li&gt;
&lt;li&gt;Visualization&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  A Small Working Example
&lt;/h3&gt;

&lt;p&gt;Let’s start simple by using some &lt;a href="https://github.com/aagnone3/zillium/blob/master/data/State_MedianValuePerSqft_AllHomes.csv"&gt;pre-aggregated data&lt;/a&gt; I downloaded from the Zillow website. This data set shows the median price by square foot for every state in the U.S. for each month from April 1996 to May 2019. Naturally, one could build a rich visualization on the progression of these prices over time; however, let’s stick with the most recent prices for now, which are in the last column of the file.&lt;/p&gt;

&lt;p&gt;Having a look at the top-10 states, there aren’t many surprises. To be clear, I was initially caught off guard by the ordering of some of these, notably D.C. and Hawaii topping the chart. However, recall the normalization of “per square foot” in the metric. By that token, I’m maybe more surprised now that California still hits #3, given its size.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cn3Yy45t--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2Am8dv-PmWxEdxXc-3f-O-Wg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cn3Yy45t--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2Am8dv-PmWxEdxXc-3f-O-Wg.png" alt=""&gt;&lt;/a&gt;Top 10 price/sqft in thousands of $$$ (May 2019)&lt;/p&gt;

&lt;p&gt;Anyways, onto the show! Since this is a visualization article, I’ll avoid throwing too many lines of code in your face, and link it all to you to it at the end of the article. In short, I downloaded a GeoJSON file of the U.S. states from the &lt;a href="https://github.com/python-visualization/folium"&gt;folium repo&lt;/a&gt;. This was a great find, because it immediately gave me the schema of the data that I needed to give to folium for a seamless process; the only information I needed to add was the pricing data (to generate coloring in the final map). After providing that, a mere 5 lines of code got me the following plot:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9z1Eo-Ht--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2AotHI92R87cptloOqONQGxA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9z1Eo-Ht--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2AotHI92R87cptloOqONQGxA.png" alt=""&gt;&lt;/a&gt;Heatmap of price/sqft of homes in the U.S. for May 2019&lt;/p&gt;

&lt;h3&gt;
  
  
  One Step Further
&lt;/h3&gt;

&lt;p&gt;Now that I’d dipped my toes into the waters of Zillow and Folium, I was ready to be immersed. I decided to create a heat map of Metro Atlanta housing prices. One of the drawbacks of the Zillow API is that it’s rather limited in search functionality — I couldn’t find any way to perform a search based on lat/long coordinates, which would have been quite convenient for creating a granular heat map. Nevertheless, I took it as an opportunity to brush up on some crawler-style code; I used the results of an initial search by a city’s name as seeds for future calls to get the &lt;a href="https://en.wikipedia.org/wiki/Comparables"&gt;comps&lt;/a&gt; (via the &lt;a href="https://www.zillow.com/howto/api/GetComps.htm"&gt;GetComps&lt;/a&gt; endpoint) of those homes.&lt;/p&gt;

&lt;p&gt;It’s worth noting that Zillow does have plenty of URL-based search &lt;a href="https://www.zillow.com/atlanta-ga/houses/2-_beds/2.0-_baths/?searchQueryState=%7B%22pagination%22:%7B%7D,%22mapBounds%22:%7B%22west%22:-84.88217862207034,%22east%22:-84.07880337792972,%22south%22:33.53377471775447,%22north%22:33.999556422130006%7D,%22usersSearchTerm%22:%22Atlanta,%20GA%22,%22regionSelection%22:%5B%7B%22regionId%22:37211,%22regionType%22:6%7D%5D,%22isMapVisible%22:true,%22mapZoom%22:11,%22filterState%22:%7B%22price%22:%7B%22min%22:300000,%22max%22:600000%7D,%22monthlyPayment%22:%7B%22min%22:1119,%22max%22:2237%7D,%22hoa%22:%7B%22max%22:200%7D,%22beds%22:%7B%22min%22:2%7D,%22baths%22:%7B%22min%22:2%7D,%22sqft%22:%7B%22min%22:1300%7D,%22isAuction%22:%7B%22value%22:false%7D,%22isMakeMeMove%22:%7B%22value%22:false%7D,%22isMultiFamily%22:%7B%22value%22:false%7D,%22isManufactured%22:%7B%22value%22:false%7D,%22isLotLand%22:%7B%22value%22:false%7D,%22isPreMarketForeclosure%22:%7B%22value%22:false%7D,%22isPreMarketPreForeclosure%22:%7B%22value%22:false%7D%7D,%22isListVisible%22:true%7D"&gt;(example)&lt;/a&gt; filters that one could use to e.g. search by lat/long (see below). Obtaining the homes from the web page then becomes a scraping job, though, and you are subject to any sudden changes in Zillow’s web page structure. That being said, scraping projects can be a lot of fun; if you’d like to build this into what I made, let me know!&lt;/p&gt;

&lt;p&gt;Returning to the chosen path, I mentioned that I used initial results as entry points into the web of homes in a given city. With those entry points, I kept recursing into calls for each homes comps. An important assumption here is that Zillow’s definition of similarity between houses includes location proximity in addition to other factors. Without location proximity, the comp-based traversal of homes will be very non-smooth with respect to location.&lt;/p&gt;

&lt;p&gt;So, what algorithms are at our disposal for traversing through a network of nodes in different ways? Of course, breadth-first search (BFS) and depth-first search (DFS) quickly come to mind. For the curious, have a look at the basic logic flow of it below. Besides a set membership guard, new homes are only added to the collection when they satisfy the constraints asserted in the &lt;code&gt;meets_criteria&lt;/code&gt; function. For now, I do a simple L2 distance check between a pre-defined root lat/long location and the current home’s location. This criterion encouraged the search to stay local to the root, for the purposes of a well-connected and granular heat map. The implementation below uses DFS by popping off the end of the list (line 5) and adding to the end of the list (14), but BFS can be quickly achieved by changing either line (but not both) to instead use the front of the list.&lt;/p&gt;

&lt;p&gt;Letting this algorithm run for 10,000 iterations on Atlanta homes produces the following map in just a few minutes! What’s more, the &lt;a href="https://anthonyagnone.com/wp-shares-aagnone/atlanta_heatmap.html"&gt;generated web page&lt;/a&gt; by folium is interactive, allowing common map navigation tools like zooming and panning. To prove out its modularity, I generated some smaller-scale maps of prices for &lt;a href="https://anthonyagnone.com/wp-shares-aagnone/boston_heatmap.html"&gt;Boston, MA&lt;/a&gt; and &lt;a href="https://anthonyagnone.com/wp-shares-aagnone/seattle_heatmap.html"&gt;Seattle, WA&lt;/a&gt; as well.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AWF-IEmo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2AQ81SBWiXe77l8xq8oqpgyw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AWF-IEmo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2AQ81SBWiXe77l8xq8oqpgyw.png" alt=""&gt;&lt;/a&gt;Heat map of Atlanta housing prices. See the interactive version &lt;a href="https://anthonyagnone.com/wp-shares-aagnone/atlanta_heatmap.html" rel="noreferrer noopener"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Code
&lt;/h3&gt;

&lt;p&gt;As promised, &lt;a href="https://github.com/aagnone3/zillium"&gt;here’s the project&lt;/a&gt;. It has a Make+Docker setup for ease of use and reproducibility. If you’d like to get an intro to how these two tools come together nicely for reproducible data science, &lt;a href="https://anthonyagnone.com/2019/07/10/towards-efficient-and-reproducible-ml-workflows-part-1-analysis/"&gt;keep reading here&lt;/a&gt;. Either way, the &lt;a href="https://github.com/aagnone3/zillium/blob/master/README.md"&gt;README&lt;/a&gt; will get you up and running in no time, either via script or Jupyter notebook. Happy viz!&lt;/p&gt;

&lt;h3&gt;
  
  
  What Now?
&lt;/h3&gt;

&lt;p&gt;There are numerous different directions in which we could take this logic next. I’ve detailed a few below for stimulation, but I’d prefer to move in the direction that has the most support, impact, and collaboration. What do you think?&lt;/p&gt;

</description>
      <category>data</category>
      <category>algorithms</category>
      <category>api</category>
      <category>datastructures</category>
    </item>
  </channel>
</rss>
