<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Emilio Carrión on Medium]]></title>
        <description><![CDATA[Stories by Emilio Carrión on Medium]]></description>
        <link>https://medium.com/@emcarrio?source=rss-ec5217ef227e------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*hFktzZqBPBdQ2QK0sKPs9g.jpeg</url>
            <title>Stories by Emilio Carrión on Medium</title>
            <link>https://medium.com/@emcarrio?source=rss-ec5217ef227e------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 03:12:41 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@emcarrio/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[The skill of communication]]></title>
            <link>https://emcarrio.medium.com/the-skill-of-communication-fe50c933ce1b?source=rss-ec5217ef227e------2</link>
            <guid isPermaLink="false">https://medium.com/p/fe50c933ce1b</guid>
            <category><![CDATA[teamwork]]></category>
            <category><![CDATA[skills]]></category>
            <category><![CDATA[communication]]></category>
            <dc:creator><![CDATA[Emilio Carrión]]></dc:creator>
            <pubDate>Tue, 26 Jul 2022 07:43:30 GMT</pubDate>
            <atom:updated>2022-07-26T07:43:30.511Z</atom:updated>
            <content:encoded><![CDATA[<p>Communication is THE SKILL. Being able to communicate effectively is one of the most important abilities a professional has. Every situation in our day to day requires some kind of communication and mastering it is one of the best investments you can do to improve yourself.</p><p>In this post, I’ll share some things I learned about it through the years (I fail to apply some of them though). Some of them come from experience, others from my wandering past in creative writing, and others from reading things about this very topic. Please fasten your seatbelts as we are taking off 🛫.</p><figure><img alt="Phonebox in the forest" src="https://cdn-images-1.medium.com/max/1024/1*dPvXmBZmRJYs7ohSwRFTLg.jpeg" /><figcaption>Image from Peter Aschof</figcaption></figure><h4>Get to the point fast 🏃</h4><p>We live in the information era. Millions of colours, texts, shapes and data are thrown to our eyes every second. Our little recently evolved brains try to keep up by taking shortcuts and plainly ignoring a great part of that information overload.</p><p>Do you want to be heard and understood? Get to your point fast, like sonic speed fast. This is a thing you can see applied to any published piece of text. The first chapter of a book for example (even the first sentence!) has to attract the attention of the reader or it will lose her forever.</p><p>Apply this to any communication you make. Be speed, communicate what is important lightning-fast ⚡.</p><h4>Be specific and synthesize 🗒</h4><p>In addition to being quick in getting to your point you should be concise, you should synthesize what you convey. And I will remark the size part of syntheSIZE. Use the number of words you need to express your ideas and no more.</p><p>I always return to the great words of Stephen King and his 10% rule. If that man knows how to do something reaaally good is writing. His book <a href="https://www.goodreads.com/book/show/10569.On_Writing">On Writing</a> is an amazing piece of gold if you want to improve your writing (and actually start doing it).</p><p>His rule of the 10% consists of letting your words breathe for a while after finishing your writing. Then you come back with a machete (I’m paraphrasing here) and cut 10% of them 🔪. For a text of 500 words, you should be left with 450 and so on.</p><p>This is not only applied to novels like the ones he writes, it can be used for any text or spoken discourse. I apply this to much anything I write. I’ll apply it to this post when finished so you’ll never see all the words sublimated in the process, but their sacrifice will have improved the end product you are currently reading.</p><h4>Know your audience 👥</h4><p>Who you want to communicate with is really important. As an effectual communicator, your main job is to communicate in a way that people understand.</p><p>I’m going to obviate the topical things about using the right language with the right people and all that BS. We have common sense, we already know that. Obviously, I will not speak with my academic tutor the same way as with my friends.</p><p>With knowing your audience I focus more on what knowledge this person has, how deep their understanding of the field we are talking about is, and the opportunity cost they have in exchange for participating in the communication.</p><h4>Elevate 🏋️‍♀️</h4><p>You should elevate low-level stuff to a higher level if you are communicating with someone not versed in the topic (like upper management in the case of technical explanations). With this we have to have clear that they are not dumb, it is just not their field and they need a little push in order to understand the details.</p><p>I experienced this myself recently at <a href="https://medium.com/u/7aeeefb24843">Mercadona Tech</a>. We have this high economic knowledge high effective business guy called Ignacio. He deeply knows his economics stuff and I know nothing about profitability and indirect costs. In a short hour, he was able to explain all the minutiae and details of the full costs models we have for our different preparation models. Like child&#39;s play. I left the room understanding each concept and being able to relate them to other contexts and projects. Amazing communication skills.</p><p>I myself often apply this elevation principle too, like when communicating high-impact incidents for example. I usually prepare two explanations of what happened. One more high level to publish in public channels where not technical people will go to check what happened and the business impact (usually short to maintain their attention span). And another more deeply technical one to relay the tricky details to other engineering members interested in why it happened.</p><p>It is like going to a doctor, understanding what happens to your body is really important for you. But you don’t know what alopecia is, so the doctor should exemplify and elevate the topic to terms your balding head can understand.</p><h4>That meeting could have been an email ✉️</h4><p>Communication emerges in many ways. Written and spoken, in person or remotely, on email, via slack, synchronously and not…</p><p>You can choose how and in what format to communicate and you should choose wisely to avoid time losses and misunderstandings.</p><p>Maybe that message doesn’t convey the mood in what sounds inside your head, maybe it can be misunderstood. Maybe that half-hour meeting with commute included could have been a two paragraphs email and have saved us all an unjustified long amount of time. Maybe if you chosed the correct way of communicating you wouldn’t have to redo half of your work due to a misunderstanding.</p><p>Choose wisely when communicating, your message is as important as the way your share it.</p><h4>Understand the problem 🧠</h4><p>Another important point in communicating is understanding what you are talking about. Albert Einstein said:</p><blockquote><em>If you can’t explain it simply, you don’t understand it well enough.</em></blockquote><p>Well, <a href="https://skeptics.stackexchange.com/questions/8742/did-einstein-say-if-you-cant-explain-it-simply-you-dont-understand-it-well-en/22409#22409">maybe he did not</a>, but it’s a nice quote to affirm my narrative. As I mentioned in <a href="https://emcarrio.medium.com/understanding-the-problem-and-making-decisions-34b5739860bb">previous posts</a>, the first and most crucial step in facing a problem (and thus communicating it) is understanding it.</p><h4>LISTEN 👂</h4><p>Communication works both ways, from you to your listener and back (when you are the listener). We usually hear but we rarely listen. Most of the time people tend to think about the next thing they are going to say and don’t actively listen to the other party. Any information transmitted in communication can change the course of it, so don’t miss anything and pay respect to your peers paying them the attention they deserve.</p><h4>Over-communicate 🗣️</h4><p>You have to over-communicate just to communicate (unknown reference 🙁). <a href="https://medium.com/@abhijitflow/tappers-listeners-af408560f1a9">We usually overestimate how much listeners understand</a>. You always have to make sure that your message is being received and that is being understood.</p><p>Don’t fear to over-communicate in order to be understood. Repeat if necessary to get your message acknowledged.</p><h4>Ask 🤔</h4><p>Ask them! Ask your peers when communicating. It will help you solve some of the problems the lack of understanding provokes. And more important, it will help engage people in the dialogue.</p><p>Ask them to involve them, ask them to know their opinion, ask them to check if everything is being understood, ask them to expand your point of view, and ask them to expand theirs. Believe me in this, just ask them.</p><h4>And DO communicate 🙏</h4><p>And finally and more important of all. Do communicate.</p><p>Communication does not start without two involved parties, and you are one of them. Engage in active communication when necessary (that happens to be almost on any occasion). Don’t let a lack of communication worsen your relationship with your team, don’t let that unspoken words guide the fate of your future ✨.</p><h4>Final words 🎵</h4><p>Hey! I hope some of these tips help you and your peers communicate better. Communication is a skill that has to be learned and practice is your best ally in this. Start communicating today and ask for feedback when necessary to improve it.</p><p>I’m going off now, if you liked this content you can find more of it <a href="https://emcarrio.medium.com/">here</a>.</p><p>Also, you can follow me on <a href="https://www.linkedin.com/in/emcarrio/">LinkedIn</a> or <a href="https://twitter.com/emcarrio">Twitter</a> for more thoughts and derailed tales 😄</p><p>💐 Here lie the 10% of the original words of this post taken out to improve its conciseness.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=fe50c933ce1b" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Choosing technologies, things to consider]]></title>
            <link>https://emcarrio.medium.com/choosing-technologies-things-to-consider-c9864afebb15?source=rss-ec5217ef227e------2</link>
            <guid isPermaLink="false">https://medium.com/p/c9864afebb15</guid>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[choices]]></category>
            <category><![CDATA[software]]></category>
            <dc:creator><![CDATA[Emilio Carrión]]></dc:creator>
            <pubDate>Tue, 31 May 2022 06:48:35 GMT</pubDate>
            <atom:updated>2022-07-21T09:37:53.287Z</atom:updated>
            <content:encoded><![CDATA[<p>Having to make a decision about the tech stack is a common problem that all the development teams have to affront at some point. Doubts will arise about what library, tool or programming language we should use to make the new big thing. In this fable, I will give you some of the reasonings I do when facing these decisions and common things to take into account.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/791/1*NJCZ_8XLHEjsXBYUfPvMrg.png" /><figcaption>The Pokemon Company, unknown image attribution</figcaption></figure><h4>It should match the business needs 💡</h4><p>The first thing to take into account is a big one. The technology choice you are making should match what the business expects. You are making a technology decision to solve some problem, to give a solution to a concrete business gap. When choosing, you have to be sure you understand what we are making the decision for, what are the requirements, and what we expect from it.</p><p>An example I always give to illustrate this topic is the choice of database technology for data analytics. What should we use? A relational database? A NoSQL one? A graph database? Well, it depends on what type of data analysis we want to get from it! You should know and understand what the purpose is and what kind of conclusions we want to extract from that data.</p><p>If your analysis focus on aggregations then a columnar database will do a better job. If you need to access different fields of each object in big processing batches, a relational database should be the choice. If you want to make conclusions from the relationships between objects, then a graph database sounds like the right decision. The business needs should guide the technology choice, not the other way around.</p><h4>Social learning, use what your friends use 👫</h4><p>Another important point when taking tech stack decisions is who you will be able to learn from. This is usually proxied through the technology’s community but can be expressed in terms of its support around you.</p><p>A good rule of thumb that I like to give as advice is that you should use what your friends use. There is no better support. If you use what the people around you are using then any doubt, problem and block can easily be solved just by turning around and asking your friend.</p><p>Social learning is a powerful thing, we humans are collaborative by nature and it makes wonders in productivity if you know how to take advantage of it.</p><h4>Hiring ⛑</h4><p>Hiring is important, do not let anyone trick you to think the opposite. Any project, even any of your side-fun-pet projects can turn into something bigger in the future. And in that future, you will face a really big problem: finding people to help you grow it to something else.</p><p>That said, if you choose a technology or language or framework that nobody uses (or nobody uses at least yet) you must be very sure that the advantages you are getting for that choice are bigger than the headaches future hire searches can give you. Bet for the widespread, believe me, you will make the incredibly difficult work of recruiters much easier.</p><h4>Inertia is a powerful force 🐉</h4><p>This topic is closely related to the previous one. In this industry, inertia is a powerful force. Established ancient forces that reign over the kingdom and rule with an iron fist. Technologies that are so rooted in enterprises that they are really difficult to avoid using in one project or another.</p><p>For these cases my advice is simple: accept your fate and kneel before them… for now. But look closely at the trends, the hidden heroes, the ones that do not fear to take down the giants. Secretly give them your support and force. In the future, they will be the ones ruling all under the sun.</p><h4>Vendors and platform 🤖</h4><p>This is another headache. Yes, if you want to develop native iOS apps you have only one choice and a shot in the foot. I mean, you can choose between Swift and Objective-C and that’s it. For anything else, you will have to go hybrid.</p><p>The platform you pretend to develop for is not key when choosing technology but it is usually a set of restrictions that narrow the number of your choices.</p><h4>Updates and maintanibility 🌀</h4><p>A software being updated is happy software. Lack of evolution support for projects, languages and libraries is their doom. They can be heavily used in the industry, and they may be really useful, but if they are not being updated to the latest systems, language versions and needs, they are destined to fall.</p><p>The worst thing you can see in a code repository of an open-source project is something along the lines of <em>last updated 5 years ago</em> or <em>not maintained anymore</em>.</p><p>So be careful when choosing this kind of technology, they can break anytime and no one is going to fix them.</p><h4>Conclusions 📑</h4><p>These are some of the things I take into account when choosing technologies and when I try to prevent future headaches. I hope this inspires some of you and help you when facing these hard decisions.</p><p>There is one more thing that I didn&#39;t mention and it is that I like to break some of those principles for fun 😄. Trying new technologies is really amazing and sometimes you find real gold, so although it may contradict some of the reasons given in this article, my last advice is to be flexible and experience new things whenever you have the time. This is really important.</p><p>And finally, to conclude, here comes the moral of this fable (a TL;DR):</p><p><em>Choose what your business needs and try first what your friends are happily using. Take into account the difficult work of your recruiters. Follow established trends but often bet for the new. Also, be clear about the restrictions of your platform and seek the maintained and the updated. And finally, but not least important, have fun!</em></p><h4>Final words 🎵</h4><p>Hey! I hope that some of this tips help you and your peers choose better technologies.</p><p>I wish you a great day! If you liked this content you can find more of it <a href="https://emcarrio.medium.com/">here</a>.</p><p>Also you can follow me on <a href="https://www.linkedin.com/in/emcarrio/">LinkedIn</a> or <a href="https://twitter.com/emcarrio">Twitter</a> for more thoughts and derailed tales 😄</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c9864afebb15" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Understanding the problem and making decisions]]></title>
            <link>https://emcarrio.medium.com/understanding-the-problem-and-making-decisions-34b5739860bb?source=rss-ec5217ef227e------2</link>
            <guid isPermaLink="false">https://medium.com/p/34b5739860bb</guid>
            <category><![CDATA[product-management]]></category>
            <category><![CDATA[decision-making]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[problem-solving]]></category>
            <dc:creator><![CDATA[Emilio Carrión]]></dc:creator>
            <pubDate>Wed, 21 Jul 2021 07:34:27 GMT</pubDate>
            <atom:updated>2021-07-21T07:34:27.548Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*A-YKbdubIN6Y-rEUVJ0uug.jpeg" /></figure><h3>The problem</h3><p>In everyday life and working in a product or in software development you face uncountable problems that have to be addressed. You have to understand them, prioritize them and decide on solutions.</p><p>In this article, I describe some of my thoughts about it (all of them highly influenced by reading a lot about problem-solving and watching great talks like <a href="https://www.youtube.com/watch?v=v_nhv6aY1Kg&amp;t=2276s">How to Become a Great Software Architect</a> by <a href="https://ewolff.com/">Eberhard Wolff</a>).</p><h4>What is the problem?</h4><p>The first and most crucial step in facing a problem is understanding it.</p><p>Quoting the philosopher <a href="https://en.wikipedia.org/wiki/John_Dewey">John Dewey</a> (and avoiding <a href="https://quoteinvestigator.com/2014/05/22/solve/">the typical problem-solving quote</a>):</p><blockquote>A problem well put is half solved.</blockquote><p>When you want to solve an issue, the first thing to do is to understand it. In order to propose good solutions, you must know what we are discussing about. What is the problem we are trying to solve.</p><p>Quoting this time <a href="https://en.wikipedia.org/wiki/Malcolm_Forbes">Malcolm Forbes</a>:</p><blockquote>It’s so much easier to suggest solutions when you don’t know too much about the problem.</blockquote><p>And those solutions will probably be flawed without the right context.</p><h4>The problem is not a solution</h4><p>Talking about solutions: an important fact is that a solution is not a problem. Avoid per example sentences like <em>the problem is the lack of…</em> that is a solution, not the problem.</p><p>You must ask the correct questions to identify the needs and constraints of the problem in order to find proper solutions. So be careful not to fall into this kind of disguised solutions that can influence the outcome decision.</p><h4>Specify, do not generalize</h4><p>It’s important to be specific in the problem definition.</p><p>It’s not the same to say that <em>our systems are crashing</em> as <em>our systems are going down due to an increase in memory usage</em>.</p><p>Specifying data or details that support the definition of your problem will help you understand it better and make better decisions based on more available context.</p><h4>Express the problem in the stakeholders’ terms</h4><p>Most of the time the problem you are facing is not affecting only you but some of your stakeholders too.</p><p>It’s important to address the problems from the point of view of all the implicated parties and how it affects them.</p><p><em>An increase in resources consumption that is affecting some processes in engineering</em> can also <em>make load times 4 times slower for the customers </em>or <em>crash some dashboards in customer support</em>.</p><p>Knowing all the affected stakeholders and what problems they are facing will help you decide and prioritize the best solution.</p><h4>It is really a problem?</h4><p>Now, having all the context and available information about your problem, you must decide if it’s really a problem we have to solve right now. <em>It is worth solving? Should we prioritize it?</em></p><p>Not all problems are critical to your business, some of them can be assumed and handled later. It’s your decision what and when to tackle each of them and work on what is really important at the moment.</p><h3>The decisions</h3><p>Once the problem, the implications and the affected stakeholders are understood, it is the time to make decisions about it. At this point you already have half of the battle won. Now let’s make the decisions that will solve the problem.</p><h4>Who has to make them?</h4><p>In a modern structure, probably your team is self-organized and composed of multi-disciplinary members.</p><p>One person may be an expert in a field or part of the architecture. This person may overlap knowledge with other team members, but probably no one has context and knowledge of everything. That would be very unrealistic.</p><p>So, who must take the correct decisions to face the problem? The answer is the team. Problem-solving is a collaborative game, everybody will have different points of view and expertise. The points where they disagree is where the real implications of your solutions will arise.</p><p>And be aware of unanimous and not problematic decisions, if it looks too good maybe it’s lacking opinion diversity and a challenge may be needed. Someone should defend other opinions although they are not hers to strengthen the final decision.</p><h4>Who owns the decision?</h4><p>Although the decision making is a collaborative effort someone has to own the decision taken. Shared ownership often creates confusion and slows its implementation.</p><p>When everyone is responsible for a decision, no one is really responsible for it.<strong> </strong>You want the person with the most context to own the decision and the outcome of implementing it. We must then differentiate joint accountability from decision ownership.</p><h4>When to make the decision?</h4><p>We face uncountable problems every day, and, as stated above, not all of them have the same priority or impact. Prioritize what is important, what is impacting your business the most and leave lesser problems for later.</p><p>Don’t be afraid of postponing relevant decisions until they really become a problem.</p><h4>What if we do nothing at all?</h4><p>So maybe your problem can be solved in a trivial way, at least for now, and then you have more time to work on problems that would really help you grow and progress.</p><p><em>Do we need a system to reschedule orders right now? Can it be done manually for now so we can focus on other important problems?</em></p><p>You can patch that kind of problems for now, until they grow enough to be relevant. In the meanwhile, you can focus on other things.</p><h4>What if it’s too late?</h4><p>If you did prioritize your problems more or less right then the <em>too late</em> shouldn’t be too critical. Maybe some revenue is lost, a couple of clients may be upset, but you did use the opportunity to work in something more critical that could have had worst implications or helped you advance.</p><p>You can’t favour everyone and every part of your business, but if you prioritize well, everybody will be happy in the long term.</p><h4>What if it’s too soon?</h4><p>Often decisions are made too early.</p><p>If you rush making decisions you can end up working on unimportant stuff. You can also fall into the trap of making choices based on too little information. In that scenario, you could end up doing twice the job due to some misconception about what the problem really is.</p><p>But don’t confuse having too little information with having it all. You usually have to make decisions with unclear information because retrieving all of it could be too expensive or take too long.</p><p>Do not precipitate but have the courage to make decisions in unclear terms if you need it to advance.</p><h4>Review your decisions</h4><p>The available information is key in the decision progress. When working on something, new information will naturally arise. The basis of your choices could have changed.</p><p>You must always be reviewing your decisions taking into account the new information available and reevaluate them accordingly. Most of the time what appears to have been a bad decision is only a decision not reviewed.</p><h3>Conclusions</h3><p>So there you have it, understand your problem. It is very important to do a good job understanding what is really happening to be able to solve it.</p><p>Don’t fall into solutions disguised as problems. Ask yourself first what is really happening instead of how you would solve it.</p><p>Understand the involved parties and ask them how they are being affected. This will give you more context that will help you make better decisions.</p><p>Problem-solving is a collaborative game. Work as a team to find the best solution and its possible implications. But after the decision is made, someone has to own it, shared ownership is often not a good idea.</p><p>Don’t be afraid of postponing the solution and focus on the most impactful problems first.</p><p>And don’t be afraid of making decisions with unclear information, you will never be able to have it all under control.</p><p>And finally, always review your decisions, new information can change how the game is played and your decisions can be outdated.</p><p>I hope you found this article interesting. Problem-solving is a really important and powerful skill to work on. If you are interested in other topics like software development, product or data science I invite you to check other of my articles like <a href="https://emcarrio.medium.com/business-logic-in-a-django-project-a25abc64718c">Business logic in a Django project</a> or <a href="https://medium.com/mercadona-tech/recomendations-i-a-scary-tale-about-vanishing-ghosts-35c69aa389be">my series about recommendation systems</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=34b5739860bb" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Business logic in a Django project]]></title>
            <link>https://emcarrio.medium.com/business-logic-in-a-django-project-a25abc64718c?source=rss-ec5217ef227e------2</link>
            <guid isPermaLink="false">https://medium.com/p/a25abc64718c</guid>
            <category><![CDATA[django]]></category>
            <category><![CDATA[business-logic]]></category>
            <category><![CDATA[software-architecture]]></category>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[Emilio Carrión]]></dc:creator>
            <pubDate>Tue, 29 Jun 2021 09:08:19 GMT</pubDate>
            <atom:updated>2021-06-29T09:08:19.488Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*pUi3vkj06Vqp_sXeiI-UbQ.jpeg" /></figure><p>Have you ever wondered where in the hello world is your business logic meant to reside in a Django project? In the models, you can argue, maybe in the managers, who really knows? Let’s talk a little about it.</p><h3>Active Record</h3><p>Quoting <a href="https://docs.djangoproject.com/en/dev/misc/design-philosophies/">Django’s design philosophy</a> models should:</p><blockquote>Include all relevant domain logic</blockquote><blockquote>Models should encapsulate every aspect of an “object,” following Martin Fowler’s <a href="https://www.martinfowler.com/eaaCatalog/activeRecord.html">Active Record</a> design pattern</blockquote><p>Mmmm, so Active Record uh, a popular design implementation used in a great variety of ORMs. Also claimed an antipattern by a relevant part of the community.</p><p>Quoting Robert Martin in Clean Code:</p><blockquote>Active Records are special forms of DTOs [Data Transfer Objects]. They are data structures with public variables; but they typically have navigational methods like <em>save</em> and <em>find</em>. Typically these Active Records are direct translations from database tables, or other data sources.</blockquote><blockquote>Unfortunately we often find that developers try to treat these data structures as though they were objects by putting business rule methods in them. This is awkward because it creates a hybrid data structure and an object.</blockquote><p>So yeah, we see some contradictions here. As Martin Fowler described them: Active Records are objects that encapsulate data access and add domain logic to that data. The problem is that this kind of structure flushes the sink any sign of <a href="https://en.wikipedia.org/wiki/Single-responsibility_principle">SRP</a> you could expect in it. And that could be a problem.</p><h3>Fat models</h3><p>So how this recommended structure is really implemented in practice? Following that model, we start building what the community calls fat models (and thin views). An extended practice recommended in a lot of learning material like <a href="https://django-best-practices.readthedocs.io/en/latest/applications.html#models">django-best-practices</a> or <a href="https://ultimatedjango.com/learn-django/lessons/adding-business-logic-to-models/">ultimatedjango</a>.</p><p>Using this pattern, we implement all the business logic in the models and managers making them fat. That’s not really a good idea because that makes the testing really difficult and very coupled to the ORM (creating you a mocking mayhem and the need of a big number of fixtures and data to create different test scenarios). Following this practice makes your business logic nearly impossible to test without using a database.</p><p>Growing your models to infinity makes maintaining them really difficult too. With every new use case, your model will grow one or several new methods and it can quickly and dangerously become a <a href="https://en.wikipedia.org/wiki/God_object">god object</a>.</p><p>So what can we do to avoid this kind of problems?</p><p>Quoting again Robert Martin’s Clean Code:</p><blockquote>The solution, of course, is to treat the Active Record as a data structure and to create separate objects that contain the business rules and that hide their internal data (which are probably just instance of the Active Record).</blockquote><h3>The business layer</h3><p>The answer is the almighty business layer where our business rules live. Sometimes divided into subsets like domain logic and application logic, it is the layer where we shall implement our business flows, actions and logic.</p><p><a href="https://codeinthehole.com/about/">David Winterbottom</a> in his great and funny article <a href="https://codeinthehole.com/lists/why-your-models-are-fat/">Why your Django models are fat</a> teaches us some good lessons like:</p><blockquote>As a rule-of-thumb, your application logic should live in modules that aren’t Django-specific modules (eg not in views.py, models.py or forms.py). If I had my way, Django would create an empty business_logic.py in each new app to encourage this.</blockquote><p>So yeah, a business logic module sounds like a great idea. A place where you implement your commands, use cases, actions or flows (they have so many names) and where they remain loosely coupled to your data sources.</p><p>Just be careful of not taking too much away from your models or you will be left with <a href="https://martinfowler.com/bliki/AnemicDomainModel.html">anemic domain models</a>. Only business logic is meant to leave, the domain logic like validations, calculations, etc are already at home.</p><h3>The data layer</h3><p>And how we can maintain this loose coupling between business logic and the dangerous and awesome Django ORM? Because it is soo easy and wonderful to use, it’s a pity that you can fall into it so easily.</p><p>The answer is treating it like a data repository. A really not used pattern to a big part of the Django developers I used to know (highly influenced by using the Django ORM everywhere).</p><p>In reality, this solution is the recommended way of doing things, although it is not advertised as a data repository at all. In every Django tutorial, you are suggested to write your queries inside custom managers to avoid repetition and writing the same query every time. But you are gaining a lot more than that, implementing the queries there decouples the ORM implementation from its use in the application, a win-win situation.</p><p>Following this principle, you can then use your <em>Model.objects</em> as it was your data repository in the business logic, reducing the coupling to the ORM and allowing you to do integration tests for the database interactions only. In the next example, we’ll see how to use it.</p><h3>Real example</h3><p>Now let’s see an example to understand the situation better.</p><p>The example is very simple: we have an <em>Address</em> model that has an <em>is_default</em> field that indicates if that address is the default one of its user.</p><p>And then we have an action that makes an address instance the default one, setting its <em>is_default</em> to <em>True</em> and setting it to <em>False</em> to the other user’s addresses. After setting the default address, we publish the changes to anyone interested.</p><p>Here first we have the example done using fat models (high coupling and low cohesion):</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ec6675d7dbf39f1189fe5a66a0ea585c/href">https://medium.com/media/ec6675d7dbf39f1189fe5a66a0ea585c/href</a></iframe><p>Some important things to notice are:</p><ul><li>The model indeed contains the business action <em>set_default.</em></li><li>It has dependencies with other models (in this case itself).</li><li>There are side-effects in the action inside the model, breaking the SRP.</li><li>To achieve unit tests for our business logic we need to mock up all the dependencies.</li></ul><p>In the last point, we have something important to discuss. You can follow 2 approaches: do an integration test where you validate the business flow with all its dependencies or do a unit test mocking all the external calls.</p><p>The problem with the integration test is that you have to test the behaviour using a real database as all the dependencies will end using the ORM, slowing down your tests and not validating the logic flow independently of the dependencies. The problem with the unit test is that you lose the integration validation of database behaviours and you have to mock everything.</p><p>So let’s look to the same example but applying a business logic layer and abstracting the database interactions to a manager (low coupling and high cohesion):</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d8f86233f20e4deae233bedde18c77a3/href">https://medium.com/media/d8f86233f20e4deae233bedde18c77a3/href</a></iframe><p>As you can see we have easier tests and more maintainable code. In this case, we implement unit tests for our business logic that are fast and validate its flow. And then integration tests for the manager that validate the data operations and its dependencies with the database.</p><p>The key in this structure is that our business logic is not aware of data integrity or how it is stored, that is the job of the managers. This way we can unit test every flow and leave the integrity checks for the integration tests of the data layer.</p><h3>Final words</h3><p>Django is a great framework, but after all, it is only a framework. It’s your job to use it correctly and structure your application to your needs.</p><p>Fat models in Django can make sense for properties (like <em>full_address</em>) and object validations, but including business logic and side effects into your Active Record objects is not really a good idea, some kind of service (or business) layer is my recommended way to go.</p><p>Be careful not to abuse the Django ORM and rely on it for everything. It is one of the best ORMs out there but as a consequence, it makes it too easy to end up with a giant, coupled application if you don’t pay attention.</p><p>And to conclude just say that these are my always evolving ideas about how to structure logic into Django projects. There are a lot of ways of doing things and every situation is different so there is no correct answer for it.</p><p>I hope you found this interesting! If you want to read about other topics like product or data science you can check my <a href="https://medium.com/mercadona-tech/recomendations-i-a-scary-tale-about-vanishing-ghosts-35c69aa389be">e-commerce recommendations series</a>. I hope to see you soon in future articles!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a25abc64718c" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Recommendations IV — A tale about data roles]]></title>
            <link>https://medium.com/mercadona-tech/recommender-iv-a-tale-about-data-roles-b748af03e6fd?source=rss-ec5217ef227e------2</link>
            <guid isPermaLink="false">https://medium.com/p/b748af03e6fd</guid>
            <category><![CDATA[data-engineering]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[ecommerce]]></category>
            <category><![CDATA[recommendation-system]]></category>
            <category><![CDATA[data-science]]></category>
            <dc:creator><![CDATA[Emilio Carrión]]></dc:creator>
            <pubDate>Mon, 30 Nov 2020 11:25:06 GMT</pubDate>
            <atom:updated>2020-11-30T11:41:43.422Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6IlE2HwrWWm6Ubs2n0CJbA.png" /></figure><h3>Recommendations IV — A tale about data roles</h3><p>A car without wheels is a useless paperweight, a sailboat without the sail is only a boat and a boring one to be precise ⛵️. In data-projects it happens the same. You can have the best data science team and the best ideas, but without the data available to play with and the ability to take the results to your customers, you can’t do anything at all.</p><h3>Data roles 📚</h3><p>Here comes the superheroes of our story, the roles of machine learning engineer and data engineer. This positions are relatively new roles that appeared due to the latest bigdata hungry and the growing affordability of this kind of developments outside the big techs.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/0*9qyFc5tLoJlJDn4v" /></figure><p>Firstly, the <strong>data engineer 🔧</strong>. When starting with a project involving data, the most important thing to do first is to have the data available. Provide the team with the data they need may sound trivial, but it’s a real challenge. A lot of pipelining and infrastructure work is involved and sometimes is difficult to connect data from different sources and make it available to work with it efficiently.</p><p>On the other hand, the <strong>data scientist 👩‍🔬</strong>. The professional that given a problem explores this available data and research and develops a solution. The result of its work can be, per example, a model or a statistical analysis.</p><p>Finally, the <strong>machine learning engineer 👷‍♀</strong>. The person that takes this model and then cleverly connects it to a production environment. Many of the times, the real value of the solution comes with this implementation.</p><h3>Our story 📕</h3><p>This role differentiation brings us to our problem. In <a href="https://medium.com/mercadona-tech/recomendations-i-a-scary-tale-about-vanishing-ghosts-35c69aa389be">previous articles of this series</a>, we discussed some of our efforts in bringing our customers personalized content to fasten their purchases. We explained the fascinating parts and omitted the boring ones. Not all was a bed of roses.</p><p>In our case, we lacked both data engineers and machine learning engineers 😢. But don’t get me wrong. The problem was not the lack of a person dedicated to these developments, but the lack of developers with the experience to take those roles and deliver their results reliably.</p><p>With the <a href="https://medium.com/mercadona-tech/recomendations-i-a-scary-tale-about-vanishing-ghosts-35c69aa389be">suggestion of alternatives in the ghost products issue</a>, there was no much problem. We only handle a catalogue of around 10K products, so the computation and memory usage was far from being an issue.</p><p>With the <a href="https://medium.com/mercadona-tech/recommendations-ii-a-twisted-tale-about-twin-products-3e4759add440">calculation of the related products</a>, we started to experience some trouble. At first, we were processing this inside our monolith, using database aggregations that made the process not so complicated. When we finally decided to move all the recommender stuff to its service we hit the wall of “<em>Oh! we don’t have the data here!</em>” and had to work to pipeline it to it with some magic (that took more time than developing the solution itself).</p><p>Then we went into Helm’s Deep trying to <a href="https://medium.com/mercadona-tech/recommendations-iii-a-flavored-tale-about-similar-tastes-1afd4a44f93d">create recommendations for hundreds of thousands of clients</a>, and all went how it was expected to go, not very well.</p><p>It is not easy to move data around. A few hundreds of megabytes are comfortable to work with, but when you are handling tens of gigabytes, things start to fail. Timeouts, Out of memory errors (OOM Kills), unending Extract-Transform-Load (ETL) jobs… That kind of things began to be our day-to-day, and frustration and tedium started to pile up 😫.</p><p>Of course, we got all the pipelining and crafting done and working, but believe me, the journey was a real nightmare.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/0*7zfV7arztNqSMQII" /></figure><h3>The moral of the story 🕊</h3><p>Experience is important. Specialization is becoming more and more noticeable with the emergence of new paradigms and highly technical fields. Invest in those specialized roles and developments will become more robust and reliable.</p><p>That doesn’t mean that a professional team in the field can’t take those roles and perform well and bring value to your customers. But they are going to hit with problems that experience and knowledge would have handled them quicker.</p><p>Here ends this recommender series. Thanks to have joined us in such an amazing adventure. All our recommendation experiences had been a rollercoaster of emotions and fun and we are glad to have had you on board.</p><p>As a final note, if you like challenges and figuring out things yourself, you could be a great match for us. And this is wonderful because <a href="https://mercadona-tech-jobs.personio.de/">we are hiring</a>! We are looking for great professionals for different roles, and you may fit in, who knows! If you want a challenge and want to try something different, please don’t hesitate to <a href="https://mercadona-tech-jobs.personio.de/">contact us</a> (And yes, we still need that data engineer!).</p><h3>Previous articles 🗒</h3><p><a href="https://medium.com/mercadona-tech/recomendations-i-a-scary-tale-about-vanishing-ghosts-35c69aa389be">Recommendations I — A scary tale about vanishing ghosts</a></p><p><a href="https://medium.com/mercadona-tech/recommendations-ii-a-twisted-tale-about-twin-products-3e4759add440">Recommendations II — A twisted tale about twin products</a></p><p><a href="https://medium.com/mercadona-tech/recommendations-iii-a-flavored-tale-about-similar-tastes-1afd4a44f93d">Recommendations III — A flavoured tale about similar tastes</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b748af03e6fd" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mercadona-tech/recommender-iv-a-tale-about-data-roles-b748af03e6fd">Recommendations IV — A tale about data roles</a> was originally published in <a href="https://medium.com/mercadona-tech">Mercadona Tech</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Recommendations III — A flavored tale about similar tastes]]></title>
            <link>https://medium.com/mercadona-tech/recommendations-iii-a-flavored-tale-about-similar-tastes-1afd4a44f93d?source=rss-ec5217ef227e------2</link>
            <guid isPermaLink="false">https://medium.com/p/1afd4a44f93d</guid>
            <category><![CDATA[recommendation-system]]></category>
            <category><![CDATA[ecommerce]]></category>
            <category><![CDATA[product-design]]></category>
            <category><![CDATA[product]]></category>
            <category><![CDATA[recommendations]]></category>
            <dc:creator><![CDATA[Emilio Carrión]]></dc:creator>
            <pubDate>Wed, 07 Oct 2020 09:01:08 GMT</pubDate>
            <atom:updated>2020-11-30T11:31:28.744Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*yMDOuVOu_E0r15BsFpbiXw.jpeg" /></figure><h3>Recommendations III — A flavoured tale about similar tastes</h3><p>When we talk about recommendations we usually refer to the magical suggestions that online platforms offer us based on our tastes and historical purchases.</p><p>There is a lot of black magic involved in modern recommendation systems. Platforms like Spotify or Netflix build their entire business model around them and have full teams dedicated to improving them. Some retail businesses even have reported increments up to 30% of their revenue by implementing custom recommendations to their customers.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xKleVEOHDTzS6lzU063FyQ.png" /></figure><p>As mentioned in <a href="https://medium.com/mercadona-tech/recomendations-i-a-scary-tale-about-vanishing-ghosts-35c69aa389be">previous articles in this series</a>, in <a href="http://mercadonatech.es/">MercadonaTech</a> we have the vision of making the life of our clients simpler. Helping them do their regular groceries faster and easier. Recommending them products they may be interested in is one of the ways we help them.</p><p>In this article, we will learn how we recommend new products to customers from their previous purchases and learn from other clients decisions.</p><h3>The study 📚</h3><p>All started with an idea, learn from our customers. As we mentioned in <a href="https://medium.com/mercadona-tech/recommendations-ii-a-twisted-tale-about-twin-products-3e4759add440">the last article</a>, groceries e-commerces are not the usual online platform where you buy occasionally. They are made to make recurrent purchases of food and care products. This means that all the orders of one customer should be quite similar.</p><p>So we knew we had customers with similar preferences. And that we could improve the purchases of our clients recommending them products that other customers with similar product profiles bought but them not.</p><p>We started our journey checking the state of the art. In these types of things, a lot of people before you have already fought against the problem. I recently read <a href="https://www.gatesnotes.com/Health/Exemplars-in-Global-Health?WT.mc_id=20200901130000_EGH-launch_BG-TW_&amp;WT.tsrc=BGTW">a blog post from Bill Gates</a> that starts with a quote that I totally agree with and that represents this point very well:</p><blockquote>“I tackle every big new problem by asking two questions: Who has dealt with this problem well? And what can we learn from them?”</blockquote><p>We learned a lot in a short time. We read some great references like <a href="https://towardsdatascience.com/introduction-to-recommender-systems-6c66cf15ada">this</a> (<a href="https://towardsdatascience.com/">towardsdatascience.com</a> blog post), <a href="https://developers.google.com/machine-learning/recommendation">this</a> (google own curse) and <a href="http://infolab.stanford.edu/~ullman/mmds/ch9.pdf">this</a> (Mining of Massive Datasets book) among others.</p><p>We got a rough idea about the different existing solutions and how they work. In product recommendations there are basically two paths to follow: the called “traditional machine learning” (I quote it because I don’t quite like the differentiation 🙁) and some new deep learning approaches.</p><p>Looking for real use cases (aside from some big players and big techs) the overall implementations made use of the first path. So we decided to start small and get some recommendations to hit production quicky in a lean way!</p><h3>Content-related recommendations 🍱</h3><p>There are two long-standing proven “traditional machine learning” approaches to recommendation systems: content-related recommendations and collaborative filtering.</p><p>To suggest products to our customers, the first thing you can think of is to recommend them products similar to the ones they have already purchased.</p><p>To do that, the logical thing to do is to take into account the characteristics of the products they have bought (the description, category, size…) and recommend similar items based on this information.</p><p>This technic is called content-related recommendations. And it’s a great way of suggesting new products to customers.</p><p>It has a couple of downsides too <em>tho. </em>Like, recommend you toilet bowls for two weeks after replacing the one that you broke accidentally 🚽 or create content bubbles where the customers only see the same set of products forever until they buy something new.</p><p>Content-related systems are a relatively easy way to create recommendations. Sadly in our case 😔, due to logistical issues and packaging fluctuations, we do not have available the descriptions or content of our products. Although it’s an approach that we have to explore soon, we have not implemented it yet.</p><h3>Collaborative filtering 👫</h3><p>The case of collaborative filtering is more interesting. This approach allows you to recommend products without having the context that surrounds the product and without needing its description or characteristics.</p><p>To calculate the recommendations, it takes into account purchases from users similar to you (we explain how this is done later). Recommendations are then based on products that the other users have bought but you have not.</p><p>To achieve this we use a traditional approach that makes use of <a href="https://en.wikipedia.org/wiki/Matrix_factorization_(recommender_systems)">matrix factorization</a>. It consists in converting a matrix into a smaller matrices product and recalculating it again to fill the voids. If this sounded too weird 🤔, now we will show you an example of how this works and how it manages to calculate recommendations.</p><h3>Calculating recommendations 🧮</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/552/1*mXXvOd8U0LCVCnvA2bs2ww.png" /></figure><p>In the example, we see the purchase history of Alice, Bob and Carol. Alice has bought milk, Bob has bought milk and eggs and Carol has bought bread and toasts. The objective here would be to recommend eggs to Alice since Bob has also bought milk like her and has also bought eggs. As a result, they could be of interest to her as well. In the case of Carol, as her tastes do not coincide with Alice’s, it should not recommend her bread or toasts.</p><p>The goal of the process is then filling those zeros with some sortable value to recommend Alice products that she has never bought and may be interested in.</p><p>As mentioned above, matrix factorization is based on taking this purchase matrix and transforming it into a product of two smaller matrices called latent vectors. Once we have these two matrices, we multiply them and obtain an approximate matrix to the original one but with variations that will allow us to rank the products that had 0 as value.</p><p>We are not going to enter in details about how matrix factorization works as it exceeds the scope of this article, but you can visit <a href="https://towardsdatascience.com/recommendation-system-matrix-factorization-d61978660b4b">this link</a> where it is explained in detail.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/760/1*xWOrN-NFg2u2lI5xfcoTaA.png" /></figure><p>In the resulting matrix above we can see that the bread and toasts score is very tiny in the Alice vector due to the low correlation between Alice and Carol. Eggs, however, have a significant score and would be recommended.</p><p>In the heatmaps below, we can see the original matrix and the recomposed one with the potential recommendations.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/740/1*-7cwPhXaO_AC_k9mZPPGcQ.png" /></figure><p>As mentioned earlier, eggs have a significant score versus bread and toasts that are close to zero.</p><p>By sorting the products by value and applying a threshold we get the final product recommendations.</p><h3>Conclusions 📓</h3><p>Customer oriented recommendations are a great and poweful tool in e-commerces. The client discovers new products that he might interested in taking in account the decisions of others with similar tastes to them.</p><p>Since the release of the recommendations in our home page, our customers have been adding around 4 products in average (products they never had bought before!). And the number of items added from this page have experienced a 15% increase 🚀.</p><p>In conclusion, our clients are finding new products they didn’t know about and are taking them home. Easier and faster purchases is all about!</p><p>More work is needed <em>tho</em>, we will continue to improve our recommendation systems to get our customers what they want, wherever and whenever they want (great goals).</p><p>This recommendations series ends here 😞 (more or less). The next and last article will bumble around the infrastructure hardships that building our recommendation systems implied. And the important figure of machine learning engineers in the new world of big data. Have fun and a good day 😄!</p><h3>Previous articles 🗒</h3><p><a href="https://medium.com/mercadona-tech/recomendations-i-a-scary-tale-about-vanishing-ghosts-35c69aa389be">Recommendations I — A scary tale about vanishing ghosts</a></p><p><a href="https://medium.com/mercadona-tech/recommendations-ii-a-twisted-tale-about-twin-products-3e4759add440">Recommendations II — A twisted tale about twin products</a></p><h3>Next articles 🗒</h3><p><a href="https://medium.com/mercadona-tech/recommender-iv-a-tale-about-data-roles-b748af03e6fd">Recommendations IV — A tale about data roles</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1afd4a44f93d" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mercadona-tech/recommendations-iii-a-flavored-tale-about-similar-tastes-1afd4a44f93d">Recommendations III — A flavored tale about similar tastes</a> was originally published in <a href="https://medium.com/mercadona-tech">Mercadona Tech</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Recommendations II — A twisted tale about twin products]]></title>
            <link>https://medium.com/mercadona-tech/recommendations-ii-a-twisted-tale-about-twin-products-3e4759add440?source=rss-ec5217ef227e------2</link>
            <guid isPermaLink="false">https://medium.com/p/3e4759add440</guid>
            <category><![CDATA[ecommerce]]></category>
            <category><![CDATA[product-design]]></category>
            <category><![CDATA[recommendations]]></category>
            <category><![CDATA[product]]></category>
            <category><![CDATA[recommendation-system]]></category>
            <dc:creator><![CDATA[Emilio Carrión]]></dc:creator>
            <pubDate>Wed, 16 Sep 2020 08:12:18 GMT</pubDate>
            <atom:updated>2020-11-30T11:30:13.125Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-pb4UVWEvM6e6w78c4Zp-w.jpeg" /></figure><h3>Recommendations II — A twisted tale about twin products</h3><p>Doing groceries is a really hard task! Usually our typical shopping adventure takes around <a href="https://pdfs.semanticscholar.org/181d/a6650ba1ae7421c31f311d87b15d1ec4f4ba.pdf">45 minutes</a> and getting there has its cost too, reaching the supermarkets takes around <a href="https://www.eijtur.org/pdf/volumes/eIJTUR-9-1-2_Hamrick_Hopkins.pdf">15 minutes</a> more in average.</p><p>So we spend about an hour (more or less) around <a href="https://www.creditdonkey.com/grocery-shopping-statistics.html">1.5 times a week</a> doing groceries (so about 53 hours a year 🙀). This can be a problem to some of our customers. And that’s one of the reasons why we decided to handle this e-commerce <em>thingy</em> from bottom-up and offer a full online Mercadona experience that can provide you what you need wherever and whenever you need it.</p><p>That’s why we have built our platform around this idea, quoting <a href="https://medium.com/mercadona-tech/recomendations-i-a-scary-tale-about-vanishing-ghosts-35c69aa389be">the previous part of this series</a>:</p><blockquote><em>In </em><a href="http://mercadonatech.es/"><em>MercadonaTech</em></a><em> we have the vision to build a platform that allows the customer to do their groceries as fast as possible and save their time to spend on something more interesting.</em></blockquote><p>In this tale we will talk about another one of our systems that is in charge of recommending products that are related between them.</p><p>This time <em>tho</em>, this product adventure will be a little different, we will focus less in the trip itself and we will go deeper into the <em>mathemagic</em> 🧙 involved.</p><p>So be ready for some numerical bumps and enjoy!</p><h3>Time is gold 💰</h3><p>This may sound a little repetitive but this is really really important to us. You may suspect that some retailers <a href="https://www.wsj.com/articles/the-slower-you-shop-the-more-you-spend-1445359614">want you to spent as much time as possible</a> purchasing in their stores. E.g. changing the product placements from time to time to make you look more around or making you follow a path that tours through all their catalog inside a wooden maze (🇸🇪). All in order to trick you and lure you into purchasing things that you may not really need (we all have fallen into this sometime).</p><p>Our business model goes totally in the other direction. We work hard to help you make your weekly or monthly groceries purchase as easy and simple as it can get. We are talking here about a regular purchase of essential things like food or care products, not whims or souvenirs. You want to purchase what you need for you and your family, and we help you get it the easiest way possible. Our wish is that you get all you need and that you return next month to trust us once again.</p><h3>Discoverability 🔍</h3><p>For you to find all you need in the less time possible some things are important to take in account. A big deal in an e-commerce is the discoverability of products you don’t know yet but you may be interested in.</p><p>Many times the discoverability of this products is based on analyzing and recommending the different variants it has or comparing those that may be related to it.</p><p>For a more visual representation about what we are trying to accomplish, we have prepared an example of two purchases. These purchases contain both milk and eggs. In one of them a customer bought bread and in the other one some other customer bought toasts.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IhfCAY6EQBOXX_8Gjuog-w.png" /></figure><p>The aim in this example would be to relate the bread with the toasts as they are usually bought together with milk and eggs, so they are bought in a similar context.</p><p>By recommending products that are bought in similar purchases we help the user find products that belong to a similar context and that may be of interest to them. The objective is to group together items that have been purchased in orders of similar composition. In other words, products that have been bought together with the same set of products. This allows us to recommend similar products that may not have been purchased together.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*28zrBqBt-k02Fht__Q9-Hw.png" /></figure><p>These recommendations should not be confused with the cross-selling functionality used by other platforms. We are not looking to sell complementary products related to the first one, instead we strive to offer the users more variety and allow them to discover new products they didn’t know about (like different types of croquettes 😋).</p><h3>The maths 🧮</h3><p>Here is where things start to going <em>mathy</em>. If you don’t have a strong algebraic background do not worry, we’ll try to explain the magic behind it as easy as possible with trivial and self-explanatory examples. You only need to read it carefully and <a href="https://www.linkedin.com/company/mercadonatech/">LinkedIn</a> us if you have any trouble 😊.</p><h4>Cooccurrence matrix</h4><p>To sum up before we start, we seek to find products whose relationship to other items is similar. We are not trying to find products that are usually bought together but we are looking to recommend products that are purchased in similar contexts. Like if you are looking at a pizza we will want to recommend you products that are usually bought in similar purchases, like other pizzas or other kind of prepared food (let’s prepare that party 😎).</p><p>To do this, the first step is to group products by purchase. The easiest way is to count how many times every product has been purchased with each other to know in how many purchases they have coinicided. This is called <a href="https://stackoverflow.com/a/24076711">the coocurrence matrix</a>. It will tell us for each of the products how many times it has been purchased with the rest of the catalogue.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1007/1*_78ii4GK5DtnF7x2mmHhqQ.png" /><figcaption>Coocurrence matrix (left), Coocurrence matrix w/ diagonal 0 (right)</figcaption></figure><p>Starting from the sample purchases presented in the previous section, we can check the resulting coocurrence matrix in the image above. You can clearly see that the bread has been bought once with the eggs and milk and the same with the toasts.</p><p>In the example, we can also see that we have represented the matrix in two ways, one of them counting the coincidence of a product with itself and in the other one setting to 0 the diagonal of the matrix, making that a product cannot coincide with itself. In the next section we will see the importance that these values have in the calculation of the related products.</p><h4>Cosine similarity</h4><p>Once we have the vectors that represent the coincidences of a product with the rest of the catalogue, we will relate the products that have similar vectors to each other. The more similar the vectors are, the more similar the products will be.</p><p>For this we use the <a href="https://en.wikipedia.org/wiki/Cosine_similarity">cosine similarity</a> of the vectors which calculates the cosine of the angle formed by the two vectors. The closer the value is to 1, the more related they are. This is just a way of calculating the difference between each of the products.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/753/1*O808OH_7bZV1ggmK7evEow.png" /><figcaption>Cosine similarity (left), Cosine similarity w/ diagonal 0 (right)</figcaption></figure><p>In the heat maps above 🔥, we see the results of calculating the cosine similarity between the vectors that define each product. The lighter the color, the more related the products are.</p><p>We see that in the first image the result relates equally the bread to milk and eggs, and to a lesser extent to toast. This happens because they have been sold together and they both are well-selling products (they appear in both purchases).</p><p>However, in the second heat map we see how bread is strongly related to toasts instead of milk and eggs that are in second place. We achieve this by eliminating the coincidences of products with themselves (setting the diagonal to 0) and thus discriminating the most sold products that appear in a passive way in all purchases.</p><p>By sorting the products by similarity and applying a threshold we get related products with production ready results 🙌!</p><h3>Results 🗒</h3><p>Helping our customers to discover new products helps them to make their groceries in less time. Our average customer adds around 3–4 products from related products in every purchase. Items that are added throught organic navigation instead of losing time looking for them.</p><p>We also observed that customers that add items from related products tend to have bigger carts, indicating that they find new products that are interesting to them, helping them discover new tastes (cod croquettes are a thing).</p><h3>Conclusions 📓</h3><p>Time is important for our customers. <a href="https://research.clicktale.com/web_analytics_benchmarks.html">Studies</a> have shown that a better discoverability of products in a e-commerce is key. Bad user experience and difficulties looking for products make customers ditch the store before having the chance of finding what they are looking for 😔. That means lost time for the customer and a lost sale for the e-commerce.</p><p>The little details are what make an e-commerce great. We strive to provide the best purchasing experience possible and related products is one of the features that make this possible.</p><p>This tale has reached its end, but our efforts don’t end here. Our main recommendation system (the one that handles the heavy stuff in our home) lays hidden waiting for you all in the next article of this series. Stay tuned 📻!</p><h3>Previous articles 🗒</h3><p><a href="https://medium.com/mercadona-tech/recomendations-i-a-scary-tale-about-vanishing-ghosts-35c69aa389be">Recommendations I — A scary tale about vanishing ghosts</a></p><h3>Next articles 🗒</h3><p><a href="https://medium.com/mercadona-tech/recommendations-iii-a-flavored-tale-about-similar-tastes-1afd4a44f93d">Recommendations III — A flavored tale about similar tastes</a></p><p><a href="https://medium.com/mercadona-tech/recommender-iv-a-tale-about-data-roles-b748af03e6fd">Recommendations IV — A tale about data roles</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3e4759add440" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mercadona-tech/recommendations-ii-a-twisted-tale-about-twin-products-3e4759add440">Recommendations II — A twisted tale about twin products</a> was originally published in <a href="https://medium.com/mercadona-tech">Mercadona Tech</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Recomendations I — A scary tale about vanishing ghosts]]></title>
            <link>https://medium.com/mercadona-tech/recomendations-i-a-scary-tale-about-vanishing-ghosts-35c69aa389be?source=rss-ec5217ef227e------2</link>
            <guid isPermaLink="false">https://medium.com/p/35c69aa389be</guid>
            <category><![CDATA[product]]></category>
            <category><![CDATA[recommendations]]></category>
            <category><![CDATA[recommendation-system]]></category>
            <category><![CDATA[product-design]]></category>
            <category><![CDATA[ecommerce]]></category>
            <dc:creator><![CDATA[Emilio Carrión]]></dc:creator>
            <pubDate>Wed, 26 Aug 2020 08:50:25 GMT</pubDate>
            <atom:updated>2020-11-30T11:29:16.781Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Pejwe8pKYR2Lm4Qz4kqLsg.jpeg" /></figure><h3>Recommendations I — A scary tale about vanishing ghosts</h3><p>Much of the online shopping experience today is enhanced by opportunities to explore new products. At <a href="http://mercadonatech.es/">MercadonaTech</a> we have a centralized system called recommender that calculates different types of recommendations oriented to a wide variety of areas to provide you the best purchasing experience.</p><p>We have the vision to build a platform that allows the customer to do their groceries as fast as possible and save their time to spend on something more interesting. Our goal is to be able to do the purchase for you, and so, the groceries would just show up magically at your home ✨. Recommender is one of the first steps in that direction.</p><p>In an effort to show some of our product adventures (let’s call them tales from now on) and how we deliver recommendations value to the customer in a lean way we wrote four articles talking about some interesting case studies that we pulled out (they are really interesting believe me).</p><p>In this first article we will talk about how a logistic problem that affected thousands of customers every month was solved with a simple implementation that brought quick value and a great purchasing experience improvement.</p><p>Be comfortable, grab some popcorn 🍿and enjoy the trip.</p><h3>Ghost products 👻</h3><p>Despite our best efforts, unfortunately we can not maintain the full catalog of products throughout the year. For example, there are seasonal products or changes in their format or characteristics. Or just sometimes we change the provider for a given class of product and so the old version you put in your cart is discontinued. Therefore, occasionally there are cancellations of products that may affect the active cart of some users 😢. Some examples are seasonal package changes like coca-cola does, product improvements that change the article’s reference or temporal products that are removed after an event ends (like Christmas products).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/728/1*hzH0WUwVkZ4hIFod_roj2g.png" /></figure><p>This implies that customers can have discontinued products in their active cart. Products that are cleaned out in the checkout process due to their current status. The client added them to their cart and wanted them but due to catalog changes they are not available anymore. This flux cause cart lines to disappear between the phase of building your cart (that can last from days to weeks because of the nature of our ecommerce) and the phase of creating the checkout. This vanishing products then are acting as a spirit disappearing the morning after Halloween 🎃. We call these entities ghost products (so spooky).</p><p>This is a double edged sword. On the one hand we are losing potential sells and the other hand (and most important) we are not delivering the customer all the products they want and they think they have bought. That is a big problem.</p><h3>First steps 🐣</h3><p>Our first step in our lean journey dealing with ghost products was simply to alert the customers about it. Alert them that some of the products in their active cart were discontinued and no longer available so they would not pass the checkout process.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/720/1*mXj5wz7UOJnOuVvHGCtzSA.png" /></figure><p>This alert allowed the customers to be aware of the incidences in their carts and have an opportunity to manually substitute the discontinued products by similar ones from the current catalog.</p><p>This quickly contributed to reducing the number of ghost products that were being cleaned out in the checkout process, bringing great value to both the customers and us (yaay!).</p><p>With only this change we reduced the ghost products arriving to the checkout process on an amazing 60%!</p><h3>The not so lean detour 🚵</h3><p>Once we got the customers aware of the problem the next logical step was to offer them tools to handle it. Substitute the products manually searching similar ones in the catalog was not the best experience and could be improved greatly with a helping UI powered by some intelligence behind the scenes.</p><p>Our plan was to recommend customers products that were similar to the ones that were discontinued, sorted by similarity and with ease to be swapped with the troubled ones. Wasn’t that an amazing plan? 🤯</p><p>In a short break from our lean adventure, some developers (and a Product Manager 🤷🏻‍♂️) went to the <a href="https://www.bigthingsconference.com/">BigThings conference</a> in Madrid. That gave us some free time between talks and in our train journey back to make a short but intense hackathon where we tried to face the problem and experiment a little bit with reinforcement learning.</p><p>We developed and deployed a funny website where we were shown two products from the same category. Then we were asked to confirm if we would substitute the first with the second or not. The idea was that with enough data and a clever algorithm like the multi-armed bandit we would be able to score and suggest similar products to one given.</p><p>Spoiler alert, was funny but not so useful (yet 🤔). The result of the experiment was not to have the required amount of data to build an usable system. Having +9000 products in our catalog did not make it easy but it was fun to share with our colleagues at the office and sort some products together. As an incentive it shown a random meme from our internal office meme pool (yes, we have one) every time you interacted with it so at least we had some laughs.</p><h3>Back to work 💪</h3><p>Coming back to our lean journey we took the problem seriously and we tried to bring some quick value to the customer.</p><p>We had some clues about how to tackle it. We knew that we only had some basic info about the products (topic that we will talk about in a couple of tales) but it seemed enough for this task. We had available data like the name, the price and the category, so we went easy.</p><p>We implemented a trivial scoring system that made use of the <a href="https://en.wikipedia.org/wiki/Levenshtein_distance">levenshtein distance</a> (that calculates the number of differences between two text strings). Two items would be similar if the levenshtein distance of their names was lower than a threshold. Sorting all similar candidates by ascending order got us acceptable results.</p><p>With some UI love from our wonderful designer and our beloved Product Manager we finally got a tool for the customers to substitute discontinued products with similar ones that would do the work.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*rtFi7EVyuafyshoBo9cXxA.gif" /></figure><p>But this was only an alpha. By the time this implementation reached production we already had outlined a stronger, more robust (and again really trivial 😅) algorithm to rule all future substitutions.</p><p>This new algorithm groups similar products tokenizing and comparing the name of the products. The tokenization process is really simple. It removes the brand and stopwords (irrelevant words like “the”, “and”, etc) then converts all words to lowercase and creates a set from them. Then calculates the size of the intersection between the sets of tokens that compose the different products inside the same category.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CfVwqwIPy8asyh4dFpmPYw.png" /></figure><p>In the example above the products’ similarity score would be 2, as the intersection of tokens has a length of 2.</p><p>By ordering the products according to the number of tokens they have in common and applying a threshold, we manage to show products similar to the discontinued ones. So awesome and simple.</p><p>With this trivial process and some infrastructure magic that you will read about in the fourth part we have managed to deliver great value to our customers and to our dear ecommerce.</p><p>To give some results we currently have a 28% conversion rate. That means that nearly 1 every 3 products that are checked to be substituted are swapped by a similar one.</p><h3>Next steps 👣</h3><p>The similar products recommendation system currently works as expected and it works really well, we are very happy with it. But as a team with a strong data background we can not let it rest there. Remember the experiment we made in the hackathon? The problems with the amount of data and the “yet 🤔” inside brackets in the value contribution result? Well, it happens that we finally have enough data! The system has been working for a few months now and the people have been hungrily substituting products non stop. A multi-arm bandit reimplementation seems not a far reality in the short-middle term. We will keep you updated about it!</p><h3>Conclusions 📓</h3><p>As already mentioned, working in a product focused team is really fun. We face challenges every day where we innovate, experiment and have fun. We are able to follow a lean methodology that brings great value to our customers with small and iterative steps that never stop.</p><p>This tale about ghosts and forgotten products has taught us that we are able to bring real value to our customers with little changes that slowly accumulate to make our product what it is today.</p><p>Unfortunately this tale finishes here, but don’t be sad! This recommendations trip doesn’t end yet, we have three more wonderful tales to tell and you are more than welcome to keep going with us in this amazing journey.</p><h3>Next articles 🗒</h3><p><a href="https://medium.com/mercadona-tech/recommendations-ii-a-twisted-tale-about-twin-products-3e4759add440">Recommendations II — A twisted tale about twin products</a></p><p><a href="https://medium.com/mercadona-tech/recommendations-iii-a-flavored-tale-about-similar-tastes-1afd4a44f93d">Recommendations III — A flavored tale about similar tastes</a></p><p><a href="https://medium.com/mercadona-tech/recommender-iv-a-tale-about-data-roles-b748af03e6fd">Recommendations IV — A tale about data roles</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=35c69aa389be" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mercadona-tech/recomendations-i-a-scary-tale-about-vanishing-ghosts-35c69aa389be">Recomendations I — A scary tale about vanishing ghosts</a> was originally published in <a href="https://medium.com/mercadona-tech">Mercadona Tech</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>