To understand machine learning concepts practically, we will build a simple Proof of Concept (PoC) demo that uses Google Prediction API, and we will apply the predictive results on the Salesforce records. The aim of this exercise is to help you understand the basic steps of machine learning without digging into minute details and to get some idea of how we can leverage external machine learning algorithms on Salesforce data and the power we add to the Salesforce data through machine learning.
Google offers a simple Prediction API. These are predefined models.
The regression type predictive model uses a numeric answer for the question based on the previous samples. For this example, we will use this regression type predictive model. Take a look at the file located at (https://github.com/PacktPublishing/Learning-Salesforce-Einstein/blob/master/Chapter1/SFOpportunity.csv). The first column is probability, the second column is opportunity stage and the last column is the opportunity revenue. If you look carefully, you will notice that there is some correlation between the type of opportunity, expected revenue, and probability.
If you observe the dataset sample closely, you will see that for opportunities of type Existing customers, the higher the expected revenue, the more the probability.
To train the Dataset, we will leverage the Prediction API provided by Google. The complete set of APIs is listed in the following table:
If you recall, machine learning consists of three steps:
- Load the sample dataset.
- Train the data.
- Use the generated function to predict the outcome for the new Dataset.
The following diagram shows the Integration Architecture that we have adopted for experimenting with Google Prediction API and Salesforce Data:
Integration Architecture For Using Google Prediction API with Salesforce
The data will be loaded into the Google Cloud bucket and trained using Prediction API manually using the console, and a model is formed. We will submit the query to the formed model by triggering an HTTP request to the Google Prediction API from Salesforce. The architecture is purposefully kept very simple to help readers grasp the fundamentals before we approach Prediction API in detail.
Note
If you have multiple Google accounts, it is recommended that you use the incognito mode of browser to experiment.
The following are the steps required to train the dataset via Google Prediction API. Note that we will use prediction.trainedmodels.insert
to train the model:
- Load the Sample Dataset: At this point, the assumption is that you have extracted data out of the Salesforce opportunity object and loaded it into the Google Cloud Storage. The steps are covered in the prerequisites section.
The following screenshot shows how one can train the model:
The request and response JSON are shown as follows. Note that the learned-maker-155103
is the
Project ID. Replace with your current Project ID.
Request Payload:
POST https://www.googleapis.com/prediction/v1.6/projects
/learned-maker-155103/trainedmodels
{
"modelType": "regression",
"id": "opportunity-predictor",
"storageDataLocation":
"salesforceeinstein/SFOpportunity.csv"
}
Note
In the previous request JSON, the learned-marker-155103
is the Project ID of the Google project. For the ID value, one can choose anything and it is used to track the status of the model training
Carefully, note that we have pointed the location in Cloud Storage where our data resides. Once successful, we get a response from the API, which is shown as follows:
Response Payload:
200
{
"kind": "prediction#training",
"id" : "opportunity-predictor",
"selfLink": "https://www.googleapis.com/prediction/v1.6
/projects/learned-maker-155103/trainedmodels/opportunity-
predictor", "storageDataLocation":
"salesforceeinstein/SFOpportunity.csv"
}
We can monitor the status of the data training via API prediction.trainedmodels.get
.
The request to execute in the console is as follows:
Request Payload:
GET https://www.googleapis.com/prediction/v1.6/
projects/learned-maker-155103/trainedmodels/opportunity-
predictor
Response Payload:
200
{
"kind": "prediction#training",
"id": " opportunity-predictor",
"selfLink": "https://www.googleapis.com/prediction/v1.6/
projects/learned-maker-155103/trainedmodels/opportunity-
predict",
"created": "2017-01-18T19:10:27.752Z",
"trainingComplete": "2017-01-18T19:10:48.584Z",
"modelInfo": {
"numberInstances": "18",
"modelType": "regression",
"meanSquaredError": "79.61"
},
"trainingStatus": "DONE"
}
You will get a response showing the training status, which is shown here:
DONE
Note that if your data does not have any correlation, then you will see a very high value of meanSquaredError
.
- Using the trained Dataset to predict the outcome: For this, we will create a simple trigger on the opportunity object in Salesforce to make an asynchronous API call to invoke the Google Prediction API to predict the probability of opportunity closure.
Before we add Triggers to Salesforce, make sure that Predicted_Probability
field is created in the Salesforce. To create a field in Salesforce follow the following steps:
- Navigate to
SETUP
| Object Manager
| Opportunity
in Lightning experience or Setup
| Opportunities
| Fields
| New
in Classic experience. - Select the
Field
type as Number (with length as 5 and decimal places as 2) and follow the defaults and save:
The trigger code uses Apex, which is similar to JAVA provided by the Salesforce platform to write business logic. For the purposes of demonstration, we will keep the code very simple:
//Trigger makes an API call to Google Prediction API
to predict opportunity probability
//Please note that this trigger is written for demonstration
purpose only and not bulkified or batched
trigger opportunityPredictor on Opportunity (after insert) {
if(trigger.isinsert && trigger.isAfter){
OpportunityTriggerHelper.predictProbability
(trigger.new[0].Id);
}
}
Note
If you are using Salesforce Classic, the navigation path to add that trigger an opportunity is SETUP
| Customize
| Opportunities
| Triggers
.
For Lightning experience, the path is SETUP
| Triggers
| Developer Console
. Use Developer Console
to create a trigger
Also note that since triggers use apex classes, first save the dependent apex classes before saving the apex trigger.
The Apex class that is invoked from the trigger is as follows:
SETUP
| Develop
| Apex Classes
//Apex Class to make a Callout to Google Prediction API
public with sharing class opportunityTriggerHelper{
@future(callout=true)
public static void predictProbability(Id OpportunityId){
Opportunity oppData = [Select Id,Amount,Type,
Predicted_Probability__c from Opportunity where Id =
:OpportunityId];
HttpRequest req = new HttpRequest();
req.setEndpoint('callout:Google_Auth');
req.setMethod('POST');
req.setHeader('content-type','application/json');
//Form the Body
PredictionAPIInput apiInput = new PredictionAPIInput();
PredictionAPIInput.csvData csvData =
new PredictionAPIInput.csvData();
csvData.csvInstance = new list<String>{
oppData.Type,String.valueof(oppData.Amount)};
apiInput.input = csvData;
Http http = new Http();
req.setBody(JSON.serialize(apiInput));
HTTPResponse res = http.send(req);
System.debug(res.getBody());
if(res.getStatusCode() == 200){
Map<String, Object> result = (Map<String, Object>)
JSON.deserializeUntyped(res.getBody());
oppData.Predicted_Probability__c =
Decimal.valueof((string)result.get('outputValue'));
update oppData;
}
}
}
The apex class for parsing the JSON is as follows:
public class PredictionAPIInput {
public csvData input;
public class csvData {
public String[] csvInstance;
}
}
Note
Salesforce Apex offers HTTP methods for us to make calls to an external API. We are leveraging that and the configuration in the named credential to make an HTTP request to the Google Prediction API.
Setting authentication for calling API from SFDC
To simplify the authentication, we will use a named credential in Salesforce and auth settings to keep it configurable. Note that this is not scalable, but it's a quick way to integrate Salesforce with Google for the purposes of demonstration only. You can use a service account or set up a full OAuth 2.0 if you are considering a scalable approach.
The steps to authorize Salesforce to access the Google Prediction API are as follows:
Generate a client
ID
and client
secret
via the Google Auth screen. To generate this, navigate to the console URL (https://console.developers.google.com/apis/credentials). Choose the subtab Oauth consent screen
and fill in the Product name shown to users
as Salesforce
and save the OAuth consent screen
form.
The following screenshot shows the OAuth consent screen
and details one has to fill in to generate the Consumer Secret
and Consumer Key
:
Once an OAuth consent screen
is created, create a web application and note the Consumer Secret
and Consumer Key
. This will be used in the Salesforce Auth. Provider
screen:
- Use
Auth in Salesforce
to set up authorization, as shown in the following screenshot. The path for it is SETUP
| Security Controls
| Auth. Providers | New
Select the Provider Type as Google
. The following screenshot shows the form. Note that we use the Consumer Key
and Consumer Secret
from step 1 as input to the Auth. Provider
form:
The following screenshot shows the saved Auth. Provider
record. Note the Callback URL
as it will be fed back to the Google OAuth consent screen
:
- Note down the
Callback URL
from the Auth. Provider
screen. The Callback URL
needs to be added back to the Google Auth screen. The following screenshot shows the redirect URL configuration in the Google OAuth screen:
- Use
Named Credentials
so that we avoid passing the authorization token. Carefully note the scope defined in the SETUP
. The path for it in Classic is: Setup
| Security Controls
| Named Credentials:
- Testing out the results is the final step to test our model and use it with a real-time record creation screen in Salesforce. Create an opportunity record and indicate the type and the amount of opportunity. Once a Salesforce record is inserted, a trigger fires, calling the Prediction API with a new Dataset, and the result is stored back in the custom probability field.
Note
Note that if you get an authentication error in the logs, go to Named Credentials
to authorize the app again.
The API that the Apex trigger code hits is as follows:
https://www.googleapis.com/prediction/v1.6/projects/learned-maker-155103/trainedmodels/opportunity-predictor/predict
To test, create the Salesforce new record and add fields such as type and amount and monitor the custom probability field on the Salesforce opportunity record.
Note
Note that we are using the custom field for probability. Also note that we have switched our Salesforce organization to use new Lightning Experience. Salesforce offers Classic and Lightning Experience. Classic is an older user interface, while Lightning Experience is a modern interface. To enable Lightning Experience in your developer org under the Setup
menu you will find a menu item named Switch To Lightning Experience. You can always toggle between Lightning and Classic in your developer org.
To switch to the Salesforce Lightning experience, consider the following screenshot:
The following screenshot shows the results obtained in Lightning Experience, and, clearly, the Predicted_Probability field is populated: