DESCRIPTION Students: Please keep in mind the OMSI rules. Save your files often, make sure OMSI fills your entire screen at all times, etc. Remember that clicking CopyQtoA will copy the entire question box to the answer box. DIRECTIONS: A perfect solution to Question 1 will receive at least an A- grade. QUESTION -ext .R -run 'Rscript ./omsi_answer1.R' (R code answer, 60 points.) Instead of giving the user a single prediction, it might be useful to give them probabilities, something like "You are 12% likely to give this movie a 5, 18% likely to give it a 4..." etc. The goal here will be to develop a function with call form CFexact(covsRatData,ratColName,qeFtn) along with a paired predict() function predict.qeCFexact(obj,newx) where covsRatData is a data frame containing a ratings column and user and item embeddings/covariates; ratColName is the name of the ratings column; qeFtn is the qe*-series function the user wishes to run; and newx is a set of new cases to predict, one case per row. Fill in the blanks. (Do not have a holdout set.) CFexact <- function(covsRatData,ratColName,qeFtn) { qeout <- qeFtn(covsRatData,ratColName,holdout=NULL) res <- qeout class(res) <- c('qeCFexact',class(qeout)) res } predict.qeCFexact <- function(obj,newx) { predout <- predict(obj,newx) } library(rectools) ml100kpluscovs <- getML100K() m1 <- ml100kpluscovs[,c('rating','userMean','itemMean')] cfout <- CFexact(m1,'rating',qeLogit) newx <- m1[c(8,88),-1] predict(cfout,newx) # 1 2 3 4 5 # 8 0.006827812 0.04158580 0.1808716 0.3887890 0.3819258 # 88 0.021705635 0.07756328 0.2586307 0.4016161 0.2404843 instEval <- getInstEval() ie <- instEval[, c('y', 'studage', 'lectage', 'service', 'dept')] set.seed(1) cfout <- CFexact(ie,'y',qeRF) newx <- ie[c(8,88),-1] predict(cfout,newx) # 1 2 3 4 5 # 8 0.456 0.450 0.092 0.002 0.000 # 88 0.008 0.008 0.450 0.058 0.476 QUESTION -ext .R -run 'Rscript ./omsi_answer2.R' (R code answer, 40 points.) You are familiar with the equation 1/(1-x) = 1 + x + x^2 + x^3 + ..., |x| < 1 Making a change of variable, we have 1/w = 1 + (1-w) + (1-w)^2 + (1-w)^3 + ..., |1-w| < 1 This suggests a similar relation for a square matrix W: W^(-1) = I + (I-W) + (I-W)^2 + (I-W)^3 + ..., ||I - W|| < 1 where I is the identity matrix and || || is one of several norms, including Frobenius. Write code to implement this, which will compute the inverse of matrix m by computing a sum through the s-th power. invViaPowers <- function(m,s) { nr <- nrow(m) i <- diag(nr) im <- i - m frb <- norm(im,'F') if (frb >= 1) return(NA) for (j in 1:s) { } tot } m <- rbind(c(1,0.5),c(0.5,1)) invViaPowers(m,6) [,1] [,2] # [1,] 1.328125 -0.656250 # [2,] -0.656250 1.328125 invViaPowers(m,6) %*% m # [,1] [,2] # [1,] 1.0000000 0.0078125 # [2,] 0.0078125 1.0000000