@@ -5,29 +5,15 @@ date: '`r Sys.Date()`'
5
5
---
6
6
7
7
``` {r setup, include=FALSE}
8
- knitr::opts_chunk$set(echo = TRUE)
8
+ knitr::opts_chunk$set(echo = TRUE, tidy=TRUE, size="large", tidy.opts=list( width.cutoff=60) )
9
9
10
10
do_eval<-FALSE
11
11
```
12
12
13
13
``` {r autodoc, child='AboutMeTech.Rmd', eval=TRUE}
14
14
```
15
15
16
- # SQL Server
17
16
18
- ## Overview
19
- - RDBMS
20
- - Use on physical or virtual machines
21
-
22
- ## Key things to manage
23
- - Data
24
- - Code
25
- - Permissions
26
- - Licences
27
-
28
- ## Next steps
29
- - [ Books Online] ( https://msdn.microsoft.com/en-us/library/ms130214.aspx )
30
- - [ SQL Server Central] ( http://www.sqlservercentral.com/ )
31
17
32
18
33
19
# R
@@ -50,7 +36,7 @@ ggplot2::qplot(mpg, wt, data = mtcars, colour = cyl)
50
36
## Versions
51
37
- [ "Standard" R] ( https://r-project.org )
52
38
- [ Microsoft R Open] ( https://mran.revolutionanalytics.com/download/ )
53
- - [ Microsoft R Server] ( https://msdn.microsoft.com/en-us/library/mt674876.aspx )
39
+ - [ Microsoft ML Server] ( https://msdn.microsoft.com/en-us/library/mt674876.aspx )
54
40
- [ TERR] ( https://docs.tibco.com/products/tibco-enterprise-runtime-for-r )
55
41
- [ Oracle R] ( http://www.oracle.com/technetwork/database/database-technologies/r/r-distribution/overview/index.html )
56
42
@@ -61,44 +47,21 @@ ggplot2::qplot(mpg, wt, data = mtcars, colour = cyl)
61
47
62
48
## Next steps
63
49
- [ Learn R] ( https://datacamp.com )
64
- - [ Check out some of my other intros to R] ( http://stephlocke.info/Rtraining )
50
+ - [ Check out some of my other intros to R] ( http://itsalocke.com/talks )
65
51
66
52
# SQL Server + R Services
67
53
68
54
## Overview
69
- - Call R through SQL Server
70
-
71
- ## What's it look like?
72
- ``` {r include=FALSE, eval=do_eval}
73
- library(DBI)
74
- library(odbc)
75
- library(RODBCext)
76
- dbConn<-dbConnect(odbc(),
77
- driver="ODBC Driver 13 for SQL Server",
78
- server="51.140.63.137",
79
- database="rsqldemo1",
80
- uid="rsqldemo",
81
- pwd="oO)sqldemooO)sqldemoO)")
82
-
83
- dbstring<-'Driver={ODBC Driver 13 for SQL Server};Server=51.140.63.137;Database=rsqldemo1;Uid=rsqldemo;Pwd=oO)sqldemooO)sqldemoO)'
84
- dbconn<-RODBC::odbcDriverConnect(dbstring)
85
- ```
86
-
87
- ``` {sql, connection=dbConn, eval=do_eval}
88
- EXECUTE sp_execute_external_script
89
- @language = N'R'
90
- ,@script = N'OutputDataSet <- InputDataSet'
91
- ,@input_data_1 = N'SELECT 1 as Col'
92
- WITH RESULT SETS ((col varchar(50) not null))
93
- ```
94
-
55
+ - Use ` sp_execute_external_script ` to call R from SQL
56
+ - Store model objects in SQL Server
57
+ - Use certain models in a native PREDICT function
95
58
96
- ## 2016 Editions
97
- - Express - R Open or base R
59
+ ## 2016/2017 Editions
60
+ - Express (w/ Advanced tools) - R Open or base R
98
61
- Standard - R Open or base R
99
- - Enterprise - R Server
62
+ - Enterprise - ML Server
100
63
101
- [ SQL Server feature comparison] ( https://www .microsoft.com/en-ie /sql-server/sql-server-editions )
64
+ [ SQL Server feature comparison] ( https://docs .microsoft.com/en-us /sql/sql -server/editions-and-components-of- sql-server-2017#Programmability )
102
65
103
66
104
67
## Key things to manage
@@ -111,17 +74,45 @@ EXECUTE sp_execute_external_script
111
74
- [ Tomaz Kastrun blog] ( https://tomaztsql.wordpress.com/ )
112
75
- [ BOL] ( https://msdn.microsoft.com/en-us/library/mt604845.aspx )
113
76
114
- # DEMO
77
+ ## Connecting to our demo env
78
+ ``` {r eval=TRUE}
79
+ library(DBI)
80
+ library(odbc)
115
81
116
- ## Add some data
117
- ``` {r, eval=do_eval}
118
- dbWriteTable(dbConn, "iris", iris, overwrite=TRUE)
82
+ driver = "ODBC Driver 13 for SQL Server"
83
+ server = "sqlsat666.database.windows.net"
84
+ database = "sqlsat66"
85
+ uid = "lockedata"
86
+ pwd = "zll+.?=g8JA11111"
87
+
88
+ dbConn<-dbConnect(odbc(),
89
+ driver=driver, server=server,
90
+ database=database, uid=uid,
91
+ pwd=pwd)
119
92
```
120
93
94
+ ## Connecting to our demo env (extra)
95
+ ``` {r eval=TRUE}
96
+ library(RODBCext)
121
97
98
+ dbstring <- glue::glue('Driver={driver};Server={server};Database={database};Uid={uid};Pwd={pwd}')
99
+ dbconn <- RODBC::odbcDriverConnect(dbstring)
100
+ ```
101
+
102
+ ## A basic execution
103
+ ``` {sql connection=dbConn, eval=do_eval}
104
+ EXECUTE sp_execute_external_script
105
+ @language = N'R'
106
+ ,@script = N'OutputDataSet <- InputDataSet'
107
+ ,@input_data_1 = N'SELECT 1 as Col'
108
+ WITH RESULT SETS ((col varchar(50) not null))
109
+ ```
110
+
111
+ # DEMO PREP
122
112
123
113
## Setup model storage area
124
- ``` {sql, connection=dbConn, eval=do_eval}
114
+
115
+ ``` {sql, connection=dbConn, eval=do_eval, error=TRUE}
125
116
CREATE TABLE [companyModels] (
126
117
[id] int NOT NULL PRIMARY KEY IDENTITY (1,1)
127
118
, [name] varchar(200) NOT NULL
@@ -134,6 +125,10 @@ WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.companyModelsHistory));
134
125
```
135
126
136
127
## Model UPSERT stored procedure
128
+ ``` {sql, connection=dbConn, eval=do_eval, echo=FALSE, result="hide"}
129
+ DROP PROCEDURE IF EXISTS modelUpsert
130
+ ```
131
+
137
132
``` {sql, connection=dbConn, eval=do_eval}
138
133
CREATE PROCEDURE modelUpsert
139
134
@modelname varchar(200) ,
@@ -158,58 +153,153 @@ WHEN NOT MATCHED THEN INSERT
158
153
);
159
154
```
160
155
156
+ ## Add some data
157
+ ``` {r, echo=FALSE}
158
+ dbWriteTable(dbConn, "flights", nycflights13::flights[1:5000,], overwrite=TRUE)
159
+ ```
161
160
162
- ## Produce a basic model
163
- ``` {sql, connection=dbConn, error=TRUE}
164
- EXECUTE sp_execute_external_script
165
- @language = N'R'
166
- ,@script = N'
167
- irisLM<-lm(Sepal.Width~., InputDataSet)
168
- OutputDataSet<-data.frame(modelname="irisLM",
169
- modelobj=paste0(
170
- serialize(irisLM,NULL)
171
- ,collapse = "")
172
- )
173
- '
174
- ,@input_data_1 = N'SELECT * FROM iris'
161
+ ``` {r, eval=FALSE}
162
+ dbWriteTable(dbConn, "flights", nycflights13::flights, overwrite=TRUE)
175
163
```
176
164
165
+
166
+ # R DEMO
167
+
177
168
## Produce a basic model
178
169
``` {r}
179
- irisLM<-lm(Sepal.Width~., iris)
180
- modelobj<-paste0(serialize(irisLM,NULL),
181
- collapse = "")
170
+ library(nycflights13)
171
+ flightLM<- lm(arr_delay ~ month + day + hour, data=flights, model = FALSE)
172
+
173
+ flightLM
182
174
```
183
175
184
- ## Store a model
176
+ ## Use model in R
185
177
``` {r}
178
+ sample_flights<- flights[1:5,]
179
+ predict(flightLM, sample_flights)
180
+ ```
181
+
182
+ ## Publish model to Microsoft ML Server
183
+ [ mrsdeploy] ( https://docs.microsoft.com/en-us/machine-learning-server/operationalize/how-to-deploy-web-service-publish-manage-in-r )
184
+
185
+ ``` {r eval=FALSE}
186
+ publishService(
187
+ "basicFlightsLM",
188
+ code = NULL,
189
+ # --- `model` is required for web service with serviceType `Realtime` --- #
190
+ model = "model = flightsLM",
191
+ # --- `serviceType` is required for this web service --- #
192
+ serviceType = "Realtime"
193
+ )
194
+ ```
195
+
196
+ ## Store a model
197
+ ``` {r eval=do_eval}
186
198
RODBCext::sqlExecute(dbconn, "exec modelUpsert @modelname=? , @modelobj=?",
187
- data = data.frame("irisLM",modelobj))
199
+ data = data.frame("modelFromR", paste0( serialize(flightLM,NULL)
200
+ ,collapse = "")))
201
+ ```
202
+
203
+ # IN-SQL DEMO - ANY MODEL
204
+
205
+ ## Produce a basic model
206
+ ``` {sql, connection=dbConn, eval=do_eval, echo=FALSE, result="hide"}
207
+ DROP PROCEDURE IF EXISTS generate_flightlm
208
+ ```
209
+
210
+ ``` {sql, connection=dbConn, error=TRUE, eval=do_eval}
211
+ CREATE PROCEDURE generate_flightlm
212
+ AS
213
+ BEGIN
214
+ EXECUTE sp_execute_external_script
215
+ @language = N'R'
216
+ ,@script = N'
217
+ flightLM<-lm(arr_delay ~ month + day + hour, data=InputDataSet, model=FALSE)
218
+ OutputDataSet<-data.frame(modelname="modelFromInSQL",
219
+ modelobj=paste0( serialize(flightLM,NULL)
220
+ ,collapse = "") )
221
+ '
222
+ ,@input_data_1 = N'SELECT * FROM flights'
223
+ WITH RESULT SETS (([name] varchar(200) NOT NULL
224
+ , [modelObj] varbinary(max) ))
225
+ END
188
226
```
189
227
190
- ## Use a model
191
- ``` {sql, connection=dbConn}
228
+ ## Produce a basic model
229
+ ``` {sql, connection=dbConn, error=TRUE, eval=do_eval}
230
+ INSERT INTO companyModels(name, modelObj)
231
+ EXEC generate_flightlm
232
+ ```
233
+
234
+ ## Use model in SQL
235
+ ``` {sql, connection=dbConn, eval=do_eval}
192
236
DECLARE @mymodel VARBINARY(MAX)=(SELECT modelobj
193
237
FROM companymodels
194
- WHERE [name]='irisLM '
238
+ WHERE [name]='modelFromR '
195
239
);
196
240
EXEC sp_execute_external_script
197
241
@language = N'R',
198
242
@script = N'
199
- OutputDataSet<-cbind ( predict(unserialize(as.raw(model)), InputDataSet),
200
- InputDataSet
243
+ OutputDataSet<-data.frame ( predict(unserialize(as.raw(model)), InputDataSet),
244
+ InputDataSet[,"arr_delay"]
201
245
)
202
246
',
203
- @input_data_1 = N'SELECT [Sepal.Width],[Sepal.Length], [Petal.Width], [Petal.Length], Species from iris ',
247
+ @input_data_1 = N'SELECT TOP 5 * from flights ',
204
248
@params = N'@model varbinary(max)',
205
249
@model = @mymodel
206
250
WITH RESULT SETS ((
207
- [Sepal.Width.Pred] FLOAT (53) NULL,
208
- [Sepal.Width] FLOAT (53) NULL,
209
- [Sepal.Length] FLOAT (53) NULL,
210
- [Petal.Length] FLOAT (53) NULL,
211
- [Petal.Width] FLOAT (53) NULL,
212
- [Species] VARCHAR (255) NULL))
251
+ [arr_delay.Pred] FLOAT (53) NULL,
252
+ [arr_delay] FLOAT (53) NULL))
253
+ ```
254
+
255
+ # NATIVE SQL DEMO
256
+ ## Produce a basic model
257
+ ``` {sql, connection=dbConn, eval=do_eval, echo=FALSE, result="hide"}
258
+ DROP PROCEDURE IF EXISTS generate_flightlm2
259
+ ```
260
+
261
+ ``` {sql, connection=dbConn, error=TRUE, eval=do_eval}
262
+ CREATE PROCEDURE generate_flightlm2
263
+ AS
264
+ BEGIN
265
+ EXECUTE sp_execute_external_script
266
+ @language = N'R'
267
+ ,@script = N'
268
+ flightLM<-rxLinMod(arr_delay ~ month + day + hour, data=InputDataSet)
269
+ OutputDataSet<-data.frame(modelname="modelFromRevo",
270
+ modelobj= rxSerializeModel(flightLM, realtimeScoringOnly = TRUE) )
271
+ '
272
+ ,@input_data_1 = N'SELECT * FROM flights'
273
+ END
274
+ ```
275
+
276
+ ## Produce a basic model
277
+ ``` {sql, connection=dbConn, error=TRUE, eval=do_eval}
278
+ INSERT INTO companyModels([name],[modelobj])
279
+ EXEC generate_flightlm2
280
+ ```
281
+
282
+ ## Use model in SQL
283
+ ``` {sql, connection=dbConn, error=TRUE, eval=do_eval}
284
+ DECLARE @model varbinary(max) = (
285
+ SELECT modelobj
286
+ FROM companyModels
287
+ WHERE [name] = 'modelFromRevo');
288
+ SELECT TOP 10 d.*, p.*
289
+ FROM PREDICT(MODEL = @model, DATA = flights as d)
290
+ WITH(Pred float) as p;
291
+ ```
292
+
293
+ ## Use model in SQL
294
+ ``` {sql, connection=dbConn, error=TRUE, eval=do_eval}
295
+ DECLARE @model varbinary(max) = (
296
+ SELECT modelobj
297
+ FROM companyModels
298
+ WHERE [name] = 'modelFromRevo');
299
+
300
+ EXEC sp_rxPredict
301
+ @model = @model,
302
+ @inputData = N'SELECT TOP 10 * FROM flights'
213
303
```
214
304
215
305
# Deploying SQL Server & R Services
@@ -253,7 +343,12 @@ WITH RESULT SETS ((
253
343
- R graphics
254
344
255
345
# Wrapup
346
+ ## Microsoft resources
347
+ - https://docs.microsoft.com/en-us/sql/advanced-analytics/r/sql-server-r-services
348
+ - https://docs.microsoft.com/en-us/sql/advanced-analytics/r/how-to-do-realtime-scoring#native-scoring-with-predict
349
+ - https://blogs.msdn.microsoft.com/sqlserverstorageengine/2017/09/25/announcing-preview-of-machine-learning-services-with-r-support-in-azure-sql-database/
350
+
256
351
## Wrapup
257
352
- Thank you
258
- - Get the slides via [ lockedata.uk ] ( http://lockedata.uk )
259
- - Get in touch! [ T: SteffLocke] ( https://twitter.com/stefflocke )
353
+ - Get the slides via [ itsalocke.com ] ( http://itsalocke.com/talks )
354
+ - Get in touch! [ \@ SteffLocke] ( https://twitter.com/stefflocke )
0 commit comments