mirror of
https://github.com/Microsoft/sql-server-samples.git
synced 2025-12-08 14:58:54 +00:00
153 lines
12 KiB
Transact-SQL
153 lines
12 KiB
Transact-SQL
USE sales
|
|
GO
|
|
|
|
-- Create view used for ML services training stored procedure
|
|
CREATE OR ALTER VIEW [dbo].[web_clickstreams_hdfs_book_clicks]
|
|
AS
|
|
SELECT
|
|
/* There is bug in TPCx-BB data generator which results in data where all users have purchased books.
|
|
This will not work for the ML training purposes. So we will treat users with 1-5 clicks in the book category as
|
|
not interested in books. */
|
|
CASE WHEN q.clicks_in_category < 6 THEN 0 ELSE q.clicks_in_category END AS clicks_in_category,
|
|
CASE WHEN cd.cd_education_status IN ('Advanced Degree', 'College', '4 yr Degree', '2 yr Degree') THEN 1 ELSE 0 END AS college_education,
|
|
CASE WHEN cd.cd_gender = 'M' THEN 1 ELSE 0 END AS male,
|
|
COALESCE(cd.cd_credit_rating, 'Unknown') as cd_credit_rating,
|
|
q.clicks_in_1,
|
|
q.clicks_in_2,
|
|
q.clicks_in_3,
|
|
q.clicks_in_4,
|
|
q.clicks_in_5,
|
|
q.clicks_in_6,
|
|
q.clicks_in_7,
|
|
q.clicks_in_8,
|
|
q.clicks_in_9,
|
|
q.wcs_user_sk
|
|
FROM(
|
|
SELECT
|
|
w.wcs_user_sk,
|
|
SUM( CASE WHEN i.i_category = 'Books' THEN 1 ELSE 0 END) AS clicks_in_category,
|
|
SUM( CASE WHEN i.i_category_id = 1 THEN 1 ELSE 0 END) AS clicks_in_1,
|
|
SUM( CASE WHEN i.i_category_id = 2 THEN 1 ELSE 0 END) AS clicks_in_2,
|
|
SUM( CASE WHEN i.i_category_id = 3 THEN 1 ELSE 0 END) AS clicks_in_3,
|
|
SUM( CASE WHEN i.i_category_id = 4 THEN 1 ELSE 0 END) AS clicks_in_4,
|
|
SUM( CASE WHEN i.i_category_id = 5 THEN 1 ELSE 0 END) AS clicks_in_5,
|
|
SUM( CASE WHEN i.i_category_id = 6 THEN 1 ELSE 0 END) AS clicks_in_6,
|
|
SUM( CASE WHEN i.i_category_id = 7 THEN 1 ELSE 0 END) AS clicks_in_7,
|
|
SUM( CASE WHEN i.i_category_id = 8 THEN 1 ELSE 0 END) AS clicks_in_8,
|
|
SUM( CASE WHEN i.i_category_id = 9 THEN 1 ELSE 0 END) AS clicks_in_9
|
|
FROM web_clickstreams_hdfs_parquet as w
|
|
INNER JOIN item as i ON (w.wcs_item_sk = i_item_sk
|
|
AND w.wcs_user_sk IS NOT NULL)
|
|
GROUP BY w.wcs_user_sk
|
|
) AS q
|
|
INNER JOIN customer as c ON q.wcs_user_sk = c.c_customer_sk
|
|
INNER JOIN customer_demographics as cd ON c.c_current_cdemo_sk = cd.cd_demo_sk;
|
|
GO
|
|
|
|
-- Inspect top 100 rows
|
|
--
|
|
SELECT TOP(100) * FROM web_clickstreams_hdfs_book_clicks;
|
|
GO
|
|
|
|
-- Create the training stored procedure
|
|
CREATE OR ALTER PROCEDURE [dbo].[train_book_category_visitor_per_credit_rating_python]
|
|
(@model_name varchar(100))
|
|
AS
|
|
BEGIN
|
|
DECLARE @model varbinary(max)
|
|
, @model_native varbinary(max)
|
|
, @input_query nvarchar(max)
|
|
, @train_script nvarchar(max)
|
|
|
|
-- Set the input query for training. We will use 80% of the data.
|
|
SET @input_query = N'
|
|
SELECT TOP(80) PERCENT SIGN(q.clicks_in_category) AS book_category
|
|
, q.college_education
|
|
, q.male
|
|
, q.clicks_in_1
|
|
, q.clicks_in_2
|
|
, q.clicks_in_3
|
|
, q.clicks_in_4
|
|
, q.clicks_in_5
|
|
, q.clicks_in_6
|
|
, q.clicks_in_7
|
|
, q.clicks_in_8
|
|
, q.clicks_in_9
|
|
, q.cd_credit_rating
|
|
FROM web_clickstreams_hdfs_book_clicks as q
|
|
';
|
|
-- Training R script that uses rxLogit function from RevoScaleR package (Microsoft R Server) to generate model to predict book_category click(s).
|
|
SET @train_script = N'
|
|
# build classification model to predict book_category
|
|
import pickle
|
|
import pandas as pd
|
|
from revoscalepy import rx_logit, rx_serialize_model
|
|
|
|
# initialize the model variables returned to SQL Server
|
|
model = bytes()
|
|
model_native = bytes()
|
|
|
|
logit_model = rx_logit(formula = """
|
|
book_category ~ college_education + male +
|
|
clicks_in_1 + clicks_in_2 + clicks_in_3 + clicks_in_4 + clicks_in_5 +
|
|
clicks_in_6 + clicks_in_7 + clicks_in_8 + clicks_in_9
|
|
""", data = indata
|
|
, report_progress = 0);
|
|
|
|
model_native = rx_serialize_model(logit_model, realtime_scoring_only = True)
|
|
model = pickle.dumps(logit_model)
|
|
model_output = {"model_name": [model_name + " - " + indata["cd_credit_rating"].iloc[0]], "model": [model], "model_native": [model_native]}
|
|
OutputDataSet = pd.DataFrame(data=model_output, columns = ["model_name", "model", "model_native"])
|
|
';
|
|
|
|
-- Generate sales model using Python script with the book clicks stats for each user
|
|
-- Additionally we train a separate model for users in a specific credit rating
|
|
-- The @input_data_partition_by_columns provides the execution of the Python script per partition (credit rating in this case)
|
|
DELETE FROM sales_models WHERE model_name LIKE CONCAT(@model_name, '%');
|
|
|
|
INSERT INTO sales_models (model_name, model, model_native)
|
|
EXECUTE sp_execute_external_script
|
|
@language = N'Python'
|
|
, @script = @train_script
|
|
, @input_data_1 = @input_query
|
|
, @input_data_1_name = N'indata'
|
|
, @input_data_1_partition_by_columns = N'cd_credit_rating'
|
|
, @params = N'@model_name varchar(100)'
|
|
, @model_name = @model_name;
|
|
END;
|
|
GO
|
|
|
|
|
|
-- Step #1
|
|
-- Train the book category prediction model:
|
|
--
|
|
DECLARE @model_name varchar(100) = 'category_model_per_credit_rating (Python)';
|
|
EXECUTE [dbo].[train_book_category_visitor_per_credit_rating_python] @model_name;
|
|
SELECT * FROM sales_models WHERE model_name LIKE CONCAT(@model_name, '%');
|
|
GO
|
|
|
|
-- Step #2
|
|
-- Predict the book category clicks for new users based on their pattern of
|
|
-- visiting various categories in the web site
|
|
-- We will use the model trained for each credit rating
|
|
--
|
|
DECLARE @model_name varchar(100) = 'category_model_per_credit_rating (Python)', @credit_rating varchar(50) = 'Low Risk';
|
|
DECLARE @sales_model varbinary(max) = (SELECT model_native FROM sales_models WHERE model_name = CONCAT(@model_name, ' - ', @credit_rating));
|
|
SELECT TOP(100)
|
|
w.wcs_user_sk
|
|
, p.book_category_Pred as book_click_prediction
|
|
, w.college_education as [College Education]
|
|
, w.clicks_in_1 AS [Home & Kitchen]
|
|
, w.clicks_in_2 AS [Music]
|
|
, w.clicks_in_3 AS [Books]
|
|
, w.clicks_in_4 AS [Clothing & Accessories]
|
|
, w.clicks_in_5 AS [Electronics]
|
|
, w.clicks_in_6 AS [Tools & Home Improvement]
|
|
, w.clicks_in_7 AS [Toys & Games]
|
|
, w.clicks_in_8 AS [Movies & TV]
|
|
, w.clicks_in_9 AS [Sports & Outdoors]
|
|
FROM PREDICT(MODEL = @sales_model, DATA = web_clickstreams_hdfs_book_clicks as w) WITH ("book_category_Pred" float) as p
|
|
WHERE p.book_category_Pred <> SIGN(w.clicks_in_category)
|
|
and w.cd_credit_rating = @credit_rating;
|
|
GO
|