<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title type="text">rywalker.com</title>
  <generator uri="http://effectif.com/nesta">Nesta</generator>
  <id>tag:www.rywalker.com,2009:/</id>
  <link href="http://www.rywalker.com/articles.xml" rel="self"/>
  <link href="http://www.rywalker.com" rel="alternate"/>
  <subtitle type="text">Ryan Walker on agile business and web software development</subtitle>
  <author>
    <name>Ryan Walker</name>
    <uri>http://rywalker.com</uri>
    <email>ry@anotherventure.com</email>
  </author>
  <entry>
    <title>Websolr on Linode</title>
    <link type="text/html" href="http://www.rywalker.com/websolr-on-linode" rel="alternate"/>
    <id>tag:www.rywalker.com,2012-01-10:/websolr-on-linode</id>
    <content type="html">&lt;p&gt;Just got off a great call with &lt;a href='https://twitter.com/#!/nz_'&gt;Nick Zadrozny&lt;/a&gt;. The purpose of the call was &lt;a href='http://recruitmilitary.com/'&gt;us&lt;/a&gt; trying to convince him to bring &lt;a href='http://websolr.com/'&gt;WebSolr&lt;/a&gt; to &lt;a href='http://www.linode.com/'&gt;Linode&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Websolr has great monitoring and replication features, and allows developers with little Java deployment + management experience to avoid having &amp;#8220;mysterious black boxes&amp;#8221; in their server cluster(s).&lt;/p&gt;

&lt;p&gt;At the end of the call, he agreed that if more Linode users were known that have serious interest in the availability of Websolr on Linode, it&amp;#8217;d push up the project in his queue.&lt;/p&gt;

&lt;p&gt;If you&amp;#8217;re interested in Websolr on Linode, &lt;a href='https://twitter.com/#!/nz_'&gt;drop Nick a note&lt;/a&gt;, help us make it happen :)&lt;/p&gt;</content>
    <published>2012-01-10T00:00:00+00:00</published>
    <category term="solr"/>
  </entry>
  <entry>
    <title>Recipes and Ingredients</title>
    <link type="text/html" href="http://www.rywalker.com/recipes-and-ingredients" rel="alternate"/>
    <id>tag:www.rywalker.com,2011-10-13:/recipes-and-ingredients</id>
    <content type="html">&lt;p&gt;I finally got my &lt;a href='http://cincyrehackathon.herokuapp.com'&gt;&amp;#8220;CincyReHackathon&amp;#8221; project&lt;/a&gt; done, and I&amp;#8217;d like to share a little about how the app works.&lt;/p&gt;

&lt;h2 id='google_prediction_fail'&gt;Google Prediction fail&lt;/h2&gt;

&lt;p&gt;Despite spending hours trying to figure it out, I couldn&amp;#8217;t get 2-legged Oauth 2 working with Google API client. On top of that, the Google Prediction training queue just would not execute a training request of non-trivial size without erroring. So I dumped it.&lt;/p&gt;

&lt;h2 id='directed_edge'&gt;Directed Edge&lt;/h2&gt;

&lt;p&gt;Searching around for a replacement, I found &lt;a href='http://directededge.com'&gt;Directed Edge&lt;/a&gt; which is a graph database-based recommendations engine, and using it was a breeze. Unlike Google, they had &lt;a href='http://developer.directededge.com/article/Getting_started_for_Ruby_developers'&gt;decent documentation for Ruby developers&lt;/a&gt; and a simple API authentication method.&lt;/p&gt;

&lt;h2 id='recipepuppy'&gt;RecipePuppy&lt;/h2&gt;

&lt;p&gt;For source data, I used RecipePuppy&amp;#8217;s &lt;a href='http://www.recipepuppy.com/about/api/'&gt;very simple and very open API&lt;/a&gt;. Thanks for that!&lt;/p&gt;

&lt;h2 id='typekit'&gt;Typekit&lt;/h2&gt;

&lt;p&gt;I took the project as an opportunity to experiment with &lt;a href='https://typekit.com/fonts'&gt;Typekit&lt;/a&gt;. Very straightforward, I think the site looks much better for the effort.&lt;/p&gt;

&lt;h2 id='vcr_for_testing'&gt;VCR for testing&lt;/h2&gt;

&lt;p&gt;Since the bulk of the app is about interacting with two external APIs, I made good use of &lt;a href='https://github.com/myronmarston/vcr'&gt;Myron Marston&amp;#8217;s VCR library&lt;/a&gt; which was a great experience as well. It just works.&lt;/p&gt;

&lt;h2 id='guard_for_testing'&gt;Guard for testing&lt;/h2&gt;

&lt;p&gt;I also used &lt;a href='https://github.com/guard/guard'&gt;Guard&lt;/a&gt; for the first time on this project, and really liked it. Learn more about it from &lt;a href='http://railscasts.com/episodes/264-guard'&gt;Ryan Bate&amp;#8217;s screencast&lt;/a&gt; on the tool.&lt;/p&gt;

&lt;h2 id='source_code_available'&gt;Source code available&lt;/h2&gt;

&lt;p&gt;The proejct uses Rails 3.1.1 and is deployed to Heroku, &lt;a href='https://github.com/ryw/cincyrehackathon'&gt;full source @ Github&lt;/a&gt;.&lt;/p&gt;</content>
    <published>2011-10-13T00:00:00+00:00</published>
  </entry>
  <entry>
    <title>Lean Startup Book Notes</title>
    <link type="text/html" href="http://www.rywalker.com/lean-startup-notes" rel="alternate"/>
    <id>tag:www.rywalker.com,2011-10-10:/lean-startup-notes</id>
    <content type="html">&lt;p&gt;&lt;a href='http://www.amazon.com/Lean-Startup-Entrepreneurs-Continuous-Innovation/dp/0307887898'&gt;Lean Startup&lt;/a&gt; is a great book by Eric Ries, highly recommended.&lt;/p&gt;

&lt;h2 id='five_principles'&gt;Five Principles&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Entrepreneurs are everywhere&amp;#8212;not just in startups, big companies need them too.&lt;/li&gt;

&lt;li&gt;Entrepreneurship is management&amp;#8212;you&amp;#8217;re building an organization in an environment of extreme uncertainty.&lt;/li&gt;

&lt;li&gt;Validated learning&amp;#8212;the primary reason for existence for a startup is to learn. The best way to do that is through scientific experiments that test each element of the vision.&lt;/li&gt;

&lt;li&gt;Build-measure-learn&amp;#8212;ideas are built into products which are measured generating data that we learn from and form new ideas, including whether to pivot or persevere. Through this loop learning informs the vision, and vision drives the learning.&lt;/li&gt;

&lt;li&gt;Innovation accounting&amp;#8212;establish the baseline, tune the engine, pivot or perservere. Cohort analysis is important concept here, because you don&amp;#8217;t get fooled by the snowball effect of traditional metrics. Good metrics need to be actionable, accessible, and auditable. Use A/B split testing once the baseline is established to improve the ratios.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='key_insights'&gt;Key insights&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Any work that generating value (providing benefit to the customer) is waste. In the context of a startup, any work that isn&amp;#8217;t directly linked to a learning experiment is waste.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;The two most important assumptions entrepreneurs make are the value hypothesis and the growth hypothesis.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Value: will the product or service really deliver value?&lt;/li&gt;

&lt;li&gt;Growth: how will customers find the product or service?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Concierge MVP&amp;#8212;operate the product with people doing the work that computers will eventually do, to test the viability of the whole concept before building a lot of software.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;An experiment is a product. And first products should not be built to be perfect. Their role is to generate data that we can learn from.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Learn the difference between dangerous vanity metrics vs. nuts-and-bolts actionable metrics.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Keep batches small&amp;#8212;strive to keep delivery as close to continuous as possible.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='four_questions_before_starting_something'&gt;Four questions before starting something&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Do customers recognize they have the problem we&amp;#8217;re trying to solve?&lt;/li&gt;

&lt;li&gt;If there was a solution, would they buy it?&lt;/li&gt;

&lt;li&gt;Would they buy it from us?&lt;/li&gt;

&lt;li&gt;Can we build a solution to that problem? (The common tendency is to jump right to this one.)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='types_of_pivots'&gt;Types of pivots&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Zoom-in Pivot&amp;#8212;a single feature becomes the product.&lt;/li&gt;

&lt;li&gt;Zoom-out Pivot&amp;#8212;what was considered the whole product becomes a single feature of a larger product.&lt;/li&gt;

&lt;li&gt;Customer Segment Pivot&amp;#8212;the product solves problems for a different customer than originally conceived.&lt;/li&gt;

&lt;li&gt;Customer Need Pivot&amp;#8212;we learn about the customer, and that they have bigger problems that we can solve, which may require tweaks to the product or perhaps a different product altogether.&lt;/li&gt;

&lt;li&gt;Platform Pivot&amp;#8212;change from an application to a platform or vice versa.&lt;/li&gt;

&lt;li&gt;Business Architecture Pivot&amp;#8212;switch from high volume, low margin to low volume, high margin, or the reverse.&lt;/li&gt;

&lt;li&gt;Value Capture Pivot&amp;#8212;changes to revenue or monitization model.&lt;/li&gt;

&lt;li&gt;Engine of Growth Pivot&amp;#8212;change in growth strategy: viral, sticky, paid.&lt;/li&gt;

&lt;li&gt;Channel Pivot&amp;#8212;change in sales or distribution, where or how it&amp;#8217;s sold or bought.&lt;/li&gt;

&lt;li&gt;Technology Pivot&amp;#8212;change to capture superior cost and/or performance.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='four_primary_ways_past_customers_drive_our_growth'&gt;Four primary ways past customers drive our growth&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Word of mouth&lt;/li&gt;

&lt;li&gt;As a side effect of product usage&amp;#8212;others see the customer using the product.&lt;/li&gt;

&lt;li&gt;Funded advertising&lt;/li&gt;

&lt;li&gt;Repeat purchase or use&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='three_engines_of_growth'&gt;Three engines of growth&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Sticky&amp;#8212;product is addicting to use.&lt;/li&gt;

&lt;li&gt;Viral&amp;#8212;people tell people about it.&lt;/li&gt;

&lt;li&gt;Paid&amp;#8212;buy ads that generate customer acquisition.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='how_to_nurture_disruptive_innovation'&gt;How to nurture disruptive innovation&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Provide scarce but secure resources&lt;/li&gt;

&lt;li&gt;Give independent development authority&lt;/li&gt;

&lt;li&gt;Embed a personal stake in the outcome&lt;/li&gt;

&lt;li&gt;Protect the parent organization if it&amp;#8217;s not used to an experimental culture&lt;/li&gt;
&lt;/ul&gt;</content>
    <published>2011-10-10T00:00:00+00:00</published>
    <category term="product-development"/>
    <category term="product-management"/>
    <category term="startup"/>
  </entry>
  <entry>
    <title>Rails web application development process</title>
    <link type="text/html" href="http://www.rywalker.com/rails-web-application-development-process" rel="alternate"/>
    <id>tag:www.rywalker.com,2011-10-09:/rails-web-application-development-process</id>
    <content type="html">&lt;p&gt;Here is the process I am presently using, from high-level planning down through actual BDD-style coding.&lt;/p&gt;

&lt;h2 id='brain_dump'&gt;Brain Dump&lt;/h2&gt;

&lt;p&gt;Using notecards, high-level brain dump of stories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;roles&lt;/li&gt;

&lt;li&gt;action/tasks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When complete, organize content and transfer to digital doc, toss cards.&lt;/p&gt;

&lt;h2 id='modeling__user_stories'&gt;Modeling &amp;amp; User Stories&lt;/h2&gt;

&lt;p&gt;Develop &amp;#8220;ubiquitous language&amp;#8221;&amp;#8211;Words that work for both the technical implementation and with conversations with users or customers. This language is also important for the screens, which should have include clear direction on how the system works. This would be in contrast to typical programmer-generated screens, which will often have usability issues.&lt;/p&gt;

&lt;p&gt;To each story, add a few sentences to describe it; just enough information to serve as a token for a conversation that will take place closer to implementation.&lt;/p&gt;

&lt;h2 id='minimum_viable_product'&gt;Minimum viable product&lt;/h2&gt;

&lt;p&gt;In true &amp;#8220;Lean Startup&amp;#8221; style, development of the app should be treated as an ongoing series of experiments to test hypothesis on what success may look like.&lt;/p&gt;

&lt;p&gt;So an important step is to ask what is the first validatable theory to begin with, preferably an important one. Then choose only those stories that directly help create an experiment to learn from.&lt;/p&gt;

&lt;h2 id='continuous_delivery'&gt;Continuous delivery&lt;/h2&gt;

&lt;p&gt;Continuous integration should be setup to continously deploy the app. There should be no such thing as &amp;#8220;releases&amp;#8221; and &amp;#8220;iterations&amp;#8221;.&lt;/p&gt;

&lt;h2 id='uifirst_development'&gt;UI-First Development&lt;/h2&gt;

&lt;h3 id='screens'&gt;Screens&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Which screens - REST conventions can do a lot of work - what is the logical name of the noun-verb combination?&lt;/li&gt;

&lt;li&gt;What&amp;#8217;s on them - design from the inside out. Just the content without the outer frame of navigation. What matters to the user of the screen. What are they trying to do? Put in words what things they are trying to do on the screen, including the various paths they may take. (Don&amp;#8217;t just assume the page should be a standard REST-template form.)&lt;/li&gt;

&lt;li&gt;Be completely rational, &amp;#8220;don&amp;#8217;t make me think&amp;#8221; - when I see the screen, I instantly know what to do with it, it&amp;#8217;s easy to complete the task.&lt;/li&gt;

&lt;li&gt;Least effective difference - give things visual priority, doing just enough to create the hierarchy.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id='flows'&gt;Flows&lt;/h3&gt;

&lt;p&gt;Think with actions, every action has 3 screens&amp;#8230;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How you get to it&lt;/li&gt;

&lt;li&gt;How do you do it&lt;/li&gt;

&lt;li&gt;What happens afterwards - how do i know it worked. What do i want to do next?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id='html__coding'&gt;HTML &amp;amp; Coding&lt;/h3&gt;

&lt;h4 id='1_html_mockup'&gt;1. HTML mockup&lt;/h4&gt;

&lt;p&gt;Explore UI options on paper, in Photoshop, or in HTML to get to a happy design for the feature. It&amp;#8217;s best to explore this in as lightweight a form as possible to avoid wasted effort.&lt;/p&gt;

&lt;h4 id='2_write_new_featurescenario'&gt;2. Write new feature/scenario&lt;/h4&gt;

&lt;p&gt;Guard runs the features and outputs pending steps, copy and paste them, and write simple code to define them (using code semantics you wish you already had.)&lt;/p&gt;

&lt;h4 id='3_pick_a_red_step__write_failing_spec__the_rspec_level'&gt;3. Pick a red step &amp;amp; write failing spec @ the rspec level&lt;/h4&gt;

&lt;p&gt;Using Rspec, specify the missing functionality. Guard will now see red at the rspec level.&lt;/p&gt;

&lt;h4 id='4_write_as_little_code_as_possible_to_make_the_spec_pass'&gt;4. Write as little code as possible to make the spec pass&lt;/h4&gt;

&lt;p&gt;Get the spec green, as quickly as possible. Guard pops the stack and reruns the scenarios you&amp;#8217;re working on. Once green, refactor anything that&amp;#8217;s needs it.&lt;/p&gt;

&lt;h4 id='5_repeat_until_your_steps_are_all_green'&gt;5. Repeat until your steps are all green.&lt;/h4&gt;</content>
    <published>2011-10-09T00:00:00+00:00</published>
    <category term="product-management"/>
    <category term="rails"/>
    <category term="software-development"/>
  </entry>
  <entry>
    <title>CincyReHackathon</title>
    <link type="text/html" href="http://www.rywalker.com/cincyrehackathon" rel="alternate"/>
    <id>tag:www.rywalker.com,2011-09-22:/cincyrehackathon</id>
    <content type="html">&lt;h2 id='cincyhackathon_was_a_great_experience'&gt;CincyHackathon was a great experience.&lt;/h2&gt;

&lt;p&gt;I met some great new people, I grew as a developer, I got to stay up and program until 3am and didn&amp;#8217;t feel like a bad person for doing it :)&lt;/p&gt;

&lt;h2 id='i_won_the_contest_but_dont_feel_done'&gt;I won the contest, but don&amp;#8217;t feel &amp;#8220;done.&amp;#8221;&lt;/h2&gt;

&lt;p&gt;Not too many people participated, but I did pull down first place and $500 in gift cards, so my wife wasn&amp;#8217;t too pissed when I came home bedraggled early Saturday evening.&lt;/p&gt;

&lt;p&gt;But the app isn&amp;#8217;t live on the internet, due to my lack of Oauth2 understanding and less-than-optimal guidance from Google on how to make it work.&lt;/p&gt;

&lt;h2 id='so_starts_cincyrehackathon'&gt;So starts CincyReHackathon&lt;/h2&gt;

&lt;p&gt;I&amp;#8217;ll give myself 12 hours, through Saturday afternoon, to do it better.&lt;/p&gt;

&lt;h2 id='directededge_over_google_prediction'&gt;DirectedEdge over Google Prediction&lt;/h2&gt;

&lt;p&gt;Google Prediction let me down quite a bit during the event. Their API has become so complicated, and isn&amp;#8217;t well supported or documented for Ruby. I think part of it is because they&amp;#8217;ve gone for a discovery-based API, and Google Prediction isn&amp;#8217;t very popular, so I was really struggling for working examples.&lt;/p&gt;

&lt;p&gt;I did finally come across a sample sinatra app buried in their API library, and it formed the basis for my final presentation, but the Oauth2 concepts (especially the way I was doing it, using the 2-legged variation) was so poorly documented that I literally spent 1/2 my time trying to get that all working rather than on my chosen problem domain.&lt;/p&gt;

&lt;p&gt;I did a little googling and have discovered &lt;a href='http://directededge.com'&gt;DirectedEdge&lt;/a&gt; who I will try to use in my re-do, and were nice enough to give me a free developer account after explaining my intentions.&lt;/p&gt;

&lt;h2 id='testdriven_vs_hackity_hack'&gt;Test-driven vs. hackity hack&lt;/h2&gt;

&lt;p&gt;While I started out test-driven during the event, I quickly abandoned the practice when shit started hitting the fan, and things felt very &amp;#8220;spiky.&amp;#8221; Now that I know what I&amp;#8217;m building, I&amp;#8217;ll approach this re-do in a more disciplined way.&lt;/p&gt;

&lt;h2 id='live_working_app_on_the_internet_vs_12_working'&gt;Live, working app on the internet vs. 1/2 working&lt;/h2&gt;

&lt;p&gt;My goal at the end of this is a working, snappy app on the web.&lt;/p&gt;

&lt;p&gt;Should be fun&amp;#8230; here we go!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repo: &lt;a href='https://github.com/ryw/cincyrehackathon'&gt;https://github.com/ryw/cincyrehackathon&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;Site: &lt;a href='http://cincyrehackathon.heroku.com'&gt;http://cincyrehackathon.heroku.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content>
    <published>2011-09-22T00:00:00+00:00</published>
  </entry>
  <entry>
    <title>CincyHackathon</title>
    <link type="text/html" href="http://www.rywalker.com/cincyhackathon" rel="alternate"/>
    <id>tag:www.rywalker.com,2011-09-09:/cincyhackathon</id>
    <content type="html">&lt;h2 id='my_project_peanut_butter_jelly_time'&gt;My project: peanut_butter_jelly_time&lt;/h2&gt;

&lt;p&gt;I&amp;#8217;ve decide to help &lt;a href='http://meruni.com'&gt;Meruni&lt;/a&gt; on their challenge to develop a way to discover complementary products. For example, &amp;#8220;jelly&amp;#8221; goes with &amp;#8220;peanut butter&amp;#8221;.&lt;/p&gt;

&lt;h2 id='challenge_1_data'&gt;Challenge #1: Data&lt;/h2&gt;

&lt;p&gt;I was hoping that Meruni&amp;#8217;s 2011 program-mate &lt;a href='http://receept.com/'&gt;Receept&lt;/a&gt; would have some grocery shopping receipt data to leverage, but they don&amp;#8217;t have any &amp;#8211; woulda been cool to mash them up. So then I had to look for some other source of data, Meruni recommended looking at recipe data.&lt;/p&gt;

&lt;p&gt;They like &lt;a href='http://punchfork.com'&gt;Punchfork&lt;/a&gt;, but to get recipe data requires paid API, and they had no way for us to upgrade free account via web. Oops, lost sale there, PunchFork.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ll use &lt;a href='http://recipepuppy.com'&gt;Recipe Puppy&lt;/a&gt; and the &lt;a href='http://code.google.com/apis/predict/'&gt;Google Prediction API&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s the process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pull a list of popular recipes.&lt;/li&gt;

&lt;li&gt;Search RecipePuppy to get a list of ingredients for each popular recipe.&lt;/li&gt;

&lt;li&gt;Create training data in CSV to upload to Google Prediction API.&lt;/li&gt;

&lt;li&gt;Build simple web app where one can type an ingredient in, and get top 10 ingredients that complement it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Wish me luck!&lt;/p&gt;
&lt;object height='345' width='420'&gt;&lt;param name='movie' value='http://www.youtube.com/v/s8MDNFaGfT4?version=3&amp;amp;hl=en_US' /&gt;&lt;param name='allowFullScreen' value='true' /&gt;&lt;param name='allowscriptaccess' value='always' /&gt;&lt;embed src='http://www.youtube.com/v/s8MDNFaGfT4?version=3&amp;amp;hl=en_US' allowfullscreen='true' type='application/x-shockwave-flash' allowscriptaccess='always' height='345' width='420' /&gt;&lt;/object&gt;
&lt;p&gt;&lt;em&gt;Update&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;See code @ the &lt;a href='https://github.com/ryw/peanut_butter_jelly_time'&gt;git repo&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;See &lt;a href='http://rywalker.com/cincyrehackathon'&gt;CincyReHackathon&lt;/a&gt; where I am giving myself a do over.&lt;/li&gt;
&lt;/ul&gt;</content>
    <published>2011-09-09T00:00:00+00:00</published>
  </entry>
  <entry>
    <title>Applying Google Prediction API to GymboreeDeals</title>
    <link type="text/html" href="http://www.rywalker.com/applying-google-prediction-api-to-gymboreedeals" rel="alternate"/>
    <id>tag:www.rywalker.com,2011-04-26:/applying-google-prediction-api-to-gymboreedeals</id>
    <content type="html">&lt;img src='http://code.google.com/apis/predict/images/predictionapi-128.png' style='float: right; padding: 0 10px;' /&gt;
&lt;p&gt;I won&amp;#8217;t go into all the details behind GymboreeDeals, but it is operated by my wife, and involves manually categorizing content. Maybe &lt;a href='http://code.google.com/apis/predict/'&gt;Google Prediction API&lt;/a&gt; can help speed up her work, or (if the gods of Olympus are smiling upon her) eliminate aspects of it.&lt;/p&gt;

&lt;p&gt;With my &lt;a href='http://rywalker.com/google-prediction-api-first-looks'&gt;newly acquired knowledge of Google Prediction API&lt;/a&gt; it was trivial to develop a prediction model.&lt;/p&gt;

&lt;p&gt;Fortunately (for my data needs), she has manually categorized more than 10,000 eBay auctions since September (~50/day) which provides a fairly good example set for Google&amp;#8217;s machine learning algorithms.&lt;/p&gt;

&lt;p&gt;To review, the process to create the trained model was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generate a CSV file with the training data (export from SQL, normalizing the text by removing punctuation and converting all text to ALL CAPS)&lt;/li&gt;

&lt;li&gt;Upload file to Google Storage&lt;/li&gt;

&lt;li&gt;Invoke training process&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With that, I have a trained model that I can invoke:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;./oauth-predict.sh gymb/prediction_models/genders \
  &amp;quot;\&amp;quot;NWT GYMBOREE BURST OF SPRING LOVE SWEET STRAWBERRY SZ 2\&amp;quot;&amp;quot;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Which returns:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
  &amp;quot;kind&amp;quot;: &amp;quot;prediction#output&amp;quot;,
   &amp;quot;id&amp;quot;: &amp;quot;gymb/prediction_models/genders&amp;quot;,
   &amp;quot;selfLink&amp;quot;:
     &amp;quot;https://www.googleapis.com/prediction/v1.2/training/gymb/prediction_models/genders/predict&amp;quot;,
   &amp;quot;outputLabel&amp;quot;: &amp;quot;Girl&amp;quot;,
   &amp;quot;outputMulti&amp;quot;: [
     {
       &amp;quot;label&amp;quot;: &amp;quot;Girl&amp;quot;,
       &amp;quot;score&amp;quot;: 0.999855
     },
     {
       &amp;quot;label&amp;quot;: &amp;quot;Boy&amp;quot;,
       &amp;quot;score&amp;quot;: 1.45E-4
     }
   ]
 }&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#8220;Sweet&amp;#8221; &amp;#8220;Love&amp;#8221; &amp;#8220;Strawberry&amp;#8221; were probably dead giveaways. How about a tougher one&amp;#8230;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;./oauth-predict.sh gymb/prediction_models/genders \
  &amp;quot;\&amp;quot;NWT GYMBOREE WILD SAFARI BASIC ORANGE KNIT SHORTS 4 4T\&amp;quot;&amp;quot;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Which returns:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;quot;outputLabel&amp;quot;: &amp;quot;Boy&amp;quot;,
&amp;quot;outputMulti&amp;quot;: [
  {
    &amp;quot;label&amp;quot;: &amp;quot;Girl&amp;quot;,
    &amp;quot;score&amp;quot;: 0.315243
  },
  {
    &amp;quot;label&amp;quot;: &amp;quot;Boy&amp;quot;,
    &amp;quot;score&amp;quot;: 0.684757
  }
]&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Much closer score, but identified &amp;#8220;Boy&amp;#8221; correctly. Very cool. Must have been the word &amp;#8220;Wild&amp;#8221;.&lt;/p&gt;

&lt;h2 id='integrating_into_rails_project'&gt;Integrating into Rails project&lt;/h2&gt;

&lt;p&gt;Let&amp;#8217;s try out the &lt;a href='http://code.google.com/p/ruby-google-prediction-api/'&gt;Ruby wrapper written by peeps @ Google&lt;/a&gt;. I add to the project&amp;#8217;s &lt;code&gt;Gemfile&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gem &amp;#39;google_prediction&amp;#39;, &amp;#39;0.0.1&amp;#39;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I run &lt;code&gt;bundle&lt;/code&gt;, then try to startup the Rails app. (Rails 3, and Ruby 1.9.2 for the new hash syntax.)&lt;/p&gt;

&lt;h2 id='did_i_mention_that_the_google_prediction_api_released_version_12_last_month'&gt;Did I mention that the Google Prediction API released version 1.2 last month?&lt;/h2&gt;

&lt;p&gt;The app won&amp;#8217;t start, &lt;code&gt;no such file to load -- jcode&lt;/code&gt; which means the gem isn&amp;#8217;t updated for 1.9 compatibility.&lt;/p&gt;

&lt;p&gt;And looking at the README, it&amp;#8217;s using old ClientLogin methodology, not OAuth. So the Ruby wrapper is for API version 1.1, not 1.2.&lt;/p&gt;

&lt;p&gt;Am I dead in the water? No.&lt;/p&gt;

&lt;p&gt;I just need to write my first gem :)&lt;/p&gt;</content>
    <published>2011-04-26T00:00:00+00:00</published>
    <category term="ebay"/>
    <category term="google-prediction-api"/>
    <category term="machine-learning"/>
  </entry>
  <entry>
    <title>Google Prediction API First Looks</title>
    <link type="text/html" href="http://www.rywalker.com/google-prediction-api-first-looks" rel="alternate"/>
    <id>tag:www.rywalker.com,2011-04-24:/google-prediction-api-first-looks</id>
    <content type="html">&lt;img src='http://code.google.com/apis/predict/images/predictionapi-128.png' style='float: right; padding: 0 10px;' /&gt;
&lt;p&gt;Sitting around on a Sunday night, decided to finally take a little dive on something that&amp;#8217;s had my eye for a while, the &lt;a href='http://code.google.com/apis/predict/'&gt;Google Prediction API&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id='signup'&gt;Signup&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Visited &lt;a href='https://code.google.com/apis/console'&gt;the Google APIs console&lt;/a&gt; and turned on the Google Prediction API.&lt;/li&gt;

&lt;li&gt;Needed to &lt;a href='https://spreadsheets.google.com/a/google.com/viewform?hl=en&amp;formkey=dEhTS1AydGxMbC1IRGZPOFJGdnRSeHc6MQ#gid=0'&gt;sign up for Google Storage account&lt;/a&gt; - this seemed discouraging, since it was a Google Docs waiting list, and I figured I&amp;#8217;d be dead in the water tonight, maybe waiting forever. I wrote as persuasive an application as I could :)&lt;/li&gt;

&lt;li&gt;I noticed that they metioned they were going to turn on billing in early 2011, pricing was only $10/month. From the console, there was a &amp;#8220;billing&amp;#8221; link that I could enable. So I decided to enable billing, hoping that would help with Google Storage account issue.&lt;/li&gt;

&lt;li&gt;Checking my email, I had already been emailed a Google Storage invite. Not sure if it was automatic or my application caught their eye (I suspect the former) but the hurdle was jumped. Woot!&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id='hello_prediction'&gt;Hello Prediction&lt;/h2&gt;

&lt;p&gt;I followed the &lt;a href='http://code.google.com/apis/predict/docs/hello_world.html'&gt;hello world tutorial&lt;/a&gt; that Google provides. I won&amp;#8217;t cut-and-paste all the steps, since the tutorial is well-written, but here are some notes from the process.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I needed to install &lt;code&gt;gsutil&lt;/code&gt; - pretty easy; &lt;a href='http://code.google.com/apis/storage/docs/gsutil.html#install'&gt;instructions here&lt;/a&gt;.&lt;/li&gt;

&lt;li&gt;I needed to &lt;a href='https://sandbox.google.com/storage/m/manage'&gt;create a Google Storage access key&lt;/a&gt;.&lt;/li&gt;

&lt;li&gt;Can&amp;#8217;t use bucket &amp;#8216;examplebucket&amp;#8217;. I used &amp;#8216;play-prediction&amp;#8217; and it allowed me to create bucket and then I copied the file up using &lt;code&gt;gsutil cp ./language_id.txt gs://play-prediction/prediction_models/languages&lt;/code&gt;.&lt;/li&gt;

&lt;li&gt;Save your Google API Access Key (found on the &lt;a href='https://code.google.com/apis/console/'&gt;API Console&lt;/a&gt; through the &amp;#8220;API Access&amp;#8221; link on the left, at the bottom of the page &amp;#8220;Simple API Access&amp;#8221;, to file &lt;code&gt;googlekey&lt;/code&gt;.&lt;/li&gt;

&lt;li&gt;I copied &lt;code&gt;oauth-train.sh&lt;/code&gt;, &lt;code&gt;oauth-check-training.sh&lt;/code&gt;, and &lt;code&gt;oauth-predict.sh&lt;/code&gt; to my local project folder, and &lt;code&gt;chmod 755&lt;/code&gt; on the to make them executable.&lt;/li&gt;

&lt;li&gt;I was able to train using &lt;code&gt;./oauth-train.sh play-prediction/prediction_models/languages&lt;/code&gt; command.&lt;/li&gt;

&lt;li&gt;&lt;code&gt;./oauth-check-training.sh play-prediction/prediction_models/languages&lt;/code&gt; yielded the expected result, training accuracy was 0.95.&lt;/li&gt;

&lt;li&gt;&lt;code&gt;./oauth-predict.sh play-prediction/prediction_models/languages &amp;quot;\&amp;quot;Sitting around on a Sunday night, decided to finally take a little dive on something that&#8217;s had my eye for a while, the Google Prediction API.\&amp;quot;&amp;quot;&lt;/code&gt; was interpreted as English correctly.&lt;/li&gt;

&lt;li&gt;&lt;code&gt;./oauth-predict.sh play-prediction/prediction_models/languages &amp;quot;\&amp;quot;El sol se levantar&#225; ma&#241;ana y qui&#233;n sabe lo que traer&#225; la marea?\&amp;quot;&amp;quot;&lt;/code&gt; was interpreted as Spanish correctly.&lt;/li&gt;

&lt;li&gt;&lt;code&gt;./oauth-predict.sh play-prediction/prediction_models/languages &amp;quot;\&amp;quot;La gloire est &#233;ph&#233;m&#232;re, mais l&amp;#39;obscurit&#233; est &#233;ternelle.\&amp;quot;&amp;quot;&lt;/code&gt; was interpreted as French correctly.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I noticed the engine didn&amp;#8217;t perform as well on short phrases, to be expected.&lt;/p&gt;

&lt;h2 id='closing'&gt;Closing&lt;/h2&gt;

&lt;p&gt;Very cool system, took me about an hour to get through the tutorial.&lt;/p&gt;

&lt;p&gt;Mission accomplished, Google Prediction API is much less abstract in my mind now.&lt;/p&gt;</content>
    <published>2011-04-24T00:00:00+00:00</published>
    <category term="google-prediction-api"/>
    <category term="machine-learning"/>
  </entry>
  <entry>
    <title>The invisible forces that shape us</title>
    <link type="text/html" href="http://www.rywalker.com/the-invisible-forces-that-shapes-us" rel="alternate"/>
    <id>tag:www.rywalker.com,2011-04-08:/the-invisible-forces-that-shapes-us</id>
    <content type="html">&lt;p&gt;At all times, there are two forces tugging on us:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The current moment, including our current emotional and physical state.&lt;/li&gt;

&lt;li&gt;Our long term view of the world, which shapes what things mean to us.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If we bring this tug-of-war into our active conciousness, we can focus ourselves to towards the achievement of our goals.&lt;/p&gt;

&lt;p&gt;We are making three decisions every moment of our life:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What am I going to focus on? On the past? The present? The future? Myself? Others?&lt;/li&gt;

&lt;li&gt;What does it mean? Is it the end? Is it the beginning? Is it punishment? Is it a reward?&lt;/li&gt;

&lt;li&gt;What am I going to do? Give up? Move forward?&lt;/li&gt;
&lt;/ul&gt;</content>
    <published>2011-04-08T00:00:00+00:00</published>
  </entry>
  <entry>
    <title>Token input for multi-select</title>
    <link type="text/html" href="http://www.rywalker.com/token-input-for-multiselect" rel="alternate"/>
    <id>tag:www.rywalker.com,2011-04-03:/token-input-for-multiselect</id>
    <content type="html">&lt;p&gt;Great &lt;a href='http://railscasts.com/episodes/258-token-fields'&gt;Railscast by Ryan Bates&lt;/a&gt; showing how to do a Facebook-like multiselect in Rails 3 with very little server side work.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://railscasts.com/episodes/258-token-fields'&gt;View RailsCast&lt;/a&gt;&lt;/p&gt;</content>
    <published>2011-04-03T00:00:00+00:00</published>
    <category term="jquery"/>
    <category term="ui"/>
  </entry>
</feed>

