Showing posts with label data. Show all posts
Showing posts with label data. Show all posts

Wednesday, January 10, 2018

Generate Music using Machine learning


The Google Brain team has a very cool project called Magenta.  It can be used for music and art generation.

I tried out a simple way to generate music using their Machine Learning models.

Steps taken on OS X:
1) install Docker and launch it, if it's not already running
2) launch a Terminal window
3) run the following command to start the Docker container
docker run -it -p 6006:6006 -v /tmp/magenta:/magenta-data tensorflow/magenta
4) After the Docker container is started, run the following command to generate 10 midi files (you can repeat this command to generate more)
melody_rnn_generate \
  --config=lookback_rnn \
  --bundle_file=/magenta-models/lookback_rnn.mag \
  --output_dir=/magenta-data/lookback_rnn/generated \
  --num_outputs=10 \
  --num_steps=128 \
  --primer_melody="[60]"
5) Open Finder and choose go to folder and enter /tmp/magenta for the folder
6) Copy the midi files to somewhere like your desktop to save the files
7) You can play the files in GarageBand or another music program like Ableton
8) If you'd like to use the files in a song that you create I would suggest using them as background percussion or something that fits with the sort of random nature of the notes in the midi files

Note: you can probably do far more interesting things than this if you tweak the command and / or model.

Hope that you enjoy.  Cheers.

Kristian

P.S. Here's something from the news that might serve as further inspiration - https://www.marketwatch.com/story/nvidia-taught-ai-to-compose-a-star-wars-song-like-john-williams-2018-01-08 .

Tuesday, April 26, 2016

Simple node.js app using YQL and Mailgun

YQL is a great and very responsive service for fetching JSON data.

Here's a simple example query.  The test button allows you to get a sample of the results and get a REST URL.

Here is some example code for fetching some ticker data.

// Get query results from Yahoo's YQL service
var request = require('request');
var fs = require('fs');

// # INSERT YOUR URLs HERE
var urls = [...];

// formatAsHtml - helper for formatting strings as simple HTML
var formatAsHtml = function (inputString, htmlTag) {
    switch (htmlTag) {
        case "b":
            formattedResult = "<b>" + inputString + "</b>";
            break;
        case "i":
            formattedResult = "<i>" + inputString + "</i>";
            break;
        case "h1":
            formattedResult = "<h1>" + inputString + "</h1>";
            break;
        case "h2":
            formattedResult = "<h2>" + inputString + "</h2>";
            break;
        case "h3":
            formattedResult = "<h3>" + inputString + "</h3>";
            break;
        case "hr":
            formattedResult = inputString + "<hr/>";
            break;
    }
    formattedResult += "<br/>";
 
    return formattedResult;
}

// logOrganizedResults - prep results for html file
var logOrganizedResults =  function (error, response, body) {
    if (!error && response.statusCode === 200) {
        console.log(formatAsHtml("Symbol " + response.body.query.results.quote.symbol,"b"));
        console.log("Name " + response.body.query.results.quote.Name);
        console.log(formatAsHtml("LastTradeWithTime " + response.body.query.results.quote.LastTradeWithTime, "i"));
        console.log(formatAsHtml("Change_PercentChange " + response.body.query.results.quote.Change_PercentChange,"b"));
        console.log("Volume " + response.body.query.results.quote.Volume);
        console.log("YearRange " + response.body.query.results.quote.YearRange);
        console.log("PercebtChangeFromYearHigh " + response.body.query.results.quote.PercebtChangeFromYearHigh);
        console.log("DaysHigh " + response.body.query.results.quote.DaysHigh);
        console.log("DaysLow " + response.body.query.results.quote.DaysLow);
        console.log(formatAsHtml("\r\n","hr"));
    } else {
        console.error(error);
    }
};

// Request data from Yahoo's YQL service
for (var i = 0; i < urls.length; i++) {
    request({url: urls[i], json: true}, logOrganizedResults);
}

You can name this node.js file as app.js or whatever you choose and run it as "node app.js > results.html" on Windows (*nix should be similar).

To send an email of the results you can do the following with the Mailgun API.

var Mailgun = require('mailgun-js');
var api_key = 'YOURKEYGOESHERE';
var domain = 'YOURDOMAINGOESHERE';
var from_who = 'YOURFROMEMAILGOESHERE';

var path = require("path");
var fp = [path.join(__dirname, 'results.html')];
var data = {
    from: from_who,
    to: "RECIPIENTGOESHERE",
    subject: 'SUBJECTGOESHERE',
    text: 'Your query results are attached.',
    attachment: fp
};

// submitEmailWithAttachment - sends email with attachment(s)
var submitEmailWithAttachment = function() {
    var mailgun = new Mailgun({apiKey: api_key, domain: domain});

    mailgun.messages().send(data, function (error, body) {
        if (error) {
            console.log('error', {error: error});
        }
        else {
            console.log("attachment sent", fp);
        }
    });
};

// Send email with the query results
submitEmailWithAttachment();

Then to put it all together, you can run it with a batch file (contents below), or a shell script on *nix.

del *.html
node app.js > results.html
node sendEmail.js

Alternatively, you could use the async npm module or some other flow control module.  Then you could host the node app in AWS Lamba, Azure, etc...  You could also improve the code a bit by refactoring and adding unit tests with Chai, or something similar.  Cheers.

P.S. The source is now on Github - https://github.com/kristianjaeger/StockDataEmailer .