mirror of
https://github.com/Microsoft/sql-server-samples.git
synced 2025-12-08 14:58:54 +00:00
update retail precision marketing demo
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 97 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 678 KiB |
@@ -1,284 +0,0 @@
|
|||||||
#############################################################
|
|
||||||
#CRM Demo on CDNOW
|
|
||||||
#Microsoft
|
|
||||||
#############################################################
|
|
||||||
##check if necessary R packages are installed
|
|
||||||
install.packages("RODBC")
|
|
||||||
|
|
||||||
library(RODBC)
|
|
||||||
|
|
||||||
##set directory
|
|
||||||
setwd("C:/Users/zhouf/Documents/Revolution Analytics/Demo/RREDemo/CRM")
|
|
||||||
data.path<-"C:/Users/zhouf/Documents/Revolution Analytics/Demo/RREDemo/CRM/Data/CDNOW_master"
|
|
||||||
output.path<-"C:/Users/zhouf/Documents/Revolution Analytics/Demo/RREDemo/CRM/Output/Xdf"
|
|
||||||
|
|
||||||
##Set Compute Context
|
|
||||||
#rxOptions(computeContext=RxLocalSeq())
|
|
||||||
rxOptions(computeContext=RxLocalParallel())
|
|
||||||
rxOptions(xdfCompressionLevel = -1)
|
|
||||||
rxOptions(reportProgress=1)
|
|
||||||
#-----------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
##Connect to SQL database via RxOdbcData
|
|
||||||
CRMSQL = "SELECT * FROM dbo.CDNOW"
|
|
||||||
CRMDS<- RxOdbcData(sqlQuery = CRMSQL,
|
|
||||||
connectionString = "Driver={SQL Server Native Client 11.0};
|
|
||||||
Server=tcp:sqlserver2012-81yms1ai.cloudapp.net,57500;
|
|
||||||
Database=RREDemoSql;Uid=zhouf;Pwd=Microsoft1;")
|
|
||||||
|
|
||||||
CRMDS<- RxOdbcData(sqlQuery = CRMSQL,
|
|
||||||
connectionString = "Driver=SQL Server;
|
|
||||||
Server=tcp:192.168.220.128,1433;
|
|
||||||
Database=sqlr;
|
|
||||||
Uid=sa;
|
|
||||||
Pwd=Microsoft1")
|
|
||||||
|
|
||||||
#CRMDS<- RxOdbcData(sqlQuery = CRMSQL,
|
|
||||||
# connectionString = "Driver={SQL Server Native Client 11.0};Server=tcp:168.63.172.116,57500;Database=RREDemoSql;Uid=zhouf;Pwd=Microsoft1;")
|
|
||||||
#CRMDS<- RxOdbcData(sqlQuery = CRMSQL,
|
|
||||||
#connectionString = "DSN=MiningDatabaseSql;Uid=zhouf;Pwd=Microsoft1;")
|
|
||||||
#CRMDataFile <- RxXdfData("CDNOW_master.xdf")
|
|
||||||
CRMDataFile<-file.path(output.path,"CDNOW_master.xdf")
|
|
||||||
##Read data with RRE
|
|
||||||
dfcolInfo<-list(
|
|
||||||
ID=list(type="factor"),
|
|
||||||
Date=list(type="character"),
|
|
||||||
Volume=list(type="numeric"),
|
|
||||||
Amount=list(type="numeric")
|
|
||||||
)
|
|
||||||
rxImport(inData=CRMDS,outFile =CRMDataFile,colInfo=dfcolInfo,overwrite =TRUE,useFastRead=TRUE)
|
|
||||||
#rxImport(inData=CRMDS,outFile =CRMDataFile,overwrite =TRUE,useFastRead=TRUE)
|
|
||||||
rxGetInfo(CRMDataFile,getVarInfo=T,numRows=3)
|
|
||||||
#------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
##Connect to SQL database via odbcConnect
|
|
||||||
#channel<-odbcConnect("Driver={SQL Server Native Client 11.0};Server=tcp:sqlserver2012-81yms1ai.cloudapp.net,57500;Database=AIAPoVSql;Uid=zhouf;Pwd=Microsoft2;")
|
|
||||||
channel<-odbcConnect(dsn="MiningDatabaseSql",uid="zhouf",pwd="Microsoft1")
|
|
||||||
|
|
||||||
channel<-odbcDriverConnect(connection="Driver=SQL Server;
|
|
||||||
Server=tcp:192.168.176.132,1433;
|
|
||||||
Database=sqlr;
|
|
||||||
Uid=sa;
|
|
||||||
Pwd=Microsoft1")
|
|
||||||
##Read data from SQL via OSR
|
|
||||||
aia<-sqlQuery(channel,paste(" select * from dbo.AIOE_MODAL_RAWDATAL_revised"))
|
|
||||||
df<-sqlFetch(channel, 'CDNOW')
|
|
||||||
df<- sqlQuery(channel,paste("select * from dbo.CDNOW"))
|
|
||||||
#df.csv <- file.path(data.path,"CDNOW_master.csv")
|
|
||||||
df.xdf<-file.path(output.path,"CDNOW_master.xdf")
|
|
||||||
dfcolInfo<-list(
|
|
||||||
ID=list(type="factor"),
|
|
||||||
Date=list(type="Date"),
|
|
||||||
Volume=list(type="numeric"),
|
|
||||||
Amount=list(type="numeric")
|
|
||||||
)
|
|
||||||
rxImport(inData=df,outFile =df.xdf,colInfo=dfcolInfo,overwrite =TRUE,useFastRead=F)
|
|
||||||
rxGetInfo(df.xdf,getVarInfo=T,numRows=3)
|
|
||||||
#------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
df.xdf<-file.path(output.path,"CDNOW_master.xdf")
|
|
||||||
df1.xdf<-file.path(output.path,"CDNOW_master1.xdf")
|
|
||||||
rxDataStep(inData=df.xdf,outFile=df1.xdf,
|
|
||||||
transforms=list(
|
|
||||||
Date=as.Date(Date,"%Y-%m-%d")
|
|
||||||
),
|
|
||||||
removeMissings=TRUE,
|
|
||||||
overwrite=T)
|
|
||||||
rxGetInfo(df1.xdf,getVarInfo=T,numRows=3)
|
|
||||||
#rxSummary(~ID+Date+Volume+Amount,df.xdf)
|
|
||||||
|
|
||||||
##Step 1: RFM Model
|
|
||||||
# set the startDate and endDate, we will only analysis the records in this date range
|
|
||||||
RFMSQL="SELECT * FROM dbo.RFM_Result"
|
|
||||||
RFMDS<- RxOdbcData(sqlQuery = RFMSQL,
|
|
||||||
connectionString = "Driver=SQL Server;
|
|
||||||
Server=tcp:192.168.176.130,1433;
|
|
||||||
Database=sqlr;
|
|
||||||
Uid=sa;
|
|
||||||
Pwd=Microsoft1")
|
|
||||||
RFMResult.xdf<-file.path(output.path,"RFM_Result.xdf")
|
|
||||||
rxImport(inData=RFMDS,outFile =RFMResult.xdf,overwrite =TRUE,useFastRead=TRUE)
|
|
||||||
rxGetInfo(RFMResult.xdf,getVarInfo=T,numRows=3)
|
|
||||||
#visualize the RFM values
|
|
||||||
rxHistogram(~R,data=RFMResult.xdf, xNumTicks=20)
|
|
||||||
rxHistogram(~F,data=RFMResult.xdf,rowSelection=F<30,
|
|
||||||
xNumTicks=20)
|
|
||||||
rxHistogram(~M,data=RFMResult.xdf,rowSelection=M<200,
|
|
||||||
xNumTicks=20)
|
|
||||||
|
|
||||||
#count frequency of each RFMscore Level
|
|
||||||
tmp<-rxCube(~F(Total_Score),data=RFMResult.xdf)
|
|
||||||
results <- rxResultsDF(tmp)
|
|
||||||
results<-results[results$Counts!=0,]
|
|
||||||
results[order(results$Counts,decreasing=TRUE),]
|
|
||||||
|
|
||||||
##Step 2: K-means Clustering
|
|
||||||
|
|
||||||
#K-means Clustering
|
|
||||||
Kmeans.xdf<-file.path(output.path,"Kmeans.xdf")
|
|
||||||
md.km <- rxKmeans(formula=~R+F+M+R_Score+F_Score+M_Score,
|
|
||||||
data = RFMResult.xdf,
|
|
||||||
outFile =Kmeans.xdf,
|
|
||||||
numClusters=8,
|
|
||||||
algorithm = "lloyd",
|
|
||||||
writeModelVars=TRUE,
|
|
||||||
overwrite=TRUE)
|
|
||||||
rxGetInfo(Kmeans.xdf,getVarInfo=TRUE,numRows=10)
|
|
||||||
|
|
||||||
centers<-round(md.km$centers,digits=2)
|
|
||||||
size<-md.km$size
|
|
||||||
centers.txt<-file.path(output.path,"centers.txt")
|
|
||||||
write.table(centers,file=centers.txt,sep=" ")
|
|
||||||
size.txt<-file.path(output.path,"size.txt")
|
|
||||||
write.table(size,file=size.txt,sep=" ")
|
|
||||||
|
|
||||||
mdDf <- rxXdfToDataFrame(file=Kmeans.xdf)
|
|
||||||
head(mdDf)
|
|
||||||
plot(mdDf[,2:7],col=mdDf$.rxCluster)
|
|
||||||
title(main="RFM-based K-means on CDNOW Data",line=3)
|
|
||||||
##Step 3: Prediction-logistic and decision tree
|
|
||||||
|
|
||||||
##1.Prediction on Personal Customer Data without considering age and sex
|
|
||||||
#Create IsVIP variable
|
|
||||||
RFMVIP.xdf<-file.path(output.path,"RFMVIP.xdf")
|
|
||||||
rxDataStep(inData=RFMResult.xdf,outFile=RFMVIP.xdf,
|
|
||||||
transforms=list(IsVIP=ifelse(Toltal_Score>=441,1,0)),
|
|
||||||
overwrite=TRUE,reportProgress=1
|
|
||||||
)
|
|
||||||
RFMVIPInfo<-rxGetInfo(RFMVIP.xdf,getVarInfo=T,numRows=3)
|
|
||||||
|
|
||||||
#Write IsVIP and Cluster result to SQL database
|
|
||||||
RFMVIP.df<-rxXdfToDataFrame(file=RFMVIP.xdf)
|
|
||||||
Cluster<-factor(mdDf$.rxCluster)
|
|
||||||
RFMVIPCluster<-cbind(RFMVIP.df,Cluster)
|
|
||||||
sqlSave(channel,RFMVIPCluster,rownames=FALSE,append=FALSE,varTypes=list(numeric="float",integer="int",Date="date"))
|
|
||||||
|
|
||||||
|
|
||||||
#Creat training/testing data set
|
|
||||||
RD<-sample(1:10,RFMVIPInfo$numRows,replace=TRUE)
|
|
||||||
str(RD)
|
|
||||||
table(RD)
|
|
||||||
RFMVIPCluster$RD<-RD;
|
|
||||||
RFMVIPCluster.xdf<-file.path(output.path,"RFMVIPCluster.xdf")
|
|
||||||
rxDataFrameToXdf(data=RFMVIPCluster,outFile=RFMVIPCluster.xdf,overwrite=TRUE)
|
|
||||||
|
|
||||||
TrainTest.xdf<-file.path(output.path,"TrainTest.xdf")
|
|
||||||
rxDataStep(inData=RFMVIPCluster.xdf,outFile=TrainTest.xdf,
|
|
||||||
transforms=list(
|
|
||||||
urv=factor(ifelse(RD<=8,'TRAIN','TEST'))
|
|
||||||
),
|
|
||||||
overwrite=T)
|
|
||||||
rxGetInfo(TrainTest.xdf,T,numRows=3)
|
|
||||||
|
|
||||||
##Split data into training/testing data set
|
|
||||||
train.xdf <- file.path(output.path,'TrainTest.urv.TRAIN.xdf')
|
|
||||||
test.xdf <- file.path(output.path,'TrainTest.urv.TEST.xdf')
|
|
||||||
|
|
||||||
rxSplit(TrainTest.xdf,outFilesBase=TrainTest.xdf,splitByFactor='urv',overwrite=T,reportProgress=1)
|
|
||||||
|
|
||||||
##Build our Logistic Regression Model with IsVIP as response
|
|
||||||
r1<- rxLogit(IsVIP~R+F+M,
|
|
||||||
data =train.xdf,
|
|
||||||
variableSelection = rxStepControl(method="stepwise",
|
|
||||||
scope = ~ R+F+M))
|
|
||||||
summary(r1)
|
|
||||||
|
|
||||||
|
|
||||||
##r1:stepwise selection shows that Monetary,Recency are significant.
|
|
||||||
##Build our Logistic REgression MOdel
|
|
||||||
r2<- rxLogit(IsVIP ~R+F,
|
|
||||||
data =train.xdf,covCoef=TRUE)
|
|
||||||
summary(r2)
|
|
||||||
|
|
||||||
##Predict our Logistic Model on our test Dataset
|
|
||||||
LogisticPred.xdf<-file.path(output.path,"LogisticPred.xdf")
|
|
||||||
rxPredict(r2,data=test.xdf,outData=LogisticPred.xdf,writeModelVars = TRUE,extraVarsToWrite="ID",computeResiduals=TRUE,computeStdErr = TRUE,
|
|
||||||
interval = "confidence",predVarNames='LogitPredict',overwrite=TRUE)
|
|
||||||
rxGetInfo(LogisticPred.xdf,getVarInfo=T,numRows=10)
|
|
||||||
LogisticPredInfoTop10<-rxGetInfo(LogisticPred.xdf,getVarInfo=T,numRows=10)
|
|
||||||
LogisticPredInfoTop10.txt<-file.path(output.path,"LogisticPredInfoTop10.txt")
|
|
||||||
write.table(LogisticPredInfoTop10$data,file=LogisticPredInfoTop10.txt,sep=" ")
|
|
||||||
|
|
||||||
LogisticPred<-rxXdfToDataFrame(file=LogisticPred.xdf)
|
|
||||||
sqlSave(channel,LogisticPred,rownames=FALSE,append=FALSE,varTypes=list(numeric="float",integer="int",Date="date"))
|
|
||||||
|
|
||||||
|
|
||||||
##Draw a ROC curve
|
|
||||||
rxRocCurve(actualVarName='IsVIP',predVarNames='LogitPredict',data=LogisticPred.xdf)
|
|
||||||
|
|
||||||
##Build a Decision Tree with Cluster as response
|
|
||||||
d1 <- rxDTree(Cluster~R+F+M,data=train.xdf,blocksPerRead=5)
|
|
||||||
d1 <- rxDTree(Cluster~R_Score+F_Score+M_Score,data=train.xdf,blocksPerRead=5)
|
|
||||||
d1Cp<- rxDTreeBestCp(d1)
|
|
||||||
d1 <- prune.rxDTree(d1, cp=d1Cp)
|
|
||||||
d1
|
|
||||||
d2 <- rxDTree(Cluster~R+F+M,data=train.xdf, pruneCp="auto")
|
|
||||||
d2 <- rxDTree(Cluster~R_Score+F_Score+M_Score,data=train.xdf, pruneCp="auto")
|
|
||||||
d2
|
|
||||||
|
|
||||||
#View Decision Tree
|
|
||||||
#View 1
|
|
||||||
library(RevoTreeView)
|
|
||||||
plot(createTreeView(d1))
|
|
||||||
plot(createTreeView(d2))
|
|
||||||
|
|
||||||
#View 2
|
|
||||||
library(rpart)
|
|
||||||
plot(rxAddInheritance(d1))
|
|
||||||
text(rxAddInheritance(d1))
|
|
||||||
title(main="RFM-based Decision Tree on CDNOW Data",line=3)
|
|
||||||
plot(rxAddInheritance(d2))
|
|
||||||
text(rxAddInheritance(d2))
|
|
||||||
title(main="RFM-based Decision Tree on CDNOW Data",line=3)
|
|
||||||
|
|
||||||
#Prediction
|
|
||||||
DTreePred.xdf<-file.path(output.path,"DTreePred.xdf")
|
|
||||||
rxPredict(d2, data=test.xdf,outData=DTreePred.xdf,predVarNames=c('prob1','prob2','prob3','prob4','prob5','prob6','prob7','prob8'),writeModelVars = TRUE,extraVarsToWrite="ID",computeResiduals=T,overwrite=TRUE)
|
|
||||||
rxGetInfo(DTreePred.xdf,getVarInfo=T,numRows=3)
|
|
||||||
DTreePredInfoTop10<-rxGetInfo(DTreePred.xdf,getVarInfo=T,numRows=10)
|
|
||||||
DTreePredInfoTop10.txt<-file.path(output.path,"DTreePredInfoTop10.txt")
|
|
||||||
write.table(DTreePredInfoTop10$data,file=DTreePredInfoTop10.txt,sep=" ")
|
|
||||||
|
|
||||||
DTreePred<-rxXdfToDataFrame(file=DTreePred.xdf)
|
|
||||||
sqlSave(channel,DTreePred,rownames=FALSE,append=FALSE,varTypes=list(numeric="float",integer="int",Date="date"))
|
|
||||||
odbcClose(channel)
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------------
|
|
||||||
##Build a Decision Tree with IsVIP as response
|
|
||||||
d<-rxDTree(IsVIP~R+F+M,data=train.xdf,maxDepth=5,blocksPerRead=5)
|
|
||||||
d1 <- rxDTree(IsVIP~R+F+M,data=train.xdf,blocksPerRead=5)
|
|
||||||
d1
|
|
||||||
d1Cp<- rxDTreeBestCp(d1)
|
|
||||||
d1 <- prune.rxDTree(d1, cp=d1Cp)
|
|
||||||
d2 <- rxDTree(IsVIP~R+F+M,data=train.xdf, pruneCp="auto")
|
|
||||||
d2
|
|
||||||
|
|
||||||
#View Decision Tree
|
|
||||||
#View 1
|
|
||||||
library(RevoTreeView)
|
|
||||||
plot(createTreeView(d))
|
|
||||||
plot(createTreeView(d1))
|
|
||||||
plot(createTreeView(d2))
|
|
||||||
|
|
||||||
#View 2
|
|
||||||
library(rpart)
|
|
||||||
plot(rxAddInheritance(d))
|
|
||||||
text(rxAddInheritance(d))
|
|
||||||
title(main="RFM-based Decision Tree on CDNOW Data",line=3)
|
|
||||||
plot(rxAddInheritance(d1))
|
|
||||||
text(rxAddInheritance(d1))
|
|
||||||
title(main="RFM-based Decision Tree on CDNOW Data",line=3)
|
|
||||||
plot(rxAddInheritance(d2))
|
|
||||||
text(rxAddInheritance(d2))
|
|
||||||
title(main="RFM-based Decision Tree on CDNOW Data",line=3)
|
|
||||||
|
|
||||||
#Prediction
|
|
||||||
DTreePred.xdf<-file.path(output.path,"DTreePred.xdf")
|
|
||||||
rxPredict(d, data=test.xdf,outData=DTreePred.xdf,writeModelVars = TRUE,extraVarsToWrite="ID",computeResiduals=T,overwrite=TRUE)
|
|
||||||
rxGetInfo(DTreePred.xdf,getVarInfo=T,numRows=3)
|
|
||||||
DTreePredInfoTop10<-rxGetInfo(DTreePred.xdf,getVarInfo=T,numRows=10)
|
|
||||||
DTreePredInfoTop10.txt<-file.path(output.path,"DTreePredInfoTop10.txt")
|
|
||||||
write.table(DTreePredInfoTop10$data,file=DTreePredInfoTop10.txt,sep=" ")
|
|
||||||
|
|
||||||
#Draw ROC
|
|
||||||
rxRocCurve(actualVarName='IsVIP',predVarNames='IsVIP_Pred',data=DTreePred.xdf)
|
|
||||||
@@ -1,173 +1,237 @@
|
|||||||
#############################################################
|
#############################################################
|
||||||
#CRM Demo on CDNOW
|
# Title : CRM Demo in-memory
|
||||||
#Microsoft
|
# Author: Microsoft
|
||||||
|
# Date: Dec, 2015
|
||||||
#############################################################
|
#############################################################
|
||||||
|
|
||||||
#install package
|
# Install package
|
||||||
|
|
||||||
install.packages("rmarkdown")
|
install.packages("rmarkdown")
|
||||||
install.packages("fpc")
|
install.packages("fpc")
|
||||||
|
|
||||||
#set directory
|
# Set directory
|
||||||
setwd("C:/Users/zhouf/Documents/Revolution Analytics/Demo/RREDemo/CRM")
|
|
||||||
data.path<-"C:/Users/zhouf/Documents/Revolution Analytics/Demo/RREDemo/CRM/Data/CDNOW_master"
|
|
||||||
|
|
||||||
|
wd <- getwd()
|
||||||
|
data.path <- file.path(wd, "Data", "CDNOW_master.csv")
|
||||||
|
|
||||||
|
# Connect to SQL database using ODBC and read data from SQL via Open Source R
|
||||||
|
|
||||||
##connect to SQL database using ODBC and read data from SQL via Open Source R
|
|
||||||
library(RODBC)
|
library(RODBC)
|
||||||
getSqlTypeInfo()
|
getSqlTypeInfo()
|
||||||
#connect from local PC
|
|
||||||
channel<-odbcDriverConnect("driver={SQL Server Native Client 11.0};server=tcp:sqlserver2012-81yms1ai.cloudapp.net,57500;database=RREDemoSql;uid=zhouf;pwd=Microsoft2;")
|
|
||||||
#connect from Windows201201
|
|
||||||
channel<-odbcConnect(dsn="MiningDatabaseSql",uid="zhouf",pwd="Microsoft1")
|
|
||||||
#connect with error
|
|
||||||
channel<-odbcDriverConnect('driver={SQL Server};server=tcp:192.168.220.128,1433;database=sqlr;uid=sa;pwd=Microsoft1')
|
|
||||||
|
|
||||||
|
|
||||||
df<-sqlFetch(channel, 'CDNOW')
|
# Connect from local PC
|
||||||
df<- sqlQuery(channel,paste("select * from dbo.CDNOW"))
|
|
||||||
|
channel <- odbcDriverConnect("driver={SQL Server Native Client 11.0};
|
||||||
|
server=tcp:sqlserver2012-81yms1ai.cloudapp.net,57500;
|
||||||
|
database=RREDemoSql;
|
||||||
|
uid=******;
|
||||||
|
pwd=******;")
|
||||||
|
|
||||||
|
df <- sqlFetch(channel, 'CDNOW')
|
||||||
|
df <- sqlQuery(channel, paste("select * from dbo.CDNOW"))
|
||||||
|
|
||||||
df$Date<-as.Date(df$Date)
|
df$Date<-as.Date(df$Date)
|
||||||
|
|
||||||
str(df)
|
str(df)
|
||||||
head(df)
|
head(df)
|
||||||
|
|
||||||
#remove the rows with the duplicated IDs to see how many customers in total
|
# Remove the rows with the duplicated IDs to see how many customers in total
|
||||||
uid <- df[!duplicated(df[,"ID"]),]
|
|
||||||
|
uid <- df[!duplicated(df[,"ID"]), ]
|
||||||
|
|
||||||
dim(uid)
|
dim(uid)
|
||||||
|
|
||||||
#call RFM source code
|
# Step 1: RFM analysis
|
||||||
source("RFM_Analysis_R_Source_Codes_V1.3.R")
|
|
||||||
|
# Call RFM source code
|
||||||
|
|
||||||
|
source(wd, "R", "RFM_Analysis_R_Source_Codes_V1.3.R")
|
||||||
|
|
||||||
|
# Set the startDate and endDate, we will only analysis the records in this date range
|
||||||
|
|
||||||
#set the startDate and endDate, we will only analysis the records in this date range
|
|
||||||
startDate <- as.Date("19970101","%Y%m%d")
|
startDate <- as.Date("19970101","%Y%m%d")
|
||||||
endDate <- as.Date("19980701","%Y%m%d")
|
endDate <- as.Date("19980701","%Y%m%d")
|
||||||
|
|
||||||
#calculate RFM value
|
# Calculate RFM value
|
||||||
df <- getDataFrame(df,startDate,endDate,tIDColName="ID",tDateColName="Date",tAmountColName="Amount")
|
|
||||||
|
df <- getDataFrame(df, startDate, endDate, tIDColName="ID", tDateColName="Date", tAmountColName="Amount")
|
||||||
|
|
||||||
head(df)
|
head(df)
|
||||||
|
|
||||||
#obtain Independent RFM score
|
# Obtain independent RFM score
|
||||||
|
|
||||||
df1 <-getIndependentScore(df)
|
df1 <-getIndependentScore(df)
|
||||||
|
|
||||||
head(df1)
|
head(df1)
|
||||||
|
|
||||||
#draw the histograms in the R, F, and M dimensions
|
# Draw the histograms in the R, F, and M dimensions
|
||||||
|
|
||||||
drawHistograms(df1)
|
drawHistograms(df1)
|
||||||
|
|
||||||
S500<-df1[df1$Total_Score>500,]
|
S500 <- df1[df1$Total_Score > 500, ]
|
||||||
dim(S500)
|
dim(S500)
|
||||||
|
|
||||||
S400<-df1[df1$Total_Score>400,]
|
S400 <- df1[df1$Total_Score > 400, ]
|
||||||
dim(S400)
|
dim(S400)
|
||||||
|
|
||||||
|
# Obtain RFM score with breaks
|
||||||
|
# Take a look at the distribution of R, F, M
|
||||||
|
|
||||||
#obtain RFM score with breaks
|
|
||||||
#take a look at the distribution of R, F, M
|
|
||||||
par(mfrow = c(1,3))
|
par(mfrow = c(1,3))
|
||||||
hist(df$Recency)
|
hist(df$Recency)
|
||||||
hist(df$Frequency)
|
hist(df$Frequency)
|
||||||
hist(df$Monetary)
|
hist(df$Monetary)
|
||||||
|
|
||||||
#set the Recency ranges as 0-120 days, 120-240 days, 240-450 days, 450-500days, and more than 500days.
|
# Set the Recency ranges as 0-120 days, 120-240 days, 240-450 days, 450-500 days, and more than 500 days.
|
||||||
r <-c(120,240,450,500)
|
|
||||||
#set the Frequency ranges as 0 ? 2times, 2-5 times,5-8 times, 8-10 times, and more than 10 times.
|
r <- c(120, 240, 450, 500)
|
||||||
f <-c(2,5,8,10)
|
|
||||||
#set the Monetary ranges as 0-10 dollars, 10-20 dollars, and so on.
|
# Set the Frequency ranges as 0-2 times, 2-5 times, 5-8 times, 8-10 times, and more than 10 times.
|
||||||
|
|
||||||
|
f <- c(2, 5, 8, 10)
|
||||||
|
|
||||||
|
# Set the Monetary ranges as 0-10 dollars, 10-20 dollars, and so on.
|
||||||
|
|
||||||
m <-c(10,20,30,100)
|
m <-c(10,20,30,100)
|
||||||
|
|
||||||
#calculate RFM score with breaks
|
# Calculate RFM score with breaks
|
||||||
df2<-getScoreWithBreaks(df,r,f,m)
|
|
||||||
|
df2 <- getScoreWithBreaks(df, r, f, m)
|
||||||
drawHistograms(df2)
|
drawHistograms(df2)
|
||||||
|
|
||||||
S500<-df2[df2$Total_Score>500,]
|
S500 <- df2[df2$Total_Score > 500, ]
|
||||||
dim(S500)
|
dim(S500)
|
||||||
|
|
||||||
S400<-df2[df2$Total_Score>400,]
|
S400 <- df2[df2$Total_Score > 400, ]
|
||||||
dim(S400)
|
dim(S400)
|
||||||
|
|
||||||
target <- df2[df2$Total_Score>=441,]
|
target <- df2[df2$Total_Score >= 441,]
|
||||||
dim(target)
|
dim(target)
|
||||||
|
|
||||||
#obtain RFM scores with quantiles as breaks
|
# Obtain RFM scores with quantiles as breaks
|
||||||
|
|
||||||
r <-c(cutpoint(df$Recency))
|
r <-c(cutpoint(df$Recency))
|
||||||
f <-c(cutpoint(df$Frequency))
|
f <-c(cutpoint(df$Frequency))
|
||||||
m <-c(cutpoint(df$Monetary))
|
m <-c(cutpoint(df$Monetary))
|
||||||
|
|
||||||
df3<-getScoreWithBreaks(df,r,f,m)
|
df3 <- getScoreWithBreaks(df, r, f, m)
|
||||||
|
|
||||||
str(df3)
|
str(df3)
|
||||||
head(df3)
|
head(df3)
|
||||||
tail(df3)
|
tail(df3)
|
||||||
|
|
||||||
RFM_Result_osr<-subset(df3,select=c("ID","Recency","Frequency","Monetary","R_Score","F_Score","M_Score","Total_Score"))
|
RFM_Result <- subset(df3,
|
||||||
colnames(RFM_Result_osr)<-c("ID","R","F","M","R_Score","F_Score","M_Score","Total_Score")
|
select=c("ID", "Recency", "Frequency", "Monetary",
|
||||||
head(RFM_Result_osr)
|
"R_Score", "F_Score", "M_Score", "Total_Score"))
|
||||||
|
|
||||||
system.time(
|
colnames(RFM_Result) <- c("ID", "R", "F", "M", "R_Score", "F_Score", "M_Score", "Total_Score")
|
||||||
sqlSave(channel,RFM_Result_osr,rownames=FALSE,append=FALSE,varTypes=list(numeric="float",integer="int"))
|
|
||||||
)
|
|
||||||
|
|
||||||
sqlUpdate(channel,df)
|
head(RFM_Result)
|
||||||
|
|
||||||
|
time <- system.time({
|
||||||
|
|
||||||
|
sqlSave(channel,
|
||||||
|
RFM_Result,
|
||||||
|
rownames=FALSE,
|
||||||
|
append=FALSE,
|
||||||
|
varTypes=list(numeric="float",
|
||||||
|
integer="int"))
|
||||||
|
})
|
||||||
|
|
||||||
|
sqlUpdate(channel, df)
|
||||||
odbcClose(channel)
|
odbcClose(channel)
|
||||||
|
|
||||||
#Clustering using RFM
|
# Clustering using RFM
|
||||||
|
|
||||||
library(fpc)
|
library(fpc)
|
||||||
library(cluster)
|
library(cluster)
|
||||||
#kmeans clustering with cluster =8
|
|
||||||
cl.fit1<-kmeans(RFM_Result_osr[,2:8],centers=8,iter.max=10,nstart=1)
|
# Kmeans clustering with number of cluster equal to 8
|
||||||
cl.fit2<-kmeans(RFM_Result_osr[,2:8],centers=8,iter.max=20,nstart=200)
|
|
||||||
|
cl.fit1 <- kmeans(RFM_Result[, 2:8],
|
||||||
|
centers=8,
|
||||||
|
iter.max=10,
|
||||||
|
nstart=1)
|
||||||
|
|
||||||
|
cl.fit2 <- kmeans(RFM_Result[, 2:8],
|
||||||
|
centers=8,
|
||||||
|
iter.max=20,
|
||||||
|
nstart=200)
|
||||||
|
|
||||||
summary(cl.fit1)
|
summary(cl.fit1)
|
||||||
|
|
||||||
cluster<-cl.fit1$cluster
|
cluster<-cl.fit1$cluster
|
||||||
centers<-cl.fit1$centers
|
centers<-cl.fit1$centers
|
||||||
size<-cl.fit1$size
|
size<-cl.fit1$size
|
||||||
plot(RFM_Result_osr[,2:4],col=cl.fit1$cluster)
|
|
||||||
|
plot(RFM_Result[, 2:4], col=cl.fit1$cluster)
|
||||||
title(main="K-means",line=3)
|
title(main="K-means",line=3)
|
||||||
|
|
||||||
##Classification using RFM
|
# Classification using RFM
|
||||||
#Create IsVIP variable
|
|
||||||
IsVIP<-ifelse(RFM_Result_osr[,'Total_Score']>=441,1,0);
|
# Create IsVIP variable
|
||||||
Cluster<-cl.fit1$cluster
|
|
||||||
RFMVIPCluster<-cbind(RFM_Result_osr,IsVIP,Cluster)
|
IsVIP <- ifelse(RFM_Result[,'Total_Score'] >= 441, 1, 0)
|
||||||
|
Cluster <- cl.fit1$cluster
|
||||||
|
RFMVIPCluster <- cbind(RFM_Result, IsVIP, Cluster)
|
||||||
|
|
||||||
|
# Create training/testing data set
|
||||||
|
|
||||||
|
RD <- sample(1:10, dim(RFMVIPCluster)[1], replace=TRUE)
|
||||||
|
|
||||||
#Create training/testing data set
|
|
||||||
RD<-sample(1:10,dim(RFMVIPCluster)[1],replace=TRUE)
|
|
||||||
str(RD)
|
str(RD)
|
||||||
table(RD)
|
table(RD)
|
||||||
RFMVIPCluster$RD<-RD;
|
|
||||||
urv=factor(ifelse(RD<=8,'TRAIN','TEST'))
|
|
||||||
TrainTest<-cbind(RFMVIPCluster,urv)
|
|
||||||
Train<-TrainTest[which(TrainTest$urv=="TRAIN"),]
|
|
||||||
Test<-TrainTest[which(TrainTest$urv=="TEST"),]
|
|
||||||
|
|
||||||
#logistic model
|
RFMVIPCluster$RD <- RD;
|
||||||
##Build our Logistic Regression Model with IsVIP as response
|
|
||||||
r1<-glm(IsVIP~R+F+M, data=Train, family = binomial)
|
urv <- factor(ifelse(RD <= 8,'TRAIN','TEST'))
|
||||||
|
TrainTest <- cbind(RFMVIPCluster, urv)
|
||||||
|
Train <- TrainTest[which(TrainTest$urv == "TRAIN"), ]
|
||||||
|
Test <- TrainTest[which(TrainTest$urv == "TEST"), ]
|
||||||
|
|
||||||
|
# Logistic model
|
||||||
|
# Build our Logistic Regression Model with IsVIP as response
|
||||||
|
|
||||||
|
r1 <- glm(IsVIP~R+F+M, data=Train, family = binomial)
|
||||||
summary(r1)
|
summary(r1)
|
||||||
|
|
||||||
p1<-predict.glm(r1,data=Test,type="response")
|
p1 <- predict.glm(r1, data=Test, type="response")
|
||||||
head(p1)
|
head(p1)
|
||||||
tail(p1)
|
tail(p1)
|
||||||
|
|
||||||
#decision tree
|
# Decision tree
|
||||||
#grow tree
|
# Grow tree
|
||||||
|
|
||||||
fit <- rpart(Cluster~R+F+M,
|
fit <- rpart(Cluster~R+F+M,
|
||||||
method="class", data=Train)
|
method="class",
|
||||||
|
data=Train)
|
||||||
|
|
||||||
|
# Display the results
|
||||||
|
|
||||||
|
printcp(fit)
|
||||||
|
|
||||||
|
# Visualize cross-validation results
|
||||||
|
|
||||||
#display the results
|
|
||||||
printcp(fit)
|
|
||||||
#visualize cross-validation results
|
|
||||||
plotcp(fit)
|
plotcp(fit)
|
||||||
#detailed summary of splits
|
|
||||||
|
# Detailed summary of splits
|
||||||
|
|
||||||
summary(fit)
|
summary(fit)
|
||||||
|
|
||||||
# plot tree
|
# Plot tree
|
||||||
|
|
||||||
library(rpart)
|
library(rpart)
|
||||||
plot(fit, uniform=TRUE,
|
|
||||||
main="Classification Tree for CDNOW")
|
plot(fit, uniform=TRUE, main="Classification Tree for CDNOW")
|
||||||
text(fit, use.n=TRUE, all=TRUE, cex=.8)
|
text(fit, use.n=TRUE, all=TRUE, cex=.8)
|
||||||
|
|
||||||
# prune the tree
|
# Prune the tree
|
||||||
pfit<- prune(fit, cp= fit$cptable[which.min(fit$cptable[,"xerror"]),"CP"])
|
|
||||||
|
pfit <- prune(fit, cp=fit$cptable[which.min(fit$cptable[,"xerror"]), "CP"])
|
||||||
|
|
||||||
|
# Plot the pruned tree
|
||||||
|
|
||||||
# plot the pruned tree
|
|
||||||
plot(pfit, uniform=TRUE,
|
plot(pfit, uniform=TRUE,
|
||||||
main="Pruned Classification Tree for CDNOW")
|
main="Pruned Classification Tree for CDNOW")
|
||||||
text(pfit, use.n=TRUE, all=TRUE, cex=.8)
|
text(pfit, use.n=TRUE, all=TRUE, cex=.8)
|
||||||
|
|
||||||
|
|||||||
@@ -1,157 +1,203 @@
|
|||||||
################################################################
|
################################################################
|
||||||
##CRM Demo in-SQL compute context
|
# Title: CRM Demo in-SQL
|
||||||
##Microsoft
|
# Author: Microsoft
|
||||||
|
# Date: Dec, 2015
|
||||||
#################################################################
|
#################################################################
|
||||||
|
|
||||||
connectionString <- "Driver=SQL Server;Server=tcp:192.168.176.130,1433;Database=sqlr;Uid=sa;Pwd=Microsoft1"
|
# Specify connection string and compute context
|
||||||
|
|
||||||
RFMData <- RxSqlServerData(
|
connectionString <- "Driver=SQL Server;
|
||||||
connectionString = connectionString,
|
Server=tcp:192.168.176.130,1433;
|
||||||
table = "RFM_Result")
|
Database=sqlr;
|
||||||
|
Uid=******;
|
||||||
|
Pwd=******"
|
||||||
|
|
||||||
|
RFMData <- RxSqlServerData(connectionString=connectionString,
|
||||||
|
table="RFM_Result")
|
||||||
|
|
||||||
cc <- RxInSqlServer(connectionString = connectionString, autoCleanup = FALSE, consoleOutput = TRUE)
|
cc <- RxInSqlServer(connectionString=connectionString,
|
||||||
|
autoCleanup=FALSE,
|
||||||
|
consoleOutput=TRUE)
|
||||||
|
|
||||||
rxSetComputeContext(cc)
|
rxSetComputeContext(cc)
|
||||||
|
|
||||||
rxGetInfo(RFMData,getVarInfo=T,numRows=3)
|
rxGetInfo(RFMData, getVarInfo=T, numRows=3)
|
||||||
|
|
||||||
#Step 1: RFM analysis
|
# Step 1: RFM analysis
|
||||||
#visualize the RFM values
|
|
||||||
rxHistogram(~R,data=RFMData, xNumTicks=20)
|
|
||||||
rxHistogram(~F,data=RFMData,rowSelection=F<30,
|
|
||||||
xNumTicks=20)
|
|
||||||
rxHistogram(~M,data=RFMData,rowSelection=M<200,
|
|
||||||
xNumTicks=20)
|
|
||||||
|
|
||||||
#count frequency of each RFMscore Level
|
# Visualize the RFM values
|
||||||
tmp<-rxCube(~F(Toltal_Score),data=RFMData)
|
|
||||||
|
rxHistogram(~R, data=RFMData, xNumTicks=20)
|
||||||
|
rxHistogram(~F, data=RFMData, rowSelection=F < 30, xNumTicks=20)
|
||||||
|
rxHistogram(~M, data=RFMData, rowSelection=M < 200, xNumTicks=20)
|
||||||
|
|
||||||
|
# Count frequency of each RFMscore Level
|
||||||
|
|
||||||
|
tmp <- rxCube(~F(Toltal_Score), data=RFMData)
|
||||||
results <- rxResultsDF(tmp)
|
results <- rxResultsDF(tmp)
|
||||||
results<-results[results$Counts!=0,]
|
results <- results[results$Counts != 0, ]
|
||||||
results[order(results$Counts,decreasing=TRUE),]
|
results[order(results$Counts, decreasing=TRUE), ]
|
||||||
|
|
||||||
|
# Step 2: K-means Clustering
|
||||||
|
|
||||||
|
KmeansData <- RxSqlServerData(connectionString=connectionString,
|
||||||
|
table = "Kmeans_Result")
|
||||||
|
|
||||||
#Step 2: K-means Clustering
|
|
||||||
KmeansData <- RxSqlServerData(
|
|
||||||
connectionString = connectionString,
|
|
||||||
table = "Kmeans_Result")
|
|
||||||
md.km <- rxKmeans(formula=~R+F+M+R_Score+F_Score+M_Score,
|
md.km <- rxKmeans(formula=~R+F+M+R_Score+F_Score+M_Score,
|
||||||
data = RFMData,
|
data=RFMData,
|
||||||
outFile =KmeansData,
|
outFile=KmeansData,
|
||||||
numClusters=8,
|
numClusters=8,
|
||||||
algorithm = "lloyd",
|
algorithm="lloyd",
|
||||||
writeModelVars=TRUE,
|
writeModelVars=TRUE,
|
||||||
overwrite=TRUE)
|
overwrite=TRUE)
|
||||||
rxGetInfo(KmeansData,getVarInfo=TRUE,numRows=10)
|
|
||||||
|
|
||||||
centers<-round(md.km$centers,digits=2)
|
rxGetInfo(KmeansData, getVarInfo=TRUE, numRows=10)
|
||||||
size<-md.km$size
|
|
||||||
centers.txt<-file.path(output.path,"centers.txt")
|
centers <- round(md.km$centers, digits=2)
|
||||||
write.table(centers,file=centers.txt,sep=" ")
|
size <- md.km$size
|
||||||
size.txt<-file.path(output.path,"size.txt")
|
centers.txt <- file.path(output.path, "centers.txt")
|
||||||
write.table(size,file=size.txt,sep=" ")
|
write.table(centers, file=centers.txt, sep=" ")
|
||||||
|
size.txt <- file.path(output.path, "size.txt")
|
||||||
|
write.table(size, file=size.txt, sep=" ")
|
||||||
|
|
||||||
|
# Connect to SQL database via odbcConnect
|
||||||
|
|
||||||
##Connect to SQL database via odbcConnect
|
|
||||||
install.packages("RODBC")
|
|
||||||
library(RODBC)
|
library(RODBC)
|
||||||
|
|
||||||
channel<-odbcDriverConnect(connection=connectionString)
|
channel<-odbcDriverConnect(connection=connectionString)
|
||||||
##Read Kmeans_Result from SQL via OSR
|
|
||||||
Kmeans.df<- sqlQuery(channel,paste("select * from dbo.Kmeans_Result"))
|
# Read Kmeans_Result from SQL via OSR
|
||||||
|
|
||||||
|
Kmeans.df <- sqlQuery(channel, paste("select * from dbo.Kmeans_Result"))
|
||||||
|
|
||||||
head(Kmeans.df)
|
head(Kmeans.df)
|
||||||
plot(Kmeans.df[,2:4],col=Kmeans.df$X_rxCluster)
|
plot(Kmeans.df[, 2:4], col=Kmeans.df$X_rxCluster)
|
||||||
title(main="RFM-based K-means on CDNOW Data",line=3)
|
title(main="RFM-based K-means on CDNOW Data", line=3)
|
||||||
|
|
||||||
##Step 3: Prediction-logistic and decision tree
|
# Step 3: Prediction-logistic and decision tree
|
||||||
#Create IsVIP variable
|
|
||||||
RFMVIPData <- RxSqlServerData(
|
# Create IsVIP variable
|
||||||
connectionString = connectionString,
|
|
||||||
table = "RFMVIP")
|
RFMVIPData <- RxSqlServerData(connectionString=connectionString,
|
||||||
rxDataStep(inData=RFMData,outFile=RFMVIPData,
|
table="RFMVIP")
|
||||||
transforms=list(IsVIP=ifelse(Toltal_Score>=441,1,0)
|
|
||||||
),
|
rxDataStep(inData=RFMData,
|
||||||
overwrite=TRUE,reportProgress=1
|
outFile=RFMVIPData,
|
||||||
)
|
transforms=list(IsVIP=ifelse(Toltal_Score >= 441, 1, 0)),
|
||||||
rxGetInfo(RFMVIPData,getVarInfo=T,numRows=3)
|
overwrite=TRUE,
|
||||||
rxGetInfo(RFMVIPRDData,getVarInfo=T,numRows=3)
|
reportProgress=1)
|
||||||
RFMVIPRDData <- RxSqlServerData(
|
|
||||||
connectionString = connectionString,
|
rxGetInfo(RFMVIPData, getVarInfo=T, numRows=3)
|
||||||
table = "RFMVIPRD")
|
rxGetInfo(RFMVIPRDData, getVarInfo=T, numRows=3)
|
||||||
RFMVIPTrainTestData <- RxSqlServerData(
|
|
||||||
connectionString = connectionString,
|
RFMVIPRDData <- RxSqlServerData(connectionString=connectionString,
|
||||||
table = "RFMVIPTrainTest")
|
table="RFMVIPRD")
|
||||||
rxDataStep(inData=RFMVIPRDData,outFile=RFMVIPTrainTestData,
|
|
||||||
transforms=list(
|
RFMVIPTrainTestData <- RxSqlServerData(connectionString = connectionString,
|
||||||
urv=factor(ifelse(RD<=8,'TRAIN','TEST'))
|
table="RFMVIPTrainTest")
|
||||||
),
|
|
||||||
|
rxDataStep(inData=RFMVIPRDData,
|
||||||
|
outFile=RFMVIPTrainTestData,
|
||||||
|
transforms=list(urv=factor(ifelse(RD <= 8,'TRAIN','TEST'))),
|
||||||
overwrite=T)
|
overwrite=T)
|
||||||
rxGetInfo(RFMVIPTrainTestData,T,numRows=3)
|
|
||||||
|
|
||||||
##Split data into training/testing data set
|
rxGetInfo(RFMVIPTrainTestData, T, numRows=3)
|
||||||
TrainData <- RxSqlServerData(
|
|
||||||
connectionString = connectionString,
|
|
||||||
table = "RFMVIPTrainTest.urv.TRAIN")
|
|
||||||
TestData <- RxSqlServerData(
|
|
||||||
connectionString = connectionString,
|
|
||||||
table = "RFMVIPTrainTest.urv.TEST")
|
|
||||||
rxSplit(RFMVIPTrainTestData,outFilesBase=RFMVIPTrainTestData,splitByFactor='urv',overwrite=T,reportProgress=1)
|
|
||||||
|
|
||||||
##Build our Logistic Regression Model with IsVIP as response
|
## Split data into training/testing data set
|
||||||
r1<- rxLogit(IsVIP ~R+F+M,
|
|
||||||
data =RFMVIPData,
|
|
||||||
variableSelection = rxStepControl(method="stepwise",
|
|
||||||
scope = ~ R+F+M))
|
|
||||||
summary(r1)
|
|
||||||
|
|
||||||
##r1:stepwise selection shows that Monetary,Recency are significant.
|
TrainData <- RxSqlServerData(connectionString=connectionString,
|
||||||
##Build our Logistic REgression MOdel
|
table = "RFMVIPTrainTest.urv.TRAIN")
|
||||||
r2<- rxLogit(IsVIP ~R+F,
|
|
||||||
data =RFMVIPData,covCoef=TRUE)
|
TestData <- RxSqlServerData(connectionString=connectionString,
|
||||||
|
table="RFMVIPTrainTest.urv.TEST")
|
||||||
|
|
||||||
|
rxSplit(RFMVIPTrainTestData, outFilesBase=RFMVIPTrainTestData,
|
||||||
|
splitByFactor='urv', overwrite=T, reportProgress=1)
|
||||||
|
|
||||||
|
## Built our Logistic Regression Model with IsVIP as response
|
||||||
|
|
||||||
|
r1<- rxLogit(IsVIP~R+F+M,
|
||||||
|
data =RFMVIPData,
|
||||||
|
variableSelection = rxStepControl(method="stepwise",
|
||||||
|
scope = ~ R+F+M))
|
||||||
|
summary(r1)
|
||||||
|
|
||||||
|
## r1:stepwise selection shows that Monetary, Recency are significant.
|
||||||
|
## Build our Logistic Regression Model
|
||||||
|
|
||||||
|
r2 <- rxLogit(IsVIP~R+F,
|
||||||
|
data=RFMVIPData, covCoef=TRUE)
|
||||||
summary(r2)
|
summary(r2)
|
||||||
|
|
||||||
##Predict our Logistic Model on our test Dataset
|
## Predict our Logistic Model on our test Dataset
|
||||||
LogisticPred.xdf<-file.path(output.path,"LogisticPred.xdf")
|
|
||||||
p2<-rxPredict(r2,data=test.xdf,outData=LogisticPred.xdf,writeModelVars = TRUE,extraVarsToWrite="ID",computeResiduals=TRUE,computeStdErr = TRUE,
|
LogisticPred.xdf <- file.path(output.path,"LogisticPred.xdf")
|
||||||
interval = "confidence",predVarNames='LogitPredict',overwrite=TRUE)
|
p2 <- rxPredict(r2, data=test.xdf, outData=LogisticPred.xdf,
|
||||||
rxGetInfo(LogisticPred.xdf,getVarInfo=T,numRows=10)
|
writeModelVars=TRUE, extraVarsToWrite="ID",
|
||||||
LogisticPredInfoTop10<-rxGetInfo(LogisticPred.xdf,getVarInfo=T,numRows=10)
|
computeResiduals=TRUE, computeStdErr=TRUE,
|
||||||
LogisticPredInfoTop10.txt<-file.path(output.path,"LogisticPredInfoTop10.txt")
|
interval="confidence", predVarNames='LogitPredict',
|
||||||
write.table(LogisticPredInfoTop10$data,file=LogisticPredInfoTop10.txt,sep=" ")
|
overwrite=TRUE)
|
||||||
|
|
||||||
|
rxGetInfo(LogisticPred.xdf, getVarInfo=T, numRows=10)
|
||||||
|
LogisticPredInfoTop10 <- rxGetInfo(LogisticPred.xdf, getVarInfo=T, numRows=10)
|
||||||
|
LogisticPredInfoTop10.txt <- file.path(output.path, "LogisticPredInfoTop10.txt")
|
||||||
|
write.table(LogisticPredInfoTop10$data, file=LogisticPredInfoTop10.txt, sep=" ")
|
||||||
|
|
||||||
|
## Draw a ROC curve
|
||||||
|
|
||||||
##Draw a ROC curve
|
|
||||||
rxRocCurve(actualVarName='IsVIP',predVarNames='LogitPredict',data=LogisticPred.xdf)
|
rxRocCurve(actualVarName='IsVIP',predVarNames='LogitPredict',data=LogisticPred.xdf)
|
||||||
|
|
||||||
##Build a Decision Tree with Cluster as response
|
## Build a Decision Tree with Cluster as response
|
||||||
d1 <- rxDTree(Cluster~R+F+M,data=TrainData,blocksPerRead=5)
|
|
||||||
d1 <- rxDTree(Cluster~R_Score+F_Score+M_Score,data=TrainData,blocksPerRead=5)
|
d1 <- rxDTree(Cluster~R+F+M, data=TrainData, blocksPerRead=5)
|
||||||
|
d1 <- rxDTree(Cluster~R_Score+F_Score+M_Score, data=TrainData, blocksPerRead=5)
|
||||||
d1
|
d1
|
||||||
d1Cp<- rxDTreeBestCp(d1)
|
d1Cp<- rxDTreeBestCp(d1)
|
||||||
d1 <- prune.rxDTree(d1, cp=d1Cp)
|
d1 <- prune.rxDTree(d1, cp=d1Cp)
|
||||||
d2 <- rxDTree(Cluster~R+F+M,data=TrainData, pruneCp="auto")
|
d2 <- rxDTree(Cluster~R+F+M, data=TrainData, pruneCp="auto")
|
||||||
d2 <- rxDTree(Cluster~R_Score+F_Score+M_Score,data=TrainData, pruneCp="auto")
|
d2 <- rxDTree(Cluster~R_Score+F_Score+M_Score, data=TrainData, pruneCp="auto")
|
||||||
d2
|
d2
|
||||||
|
|
||||||
#View Decision Tree
|
# View Decision Tree
|
||||||
#View 1
|
|
||||||
|
# View 1
|
||||||
|
|
||||||
library(RevoTreeView)
|
library(RevoTreeView)
|
||||||
|
|
||||||
plot(createTreeView(d1))
|
plot(createTreeView(d1))
|
||||||
plot(createTreeView(d2))
|
plot(createTreeView(d2))
|
||||||
|
|
||||||
#View 2
|
# View 2
|
||||||
|
|
||||||
library(rpart)
|
library(rpart)
|
||||||
|
|
||||||
plot(rxAddInheritance(d1))
|
plot(rxAddInheritance(d1))
|
||||||
text(rxAddInheritance(d1))
|
text(rxAddInheritance(d1))
|
||||||
title(main="RFM-based Decision Tree on CDNOW Data",line=3)
|
title(main="RFM-based Decision Tree on CDNOW Data",line=3)
|
||||||
|
|
||||||
plot(rxAddInheritance(d2))
|
plot(rxAddInheritance(d2))
|
||||||
text(rxAddInheritance(d2))
|
text(rxAddInheritance(d2))
|
||||||
title(main="RFM-based Decision Tree on CDNOW Data",line=3)
|
title(main="RFM-based Decision Tree on CDNOW Data",line=3)
|
||||||
|
|
||||||
#Prediction
|
# Prediction
|
||||||
DTreePred.xdf<-file.path(output.path,"DTreePred.xdf")
|
|
||||||
rxPredict(d1, data=test.xdf,outData=DTreePred.xdf,writeModelVars = TRUE,extraVarsToWrite="ID",computeResiduals=T,overwrite=TRUE)
|
|
||||||
rxGetInfo(DTreePred.xdf,getVarInfo=T,numRows=3)
|
|
||||||
DTreePredInfoTop10<-rxGetInfo(DTreePred.xdf,getVarInfo=T,numRows=10)
|
|
||||||
DTreePredInfoTop10.txt<-file.path(output.path,"DTreePredInfoTop10.txt")
|
|
||||||
write.table(DTreePredInfoTop10$data,file=DTreePredInfoTop10.txt,sep=" ")
|
|
||||||
|
|
||||||
DTreePred<-rxXdfToDataFrame(file=DTreePred.xdf)
|
DTreePred.xdf<-file.path(output.path,"DTreePred.xdf")
|
||||||
sqlSave(channel,DTreePred,rownames=FALSE,append=FALSE,varTypes=list(numeric="float",integer="int",Date="date"))
|
rxPredict(d1, data=test.xdf, outData=DTreePred.xdf,
|
||||||
|
writeModelVars=TRUE, extraVarsToWrite="ID",
|
||||||
|
computeResiduals=T, overwrite=TRUE)
|
||||||
|
|
||||||
|
rxGetInfo(DTreePred.xdf, getVarInfo=T, numRows=3)
|
||||||
|
|
||||||
|
DTreePredInfoTop10 <- rxGetInfo(DTreePred.xdf, getVarInfo=T, numRows=10)
|
||||||
|
DTreePredInfoTop10.txt <- file.path(output.path, "DTreePredInfoTop10.txt")
|
||||||
|
write.table(DTreePredInfoTop10$data, file=DTreePredInfoTop10.txt, sep=" ")
|
||||||
|
|
||||||
|
DTreePred <- rxXdfToDataFrame(file=DTreePred.xdf)
|
||||||
|
|
||||||
|
sqlSave(channel, DTreePred, rownames=FALSE, append=FALSE,
|
||||||
|
varTypes=list(numeric="float",
|
||||||
|
integer="int",
|
||||||
|
Date="date"))
|
||||||
odbcClose(channel)
|
odbcClose(channel)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,10 @@ This sample consists of the following directory structure.
|
|||||||
|
|
||||||
To jumpstart, run the T-SQL files (crm_demo.sql)
|
To jumpstart, run the T-SQL files (crm_demo.sql)
|
||||||
|
|
||||||
|
**Note**
|
||||||
|
|
||||||
|
This is a demo built on SQL 2016 RC1 in Dec 2015. To try out it, please modify it to fit the new version of SQL Server R Services.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
--use the database RREDemoSql
|
--use the database RREDemoSql
|
||||||
|
|
||||||
use sqlr;
|
use sqlr;
|
||||||
go
|
go
|
||||||
|
|
||||||
@@ -6,6 +7,7 @@ drop procedure if exists get_CDNOW_RFM
|
|||||||
go
|
go
|
||||||
|
|
||||||
--create stored procedure to get RFM
|
--create stored procedure to get RFM
|
||||||
|
|
||||||
create proc get_CDNOW_RFM (@start datetime = '1900-1-1', @end datetime = '3000-1-1', @now datetime = null)
|
create proc get_CDNOW_RFM (@start datetime = '1900-1-1', @end datetime = '3000-1-1', @now datetime = null)
|
||||||
as
|
as
|
||||||
begin
|
begin
|
||||||
@@ -27,12 +29,14 @@ end
|
|||||||
go
|
go
|
||||||
|
|
||||||
--execute the stored procedure to obtain CDNOWRFM table
|
--execute the stored procedure to obtain CDNOWRFM table
|
||||||
|
|
||||||
exec dbo.get_CDNOW_RFM @start='1997-1-1',@end='1998-7-1',@now='1998-7-1'
|
exec dbo.get_CDNOW_RFM @start='1997-1-1',@end='1998-7-1',@now='1998-7-1'
|
||||||
go
|
go
|
||||||
|
|
||||||
drop procedure if exists BreakScoreRFM
|
drop procedure if exists BreakScoreRFM
|
||||||
go
|
go
|
||||||
|
|
||||||
|
--create stored procedure to break RFM score
|
||||||
|
|
||||||
create proc BreakScoreRFM (@start datetime = '1900-1-1', @end datetime = '3000-1-1', @now datetime = null,
|
create proc BreakScoreRFM (@start datetime = '1900-1-1', @end datetime = '3000-1-1', @now datetime = null,
|
||||||
@r_cut varchar(254) = null, @f_cut varchar(254) = null, @m_cut varchar(254) = null)
|
@r_cut varchar(254) = null, @f_cut varchar(254) = null, @m_cut varchar(254) = null)
|
||||||
@@ -175,10 +179,13 @@ end
|
|||||||
|
|
||||||
go
|
go
|
||||||
|
|
||||||
|
--execute the stored procedure to obtain RFM_Score table
|
||||||
|
|
||||||
exec dbo.BreakScoreRFM @start ='1997-1-1', @end = '1998-7-1' ,@now = '1998-7-1', @r_cut ='142-433-486-513', @f_cut = '1-1-2-4', @m_cut ='14.37-20.25-29.37-44.29'
|
exec dbo.BreakScoreRFM @start ='1997-1-1', @end = '1998-7-1' ,@now = '1998-7-1', @r_cut ='142-433-486-513', @f_cut = '1-1-2-4', @m_cut ='14.37-20.25-29.37-44.29'
|
||||||
go
|
go
|
||||||
|
|
||||||
--combine RFM and RFM_Score
|
--combine RFM and RFM_Score
|
||||||
|
|
||||||
drop table RFM_Result;
|
drop table RFM_Result;
|
||||||
select a.*, b.R_Score, b.F_Score, b.M_Score, b.Toltal_Score
|
select a.*, b.R_Score, b.F_Score, b.M_Score, b.Toltal_Score
|
||||||
into RFM_Result
|
into RFM_Result
|
||||||
@@ -188,7 +195,8 @@ from
|
|||||||
a.[ID] = b.[ID];
|
a.[ID] = b.[ID];
|
||||||
select top 10 * from RFM_Result;
|
select top 10 * from RFM_Result;
|
||||||
|
|
||||||
--visualize RFM
|
--create stored procedure to visualize RFM
|
||||||
|
|
||||||
drop procedure if exists visualizeRFM;
|
drop procedure if exists visualizeRFM;
|
||||||
go
|
go
|
||||||
create procedure visualizeRFM
|
create procedure visualizeRFM
|
||||||
@@ -235,6 +243,7 @@ grant execute on visualizeRFM to rdemo;
|
|||||||
go
|
go
|
||||||
|
|
||||||
--clustering based on RFM
|
--clustering based on RFM
|
||||||
|
|
||||||
drop table if exists Kmeans_Result;
|
drop table if exists Kmeans_Result;
|
||||||
drop table if exists CDNOW_rx_models;
|
drop table if exists CDNOW_rx_models;
|
||||||
go
|
go
|
||||||
@@ -251,6 +260,8 @@ create table Kmeans_Result (
|
|||||||
);
|
);
|
||||||
go
|
go
|
||||||
|
|
||||||
|
--create stored procedure to do clustering
|
||||||
|
|
||||||
drop procedure if exists generate_CDNOW_rx_Kmeans;
|
drop procedure if exists generate_CDNOW_rx_Kmeans;
|
||||||
go
|
go
|
||||||
create procedure generate_CDNOW_rx_Kmeans
|
create procedure generate_CDNOW_rx_Kmeans
|
||||||
@@ -261,13 +272,13 @@ begin
|
|||||||
, @script = N'
|
, @script = N'
|
||||||
require("RevoScaleR");
|
require("RevoScaleR");
|
||||||
CDNOWKmeans <- rxKmeans(formula=~R+F+M+R_Score+F_Score+M_Score,
|
CDNOWKmeans <- rxKmeans(formula=~R+F+M+R_Score+F_Score+M_Score,
|
||||||
data = RFM_Result,
|
data=RFM_Result,
|
||||||
#outFile =Kmeans_Result,
|
#outFile=Kmeans_Result,
|
||||||
numClusters=8,
|
numClusters=8,
|
||||||
algorithm = "lloyd",
|
algorithm="lloyd",
|
||||||
writeModelVars=TRUE,
|
writeModelVars=TRUE,
|
||||||
overwrite=TRUE)
|
overwrite=TRUE)
|
||||||
rxKmeans_model <- data.frame(payload = as.raw(serialize(CDNOWKmeans, connection=NULL)));
|
rxKmeans_model <- data.frame(payload=as.raw(serialize(CDNOWKmeans, connection=NULL)));
|
||||||
'
|
'
|
||||||
, @input_data_1 = N'select * from RFM_Result'
|
, @input_data_1 = N'select * from RFM_Result'
|
||||||
, @input_data_1_name = N'RFM_Result'
|
, @input_data_1_name = N'RFM_Result'
|
||||||
@@ -275,7 +286,8 @@ begin
|
|||||||
with result sets ((model varbinary(max)));
|
with result sets ((model varbinary(max)));
|
||||||
end;
|
end;
|
||||||
go
|
go
|
||||||
--how to write Kmeans_Result back to database?
|
|
||||||
|
--how to write Kmeans_Result back to database?[To Be Modified]
|
||||||
|
|
||||||
insert into CDNOW_rx_models (model)
|
insert into CDNOW_rx_models (model)
|
||||||
exec generate_CDNOW_rx_Kmeans;
|
exec generate_CDNOW_rx_Kmeans;
|
||||||
@@ -283,7 +295,7 @@ update CDNOW_rx_models set model_name = 'rxKmeans' where model_name = 'default m
|
|||||||
select * from CDNOW_rx_models;
|
select * from CDNOW_rx_models;
|
||||||
go
|
go
|
||||||
|
|
||||||
--cannot write result table back to data base in rxKmeans.
|
--create stored procedure to build logistic regression model
|
||||||
|
|
||||||
drop procedure if exists generate_CDNOW_rx_Logit;
|
drop procedure if exists generate_CDNOW_rx_Logit;
|
||||||
go
|
go
|
||||||
@@ -294,11 +306,11 @@ begin
|
|||||||
@language = N'R'
|
@language = N'R'
|
||||||
, @script = N'
|
, @script = N'
|
||||||
require("RevoScaleR");
|
require("RevoScaleR");
|
||||||
CDNOWLogit<- rxLogit(IsVIP~R+F+M,
|
CDNOWLogit <- rxLogit(IsVIP~R+F+M,
|
||||||
data =RFMVIPCluster,
|
data=RFMVIPCluster,
|
||||||
variableSelection = rxStepControl(method="stepwise",
|
variableSelection=rxStepControl(method="stepwise",
|
||||||
scope = ~ R+F+M))
|
scope=~R+F+M))
|
||||||
summary(CDNOWLogit)
|
summary(CDNOWLogit)
|
||||||
rxLogit_model <- data.frame(payload = as.raw(serialize(CDNOWLogit, connection=NULL)));
|
rxLogit_model <- data.frame(payload = as.raw(serialize(CDNOWLogit, connection=NULL)));
|
||||||
'
|
'
|
||||||
, @input_data_1 = N'select * from RFMVIPCluster'
|
, @input_data_1 = N'select * from RFMVIPCluster'
|
||||||
@@ -314,6 +326,8 @@ update CDNOW_rx_models set model_name = 'rxLogit' where model_name = 'default mo
|
|||||||
select * from CDNOW_rx_models;
|
select * from CDNOW_rx_models;
|
||||||
go
|
go
|
||||||
|
|
||||||
|
--create stored procedure to build decision tree model
|
||||||
|
|
||||||
drop procedure if exists generate_CDNOW_rx_Dtree;
|
drop procedure if exists generate_CDNOW_rx_Dtree;
|
||||||
go
|
go
|
||||||
create procedure generate_CDNOW_rx_Dtree
|
create procedure generate_CDNOW_rx_Dtree
|
||||||
@@ -323,8 +337,8 @@ begin
|
|||||||
@language = N'R'
|
@language = N'R'
|
||||||
, @script = N'
|
, @script = N'
|
||||||
require("RevoScaleR");
|
require("RevoScaleR");
|
||||||
CDNOWDtree <- rxDTree(Cluster~R+F+M,data=RFMVIPCluster, pruneCp="auto")
|
CDNOWDtree <- rxDTree(Cluster~R+F+M, data=RFMVIPCluster, pruneCp="auto")
|
||||||
rxDtree_model <- data.frame(payload = as.raw(serialize(CDNOWDtree, connection=NULL)));
|
rxDtree_model <- data.frame(payload=as.raw(serialize(CDNOWDtree, connection=NULL)));
|
||||||
'
|
'
|
||||||
, @input_data_1 = N'select * from RFMVIPCluster'
|
, @input_data_1 = N'select * from RFMVIPCluster'
|
||||||
, @input_data_1_name = N'RFMVIPCluster'
|
, @input_data_1_name = N'RFMVIPCluster'
|
||||||
@@ -339,6 +353,7 @@ update CDNOW_rx_models set model_name = 'rxDtree' where model_name = 'default mo
|
|||||||
select * from CDNOW_rx_models;
|
select * from CDNOW_rx_models;
|
||||||
go
|
go
|
||||||
|
|
||||||
|
--create stored procedure to predict whether the customer is VIP or not
|
||||||
|
|
||||||
drop procedure if exists predict_CDNOW_IsVIP;
|
drop procedure if exists predict_CDNOW_IsVIP;
|
||||||
go
|
go
|
||||||
@@ -350,12 +365,12 @@ begin
|
|||||||
exec sp_execute_external_script
|
exec sp_execute_external_script
|
||||||
@language = N'R'
|
@language = N'R'
|
||||||
, @script = N'
|
, @script = N'
|
||||||
require("RevoScaleR");
|
require("RevoScaleR");
|
||||||
CDNOWmodel<-unserialize(rx_model);
|
CDNOWmodel <- unserialize(rx_model);
|
||||||
CDNOWpred<-rxPredict(CDNOWmodel,data=RFMVIPCluster,writeModelVars = TRUE);
|
CDNOWpred <- rxPredict(CDNOWmodel, data=RFMVIPCluster, writeModelVars = TRUE);
|
||||||
OutputDataSet <- cbind(RFMVIPCluster[,1], CDNOWpred$IsVIP, round(CDNOWpred$IsVIP_Pred,2));
|
OutputDataSet <- cbind(RFMVIPCluster[,1], CDNOWpred$IsVIP, round(CDNOWpred$IsVIP_Pred,2));
|
||||||
colnames(OutputDataSet) <- c("ID", "IsVIP.Actual", "IsVIP.Expected");
|
colnames(OutputDataSet) <- c("ID", "IsVIP.Actual", "IsVIP.Expected");
|
||||||
OutputDataSet<-as.data.frame(OutputDataSet);
|
OutputDataSet <- as.data.frame(OutputDataSet);
|
||||||
'
|
'
|
||||||
, @input_data_1 = N'
|
, @input_data_1 = N'
|
||||||
select * from RFMVIPCluster'
|
select * from RFMVIPCluster'
|
||||||
@@ -367,9 +382,13 @@ OutputDataSet<-as.data.frame(OutputDataSet);
|
|||||||
end;
|
end;
|
||||||
go
|
go
|
||||||
|
|
||||||
|
--execute the stored procedure to obtain the prediction on IsVIP
|
||||||
|
|
||||||
exec predict_CDNOW_IsVIP 'rxLogit';
|
exec predict_CDNOW_IsVIP 'rxLogit';
|
||||||
go
|
go
|
||||||
|
|
||||||
|
--create stored procedure to predict which cluster the customer belongs to
|
||||||
|
|
||||||
drop procedure if exists predict_CDNOW_Cluster;
|
drop procedure if exists predict_CDNOW_Cluster;
|
||||||
go
|
go
|
||||||
create procedure predict_CDNOW_Cluster (@model varchar(100))
|
create procedure predict_CDNOW_Cluster (@model varchar(100))
|
||||||
@@ -380,15 +399,20 @@ begin
|
|||||||
exec sp_execute_external_script
|
exec sp_execute_external_script
|
||||||
@language = N'R'
|
@language = N'R'
|
||||||
, @script = N'
|
, @script = N'
|
||||||
require("RevoScaleR");
|
require("RevoScaleR");
|
||||||
CDNOWmodel<-unserialize(rx_model);
|
CDNOWmodel <- unserialize(rx_model);
|
||||||
CDNOWpred<-rxPredict(CDNOWmodel,data=RFMVIPCluster, predVarNames=c("prob1","prob2","prob3","prob4","prob5","prob6","prob7","prob8"),writeModelVars = TRUE,extraVarsToWrite="ID",computeResiduals=T,overwrite=TRUE);
|
CDNOWpred <- rxPredict(CDNOWmodel,
|
||||||
OutputDataSet <- round(cbind(RFMVIPCluster[,1], RFMVIPCluster[,10],
|
data=RFMVIPCluster,
|
||||||
CDNOWpred$prob1,CDNOWpred$prob2,CDNOWpred$prob3,CDNOWpred$prob4,
|
predVarNames=c("prob1", "prob2", "prob3", "prob4", "prob5", "prob6", "prob7", "prob8"),
|
||||||
CDNOWpred$prob5,CDNOWpred$prob6,CDNOWpred$prob7,CDNOWpred$prob8),2);
|
writeModelVars=TRUE, extraVarsToWrite="ID",
|
||||||
colnames(OutputDataSet) <- c("ID", "Cluster.Actual", "Cluster1.Prob","Cluster2.Prob","Cluster3.Prob","Cluster4.Prob","Cluster5.Prob","Cluster6.Prob","Cluster7.Prob","Cluster8.Prob");
|
computeResiduals=T, overwrite=TRUE);
|
||||||
OutputDataSet<-as.data.frame(OutputDataSet);
|
OutputDataSet <- round(cbind(RFMVIPCluster[,1], RFMVIPCluster[,10],
|
||||||
'
|
CDNOWpred$prob1,CDNOWpred$prob2,CDNOWpred$prob3,CDNOWpred$prob4,
|
||||||
|
CDNOWpred$prob5,CDNOWpred$prob6,CDNOWpred$prob7,CDNOWpred$prob8),2);
|
||||||
|
|
||||||
|
colnames(OutputDataSet) <- c("ID", "Cluster.Actual", "Cluster1.Prob","Cluster2.Prob","Cluster3.Prob","Cluster4.Prob","Cluster5.Prob","Cluster6.Prob","Cluster7.Prob","Cluster8.Prob");
|
||||||
|
OutputDataSet<-as.data.frame(OutputDataSet);
|
||||||
|
'
|
||||||
, @input_data_1 = N'
|
, @input_data_1 = N'
|
||||||
select * from RFMVIPCluster'
|
select * from RFMVIPCluster'
|
||||||
, @input_data_1_name = N'RFMVIPCluster'
|
, @input_data_1_name = N'RFMVIPCluster'
|
||||||
@@ -399,5 +423,7 @@ OutputDataSet<-as.data.frame(OutputDataSet);
|
|||||||
end;
|
end;
|
||||||
go
|
go
|
||||||
|
|
||||||
|
--execute the stored procedure to obtain the prediction on Cluster
|
||||||
|
|
||||||
exec predict_CDNOW_Cluster 'rxDtree';
|
exec predict_CDNOW_Cluster 'rxDtree';
|
||||||
go
|
go
|
||||||
@@ -2,20 +2,25 @@ use sqlr;
|
|||||||
go
|
go
|
||||||
drop table if exists CDNOW;
|
drop table if exists CDNOW;
|
||||||
go
|
go
|
||||||
|
|
||||||
-- create the fraud table to hold invoice data:
|
-- create the fraud table to hold invoice data:
|
||||||
|
|
||||||
create table CDNOW(
|
create table CDNOW(
|
||||||
[ID] int not null,
|
[ID] int not null,
|
||||||
[Date] date not null,
|
[Date] date not null,
|
||||||
[Volume] int not null,
|
[Volume] int not null,
|
||||||
[Amount] float not null);
|
[Amount] float not null);
|
||||||
go
|
go
|
||||||
-- Modify path to the data file: "po.txt"
|
|
||||||
|
-- Modify path to the data file: "CDNOW_master.csv"
|
||||||
|
|
||||||
bulk insert CDNOW
|
bulk insert CDNOW
|
||||||
from 'C:\sqlr\mydemos\CRM\CDNOW_master.csv'
|
from 'C:\sqlr\mydemos\CRM\CDNOW_master.csv'
|
||||||
with(
|
with(
|
||||||
fieldterminator = ',',
|
fieldterminator = ',',
|
||||||
firstrow = 2);
|
firstrow = 2);
|
||||||
go
|
go
|
||||||
|
|
||||||
--create clustered columnstore index cs_CDNOW on CDNOW;
|
--create clustered columnstore index cs_CDNOW on CDNOW;
|
||||||
--go
|
--go
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user