<?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 Sid Arcidiacono on Medium]]></title>
        <description><![CDATA[Stories by Sid Arcidiacono on Medium]]></description>
        <link>https://medium.com/@sid-arcidiacono?source=rss-77c814d7979d------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*PAND-LLbMw0jQVwcOnUC0g.jpeg</url>
            <title>Stories by Sid Arcidiacono on Medium</title>
            <link>https://medium.com/@sid-arcidiacono?source=rss-77c814d7979d------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 15:55:25 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@sid-arcidiacono/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[Let’s Talk: The Ethical AI Conversation, and How Biotech Is Failing]]></title>
            <link>https://medium.com/data-science/lets-talk-the-ethical-ai-conversation-and-how-biotech-is-failing-a1dcfd63aba1?source=rss-77c814d7979d------2</link>
            <guid isPermaLink="false">https://medium.com/p/a1dcfd63aba1</guid>
            <category><![CDATA[fairness-and-bias]]></category>
            <category><![CDATA[biotechnology]]></category>
            <category><![CDATA[editors-pick]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[data-science]]></category>
            <dc:creator><![CDATA[Sid Arcidiacono]]></dc:creator>
            <pubDate>Fri, 20 Aug 2021 19:52:30 GMT</pubDate>
            <atom:updated>2021-08-23T19:38:59.119Z</atom:updated>
            <content:encoded><![CDATA[<h4><a href="https://towardsdatascience.com/tagged/fairness-and-bias">Fairness and Bias</a></h4><h4>How companies are pouring millions into AI solutions that cause more harm than good</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*ygRFvDBPF38mFozB" /><figcaption>Photo by <a href="https://unsplash.com/@nci?utm_source=medium&amp;utm_medium=referral">National Cancer Institute</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>In 2019, I was entrenched in volunteer work at a small free clinic in North Hollywood, California. Actually in pursuit of my California phlebotomy (blood drawing) credential, my goal was to continue work in clinical settings, and to finish my degree to become a doctor. I wanted, like many of us, to help patients — to make a positive difference in the lives of <em>people.</em></p><p>It was not very long after that I discovered computer science, artificial intelligence, and biotechnology. Hooked on the idea and disillusioned with a traditional academic path, I jumped at the opportunity to join a startup-like college in San Francisco, accelerate my degree path, and <em>get into tech</em>. It was all so shiny and promising. Papers on top of papers were being published with titles like <a href="https://www.genengnews.com/insights/trends-for-2020/artificial-intelligence-is-helping-biotech-get-real/">“Artificial Intelligence Helping Biotech Get Real”</a>, <a href="https://optellum.com/2021/04/ai-breakthrough-could-speed-up-lung-cancer-diagnosis-and-save-the-nhs-millions/">“AI Breakthrough Could Speed Up Lung Cancer Diagnosis …”</a>, and many, many more. Months into pursuit of my new, shiny degree, I was doing aggressive research into the field, and even had begun working in it.</p><p>Pause. The Covid-19 pandemic seemed to accelerate the AI diagnostic space, with <a href="https://www.technologyreview.com/2021/07/30/1030329/machine-learning-ai-failed-covid-hospital-diagnosis-pandemic/">poor results</a>. Venture capitalists, large investment firms, academic organizations, and big pharma continued to pour millions into so-called “AI focused biotech” startups. While large conference platforms seem to always accept a single keynote speaker on fairness or ethics in AI (mostly focused on disparate outcomes between demographic groups — a crucial part of the conversation, but a part nonetheless), my LinkedIn feed, industry contacts, and tech-news outlets served crickets on the conversation of ethical standards for the artificial intelligence boom. The biotechnology companies themselves continued to post job openings for subject matter expert “Data Scientists”, leaving no space in the room for anyone without a laser-focused Ph.D. dissertation, anyone who might have less of a stake in innovation for innovation’s sake, anyone willing to stand in the corner and ask the crucial question:</p><p><strong>“We can, but <em>should we?</em>”</strong></p><h4>Building Systems Designed for Failure</h4><p>Physicians swear an oath to “first do no harm”, but professionals falling under the ubiquitous umbrella of bioinformaticians, data scientists, and machine learning engineers swear no such oath.</p><p>Instead, when we’re hired, we market ourselves based on metrics. Biotechnology companies may have noble missions, but are still profit-driven companies focused on <em>what value you bring them</em> from a hard-number standpoint. As data practitioners, we are not selling our talents based on how fuzzy and warm we made a patient or their family feel through the promise of a technology we developed, we sell ourselves based on the percentage of test-data oncology biopsy slides our algorithm correctly identified as pre-cancerous (for example). Not to mention: assuming a technology we create gets to the “wild”, that patient and their family have no idea how our tech works. It’s up to us to be honest about how much it can really be trusted — and that kind of honesty doesn’t often get us far in our careers, or get us published or recognized.</p><p>If you’re clamoring for a better, real world example of a potentially devastating and dramatic failure, take IBM’s “Watson for Oncology” project. After a $62 million dollar investment, <a href="https://www.statnews.com/2018/07/25/ibm-watson-recommended-unsafe-incorrect-treatments/">studies found that the recommendations made by the so-called “supercomputer” were often potentially deadly</a>. The project inevitably was rolled back, a loss.</p><p>Or, read <a href="https://www.technologyreview.com/2021/07/30/1030329/machine-learning-ai-failed-covid-hospital-diagnosis-pandemic/">this article</a> I linked earlier on the hundreds of Covid diagnostic applications that were proven to do more harm than good.</p><p>“AI for healthcare” is a term with so much potential and almost palpable kinetic energy that many of us practitioners feel galvanized to become a part of it. The truth of the matter seems to be that in many cases, AI technologies are a cry for help — <a href="https://www2.deloitte.com/us/en/insights/industry/life-sciences/rise-of-artificial-intelligence-in-biopharma-industry.html">the world of R&amp;D is increasing its pace, and large, slow-moving scientific companies <em>need</em> an accelerator to keep up</a>. The promise and potential of automation, accelerated discovery, fast triaging, and lowering costs for radiological, pathology, or diagnostic services are just too good to pass up. The sadder part of this truth, though, is that most of our technology <a href="https://www.healthcareitnews.com/news/ai-healthcare-not-so-fast-study-outlines-challenges-dangers-machine-learning">just isn’t ready for clinical use</a>. How honest we are about this seems to be contingent on how dramatically we need to increase profit margins, impress investors, or keep up with the multi-billion dollar “Joneses” to maintain a name in industry.</p><h4>Taking it Back to Move Forward: Building Better Systems</h4><p>What good scientists know is that good science takes time. The mavericks of medical innovation maintained equilibrium with the traditional academics who understood that sometimes you can try something new, but you shouldn’t try just for the sake of trying: not when there’s a patient on the table.</p><p>Biotech company CEOs, investors, machine learning engineers, data scientists, bioinformaticians, data analysts, data engineers, you get the point: we don’t <em>see those patients on the table</em>. Abstraction can be a tricky thing. It allows us to take bold steps forward, but simultaneously enables us to be bolder than we would, did we have to look into the eyes of the human being who may be put on a ventilator unnecessarily because of poorly designed Covid-19 triaging software. Or given drugs that increase bleeding because of a poor recommendation from an algorithm, or testing a new drug and dealing with severe adverse reactions, and so on.</p><p><a href="https://www.labiotech.eu/in-depth/history-biotechnology-genentech/">The beginnings of the so-called “biotech” industry as we know it roughly four decades ago</a> made us — the tech people — practitioners in a sacred space, right along with the clinicians who see, in the flesh, the impact of their work, <em>and now ours.</em> We need oaths — we need to develop systems with ethics in mind, from the very beginning.</p><p>In every brainstorming meeting you have with your team, you need to have someone in the corner who isn’t wrapped up in the rat race of their own career, or focused on improving potential quarterly profit margins. Biotech, in a nutshell, cannot remain what it is: money hungry, innovative for the sake of innovation and publication, full of hubris and over-trusting of the programs we develop, of the buzzwords “deep learning” and “AI”.</p><p>We need industry-wide ethical standard operating procedures. We need someone in the corner who will ask us:</p><p><strong>“We can do this, <em>but should we?</em>” </strong>without fear of reproach.</p><p>In the long run, the ethical conversation is the best one you can have for your company, even if it’s sacrificial of short-term press-release glory or temporary product hype. More importantly, the ethical conversation is the best one you can have for any potential future patients impacted by your product or innovation.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a1dcfd63aba1" width="1" height="1" alt=""><hr><p><a href="https://medium.com/data-science/lets-talk-the-ethical-ai-conversation-and-how-biotech-is-failing-a1dcfd63aba1">Let’s Talk: The Ethical AI Conversation, and How Biotech Is Failing</a> was originally published in <a href="https://medium.com/data-science">TDS Archive</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Intro to Docker ]]></title>
            <link>https://sid-arcidiacono.medium.com/intro-to-docker-95e46d901798?source=rss-77c814d7979d------2</link>
            <guid isPermaLink="false">https://medium.com/p/95e46d901798</guid>
            <category><![CDATA[docker]]></category>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[mlops]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[computer-science]]></category>
            <dc:creator><![CDATA[Sid Arcidiacono]]></dc:creator>
            <pubDate>Thu, 22 Jul 2021 22:23:39 GMT</pubDate>
            <atom:updated>2021-07-22T22:23:39.003Z</atom:updated>
            <content:encoded><![CDATA[<p>Docker is a containerization tool that’s becoming more and more widely adopted in industry because of the ecosystem of services it’s compatible with, its relative ease of use, and its availability of support. But what <em>is </em>containerization, and why do we use it?</p><p>In the wise words of Wikipedia, Docker is:</p><blockquote>an open-source project that automates the deployment of software applications inside <strong>containers</strong> by providing an additional layer of abstraction and automation of <strong>OS-level virtualization</strong> on Linux.</blockquote><p>Let’s clear this up a bit.</p><h3>Why Containers? 📦</h3><p>Using a service like Docker to put applications and programs into <em>containers </em>has the primary purpose of maintaining a consistent machine environment for an application or piece of software, no matter what server it lives on — on-premise, cloud, what OS the server has, and so on. There are a few other adjacent benefits, but for now, let’s keep it simple: Docker packages our code and dependencies, so that we can maintain a consistent machine environment for our software.</p><p>You might be asking (and you’d be right to ask) — what’s the difference between Docker and a Virtual Machine, then? Why wouldn’t I just spin up a VM for my code, and call it a day?</p><p>While a VM achieves the goal of sandboxing software and its dependencies inside an isolated environment, it does so at a cost. The computational cost of virtualizing an entire machine is pretty high. The Docker <a href="https://docker-curriculum.com/">curriculum </a>expresses how Docker is different (better than I can):</p><p><em>Containers take a different approach: by leveraging the low-level mechanics of the host operating system, containers provide most of the isolation of virtual machines at a fraction of the computing power.</em></p><p>For conceptual purposes, you can think of a Docker container like a compact version of a VM — a sandbox environment that only uses what it needs of a virtual OS to run your software.</p><p>Containers make deployment easy, reproducible, and standardized. This is why we like them.</p><h3>Taking a Step Back 👣</h3><p>Now that we understand what containers are, what Docker is, and why we care, let’s take a step back and set some expectations. In this article, we’ll:</p><ul><li>Go over some important terminology you’ll encounter when working with Docker; like containers (check! ✅), images, and registries</li><li>Walk through installing Docker on Linux</li><li>Go through basic Docker commands to familiarize ourselves with those we’ll use most often</li></ul><h3>Wait, What’s an Image? 🖼</h3><p>Let’s use the analogy of a container ship on the ocean to get the hang of our terminology. One container ship holds many different containers from a variety of companies, and each container is full of goods. Let’s zoom in on one container. This container holds a specific amount of specific kinds of goods, and they didn’t get there on accident. Someone at the company shipping this container laid out for workers what should go inside it.</p><p>An image is the person who tells the workers what to pack in the container. In other words, it’s like a blueprint for containers to be built off of. If you’re familiar with data terms, an image has a one-to-many relationship with all containers based off of it — many containers can be spun up off of a single image.</p><h3>What About a Registry? 🗂</h3><p>Well, I know this is a lot of terms, but registries (also called <em>image registries, container registries, or image repositories </em>depending on the cloud services you use) are actually pretty straightforward. If we have a lot of software, we’re likely going to need somewhere to store all of the blueprints.</p><p>So, if our images are our blueprints, our containers are our running sandboxed applications, our registries are kind of like a bookshelf or a filing cabinet that hold our images. This allows us to pull our own images, or, if your projects are open source, for others to pull your images and be able to spin up an instance of your application on their own machine without needing to worry about installing any dependencies or configuring their environment at all (aside from just having Docker installed).</p><p>Before we move on, take a look at the diagram below to get familiar with the terms we’ve just talked about.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EVRyG6VkJQxj5F8oV-aKrA.png" /><figcaption>Image courtesy of <a href="http://docs.microsoft.com/">source</a>.</figcaption></figure><h3>Setting up Docker ⚓️</h3><p>While Windows and Mac allow a desktop download, most Ubuntu distros don’t have a GUI. This tutorial will walk you through setting up Docker on Ubuntu, which will be useful for deployment within Linux VMs. If you have a Windows or Mac machine, check out the links below to get Docker set up, then catch back up with us in the next section.</p><p>For Windows, use <a href="https://docs.docker.com/docker-for-windows/install/">this resource</a>.</p><p>For Mac, use <a href="https://docs.docker.com/docker-for-mac/install/">this resource</a>.</p><p>Pull up terminal on your Linux machine, and run update before installing anything:</p><p>$ sudo apt update</p><p>You can also run upgrade after, to be sure you’re up to date with installed packages:</p><p>$ sudo apt upgrade</p><p>If the kernel doesn’t upgrade, you’re good to move on. If it does, reboot with:</p><p>$ sudo reboot</p><p>Afterwards, we can install Docker:</p><p>$ sudo apt install docker.io</p><p>If you have any issues installing the docker.io package, check out the below resources to troubleshoot:</p><ol><li><a href="http://docker.io/">Docker docs</a></li><li><a href="https://www.linux.com/topic/desktop/how-install-and-use-docker-linux/">Linux.com</a></li></ol><p>You can check that Docker was successfully installed with:</p><p>$ sudo docker --version</p><p>But why do we have to use sudo?</p><p>Docker out of the box requires admin permissions. For security reasons, you don’t always want to use Docker as the root user or always have to use sudo. The following steps take you through setting up a user to use with Docker, and then rebooting.</p><p>$ sudo usermod -a -G docker $USER</p><p>Once you’ve run this, log out and back in and try running:</p><p>$ docker --version</p><p>to check that permissions have changed. If they haven’t you’ll receive an error.</p><p>Now, try running Docker’s “Hello World” image to verify your install:</p><p>$ docker run hello-world</p><p>Nice! If that was successful, we’re ready to chat about some Docker commands.</p><h3>Docker Commands 📃</h3><p>There are a few Docker commands you’ll use often and want to know. For a comprehensive list of all commands and links to more details on them, check out the <a href="https://docs.docker.com/engine/reference/commandline/docker/#:~:text=Child%20commands%20%F0%9F%94%97%20%20%20%20Command%20,%20Manage%20contexts%20%2039%20more%20rows%20">Docker documentation</a>.</p><ul><li>run</li><li>build</li><li>exec</li><li>logs</li><li>ps</li><li>images</li></ul><p>Let’s start with build. The syntax for build is:</p><p>$ docker build [OPTIONS] PATH | URL | -</p><p>build builds a docker image from a Dockerfile and what’s referred to as a <em>context</em>. A context can be your project directory, a GitHub repository, and more, depending on what options are specified and if you provide a URL.</p><p>Docker run runs a container based off of a built image (there’s a little more to it than that, but you don’t have to worry about that for now. Check the docs if you’re interested). It’s syntax is as follows:</p><p>$ docker run [OPTIONS] IMAGE [COMMAND] [ARG...]</p><p>Some options commonly provided to run are port mappings, volumes, detach, and so on.</p><p>Docker ps allows you to list the containers on your machine. Providing the -a flag allows you to see both running and stopped containers.</p><p>$ docker ps [OPTIONS]</p><p>Similarly, Docker images allows you to list the images on your machine:</p><p>$ docker images</p><p>Docker logs provides you with logging output for running containers, which is valuable for debugging and troubleshooting. The syntax is as follows:</p><p>$ docker logs [OPTIONS] CONTAINER</p><p>Here, CONTAINER can either specify a container name or ID, both provided in the output of docker ps.</p><p>A common use for docker logs is:</p><p>$ docker logs --follow my-container</p><p>The --follow option tells the logs to stay up and auto-update with new data as the container application is running.</p><p>Finally, Docker exec runs a new command in a running container.</p><p>$ docker exec [OPTIONS] CONTAINER COMMAND [ARG...]</p><h3>Wrapping Up</h3><p>Hopefully now you feel like you have a better understanding of what Docker is, why we use it, and how to get things set up and running on your own machine. We’ve covered:</p><ul><li>Important terminology you’ll encounter when working with Docker; like containers, images, and registries ✅</li><li>Installing Docker on Linux ✅</li><li>Basic Docker commands to familiarize ourselves with those we’ll use most often ✅</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=95e46d901798" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Classifying the PROTEINS Benchmark Dataset]]></title>
            <link>https://medium.com/data-science/classifying-the-proteins-benchmark-dataset-ec18e728a17a?source=rss-77c814d7979d------2</link>
            <guid isPermaLink="false">https://medium.com/p/ec18e728a17a</guid>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[graph-neural-networks]]></category>
            <category><![CDATA[deep-learning]]></category>
            <dc:creator><![CDATA[Sid Arcidiacono]]></dc:creator>
            <pubDate>Mon, 17 May 2021 01:59:35 GMT</pubDate>
            <atom:updated>2021-05-17T23:28:00.293Z</atom:updated>
            <content:encoded><![CDATA[<h4>Two ways to implement Graph Convolutional Networks</h4><p><em>This is part four in a series on graph theory and graph convolutional networks.</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_UKdazyQe2cIdY5VcTX46g.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/@photoholgic?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Photoholgic</a> on <a href="https://unsplash.com/s/photos/science?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><p>If you’ve been reading this whole series, you’ve been with me on this entire journey — through <a href="https://medium.com/mlearning-ai/why-graph-theory-is-cooler-than-you-thought-4df73e2a4950">discussing what graph theory is and why it matters</a>, what a <a href="https://medium.datadriveninvestor.com/graph-convolutional-networks-explained-d88566682b8f?source=your_stories_page-------------------------------------">graph convolutional network even is</a> and <a href="https://towardsdatascience.com/what-makes-graph-convolutional-networks-work-53badade0ce9?source=your_stories_page-------------------------------------">how they work</a>, and now we’re here, to the fun part — building our own GCN.</p><p>If you’re new to this series, that’s totally fine, too! In either case, let’s get coding!</p><p>For this tutorial, we’re going to be walking through two implementations of GCNs to classify the PROTEINS benchmark dataset. <em>If you want to find attribution or papers on this data, or download it to look at it yourself, you can find it </em><a href="https://chrsmrrs.github.io/datasets/docs/datasets/"><em>here</em></a><em> under the “Bioinformatics” heading. </em>You can also take a look at the whole notebook <a href="https://colab.research.google.com/drive/1W0syoaSSP-MpFhYC14cBV0O32Esyr_zF?usp=sharing">here</a>. Attributions for the code can be found in the <a href="https://github.com/sidneyarcidiacono/graph-convolutional-networks#readme">repository</a> for this project.</p><h4>Part I: GCNs with Spektral</h4><p>What is <a href="https://graphneural.network/">Spektral</a>? According to their homepage:</p><blockquote>Spektral is a Python library for graph deep learning, based on the Keras API and TensorFlow 2. The main goal of this project is to provide a simple but flexible framework for creating graph neural networks (GNNs).</blockquote><p>Getting started with Spektral is extremely easy because of the forethought put into the project — if you’ve done any modeling with Keras or Tensorflow, I think you’ll find Spektral quite intuitive.</p><p>Additionally, Spektral has many benchmark graph datasets built in, meaning that you avoid the fuss of needing to ensure your data is in the right format for modeling with GNNs, and can easily get started experimenting.</p><p>Whether you’re following this tutorial in Colab or just a plain ol’ Jupyter Notebook, our first step will be the same. Spektral is not one of the built-in libraries in Colab, so we’ll need to install it:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8ebe0430bd2a3463fc06ae958b485100/href">https://medium.com/media/8ebe0430bd2a3463fc06ae958b485100/href</a></iframe><p>PROTEINS is one of the benchmark datasets for graph kernals from TU Dortmund. You can access this class of datasets from the TUDataset class, which we access by first importing and then instantiating an object of it, with the name of which TUDataset we’d like to access passed in:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e9e922a735d13ac7d7bb11341d631675/href">https://medium.com/media/e9e922a735d13ac7d7bb11341d631675/href</a></iframe><p>When we load in our dataset, we can see how many graphs it contains in the n_graphs property. Here, we can see that this dataset has 1113 graphs. In this dataset, these are split into two distinct classes.</p><p>Spektral’s GCNConv layer is based off of the paper: “<a href="https://arxiv.org/abs/1609.02907">Semi-Supervised Classification with Graph Convolutional Networks</a>” by Thomas N. Kipf and Max Welling. This is perfect, as this is the paper we’ve been referencing if you’ve been following this series so far. If you haven’t, I’d recommend checking out the paper as well as my article on how these networks work to get a better grasp on what Spektral is doing for us behind the scenes!</p><p>Since this is the layer we want to use, we’re going to have to perform some preprocessing. Spektral makes this super easy with their GCNFilter class, which performs the preprocessing steps (outlined in the paper) for us in just two lines of code.</p><p>First, import GCNFilter from spektral.transforms , and then call .apply() on our dataset, passing in the instance of GCNFilter :</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d6182306518903553e861c4694ecfac4/href">https://medium.com/media/d6182306518903553e861c4694ecfac4/href</a></iframe><p>At this stage, we want to be sure to perform our train/test split. I do this by shuffling the data and then taking slices (about 80/20% respectively) for this simple example, but you’re welcome to optimize this step further once you get comfortable with this implementation!</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/aceef9b0f3b2396479de4cbee0aec77e/href">https://medium.com/media/aceef9b0f3b2396479de4cbee0aec77e/href</a></iframe><p>Now, let’s import the layers we’ll need for our model:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d11f7909a168a03778259676846dcc48/href">https://medium.com/media/d11f7909a168a03778259676846dcc48/href</a></iframe><p>Wait a minute — aren’t these import statements from Keras? Don’t worry — this isn’t by accident. Because Spektral is built on top of Keras, we can easily use the Keras functional API to build our model, adding in Spektral specific layers as we go to handle the graph-structured data.</p><p>We import Dense and Dropout layers — Dense is your typical dense neural network layer that performs forward propagation, and Dropout randomly sets input units to 0 at a rate which we set. The intuition here is that this step can help avoid overfitting*.</p><p>Then, we import our GCNConv layer, which we introduced earlier, and our GlobalSumPool layer. Spektral defines this layer concisely for us:</p><blockquote>A global sum pooling layer. Pools a graph by computing the sum of its node features.</blockquote><p>And that’s all there is to it! Let’s build our model:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6ebbb72a9b8a5da498d162bc5059ddc0/href">https://medium.com/media/6ebbb72a9b8a5da498d162bc5059ddc0/href</a></iframe><p>Here, we use model subclassing to define our model. We’re going to pass n_hidden : the number of hidden layers and n_labels : the number of labels (target classes) to our model when we instantiate it for training.</p><p>Then, within __init__ , we define all of our layers as properties. Within call , we define this method to create and return our desired output by calling our layers on input in sequence.</p><p>Let’s instantiate our model for training!</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/977fa092faea0c6508dd7a12c353041e/href">https://medium.com/media/977fa092faea0c6508dd7a12c353041e/href</a></iframe><p>Here, we’re going to initialize 32 hidden layers and the number of labels our data have. Spektral conveniently gives us an n_labels property on our TUDataset when we read it in. <em>The benefit of this is that you can use this same code with any other Spektral dataset without modifications if you’d like to explore other data!</em></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2064c4388c55573e48b2dbb012397813/href">https://medium.com/media/2064c4388c55573e48b2dbb012397813/href</a></iframe><p>Above, we’re calling .compile() on our model. If you’re familiar with Keras, you’ll be familiar with this method. We’ll pass in our optimizer, adam , and define our loss function, categorical crossentropy .</p><p>Now we reach a snag. Those of you familiar with Tensorflow and Keras might be tempted to just try to call model.fit() and call it a day. However, even though Spektral makes the process of building GNNs seamless on top of Keras, we can’t exactly work with our data the same way.</p><p>Because we’re using graph-structured data, we need to create batches to feed our Keras model. For this task, Spektral still makes our lives easier by providing <a href="https://graphneural.network/loaders/">Loaders</a>.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ffb9d67d55785618db7d1c542fd2c0d7/href">https://medium.com/media/ffb9d67d55785618db7d1c542fd2c0d7/href</a></iframe><p>Now that we’ve taken care of batching, we can call model.fit() . We won’t need to specify batches, just pass in our loader, since it works as a generator. We will need to provide our steps_per_epoch parameter for training.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/cc8cfd31a2a51c72c2a862d9552979a8/href">https://medium.com/media/cc8cfd31a2a51c72c2a862d9552979a8/href</a></iframe><p>For this simple example, we’ve only chosen 10 epochs. To validate, let’s create a loader for our test data:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/36acf1ab32968615e5289d3a91b8aaf5/href">https://medium.com/media/36acf1ab32968615e5289d3a91b8aaf5/href</a></iframe><p>And we’ll feed it to our model by calling .load() .</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8cdb8d3c519d507fe960f441a8e604a8/href">https://medium.com/media/8cdb8d3c519d507fe960f441a8e604a8/href</a></iframe><p>That concludes building GCNs with Spektral! I urge you to play around with optimizing this example, or diving into other GNNs you can build with Spektral.</p><h4>Part II: GCNs with Pytorch-Geometric</h4><p>Even though Spektral gives us an excellent library of graph neural network layers, loaders, datasets, and more, there are times where we might want a little more fine-tuned control, or where we might want to have another tool for the job.</p><p><a href="https://pytorch-geometric.readthedocs.io/en/latest/">Pytorch-Geometric</a> also provides GCN layers based on the Kipf &amp; Welling paper, as well as the benchmark TUDatasets. Implementation looks slightly different with PyTorch, but it’s still easy to use and understand.</p><p>Let’s get started! We’ll be working off of the same <a href="https://colab.research.google.com/drive/1W0syoaSSP-MpFhYC14cBV0O32Esyr_zF?usp=sharing">notebook</a>, beginning right below the heading that says “Pytorch Geometric GCN”. Attribution for this code is provided.</p><p>Our first step, as usual, is to install our required packages:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/184af84e20be4d3c9393c33b1b11d70a/href">https://medium.com/media/184af84e20be4d3c9393c33b1b11d70a/href</a></iframe><p>Now, let’s grab our dataset:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/677dfb7400b0686baae1f03d32d89ddb/href">https://medium.com/media/677dfb7400b0686baae1f03d32d89ddb/href</a></iframe><p>And take a look into our data:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c0aa2e0df7a9807f258302d1bffd1d74/href">https://medium.com/media/c0aa2e0df7a9807f258302d1bffd1d74/href</a></iframe><p>Here, it’s demonstrated that there are a variety of properties provided by Pytorch-Geometric on our TUDataset object. This provides us a lot of information that we can use to fine-tune our approach later, as well as deeply understand our data.</p><p>Now that we know what our data looks like, we’re going to perform our train/test split. For this example I also use a simple shuffling and then slicing method, but as always, I encourage you to look into optimizations for this step!</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b764fdd133e9d47b2a2065e823b56f7d/href">https://medium.com/media/b764fdd133e9d47b2a2065e823b56f7d/href</a></iframe><p>Pytorch also provides us with DataLoaders for batching:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2b5a10166811ae45b40c736c8fa13248/href">https://medium.com/media/2b5a10166811ae45b40c736c8fa13248/href</a></iframe><p>Now that we’ve taken care of that step, we can build our model. We’ll use a similar approach, but remember that now we’re using Pytorch instead of Keras.</p><p>We’ll import our functional layer (similar to Keras’ Dense layer), our GCNConv layer, and a global_mean_pool layer. This performs a similar pooling operation as Spektral’s GlobalSumPool , but by taking the mean rather than the sum of neighboring nodes.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c22435d7179272fdb4e81f36d2eafa02/href">https://medium.com/media/c22435d7179272fdb4e81f36d2eafa02/href</a></iframe><p>When we build our model, we inherit from Pytorch’s GCN model, and then initialize three convolutional layers. We’ll pass in the number of hidden channels when we instantiate our model.</p><p>Then, we build a forward() method, which is similar to the call() method we build earlier in our Spektral GCN. This tells our model how to propagate our inputs through out convolutional layers. With Pytorch, we explicitly define our activation function. In this example, we use relu .</p><p>Prior to our final classification, we perform our pooling, and then set our dropout and pass our inputs through a final linear layer.</p><p>While there are a lot of opportunities to customize and fine-tune our Spektral model, I like how explicitly we define our architecture with Pytorch. When it comes to “which approach is better”, like most things, it depends on what your team needs to prioritize (explain-ability over efficiency of quickly proving concept, for example).</p><p>Let’s take a look at the resulting architecture:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*iiu6WUayTffObujHSY6UaQ.png" /></figure><p>Next, we’ll need to:</p><ol><li>Set our optimizer — we’ll be using adam for this implementation as well</li><li>Define our loss function — similarly, we’ll keep categorical crossentropy</li><li>Define train and test functions, and then call them for a set amount of epochs.</li></ol><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ac25ac234a737d3f0c00621bb7923573/href">https://medium.com/media/ac25ac234a737d3f0c00621bb7923573/href</a></iframe><p>We’re using many more epochs for this example, and as such, we achieve better metrics. There isn’t an inherent reason for this aside from the code examples I used to help build the models and learn each respective library. Also, given that the Pytorch-Geometric implementation was my final implementation, I focused more on results than in my earlier experiments. As always, I encourage you to play with and optimize the code and make it better!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/924/1*lt1rS4uURSOXVgabkGqzjA.png" /></figure><p>Looking at the last 20 training epochs, we see that we achieve about 71.34% training accuracy and about 62.67% test accuracy. Evaluating accuracy on the test data around epoch 186, one potential optimization would be early stopping callbacks that ensure we stop training once we achieve convergence, to avoid overfitting the model.</p><p>There are more optimizations we can make, but this has been a long article, so we’ll stop here, and I’ll leave you to your own experimentation and optimization!</p><p><strong>Notes</strong>:</p><p>* — For more information on dropout or why it works, check out <a href="https://ai-pool.com/a/s/dropout-in-deep-learning">this</a> source.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ec18e728a17a" width="1" height="1" alt=""><hr><p><a href="https://medium.com/data-science/classifying-the-proteins-benchmark-dataset-ec18e728a17a">Classifying the PROTEINS Benchmark Dataset</a> was originally published in <a href="https://medium.com/data-science">TDS Archive</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[What Makes Graph Convolutional Networks Work?]]></title>
            <link>https://medium.com/data-science/what-makes-graph-convolutional-networks-work-53badade0ce9?source=rss-77c814d7979d------2</link>
            <guid isPermaLink="false">https://medium.com/p/53badade0ce9</guid>
            <category><![CDATA[graph-theory]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[computer-science]]></category>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[deep-learning]]></category>
            <dc:creator><![CDATA[Sid Arcidiacono]]></dc:creator>
            <pubDate>Tue, 04 May 2021 20:35:04 GMT</pubDate>
            <atom:updated>2021-05-05T13:01:48.309Z</atom:updated>
            <content:encoded><![CDATA[<h4>A breakdown of the mathematical intuition behind GCNs.</h4><p><em>This is the third part of a series on </em><a href="https://medium.com/mlearning-ai/why-graph-theory-is-cooler-than-you-thought-4df73e2a4950"><em>graphs</em></a><em> and </em><a href="https://medium.datadriveninvestor.com/graph-convolutional-networks-explained-d88566682b8f?source=your_stories_page-------------------------------------"><em>graph theory in machine learning</em></a><em>.</em></p><p>By now, if you’ve been following this series, you may have learned a bit about graph theory, why we care about graph structured data in data science, and what the heck a “Graph Convolutional Network” is. Now, I’d like to briefly introduce you to <em>what makes these things work.</em></p><p><em>For my friends in the field who may know a bit about this subject, I’ll be talking about the intuition behind </em><a href="http://arxiv.org/abs/1609.02907"><em>Kipf &amp; Welling’s</em></a><em> 2017 paper on graph convolutions for semi-supervised learning (Thomas Kipf wrote a more digestible explanation of this concept </em><a href="https://tkipf.github.io/graph-convolutional-networks/"><em>here</em></a><em>), although other approaches have been developed since improving on this methodology. My goal is to introduce the mathematical concepts, rather than provide an extensive overview of the topic.</em></p><p>Now, if you aren’t a mathematician, data scientist, or even a computer scientist, don’t run away just yet. The goal is to take the academic papers and break down the concepts so that anyone can understand. Feel free to leave a reply at the end letting me know if I’ve achieved this goal or not!</p><h4>Let’s Get Going! — GCNs, What’s the Goal?</h4><p>In Thomas N. Kipf’s <a href="https://tkipf.github.io/graph-convolutional-networks/">blog post,</a> he says the goal of a Graph Convolutional Network is to:</p><blockquote>“…learn a function of signals/features on a graph G =(v, e)”</blockquote><p>But what does that even mean? Let’s break it down.</p><p>There are different methods for performing <em>some prediction or classification </em>on <em>graphs </em>or <em>nodes. </em>But we’re focused on Graph Convolutional Networks, for <em>classification on </em><strong><em>graphs*.</em></strong> This means, to provide a concrete example, that for something like a <strong>protein,</strong> which has a structure represented by an entire graph:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/411/1*Mi3tQlobhC5r1k6Ima7Z5Q.gif" /><figcaption>Basic structure of a protein, where multiple amino acids are chained via peptide bonds, courtesy of <a href="https://swift.cmbi.umcn.nl/teach/alg/infopages/peptide_bond.gif">source</a>.</figcaption></figure><p>We might want a way to embed this graph’s <strong>features </strong>such that we could <strong>classify <em>what protein we’re looking at.</em></strong></p><p>So, let’s return to our quote above. We want to learn the <em>function </em>of features on a graph. In other words, we want to learn the relationships between features — in the protein example, that might be specific bond representations between certain atoms, or the atomic representations themselves — given our graph’s specific network structure. In other words: how do combinations of <strong><em>nodes and bonds </em></strong>(edges)<strong><em> </em></strong>impact what<strong><em> protein this is that we’re looking at (target label)?</em></strong></p><p><em>Disclaimer: this, like many things in this post, is a slight oversimplification. The purpose of this is to share the intuition behind GCNs, and make it accessible. For full explanations and mathematical proofs, I encourage you to dive deeper into the papers cited at the bottom.</em></p><p><strong>Why not a normal Convolutional Neural Network? </strong>We’ve<em> </em>spoken a bit in <a href="https://medium.datadriveninvestor.com/graph-convolutional-networks-explained-d88566682b8f?source=your_stories_page-------------------------------------&amp;gi=8ec29311e21f">previous articles</a> about the difficulties traditional machine learning &amp; deep learning models face when confronted with arbitrarily structured (non-Euclidean) data. What a GCN allows us to do is embed the graph structure into a two-dimensional representation, overcoming this barrier that we would encounter if we attempted to classify this graph using a traditional CNN.</p><p>You can think of embedding like taking a three dimensional molecule model, like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fLwcpnFcUSS97TwlIxrJ2w.jpeg" /><figcaption>Photo courtesy of <a href="https://unsplash.com/@vlisidis">Terry Vlisidis</a> on Unsplash</figcaption></figure><p>And drawing it on a piece of paper, to carry with us and memorize.</p><h4>To Understand How, Let’s Look at Forward Propagation.</h4><p>I may be projecting my learning style on my readers, but to really fully grasp the formulas that Kipf proposed, I had to go back to basics and review forward propagation. Let’s take a quick second to look at the forward propagation formula:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*aTXzY8HhSGCfloTfcXvopA.png" /><figcaption>Forward propagation equation for regular neural networks. Image courtesy of <a href="https://towardsdatascience.com/understanding-graph-convolutional-networks-for-node-classification-a2bfdb7aba7b">source</a></figcaption></figure><p>Don’t let this formula scare you. All it’s saying is that the feature representation at the <em>next layer </em>is equal to the result of performing <em>some activation function </em>on the weights at the <em>current layer </em>times the <em>feature representation at the current layer </em>plus the bias at the current layer.</p><p>Maybe that still feels dense, and if it does, that’s okay. You can think of this this way: <em>this formula represents is a series of computational steps we take to get to an output, </em>passing the result through each layer in our neural network until <em>i </em>is our final (output) layer. (If you know the basics of programming, you can conceptualize this like a for loop: “for each layer in our neural network’s layers, perform this calculation to return a final value.”)</p><p>Our <em>activation function </em>(represented as sigma)<em> </em>might be something like ReLu, and our <em>feature representation </em>can be thought of in terms of our protein example, where each atom in our molecule is represented by, (for the sake of our simple example), its atomic number. We would then want our final output at our last layer to be the <em>representation of what protein we’re looking at — </em>our classification. Don’t worry too much about bias for now if you don’t know what it is, we won’t be discussing it further in this article.</p><blockquote><strong><em>Check-In</em></strong></blockquote><blockquote><em>It’s possible that if you’re maybe a bit new to all this your brain is hurting right about now, and that’s fine. Let’s take a second to review and digest what we’ve learned before we go further:</em></blockquote><blockquote><em>1. One goal of a GCN is to take an arbitrarily structured graph and embed it into a two-dimensional representation of a network.</em></blockquote><blockquote><em>2. Additionally, we want to understand the </em>functions of features on a graph<em> — we want to know how </em>stuff<em> influences other </em>stuff<em> (how features in our graph influence our target).</em></blockquote><blockquote>3. <em>We’ve reviewed </em>forward propagation<em> for regular neural networks, and understand what this equation tells us.</em></blockquote><h4>Forward Propagation — How Does This Relate to GCNs?</h4><p>Similar to any neural network, Graph Convolutional Networks need a way to propagate values forward through layers to achieve their goals. However, given that our data is not Euclidean, we’re going to need to make a few slight adjustments to the regular forward propagation equation we discussed above.</p><p>First, we need a way to represent our graph computationally. If you remember all the way back to my first article on Graph Theory, or if you remember your mathematics (or, for the computer scientists in the room, your data structures courses), you’ll remember that one way to represent a graph is with an <strong>Adjacency Matrix</strong>. Let’s take a look at one example:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/722/1*wtPaHzg5KskO3EdQt80_ag.png" /><figcaption>Adjacency matrix of an undirected graph, shown on the left.</figcaption></figure><p>Our adjacency matrix is effectively a <em>sparse matrix </em>where we have rows and columns representing <strong>node labels </strong>and a binary representation of whether or not any two nodes are connected to each other. 0 corresponds to “no connection”, where a 1 represents a connection (an <strong>edge</strong>).</p><p>So, we have our first missing piece of the GCN puzzle: our <strong>adjacency matrix, </strong>which we’ll call <strong>A.</strong></p><p>Now, we need to make sure we insert <strong>A </strong>into our propagation equation. <em>Since I said not to worry about bias (and since the article I’m referencing for images also omits this value from its images, this works well), you won’t see it in the following representation.</em></p><p>Let’s take a look at our equation so far:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*F7aj3Y2mpSJ9Wktp2tVaqA.png" /><figcaption>Forward propagation equation for graph convolutional network. Image courtesy of <a href="https://towardsdatascience.com/understanding-graph-convolutional-networks-for-node-classification-a2bfdb7aba7b">source</a> with my own annotations added.</figcaption></figure><p>But we aren’t quite done yet. There are two problems:</p><ol><li>If we solely look at <strong>A, </strong>we’ll look at all of a given node’s neighbors, but not that node itself. We’ll deal with this in a moment.</li><li>What is A*?<strong> A</strong>, as we initially discussed it, was not normalized. Since we’re going to have to multiply our weights and feature representations by our sparse adjacency matrix <strong>A, </strong>we can anticipate that the scale of the feature representations and weights will dramatically change with the scale of <strong>A. So, A* is normalized A. </strong>Let’s talk about what that means:</li></ol><p>Kipf &amp; Welling introduced a method to normalize <strong>A </strong>that takes care of this second problem. First, we need the <a href="https://en.wikipedia.org/wiki/Degree_matrix"><em>diagonal node degree matrix</em></a><em>, </em><strong><em>D. </em></strong>If that sentence feels confusing, check out the linked article! One of the ways to normalize <strong>A </strong>would be to multiply with <strong>D, </strong>but Kipf &amp; Welling introduce us to another method called symmetric normalization. This equates to:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/204/1*Ra_5BaRtTMzjvxu3FVauHg.png" /><figcaption>Symmetric normalization representation of Adjacency Matrix (A) and Degree Matrix (D), courtesy of <a href="https://tkipf.github.io/graph-convolutional-networks/">source</a>.</figcaption></figure><p>You’ll see this in action when we provide our final equation! Now, that we’ve addressed our normalization issue, we’re almost there. We have one more thing to add: self-loops.</p><p>We want to learn representations for all of the nodes in our graph, and this means that we need to change something about our graph. Because this is a lengthy article already, I’ll once again quote Thomas Kipf from his <a href="https://tkipf.github.io/graph-convolutional-networks/">blog post</a> to explain:</p><blockquote>“… multiplication with A means that, for every node, we sum up all the feature vectors of all neighboring nodes but not the node itself (unless there are self-loops in the graph). We can &quot;fix&quot; this by enforcing self-loops in the graph: we simply add the identity matrix to A.”</blockquote><p>Here, we arrive at our next step: enforcing self-loops. This means that we need our nodes to also connect back to themselves, looking something like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/173/1*iQ_vEMSVkrM-3q9XEv3yLA.png" /><figcaption>Self loop on a single node, courtesy of <a href="https://commons.wikimedia.org/wiki/File:Self-loop.png">source</a>.</figcaption></figure><p>If you’re not 100% sure what Kipf was talking about in his quote regarding the <em>Identity Matrix</em>, remember that the identity matrix is an <em>n</em> x <em>n </em>matrix<em> with 1’s </em>on the main diagonal (top left to bottom right) and zeroes elsewhere:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/467/1*DX_owLAsSYgqa6gw2nsIOw.png" /><figcaption>Identity matrices <em>n x n, courtesy of </em><a href="https://en.wikipedia.org/wiki/Identity_matrix"><em>source</em></a><em>.</em></figcaption></figure><p>Where <em>n </em>is, in our use case, going to be the dimension of our adjacency matrix <strong>A.</strong></p><p>Now that we’ve normalized A with its degree matrix and enforced self-loops by adding our identity matrix, we arrive at our final equation for forward propagation in graph convolutional networks:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/670/1*s5M3nMa8M9NUQrlP7WRq9w.png" /><figcaption>Forward propagation equation for graph convolutional networks — equation to derive function of feature representation for layer (l) for adjacency matrix (A), courtesy of <a href="https://tkipf.github.io/graph-convolutional-networks/">source</a> with my own annotations added.</figcaption></figure><p>Let’s break down this new equation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/368/1*y5NRVru7tL-Zmr4WLE6y2g.png" /><figcaption>First clause of forward propagation equation for GCNs.</figcaption></figure><p>This piece says: “The function of our features for layer <em>l </em>given adjacency matrix <strong>A</strong>”. <em>This is what we’re looking to solve for</em>. Remember one of our original goals, to <strong>find the functions of features for a graph.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/870/1*1pFwCZKDTjoWck51j2Qbkw.png" /><figcaption>Second clause of forward propagation equation for GCNs.</figcaption></figure><p>Let’s break this second part down. Remember, this is to the right of the equal sign — this is what we’re using to find the functions of our features.</p><p>Remember that sigma (𝝈) represents an activation function (such as ReLu). So what this clause represents is the result of the activation function on the diagonal degree matrix (<em>D̂</em>)*<em> </em>of Â, which is our adjacency matrix (A) added to the identity matrix, which we’ve normalized using “symmetric normalization”. These are then multiplied by our feature representations and our weights for our current layer, <em>l.</em></p><p><strong>Wait — let’s take a step back.</strong></p><p>Let’s talk through that last piece piece to our puzzle. Remember how we talked about our protein example, and how our nodes might have a <em>label, </em>like, the name or abbreviation of an atom (i.e: carbon, or C), as well as a <em>feature representation, </em>which might be something like their atomic number?</p><p>These representations in this example become our <strong>feature representation vectors, </strong>and for our equation above, represent <em>H</em> of <em>l.</em></p><h4>Sum it All Up — In a Few Words</h4><p>You’ve just learned how to find the <strong>functions of features for a given graph, <em>G </em></strong>given its adjacency matrix, <em>A, </em>and its degree matrix, <em>D.</em></p><p>You’ve reviewed forward propagation, and learned how it differs for graph convolutional networks. You’ve learned about some important caveats to consider when dealing with arbitrarily structured data, like the importance of having or creating self-loops and of normalizing our adjacency matrix.</p><p>Nice! You’re well prepared to take on the next step — which will be coming soon — and which should be much more fun: actually classifying stuff with GCNs.</p><p>If you want to learn even more before next time, check out all of the papers and sources that were so invaluable in the writing of this article:</p><ol><li><a href="https://arxiv.org/abs/1609.02907">Semi-Supervised Classification with Graph Convolutional Networks,</a> Kipf &amp; Welling (ICLR 2017)</li><li><a href="https://tkipf.github.io/graph-convolutional-networks/">Graph Convolutional Networks</a>, Thomas Kipf</li><li><a href="https://towardsdatascience.com/understanding-graph-convolutional-networks-for-node-classification-a2bfdb7aba7b">Understanding Graph Convolutional Networks for Node Classification</a>, Inneke Mayachita</li></ol><p>Notes:</p><ol><li><em>*GCNs can be used for node-level classification, as well, but we don’t focus on that here, for the sake of a simplified example.</em></li><li><em>*this represents ‘D-hat’, Medium’s mathematical notation support is lacking a bit</em></li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=53badade0ce9" width="1" height="1" alt=""><hr><p><a href="https://medium.com/data-science/what-makes-graph-convolutional-networks-work-53badade0ce9">What Makes Graph Convolutional Networks Work?</a> was originally published in <a href="https://medium.com/data-science">TDS Archive</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Graph Convolutional Networks — Explained.]]></title>
            <link>https://medium.com/data-science/graph-convolutional-networks-explained-d88566682b8f?source=rss-77c814d7979d------2</link>
            <guid isPermaLink="false">https://medium.com/p/d88566682b8f</guid>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[graph-theory]]></category>
            <category><![CDATA[computer-science]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[data-science]]></category>
            <dc:creator><![CDATA[Sid Arcidiacono]]></dc:creator>
            <pubDate>Fri, 09 Apr 2021 06:03:51 GMT</pubDate>
            <atom:updated>2021-05-19T03:41:04.386Z</atom:updated>
            <content:encoded><![CDATA[<h3>Graph Convolutional Networks — Explained</h3><h4>A non-convoluted look into graph theory and machine learning</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YECeOxlko9KoOJNw8RNm3A.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/@alinnnaaaa?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Alina Grubnyak</a> on <a href="https://unsplash.com/s/photos/network?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><p>In my last article on graph theory, I briefly introduced my latest topic of interest: Graph Convolutional Networks. If you’re here thinking “what do those words mean?”, you’re in the right place. In this article, we’re going to break this topic down, step by step.</p><p><strong>Part I: What’s This Graph Thing?</strong></p><p>If this is the first you’re hearing this ‘graph’ word, I’m sorry, but you have some homework to do. Before we can dive deeper into this topic, you should check out my <a href="https://medium.com/mlearning-ai/why-graph-theory-is-cooler-than-you-thought-4df73e2a4950">last article</a> briefly introducing graph theory (and why we care about it). I’ll wait here!</p><p>Alright, now that you’re back, let’s explain a bit further. Graph theory is a mathematical theory, which simply defines a graph as:</p><p><em>G = (v, e) </em>where <em>G </em>is our graph, and <em>(v, e) </em>represents a set of vertices or <strong>nodes </strong>as computer scientists tend to call them, and <strong>edges</strong>, or connections between these <strong>nodes. </strong>Graph theory exists because we need a way computationally and mathematically to <em>represent relationships between </em><strong><em>things</em></strong><em>.</em>These <em>things </em>can be anything: users on a social media platform, physical neighbors in a community, addresses or locations (coordinates) on a map, pixels in an image, or neurons in our brain. The basis of graph theory as it relates to machine learning in particular is that much of our data can be best understood when we can represent its relationships. Therefore, we’d like a way to embed these relationships so that we can then work with the whole of the data.</p><p>But let’s not get too far ahead of ourselves — we have some more terms to define.</p><p><strong>Part II: Convolution? That sounds… convoluted.</strong></p><p>Let’s bring it back to the <em>things </em>which have relationships with other <em>things </em>that we want to understand. Simple enough, right? Let’s consider, for example, we have pixels in an image. Those pixels are always related to every other pixel in an image. This image has a set structure, and the pixels remain within proximity to other pixels in a fixed way. Let’s take a look:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/395/1*5mj1VpWuTVbgMsqrPgNkrQ.png" /><figcaption>Corner pixel neighborhood representation, courtesy of Marco Balsi via <a href="https://www.researchgate.net/profile/Marco-Balsi/publication/266178373/figure/fig4/AS:669372586663951@1536602269858/Neighborhood-of-a-corner-pixel-in-a-CNN-defined-on-a-2-torus.png">source</a>.</figcaption></figure><p>If you can tell, this fits our definition of a graph. Implicitly, an image <em>is ‘</em>viewed’ as a graph by a different type of neural network: a <a href="https://towardsdatascience.com/a-comprehensive-guide-to-convolutional-neural-networks-the-eli5-way-3bd2b1164a53?gi=36cb8c030e2f">Convolutional Neural Network</a>. In this article, I’ll be breezing through the very basic concepts of convolutional neural networks to explain graph convolutional nets. However, if you aren’t aware of CNN’s, I highly recommend taking a look at the linked source after reading this article to gain a well-rounded understanding of all of these topics.</p><p>You may be able to intuit from their name that graph convolutional networks and convolutional neural networks share some things in common. You would be correct to think this — the intuition behind GCN’s and CNN’s is extraordinarily similar.</p><p>But what is our CNN doing with this image above? If it’s technically a graph, why do we need this other thing? Well, I’m glad you asked!</p><p>Images are implicitly graphs of pixels connected to other pixels, but they always have a fixed structure. As our convolutional neural network is sharing weights across neighboring cells, it does so based on some assumptions: for example, that we can evaluate a 3 x 3 area of pixels as a “neighborhood”. The assumptions on which our convolutional neural networks work rely on 2-dimensonal, regular data (also called <em>Euclidean </em>data, if you’re well-versed in domain terminology).</p><p>Our social media networks, molecular structure representations, or addresses on a map <em>aren’t </em>two-dimensional, though. They also don’t have a necessary size or structure. We encounter difficulty when trying to cram non-Euclidean or arbitrarily structured data into CNN’s, since that’s about where they reach their limit and stop being useful.</p><p><strong>Part III: Networks</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/665/1*uvBLSbUBbuZppwqATDEQRQ.png" /><figcaption>Pixel representation versus arbitrarily structured graph, courtesy of <a href="https://arxiv.org/pdf/1901.00596.pdf">source</a>.</figcaption></figure><p>We’ve established that we have these arbitrarily structured networks of stuff that don’t fit into our traditional convolutional neural networks. In fact, they don’t really work with a lot of different kinds of neural networks. As such, there are <a href="https://medium.com/analytics-vidhya/getting-the-intuition-of-graph-neural-networks-a30a2c34280d">graph neural networks</a>, of which graph convolutional networks are a basic variant.</p><p>In this article, I won’t be getting into the mathematics behind graph convolutional networks (even though it’s quite fun) — I just want to discuss the intuition. <em>(Don’t worry — I cover the mathematics in the </em><a href="https://towardsdatascience.com/what-makes-graph-convolutional-networks-work-53badade0ce9?source=your_stories_page-------------------------------------"><em>next</em></a><em> article of the series.)</em></p><p>Effectively, the primary difficulty in embedding features represented as both nodes and edges is this matter of arbitrary space usage, and a lack of Euclidean distance between neighbors. With those facets, we must base approaches off of different assumptions. Here, I’ll be primarily discussing graph convolutional networks as they’ve been discussed by <a href="http://arxiv.org/abs/1609.02907">Kipf &amp; Welling</a>, although there are various approaches.</p><p>We’ve learned about how <em>convolution</em> in neural networks is a method of sharing weights between neighbors. First, to determine neighbors, we’re going to need to provide some data.</p><p>Where the normal neural network forward propagation function determines the feature representation of the <em>next </em>hidden layer by evaluating our <em>weights, feature representation and bias </em>for our <em>current </em>layer, our graph convolutional network is going to add an <em>adjacency matrix </em>to the equation. There is also our non-linear activation function, which, since I’m trying to not get too mathematical, I’m ignoring in our considerations for now.</p><p>Do we remember what an adjacency matrix looks like? Here’s a refresher:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/850/1*KuKeonv0TPB86cSC48XnFA.jpeg" /><figcaption>Simple graph and its adjacency matrix, courtesy of Safet Penjić via <a href="https://www.researchgate.net/figure/Simple-graph-G-5-and-its-adjacency-matrix_fig3_273062204">source</a>.</figcaption></figure><p>What <strong>A </strong>is is a matrix representation of the connections within our graph, 𝝘₅. Each row or column label represents the node with the same number label, and a <em>1 </em>in an intersecting row/column represents an edge between those nodes.</p><p>For those of you familiar with machine learning already, this looks a bit like a <em>sparse matrix, </em>right? See, this isn’t all so new after all.</p><p>Effectively, representing our graph as an adjacency matrix enables us to provide it to the net in the form of a <em>tensor, </em>something our model can work with.</p><p>Before we can just hand this matrix over to our propagation equation, though, we need to ensure that we normalize our values. The intuition behind this is similar to normalizing any data we feed through a neural network: values of vastly different degrees of magnitude can cause our network to learn higher weights for values that it shouldn’t, simply because those values were initially much higher than other values. For our purposes here, we’re just going to mention normalization. I’ll dive more deeply into Kipf &amp; Welling’s methodology and intuition in the next article.</p><p>Once we’ve normalized our data, we’ll perform some kind of aggregation between neighboring nodes — for example, take an average. The intuition here for semi-supervised learning is that similar nodes are likely to share the same label. We can imagine this process as the passing of a message, where each layer of our GCN takes an aggregate of a neighbor node, and passes it one “hop” away, to the next node.</p><p>So if we have a three-layer GCN, we can convolve each node’s ‘third-order’ neighborhood. In human terms, this means that we can pass a message to each node’s neighbor three “hops” away and effectively embed the community structure of our graph. If, however, we have a graph with many more “hops”, we would need more layers to effectively embed our graph structure.</p><p>If you’re feeling anything like I did when I first delved into this topic, you’re probably ready for a break. Before I let you off the hook, let’s take a look at what we’ve learned:</p><ol><li>We’ve recapped the essentials of graph theory, and understood why we care about this as machine learning engineers and data scientists.</li><li>We’ve looked at convolutional neural networks, evaluated the term “convolution” briefly, and discussed their limitations.</li><li>We’ve taken a brief peek behind the scenes of the intuition behind graph convolutional networks, and we mostly understand why they work!</li></ol><p>Alright, take a rest for now, and don’t forget to give yourself a pat on the back! You’ve learned a lot in a short span. I look forward to next time, where we’ll dive deeper into the mathematics that make all of this work, and learn how to start coding up our very own GCN.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d88566682b8f" width="1" height="1" alt=""><hr><p><a href="https://medium.com/data-science/graph-convolutional-networks-explained-d88566682b8f">Graph Convolutional Networks — Explained.</a> was originally published in <a href="https://medium.com/data-science">TDS Archive</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Predicting the Stock Market — Meaningfully]]></title>
            <link>https://medium.com/star-gazers/predicting-the-stock-market-meaningfully-944f78030b2?source=rss-77c814d7979d------2</link>
            <guid isPermaLink="false">https://medium.com/p/944f78030b2</guid>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[stock-market]]></category>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[financial-analysis]]></category>
            <dc:creator><![CDATA[Sid Arcidiacono]]></dc:creator>
            <pubDate>Wed, 24 Mar 2021 03:40:41 GMT</pubDate>
            <atom:updated>2021-03-26T15:23:43.230Z</atom:updated>
            <content:encoded><![CDATA[<h3>Predicting the Stock Market — Meaningfully</h3><h4>Tackling the impossible, step by step.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IWKTDXElpzLDMMnFLdn4Zw.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/@chrisliverani?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Chris Liverani</a> on <a href="https://unsplash.com/s/photos/stock?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><p>A colleague of mine, when I told him about an ongoing project, said: “Oh, you’re really building a money printer!” To predict the stock market accurately would be a game changer —this hopefully goes without saying. But, when massive financial firms with seemingly endless resources are looking to tackle the same problem, what space is there for anyone else? Besides, can one even begin to attack this in a different way, to provide even somewhat meaningful results?</p><h4>Starting from… Not-Quite-Scratch</h4><p>Kaggle is full of notebooks with toy examples of sentiment analysis for stock market prediction: notebooks which evaluate, based on general news headlines, if the “market” will go up or down. While these are really excellent tools for learning more about machine learning, they’re hardly interesting for high-frequency trading or actual investors. Other approaches often look at historical data, and attempt to use various regression approaches to predict where prices will be over time, for a given company. Here, figuring out <em>what features legitimately affect price</em> becomes an issue, as well as figuring out which historical trends will continue to hold true in the future. HFT’s (High Frequency Traders) and massive financial firms commonly scoop up these approaches as soon as anything new and promising is found, leaving those of us with less resources in the dust.</p><blockquote><strong>Instead of predicting price trends, I took a different approach, asking the question: “what if we could predict public sentiment about a company in a way which tends to influence their stock price, rather than JUST the price itself?”</strong></blockquote><p>To start, I looked at the existing sentiment analysis approaches, and played around with some of the code that I found. In considering what problem this code was actually solving, I was able to ask a crucial question:</p><p><em>“Based on a headline about company X, what can we learn about public sentiment, and the change that we might see in X’s stock price?”</em></p><p>The problem with generic sentiment analysis approaches, is that they inevitably use data on entire markets. This means that we have a binary classification (most often) that says:</p><blockquote>“For these 25 top headlines, DOW goes up” -&gt; 1</blockquote><blockquote>“For these 25 top headlines, DOW goes down” -&gt; 0</blockquote><p>But what would this mean for me, as an average investor? Certainly not much. For how long will this news depress the markets? For how long will it improve them? Are there any companies within this market that *aren’t* meaningfully affected by this news? What’s the actual relationship between a headline, and stock price X?</p><h4>Shifting the Approach, to Prove That I Could</h4><p>Can a relationship between <em>headline y</em> and <em>stock price X</em> even be proven, or are there too many moving pieces?</p><p>The first step in answering some of my own questions came after playing around with some models and generic data. I realized that this approach would never provide me with anything meaningful, and I needed to seek out more data. Specifically, I recognized that to get a better look at this problem, we need to take into consideration:</p><ol><li><strong>What company we’re looking at</strong> -&gt; we need a label (i.e: AAPL or Apple)</li><li><strong>What news has an effect on that company</strong> -&gt; general news (i.e: “supply chains disrupted due to COVID) or specific news (i.e: “Apple CEO Steve Jobs died Tuesdsay)</li><li><strong>What effect the news has</strong> -&gt; on the day the article was published, did that company’s stock price go up, or down?</li></ol><p>No data existed with these labels, so I set off to get my own. A partner on the project, Yin Chang, <a href="https://medium.com/nerd-for-tech/how-to-scrape-dow-jones-industrial-average-data-from-yahoo-finance-bd2cba5d163a">coded up some web scrapers to get market data and news</a>. Using this, I was able to compile enough data points to at least get started. You can find the data <a href="https://www.kaggle.com/sidarcidiacono/news-sentiment-analysis-for-stock-data-by-company">here</a>, if you’d like to do some playing around of your own.</p><p>The next step was to prove the concept — <em>can we predict whether the stock will go up, down, or hold, based on relevant headlines about a company?</em></p><p>The importance in approaching this in stages cannot go understated. Sure, I could have compiled the headline and class data, the ticker symbol labels for the companies and loads of historical data and jumped right into a combined approach of sentiment analysis and prediction of how much a stock increased or decreased on the day of a headline, but it would be akin to just drawing a regression line on a scatterplot without knowing if the data is actually correlated. In other words, it would likely be garbage, even if I could get my metrics to look pretty.</p><p>In order to not just <strong>predict </strong>the stock market, but to predict it <strong>meaningfully, </strong>we have to take small steps towards analyzing and proving relationships between data points. There is a network of things which, when seen as a whole, can be evaluated and understood as impacting public sentiment about a company and therefore influencing its stock price. News headlines are just a small piece of this puzzle — but we first have to prove that they’re a piece of the puzzle.</p><p>At this stage, we’re working on proving this piece. The first step towards this was defining a model architecture that could perform sentiment analysis and prediction gracefully and accurately. My experiments with Naive Bayes and Random Forest Classifiers proved to me that for this portion they didn’t quite cut it. Based on my research in this area, I knew to turn to an old friend of mine, LSTM Recurrent Neural Networks.</p><p>For those who aren’t versed in data science language (because let’s be honest, it certainly wasn’t developed for beginners), an LSTM — Long Short Term Memory — is a type of neural network that “remembers” steps in its learning. To keep this section short and sweet and not too overwhelming, I’m going to oversimplify just a bit (a lot) and say that <strong>this makes it good at sentiment analysis.</strong></p><p>Once a model was decided on, it was possible to take my <em>toy </em>approach as a start, and attempt to create a model that was <em>good </em>at this one thing. The initial approach answers our above question, and provides a classification based on headlines and Tweets about a company:</p><blockquote>0 -&gt; the stock will go down</blockquote><blockquote>1 -&gt; the stock will go up</blockquote><blockquote>2 -&gt; the stock will hold</blockquote><p>With this initial approach, <a href="https://stockstalker.tk/">StockStalker</a> was formed. An app prepared to inform <em>average investors — </em>not HFT’s — about the impact of daily news on the public sentiment about a company, and in turn, the way that company is likely to perform.</p><p>While our alpha version has a long way to go, (and lots more analysis to do!) we’ve come a long way in proving our initial concept: <strong>can we predict how a company is likely to perform based on relevant news? </strong>From here, there are a myriad of improvements to make, but we’re off to a good start.</p><p>To solve a problem everyone wants to solve, sometimes you have to look at things a little differently. This is why we created StockStalker — to predict the market, meaningfully.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=944f78030b2" width="1" height="1" alt=""><hr><p><a href="https://medium.com/star-gazers/predicting-the-stock-market-meaningfully-944f78030b2">Predicting the Stock Market — Meaningfully</a> was originally published in <a href="https://medium.com/star-gazers">Star Gazers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Why Graph Theory is Cooler Than you Thought]]></title>
            <link>https://medium.com/data-science/why-graph-theory-is-cooler-than-you-thought-4df73e2a4950?source=rss-77c814d7979d------2</link>
            <guid isPermaLink="false">https://medium.com/p/4df73e2a4950</guid>
            <category><![CDATA[thoughts-and-theory]]></category>
            <category><![CDATA[computer-science]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[editors-pick]]></category>
            <category><![CDATA[graph-theory]]></category>
            <dc:creator><![CDATA[Sid Arcidiacono]]></dc:creator>
            <pubDate>Fri, 26 Feb 2021 06:34:06 GMT</pubDate>
            <atom:updated>2021-05-25T17:57:17.036Z</atom:updated>
            <content:encoded><![CDATA[<h4><a href="https://towardsdatascience.com/tagged/thoughts-and-theory">Thoughts and Theory</a></h4><h3>Why Graph Theory Is Cooler than You Thought</h3><h4>Graph theory in machine learning, and how it’s changed the game</h4><p><em>This is the first article in a four-part series on graph theory and graph neural networks.</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BpWEu9enr-xsVo9yAGrpRA.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/@dulgier?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Nastya Dulhiier</a> on <a href="https://unsplash.com/s/photos/connected?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><h4>What are Graphs?</h4><p>Talk to a scientist in just about any discipline, and ask them the question — based on their discipline — “how does <em>th</em>at stuff work?” You’ll likely find that there are systems and networks that you have to consider before you can <em>really</em> understand how any given thing works: whether that’s the human body, a food chain in an ecosystem, a chemical reaction, or a society as a whole. Without understanding the relationship between two animals in an ecosystem, two atoms in a molecule, or cells and tissues in our body, you just have a bunch of data: a list of cells, a readout of animals and what they eat, etc.</p><p>Traditional machine learning models often take data this way: they take lists or tables of data and do some <em>stuff</em> (the details of which depend on the algorithm being used as well as a few other parameters) to make predictions about a thing. <strong>But for some problems, there’s a better way.</strong></p><p>Graphs are data structures that represent networks of, or relationships between, the data they contain. Typically, they’re represented as “nodes” and lines, or “edges”.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Htx7vzWhvSE6f7cWh4hlqQ.png" /><figcaption>Fig. 1: An example of a social media network represented as a graph, with dotted or full lines indicating the strength of relationships. Image by <a href="https://pixabay.com/users/gdj-1086657/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=3846597">Gordon Johnson</a> from <a href="https://pixabay.com/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=3846597">Pixabay</a></figcaption></figure><p>Figure 1, above is an example of an “undirected graph”, or, a graph in which data has a two-way relationship with other data. This means that each <em>node </em>in our graph, each representing a person in a social network, is connected with each other node. This might represent a networking site like LinkedIn, where once you’re connected with someone you’re connected with each other. An example of a directed social network graph might be Twitter, where users follow each other (and not always mutually).</p><p>The images which represent data (users) are called <strong>nodes</strong> or <strong>vertices, </strong>and the lines which connect them are called <strong>edges.</strong> These lines represent relationships between the vertices, and can be represented, as an “all or nothing relationship” (i.e: you’re following someone or you aren’t) or as a “weighted” relationship (i.e: a solid line can represent higher engagement between two users, while a dotted line can represent a weaker relationship or lower engagement).</p><p>At this point, it’s possible you’re feeling how I felt when I first was introduced to graphs and graph theory in a computer science class: bored and possibly slightly confused. The good news is, since we’ve covered some of the terminology that’s necessary to understand the good stuff, we can start to get into <strong>why graphs matter, and what makes them so cool.</strong></p><h4>So, what?</h4><p>Graphs are already used for some pretty neat stuff in computer science: your Maps application, for example, is using graphs behind the scenes to store data about locations and the streets that connect them, and is using shortest-distance algorithms to find you the <em>shortest route to your destination.</em></p><p>But it gets even better when we start to look at using graphs for machine learning. Because graphs demonstrate comprehensive relationships between pieces of data (as compared to ordered lists of data, or <a href="https://machinelearningmastery.com/introduction-to-tensors-for-machine-learning/">tensors</a> which tell us little about the relationships between data points or features by themselves), we can use them to perform in-depth analysis and make predictions based on these relationships.</p><h4>Graph Theory &amp; Machine Learning — But How?</h4><p>Before we get to reap the benefits of combining these graphs or networks we keep talking about with machine learning, we have to somehow represent our graph in a way that a computer — and then a machine learning algorithm — can understand.</p><p>Graphs can be represented traditionally in one of three basic ways:</p><ol><li><strong>An Adjacency Matrix</strong></li></ol><p>Adjacency matrices do… kind of just what they sound like they’d do. They represent connections, or <em>edges</em>, between different nodes using a matrix. We can look at an example to illustrate what this might look like:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/850/1*KuKeonv0TPB86cSC48XnFA.jpeg" /><figcaption>Fig. 2: Simple graph and its adjacency matrix, courtesy of Safet Penjić via <a href="https://www.researchgate.net/figure/Simple-graph-G-5-and-its-adjacency-matrix_fig3_273062204">source</a>.</figcaption></figure><p>Here, we can find an edge between two notes by finding where their labels intersect in our matrix. We can see, for example, that node 1 is not connected to itself, but that it is connected to node 2.</p><p><strong>2. An Edge List</strong></p><p>An edge list is another way to represent our network — or graph — in a way that’s computationally understandable. Here, we represent pairs of connected nodes within a list. You can see an example below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/962/1*5K11xP7UOb8Te3Kz4k2PrA.png" /><figcaption>Fig. 3: An edge list contains pairs of vertices or nodes which are connected to each other. Image author’s own.</figcaption></figure><p><strong>3. An Adjacency List</strong></p><p>Adjacency lists combine the above two approaches, representing a list of nodes, connected to a list of all of the nodes they’re directly connected to. To illustrate, let’s look at an example:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/396/1*EfJuPpw7inZHZt8vImcJWQ.png" /><figcaption>Fig. 4: Visual representation of an adjacency list for graph 𝝘₅ from Fig. 2. This shows that for Node 1, we have a list of connected nodes, and so on. Image author’s own.</figcaption></figure><p>With the above three approaches, we’re able to tackle the difficulty of representing graphs computationally in our code. However, there are still some challenges when feeding graphs to machine learning models. Traditionally, deep learning models are good at handling data which takes up a fixed amount of space and is unidirectional. No matter how we represent them, graphs don’t take up a fixed amount of space in memory, and aren’t continuous, but rather, each node holds a reference to nodes it’s directly connected to.</p><p>There are some really fabulous ways of tackling these challenges, which I’ll dive deeper into in a later article. For now, I’ll leave you with a few resources to research on your own should you be interested, which are providing us with new ways to expand the problems machine learning is able to solve.</p><ul><li><a href="https://towardsdatascience.com/how-to-do-deep-learning-on-graphs-with-graph-convolutional-networks-7d2250723780">Learn about Deep Learning on Graphs with Graph Convolutional Networks</a></li><li><a href="https://cs.stanford.edu/people/jure/pubs/graphrepresentation-ieee17.pdf">Learn about DeepWalk — a project finding another way to represent graphs for machine learning</a></li></ul><h4>Graph Theory and Machine Learning — What Can we Do With It?</h4><p>Nothing exists in a vacuum, and understanding the interconnected networks of data that make up many of our scientific disciplines provides the exciting potential to answer so many questions — more than I can begin to wrap into this article.</p><p>What if we could better understand the human brain? What if we could make predictions about the effect of some stimulus or change on an ecosystem? Or, predict which compound is the most likely to create an effective drug?</p><p>The <strong>best part of everything we’ve just learned</strong> is that we can — and it isn’t simply a theoretical possibility, but something we’re doing right now!</p><p>Graph theory is already being used for:</p><ol><li><a href="https://medium.com/swlh/graph-theory-machine-learning-in-neuroscience-30f9bec5d182">Diagnostic modeling (predicting to a certain degree of certainty whether or not a patient has a specific diagnosis)</a>.</li><li><a href="https://www.nature.com/articles/s41698-017-0029-7">Helping with the diagnoses and treatment of patients with cancer</a>.</li><li><a href="https://arxiv.org/pdf/2012.05716.pdf">Developing pharmaceuticals (medications)</a>.</li></ol><p>4. <a href="https://www.frontiersin.org/articles/10.3389/fevo.2019.00402/full">Seeking to develop a theoretical synthesis between the theories of ecology and evolution</a>.</p><h4>How Graph Theory Makes it All Happen</h4><p>Let’s dive a little deeper into these applications, so we can look at the utilization of graph theory within them in more detail.</p><p>Let’s use diagnostic models as an example. Specifically, I want to look at this example of network analysis being used for the diagnosis and identification of possible schizophrenia in patients:</p><p><a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3782171/">Graph-based network analysis in schizophrenia</a></p><p>Using graphs to represent network analyses of the brain, neuroscientists are able to map key findings related to the diagnosis of schizophrenia. Given that there are certain markers for the onset of schizophrenia:</p><ul><li>less efficiently wired networks</li><li>less local clustering</li><li>less hierarchical organization</li></ul><p>We could potentially evaluate these networks with a machine learning algorithm and predict the probability a patient has or will develop schizophrenia based on these markers.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*LfCQLuqZr1NG1qN9ZYYTZg.jpeg" /><figcaption>Photo by <a href="https://www.pexels.com/@mart-production">MART PRODUCTIONS</a> on <a href="https://www.pexels.com/photo/technology-computer-room-health-7089290/">Pexels</a></figcaption></figure><p>Without the knowledge of these networks, in this example, this kind of analyses becomes an entirely different neurological analysis of the patient. The promising discoveries of these findings for schizophrenia has promising implications for the diagnosis and treatment of this disorder — possible early diagnosis and intervention that goes far beyond simply evaluating symptoms.</p><p>This is just an example, but is entirely illustrative of the benefits of graph theory in machine learning as it intersects with other disciplines.</p><p>The fact of the matter is, there is often much more to our data than we can represent in lists, data frames, or tensors alone. While there are ways to explore our data and present it in such a way that we can hypothesize relationships and even enable our algorithms to predict these, when we’re able to represent the connections between our data in a different way, we’re able to <em>do more</em> with the data that we have.</p><p>When we understand the ways in which <em>things </em>relate to one another, we understand them better: we can make more comprehensive predictions, and answer harder questions, with some pretty life changing results.</p><p><em>Want to learn more? Check out the rest of the series:</em></p><ul><li><a href="https://sid-arcidiacono.medium.com/graph-convolutional-networks-explained-d88566682b8f?source=your_stories_page-------------------------------------">Graph Convolutional Networks — Explained</a></li><li><a href="https://towardsdatascience.com/what-makes-graph-convolutional-networks-work-53badade0ce9?source=your_stories_page-------------------------------------">What Makes Graph Convolutional Networks Work?</a></li><li><a href="https://towardsdatascience.com/classifying-the-proteins-benchmark-dataset-ec18e728a17a?source=your_stories_page-------------------------------------">Classifying the PROTEINS Benchmark Dataset</a></li></ul><p><strong>Attributions:</strong></p><ol><li><a href="https://towardsdatascience.com/graph-theory-and-deep-learning-know-hows-6556b0e9891b?gi=62c6142fc84c">Everything You Need to Know About Graph Theory and Machine Learning</a></li><li><a href="https://medium.com/swlh/graph-theory-machine-learning-in-neuroscience-30f9bec5d182">Graph Theory &amp; Machine Learning in Neuroscience</a></li><li><a href="https://www.kdnuggets.com/2019/08/neighbours-machine-learning-graphs.html">Knowing Your Neighbours — Machine Learning on Graphs</a></li><li><a href="https://www.nature.com/articles/s41698-017-0029-7">Network-based machine learning and graph theory algorithms for precision oncology</a></li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4df73e2a4950" width="1" height="1" alt=""><hr><p><a href="https://medium.com/data-science/why-graph-theory-is-cooler-than-you-thought-4df73e2a4950">Why Graph Theory is Cooler Than you Thought</a> was originally published in <a href="https://medium.com/data-science">TDS Archive</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[To the Others Like Me…]]></title>
            <link>https://sid-arcidiacono.medium.com/to-the-others-like-me-f9ecb82b28c9?source=rss-77c814d7979d------2</link>
            <guid isPermaLink="false">https://medium.com/p/f9ecb82b28c9</guid>
            <category><![CDATA[representation]]></category>
            <category><![CDATA[speech]]></category>
            <category><![CDATA[tech]]></category>
            <category><![CDATA[communication]]></category>
            <category><![CDATA[empowerment]]></category>
            <dc:creator><![CDATA[Sid Arcidiacono]]></dc:creator>
            <pubDate>Mon, 09 Nov 2020 20:07:33 GMT</pubDate>
            <atom:updated>2020-11-09T23:20:35.782Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CY9uB3tKQQamnUE7owWJ6w.jpeg" /></figure><p>To the others like me, who don’t belong in tech. Others, who, like me, never saw a future for themselves — let alone one like this. Others who never saw themselves as seeking a career, an office job. Others like me who never thought they could change the world or build something new. Others like me who reminisce too often about childhood friends that will never have the chance to “turn things around”, who live with the weight of the privilege of walking away from a life that tried too hard to claim theirs.</p><p>Some of us are members of groups that are historically marginalized and underrepresented in tech to begin with. Some of us may fit in better. But we all carry the sense of being unable to relate to our peers. Hiding certain tattoos, not speaking about the past, we are dedicated to moving forward, to making something of ourselves. We don’t speak about survivor’s guilt, about how “turning life around” requires walking away from everything we once knew.</p><p>To the others like me, who aren’t sure if they can make it in this world of savvy children of entrepreneurs and venture capitalists, these clean-cut kids who had robotics clubs and programming courses in their high schools, I am here to tell you you can.</p><p>To the others like me, who consider what their childhood friends would say if they were here to see them now, who may be seen as stuck up by their own families: you do belong, if you want to.</p><p>To the others like me, who feel like traitors: you have this chance to do good for your loved ones. Too often it won’t feel like you’re doing anybody any good but yourself, but you are providing yourself the opportunity to make real change. What you do with these new found powers is up to you and you alone. There is a way to stay true to yourself and your background and provide a better life for yourself and your children than the one you grew up with.</p><p>To the others like me who know that speaking about class and race in tech is more than diversity initiatives and claiming that everyone belongs, we can change things. Understanding what a big leap it is for anyone to walk away from their neighborhood, their friends, understanding that culturally <em>this is not a choice some can make</em>, we can provide the foundation for “turning things around” to be seen as acceptable for our children and their peers. We can make making things better an option, we can bring resources back to our communities, and we can demonstrate our own worth: to ourselves, our peers, our mentors and instructors.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f9ecb82b28c9" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Sensitivity Training]]></title>
            <link>https://sid-arcidiacono.medium.com/sensitivity-training-2bf6f56526c0?source=rss-77c814d7979d------2</link>
            <guid isPermaLink="false">https://medium.com/p/2bf6f56526c0</guid>
            <category><![CDATA[self-improvement]]></category>
            <category><![CDATA[communication]]></category>
            <category><![CDATA[adaptability]]></category>
            <category><![CDATA[self-awareness]]></category>
            <category><![CDATA[humor]]></category>
            <dc:creator><![CDATA[Sid Arcidiacono]]></dc:creator>
            <pubDate>Mon, 28 Sep 2020 16:28:43 GMT</pubDate>
            <atom:updated>2020-10-02T22:03:59.162Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lV1nrmIm2M3kghO_0YJ0xw.png" /><figcaption>Palm Trees in a neighborhood I stayed in in LA</figcaption></figure><p>It’s fair to say that I have not always been the most humorous person. Growing up, I was teased quite a bit for being a bit too studious, wearing glasses, and knowing all the answers. As time went on, I got contact lenses, stopped raising my hand in class, stopped trying to be too friendly, and exited the traditional school environment as quickly as I could. Living in some interesting environments at the time, I straddled a strange line between being very young and professionally accomplished, and simultaneously needing (for a multitude of reasons) to stay close to peers engaging in behaviors that were anything but “professional”. When attempting to go to college the first two times, and integrate into these new social environments, I found myself in a position similar to high school: unable to relate to my scholarly peers on any kind of level beyond having classes together, and eventually leaving, feeling as though I didn’t belong, or didn’t deserve to be there.</p><p>Fast forward to today, after years of working to dramatically change my circumstances. Attempting to integrate is often clumsy, and this awkwardness I feel is most noticeable in my attempts at humor. Serious, deadpan, and dry, what was once seen as witty in prior social circles now often either goes unnoticed or is seen as intensely critical rather than funny. Observant to an extreme degree, cutting or sarcastic comments about things no one else may notice about a stranger once were praised and met with laughter, but now are met with comments like, “that’s a little mean.” In getting to know this new social group, I am learning how to adopt to more accepted forms of humor, rather than defensive humor. Things that my new peers find very funny and relatable leave me feeling a bit like I’ve been living under a rock for several years, but I’m slowly growing to appreciate this slightly friendlier and sweeter form of humor, shared in Zoom chats and Slack channels.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2bf6f56526c0" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[I love your take on French versus American humor.]]></title>
            <link>https://sid-arcidiacono.medium.com/i-love-your-take-on-french-versus-american-humor-4fb2022ae698?source=rss-77c814d7979d------2</link>
            <guid isPermaLink="false">https://medium.com/p/4fb2022ae698</guid>
            <dc:creator><![CDATA[Sid Arcidiacono]]></dc:creator>
            <pubDate>Mon, 28 Sep 2020 15:59:59 GMT</pubDate>
            <atom:updated>2020-09-28T15:59:59.199Z</atom:updated>
            <content:encoded><![CDATA[<p>I love your take on French versus American humor. Your anecdote about Le Pére Noël est une Ordure reminds me of reading Martin McDonagh for a literature class. While I loved the fact that all his characters were deeply flawed and terrible, most of my classmates were a bit confused by this. We Americans are very groomed to seek out a protagonist, and quite honestly, in life things are rarely that simple. The realism adds to the comedy, if you&#39;re prepared to see the satirical humor in it. Thank you so much for sharing this perspective!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4fb2022ae698" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>