using machine learning to build connections between emotions

Similar projects worth following
After working on #bioloop, I wanted to develop software to understand other feelings than stress. rin is designed to interpret the connections between multiple emotions, providing the ability for computers to predict how a user feels based on minimal input.

I'm working on this section and will be clearing it up the project logs...

How rin works

To train the distance matrix, the user enters several emotions that they are and aren't feeling. The matrix is then populated with numbers. Cells where two emotions are NOT related (a yes and a no/mabye feeling) are increased by 1 or 0.5 (no or maybe). These are then clustered based on connection. Less connected emotions are grouped together with a hierarchal clustering model, until all 45 of the preset emotions are in 4 or 5 groups. The user then can be asked anytime if they are feeling a particular emotion, and the rest of the emotions in that group are returned. I still need to add more stuff so that the computer can council the user for each of the emotions, offering them assistance based on how they are feeling. 

Future Directions 

First, I want to make rin available as an easy to use android application so that anyone can use it for free without having to pay for hardware. Because I want rin to supplement mental health services, having it as free software is will make it more accessible. 

Because this is Hackaday, I also want to make hardware that runs rin, possibly in a self-contained handheld device or desktop assistant. Because all of my projects is written in python, I can either port it to C and use a microcontroller, or keep it in python and use a single-board computer in my design to simplify things greatly. I haven't decided which direction to take with this yet. 

  • log #8

    qquuiinn01/04/2018 at 09:05 0 comments

    I figured out the problem with the distances always defaulting to zero. This meant using complete linkage to determine the distance between two points in the distance matrix. Therefore, the training matrix I've been using nicely splits into four or five branches, before merging into one huge branch. This is a new problem: how do I know when to stop merging matrix elements? For now, I've decided to stop when 5 categories are created, which seems like a good balance between large groups and small, single cell clusters. 

    I also packaged everything into a single python file with a command prompt. This makes it really easy to train the matrix or run clustering pretty easily. The last function that I implemented asks the user for different emotions until they are feeling one, then it spits out the rest of the emotions clustered into that one. Right now, that's the absolute best that rin can do. 

    Past this point, I want to use these emotion clusters to do something more, perhaps provide comfort, relaxation, or praise through a virtual assistant. That part is significantly more complex and will probably involve tailoring specific responses for each of the 45 emotions in the matrix 

    But for now, you can go to the GitHub link on the side and download the mostly complete version of rin I have. Only get the file, and run it with python3, preferably in a new folder so there's a separate space for the storage files. 

  • Log #7

    qquuiinn01/03/2018 at 05:20 0 comments

    It took a bit of thinking, but I finally implemented the rest of the hierarchical clustering algorithm in python. However, there were a few fallbacks:

    For one, there's a LOT of blank spaces in the array. Right now, I'm trying to train a 45 * 45 emotion distance matrix entirely by hand. which involves sitting down at a computer several times a day and answering questions about my feelings to the python script that I wrote. I want rin to be able to adapt to each user, which means the user should train rin themselves as well, but this will take way more time than I ever imagined.

    I thought about shrinking the length of the emotional association list, but there's too many good description words for emotions in there. Maybe add a way for the user to reject emotions or use a matrix that only includes emotion data that they have chosen? 

    Either way, I'll keep training rin in hopes that I'll finally create a dense enough distance matrix. Right now, all the 0's are being jammed together, meaning that the first 10 emotions are all in one huge similarity tree. I don't want to extrapolate by assuming that the first 10 emotions are all similar, so I'm holding off on playing with the similarity data until I've trained rin more. 

  • log #6

    qquuiinn12/31/2017 at 05:53 0 comments

    I found the module that's in the smart speaker that I talked about in the last post. It's here in quantity one for US$15. There isn't a whole lot in the way of other projects that use this module, but the manufacturer has a nice GitHub page with all of the chipset info on it, and I can copy the schematic of the smart speaker module (which looks like a handful of resistors and inductors). It looks like the most I'll have to do is set up the bare module with support parts, wire up a USB-A female connector, and load openWRT through a flash drive. 

    I've been thinking more and more about implementing hierarchal clustering, which is all about finding the most connected pairs with the most similarities. However, the distance formula for single-link clustering implies that the most connected nodes will have the smallest numerical values attached to them. Before, I was increasing the value of emotion linkages that were find together, like finding 'relaxation' and 'joy' and connecting the two together. 

    Playing around, I inverted it, so that the only nodes that see their numerical score increased are the yes/no connections. So if the user is feeling 'joy' and not 'frustration,' the score at the location where those two intersect increases. In the first training session, I found that I got way more data stored on the matrix, and this makes a little sense. Rather than trying to infer emotional connections, I'll be throwing away the connections that don't make any sense together. It's true that before any extensive input, it will look like most emotions WILL be connected, but that's beyond the point. I'd rather expose new connections that I've never thought of before rather than explaining the ones I made already and recalling those. This makes the clustering formula easier to apply as well; I hope to have the code for that done by the end of my winter break.

  • log #5

    qquuiinn12/30/2017 at 05:57 0 comments

    I finished adding the ability to save to a file. Right now, the python command line application can ask the basic "how are you feeling?" question and save that data to an external matrix. This is half the battle: I can get the data from the user, but I can't do anything with it yet. With enough training, I can hopefully accumulate enough data over time to start playing with hierarchical clustering in the future. I'll be playing with either a web frontend or basic desktop GUI as well, I'd like something nicer looking if I don't do hardware. And stickers? Stickers. Rin stickers would be a fun way to have 'hardware' if I don't actually have any.

    Speaking of hardware, It's been on my mind more and more. Python is making life really easy for me, but there will eventually be a time where I have to port to a less powerful device than my laptop if I want to make a tomogatchi-style handheld. Thus, I've been looking for platforms that can conformably run full python while also being low-power and low-level enough for me to hack around. Think something less powerful than a raspberry pi zero, but more powerful than a esp32. 

    First, I've been considering the mediaTek MT7688. Seedstudio makes a development board based around that chipset that's relatively inexpensive, and the chip runs full linux. There's also an AcSip module that they used for a smart speaker board, which looks like a SMT module that I could roll into a completed PCB, but I can't find anything about that module online besides a datasheet from AcSip. Perhaps I could buy the smart speaker module, desolder the module and solder it into my final project? 

    Along those lines, I also checked out the VoCore, an openWRT single board computer that runs linux on an inexpensive, low power platform. This is my ideal platform, but I've been looking for standalone modules with the same chipset, which I can't find. I don't want to integrate a full dev board into my final project, so I'll keep looking.

    Ideally, I'd like to use something like the BeagleBone and move to the "Beaglebone on a chip" but the chip in question is around $50 for one?! The BeagleBone is a really good dev board with plenty of community support, though, so I may end up going with it. 

  • Log #4

    qquuiinn12/29/2017 at 05:17 0 comments

    I switched from C to Python for the proof-of-concept for rin. In fact, I might just ditch the hardware idea entirely and try to make rin into a full-featured python program, followed by some sort of web service that runs rin on a cloud instance. Really good software would be more accessible than hardware, and because rin probably won't be too resource intensive, a simple javascript webpage with python in the background with support for multiple users could be very, very cheap, somewhere around the range of $30 USD. 

  • Log #3

    qquuiinn12/24/2017 at 05:04 0 comments

    I threw up the GitHub repo on the links page, and am (trying) to spend more time finishing up the basic C implementation. 

  • Log #2: Learning C

    qquuiinn12/23/2017 at 04:00 0 comments

    Not much to report. I'm learning how to program in C (slowly), and might throw the GitHub up soon. I'll bring the project live by the end of the year, or around then. I'll also probably design project stickers for fun, or because I can. 

  • Log #1: Finding New Approaches

    qquuiinn12/21/2017 at 20:16 0 comments

    I've been spending a lot of time with Wikipedia trying to figure some details out about this project:

    First, using an NN may not be the best idea. It requires training data, and I don't think it would be the best idea to hand off an emotional model to somebody else to train, because I'm trying to get everything to emotionally adapt to the user, rather than have the user conform to someone else's. Instead, I'm trying to get something closer to grouping: grouping emotions together so that the learning model can infer other emotions. For example, if the user is feeling lonely, the model can infer that they're also feeling depressed. 

    The best way to pull that off, then, is to use hierarchical clustering to build a hierarchy of clusters. One cluster (emotion) can then be related to other clusters through linkage, measuring the euclidian distance between points to organize many emotions into only a few. Data would be stored in a distance matrix, which has a numerical value for the relatedness of two emotions. For example, the intersection between lonely and depressed would have a higher score than the intersection on the chart between lonely and hungry. You could also visualize it as a map with lines connecting different nodes, each connection scored based on strength. I'm still a little fuzzy on it, but I'll spend some more time researching.

    An alternative would be using the distance matrix, but focusing on single linkages which eliminates the need for an algorithm. That model would be less complex with inferences, but easier to implement with less false conclusions. 

    On the user input side of things, I found EARL, or the Emotion Annotation and Representation Language, which was designed to add emotion data to XML so computers could read it. EARL defines 48 simple human emotions, so I think that's a good start. The model will be asking "Do you feel X?" with X substituted for the emotion in question. As the distance matrix gets better and better, questions would be asked that follow well-known connections, as well as less-known connections between emotions to verify that they are still connected or not connected. 

    Building a distance matrix with all 48 EARL emotions and a floating point number in each matrix cell representing the average connectedness between two emotions would require 9216 bytes of data, or 18KB. Assuming I do all calculations in RAM, which would be faster than using an external flash chip, I would have to use a Teensy 3.2, which has 64KB of RAM. The LC has 8K, and the Arduino (ATMEGA328) has 2K, which isn't enough. I'll probably go with a 32 bit microcontroller anyway to speed up all the floating point math, but RAM will definitely be a pain point. I could, of course, just toss in a raspberry pi zero with python and an ML library, but where's the fun in that? It's possible I could get away with external SRAM or FRAM and constantly pull data over the SPI bus if that's fast enough. And half the emotions, 24, would squeeze the table just under 5K, enough for the LC assuring I don't use any other floating point numbers. 

View all 8 project logs

Enjoy this project?



PointyOintment wrote 07/24/2018 at 09:39 point

So it's like a Markov chain for user-identified emotions, except it's more of a web than a chain?

  Are you sure? yes | no

qquuiinn wrote 07/30/2018 at 21:51 point

Yes, the network is more like a web but the result is a grouping of emotions

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates