简体   繁体   中英

Plot and solve an equation in R

I want to find the value of u that minimizes my equation (least squares) sum(w*(xu)^2)

Is is possible to plot this equation in R? This would probably let me visually pick the value u that minimizes the equation.

Is is also possible to solve for u value that minimizes the equations?

x <- c(0.18, -1.54, 0.42, 0.95)
w <- c(2, 1, 3, 1)
sum(w*(x-u)^2)

You must be taking the Regression Models coursera.org class. This is the first question of the first quiz. If you recall from the class, the value that minimizes that sum is simply the average of your values in x . There is no need to plot this.

However , you have weights to deal with now. What these weights imply is that these show how many times you see a particular value. Using your example, you would see 0.18 2 times, -1.54 1 time, 0.42 3 times and 0.95 1 time. As such, we have 7 numbers in total.

If you want to find the actual mean / average of this, you would simply do:

values <- (0.18 + 0.18 - 1.54 + 0.42 + 0.42 + 0.42 + 0.95)
numberElements <- 7
mu <- values / numberElements

However, if you want to do this more elegantly, it is really just:

values <- (2*0.18 + 1*(-1.54) + 3*(0.42) + 0.95)
numberElements <- 7
mu <- values / numberElements

This isn't very R friendly. As such, we can simply use x and w to do this for us. You would just do:

mu <- sum(x*w) / sum(w)

The first part of the computation (numerator) achieves what I did with values in the second bit of code I showed you. It takes each number and multiplies it by its corresponding weight. The denominator simply adds up all of the weights together, which corresponds to the total number of numbers we see in our data.

Once you compute this, the answer is thus 0.1471 . This would be the value that minimizes that weighted sum of square differences.


If you wish to plot the value, you can. Just create a new function that encapsulates this weighted sum, and have a value of u that you put in, along with the values of x and w . We can do this by the following function :

squaredError <- function(x, w, r=seq(0,1,0.001)) {
    se <- function(u) {
        sum(w*(x-u)^2)
    }
    sapply(r, se)
}

This defines a function called squaredError that takes in two inputs and optionally three. The first and second inputs are the x and w vectors defined previously and r denotes a range of mu values you want to test for finding the sum of squared errors. By default, I made this between 0 and 1 in steps of 0.001 . I have created an auxiliary function inside where x and w already have lexical scope. The function simply takes in one value which is u , the mean we are testing. We then call sapply to iterate over all values of mu that we specified in to squaredError . The output of squaredError will give you the sum of squared errors for each value you specify as mu . We can then plot our results.

# Figure out which index gives us the minimum value
# Assume x and w are defined as before
r <- seq(0,1,0.001)
out <- squaredError(x, w, r)
minIndex <- which.min(out)
minMu <- r[minIndex] # This reports 0.147... not exact but that depends on the resolution of r
minObjective <- out[minIndex] # This reports 3.716543 which is the least sum of squared error

plot(r, out)
abline(v=minMu, lwd=5, col="red")

The above code finds where the minimum is, and draws the sum of squared errors on the y -axis with the selected mu values on the x -axis. We then draw a vertical line denoting where the minimum is located. You get:

在此处输入图片说明

Note that you can use optimize as stated by @MrFlick. However, if you want to do it graphically, this is one possible approach.

In general, if you want to optimize a function for a single parameter, you can use the optimize function

x <- c(0.18, -1.54, 0.42, 0.95)
w <- c(2, 1, 3, 1)

optimize( function(u){ sum(w*(x-u)^2) }, interval=c(-100,100))

# $minimum
# [1] 0.1471429
# 
# $objective
# [1] 3.716543

If you want, you can plot this objective function for different values of u as well. Here we define a function of u (we use sapply because otherwise the sum() would collapse the results when running the function for multiple points) and plot it using curve()

obj <- function(U){sapply(U, function(u) sum(w*(x-u)^2))}
curve(obj, from=-2, to=2)

and you can see the minimum occurs near 0.1471429.

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM