 Hello everyone and welcome to another episode of Code Emporium where we are going to talk about model interpretation. So we know that models, when they make predictions, we can assess how well they make predictions, but why do models make the predictions that they do? Hence the point of this video. Before we move on, just a quick favor, can you destroy that like button for the YouTube algorithm gods to pick up? That would be lovely. The more likes videos like this get, the algorithm will be like, hey, this video is pretty sick and send this video out to people like yourself. By just hitting that like button, you're helping us all out as a community. This is so much appreciated. So thank you. Well, we're going to be using the Boston housing data set for this entire video where the inputs here, let me just open this up. The inputs are a set of 14 features for regions in Boston, like crime rate and well, percentage of businesses that are in the area. And the output, the vibe, why variable will be the median house price for houses in a particular region in Boston. And so we have about like 500 to 600 samples in our data set. And we're going to be making predictions off of them and trying to interpret them. So let's say that I want to start by fitting a linear regression against this entire data set. Right. And we're going to use the mean absolute error as the evaluation metric. And I get a pretty reasonable amount right here. That's great. But now let's say I want to do some model interpretation, understand what is contributing to this and what are the most important features. And so I use stats models and try to come up with this summary table over here. And in this entire preprocessing step, I did some standard scaling and yeah. So they have mean zero standard deviation one. And at this rate, I could look at the coefficients and kind of look at this and say, well, this is equivalent or proportional to the feature importance as long as they are significant coefficients. So some significant values here will be like L stat, which has a very high magnitude value compared to the rest. And this would be like one of the most important coefficients closely followed by probably this dis right. And so on, which this is reasonable to just to say reasonable assumption to make. But let's say that I now want to change my model from linear regression to a random forest regressor. Right. So the only thing that changes here now is like adding a random forest regressor, all the preprocessing steps remain the same. And I get another test MAE, which is pretty reasonable too. And when I look at the feature importance here, though, I kind of see something similar else that is still up there. But it's it's a little similar, a little different, not too, not too crazy different. But yeah, in general, it is a different way of assessing feature importance because here I'm using a built in method call right here, which essentially determines feature importance depending on the node impurities of the tree that's constructed. Yeah. And this is though very specific to these tree based algorithms. But let's say now I want to change it from random forest regressor to a neural network, where now I'm like flushing out a neural network architecture right here. I'm building with PyTorch, by the way. And so I have one hidden layer with an output layer, no activation functions here. And I'm using mini batch gradient descent to process all these batches. And when I look at my test MAE, well, it still it performs really well, probably better than all the rest right here because of its MAE. But unfortunately, though, I don't really have a direct way to identify feature importance of a neural network, not with like a built in function that I can just visualize, at least as far as I know right now. And on top of that, in general, when looking at all these three methods, I don't see like a single way to define feature importance that is model agnostic. So one way that I can just feed any kind of model in order to get a feature importance for, well, these for every feature. And on top of that, what if I want to know, like for a given sample, why it's predicting the way that it is? Like what is contributing to a specific samples prediction to and not just feature importance? Well, all of those, honestly, can be answered using Shapley values. And we're going to be taking a look at that later. But before that, let's take an intuitive look at how we would intuitively interpret models. Now let's think about this for a sec. OK, let's first reconstruct our linear regression model. We have it. That's great. Let's pass in now a non feature data frame, basically a data frame of just NANDs for all the features. And let's see what our model outputs. Now, obviously, well, with all these NANDs, they're going to be imputed by your simple imputer right here, which is going to, well, right here, actually, which is going to, by default, imputing the mean value of those features. And when we do, we get a model output of twenty two point seven six seven. And this is, you can say, the the expected output of the model or the base value, more technical terms. Now let's just take one of our test samples. I'm just taking the first one right here. And this is how the data frame sample looks and we throw it into our model and it makes a prediction of fifteen point eight five one, which is fifteen point five one thousand dollars is the median house price. That's fine. But how do we get from this twenty two thousand right here or twenty two point seven six seven all the way down to fifteen point eight five one? It's because of these features, right? But how do I know which features contributed how much? Well, the way I would probably do it is just first take one feature at a time like crime and then try to vary up and down and see how the model output varies with, you know, varying crime. Same do that with ZN how vary this, see how the output varies. A good way to visualize exactly this is using partial dependency plots. So I'm going to construct a partial dependency plot right over here. And for crime, for example, it's exactly what I mentioned. The X axis is the feature crime and the Y axis is the model output as we vary crime when we're given crime. So this gray data frame, I mean, this great not great data frame, this gray histogram over here is the distribution of all the test samples, the crime of the off these test samples. You can see that they're all pretty low over here. And the crosshair is the expected values. So this cross this line is kind of close to like twenty two point seven. You know, around that value, at least it's dependent internally. There's like an internal logic for computing this one might be slightly different, but it's around twenty two point seven that we discussed. And the corresponding crime right here is the kind of expected value of this feature crime right here, right, ignoring the red parts for now. So you can see that we have the same for partial dependency plots for Rad. So as the rad increases, you can see that the model output increases as age decrease, as age increases. Well, the expected value also increases. But you can see that the Y axis is, you know, kind of small. It's only in this entire area is not even going to increase it by like one point two. So although age is a factor and is proportional positively, it's not really that significant. So no matter what age is, it's not going to affect the model output that much. Right. Now, looking at the individual samples, so let's say I want to look at it, you know, OK, let the effect of a particular sample on a, you know, on the model output. Well, that's where these red lines in the black dot come in. So for this, you remember, I'm taking the same exact sample that we saw before where the crime was four point seven. If you look here, four point seven was that, right. And if you look at the X axis, that corresponds to like this part right. This part right here, and you can see it's a long four point seven. But the Y axis, of course, you know, I don't know why that this this dot is actually misposition. This dot should be on the blue line and this the top part of this red line right here, this part should be on the gray line, right. Maybe it's a lot easier to see with this example. Yeah, it's also shifted up. This dot should be on the blue line. This bottom part of the red line should be on this red line. So for this particular sample, the same sample, the rad was 24. And you can visualize we can see that just by going up here. Rad was 24 right up here, right. So plotting this out, you can see that the difference in the model output from the expected value, it is, it is now like something like 20, twenty seven or twenty eight, right. So it has a huge effect on the model output, increasing it by like three and four, four and a half. I don't know, something like not four and a half. It's like twenty two point five plus something is twenty eight. So it's like five and a half or something like that, right. And this entire value, this length of the red line, thus becomes the contribution of this particular feature rad by this particular sample zero, right. And we call this red line or the magnitude of this red line, the Shapley value, right. And so we can have Shapley values for every sample, every feature of every single sample in our entire data set. So I can keep plotting plots like this, the length of this red line is again another Shapley value. But, you know, this it kind of gets hard to plot so many plots for every feature, every sample. And so let's say that for every sample, I want to plot it. I want to know all of these these red lines for every single feature for a particular sample. And so we have representations from Shap the library in Python that provides exactly that. I'm looking at the same exact sample, right. Remember twenty four rad, we saw that before, right. And I am going to plot it for every other feature, though, right here. And you can see that this gray line, there's like a little gray line that's going up here, and it says f of X is fifteen point eight five one. That is the model output and the expected value for my output. That was twenty three point three seven six. We determined it to be like twenty two point seven. But, you know, internal features of like Shap kind of have determined it this way, which is similar. And so the difference between these two is negative seven point five. How did we come up with? How on earth did we get from twenty three here to fifteen point eight five here? Well, it's shown by every single feature right here. So it looks like rad had a huge impact by increasing, you know, having a positive influence on, you know, increasing the prices specifically for this specific sample. And then the tax, Elstad B and Knox had a good impact in bringing down the entire price. And so we're able to visually interpret why exactly this specific sample is given an output of fifteen point eight five one. Now, a cooler way to like I like seeing a condensed representation. It's exactly the same pieces of information, but just not in a waterfall model. Sometimes this is easy to look at whatever you feel is comfortable. So now that we have, yeah, this is for an individual sample, though. But what if we want to bubble this up to determine model importance? Well, all you need to do is take all the shot values for every single feature in every single sample. And for every single feature column, we are going to just determine the mean of the absolute value of the shatley value. So column wise is take the mean of the absolute value. And so you end up with a plot that's like this, where the shatley values would be proportional to contribution. Right. And so we can see that for again, this was a linear regression model. Rad is the most important feature, followed by tax, followed by L stat, followed by this followed by P ratio and so on. Right. And so I that's kind of why I have like a note over here that says like what features are important to the sort of linear regression model? Yeah, this plot is kind of the exact same thing. It's going to give you the exact same information. It's just a standardized way of plotting it out. That's all. OK, cool. And now that we have a linear regression interpreted, even if I wanted to replace this entire network with a neural network, sorry, this entire model with a neural network instead. This is the exact same code that I showed you before. And we're getting a very similar M.A.E. Yeah. And now I can just create a summary plot, which is basically, you know, determine the shatley values and then aggregate them across every column. And you get, well, feature importance. And this is a very standardized way so that, you know, for any model that I want to create and any model I want to interpret, I can. And I can also determine it for every single sample. I can determine the contribution for every single feature in that sample or for every single feature I can determine, you know, the feature importance across the entire data set. So yeah, that's actually the good basis of shatley values. There are there's a documentation for SHAP, which is the main library I used for creating these shatley values. I will link that down in the description. But now armed with this knowledge, I think it'll be easier for you to understand exactly the mathematical takes on shatley values that you see in documentation. I've linked to it in here below. And if you click that, it'll redirect you to, you know, this, this very nice and detailed like page on just understanding, like interpretable machine learning. I honestly recommend you to go through this. It's a great read with a lot of examples and also lots of good mathematical detail. So let's say that we have this model, right? It's a linear regression model for now, FFX, right? And we could determine feature importance here by just taking the effect of the model minus the effect minus like the expected value of that feature. And I know there is like some and if you aggregated across all like features right here of a particular sample, you get this expression and this expression is exactly what we did. So you see FFX over here. FFX is essentially, well, that's the model output. So for that particular sample, it was like 15.871, right? And then this expected value of the model output was that 23.3 or 20 22.7, whatever you want to interpret it. And the difference is like negative 7.5, which is the overall like contribution that we have for this, this exact sample, right? And this negative 7.5 is to be padded out with all the 13 or 14 features that we have in the Boston data set. So do go through this for more mathematical intuition. And I hope I hope like this entire video does help you understand better Shapley values and also interpreting models. So now you can interpret any machine learning model you want with ease. So go try it out. It's really cool. Leave some links in the description below. And until next time, take it easy.