text:
Search for a tool
Base N Convert

Tool to write numbers in base N (change of basis / convert). In numeral systems, a base (radix) is the value of successive powers when writing a number.

Results

Base N Convert -

Tag(s) : Arithmetics

Share
dCode and more

dCode is free and its tools are a valuable help in games, maths, geocaching, puzzles and problems to solve every day!
A suggestion ? a feedback ? a bug ? an idea ? Write to dCode!

Please, check our dCode Discord community for help requests!
NB: for encrypted messages, test our automatic cipher identifier!

Thanks to your feedback and relevant comments, dCode has developed the best 'Base N Convert' tool, so feel free to write! Thank you!

# Base N Convert

## Converting Base 10 to Base N

### What are default symbols?

A number in base 10 is written with the digits' 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9` are used. For other bases, it is common to use letters, more precisely the following characters: 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ (Beware to lowercase and uppercase from base 37) in order to write numbers up to base 62.

### How to convert from a base to another?

A number $N$ in base $b$ can be written with an addition of powers in this base $b$.

Example: The number $N = 123_{(10)}$ (base 10) verifies the equality $$N = 789 = 7 \times 100 + 8 \times 10 + 9 \times 1 = 7 \times 10^2 + 8 \times 10^1 + 9 \times 10^0$$

 $N=$ $c2$ $c1$ $c0$ $789$ $7$ $8$ $9$

Take a number $N$ made of $n$ digits ${ c_{n-1}, c_{n-2}, ..., c_2, c_1, c_0 }$ in base $b$, it can be written it as a polynomial:

$$N_{(b)} = \{ c_{n-1}, ..., c_1, c_0 \}_{(b)} = c_{n-1} \times b^{n-1} + ... + c_1 \times b^1 + c_0 \times b^0$$

To compute a base change, base $10$ is the reference, or an intermediate step.

Example: To change from base $3$ to base $7$, calculate base $3$ to base $10$, then from base $10$ to base $7$.

### How to convert from base 10 to base n?

Use the following algorithm to convert from base $10$ to base $n$:

$$q_0=n; i=0; \mbox{ while } q_i > 0 \mbox{ do } (r_i = q_i \mbox{ mod } b; q_{i+1}= q_i \mbox{ div } b ; i = i+1 )$$

The converted number is composed of digits $r_{i=0...n-1}$ (with $r_0$ the digit of the units).

Example: $N = 123_{(10)}$ (base 10) is converted to base $7$:

$$q_0 = 123 \\ r_0 = 123 \mbox{ mod } 7 = 4 \;\;\; q_1 = 123 \mbox{ div } 7 = 17 \\ r_1 = 17 \mbox{ mod } 7 = 3 \;\;\; q_1 = 17 \mbox{ div } 7 = 2 \\ r_2 = 2 \mbox{ mod } 7 = 2 \;\;\; q_2 = 2 \mbox{ div } 7 = 0 \\ 123_{(10)} = 234_{(7)}$$

### How to convert from base n to base 10?

To convert a number $N_1$ written in base $b$ in a number $N_2$ written in base $10$, use the fact that $N_1$ is made of $n$ digits ${ c_{n-1}, c_{n-2}, ..., c_1, c_0 }$ and apply the following algorithm:

$$N_2 = c_{n-1} ; \mbox{ for } ( i=n-2 \mbox{ to } 1 ) \mbox{ do } N_2=N_2 \times b+c_i$$

The number $N_2$ is written in base $10$.

The algorithm is equivalent to the calculation $$(( c_{n-1} \times b + c_{n-2} ) \times b + c_{n-3} ) ... ) \times b + c_0$$

Example: Take the number $123_{(7)}$ (in base $7$), and apply the conversion algorithm:

$$123 = \{1,2,3\} \\ N = 1 \\ N = 1*7+2 = 9 \\ N = 9*7+3 = 66 \\ N = 123_{(7)} = 66_{(10)}$$

So $123_{(7)}$ is equal to $66_{(10)}$ in base $10$.

### What are usual bases?

— base 2 (binary system - base2) in informatics

— base 3 (trinary system - base3)

— base 8 (octal system - base8)

— base 9 (nonary system - base9)

— base 10 (decimal system - base10)

— base 12 (duodecimal system - base12), for month or hours

— base 16 (hexadecimal system - base16) in informatics for bytes

— base 20 (vigesimal system - base20) by Mayas and Aztecs

base 26 (alphabetic system - base26)

base 36 (alphanumeric system - base36)

— base 60 (sexagesimal system - base60) for minutes, seconds by Sumerians and Babylonians.

base 62 (full alphanumeric system - base62)

All the basics can be used for computer coding or any other math problem.

Example: Encoding and decoding base64 is common on the Internet.

## Source code

dCode retains ownership of the online "Base N Convert" source code. Except explicit open source licence (indicated CC / Creative Commons / free), the "Base N Convert" algorithm, the applet or snippet (converter, solver, encryption / decryption, encoding / decoding, ciphering / deciphering, translator), or the "Base N Convert" functions (calculate, convert, solve, decrypt / encrypt, decipher / cipher, decode / encode, translate) written in any informatic language (Python, Java, PHP, C#, Javascript, Matlab, etc.) and all data download, script, copy-paste, or API access for "Base N Convert" are not public, same for offline use on PC, tablet, iPhone or Android ! Remainder : dCode is free to use.

## Need Help ?

Please, check our dCode Discord community for help requests!
NB: for encrypted messages, test our automatic cipher identifier!


text:
# What is the name of the following theorem: dimension of complex irreducible representation divides order of group

-

Georg Frobenius, Über die Primfactoren der Gruppendeterminante, Sitzungsber. Akad. Berlin (1896) 1343-1382. The theorem is announced at the beginning, p. 1344:

Der Grad $f$ ist ein Divisor der Ordnung $h$

and proved at the very end, p. 1382:

Daher ist die Zahl $e=f$ ein Divisor der Ordnung $h$.

P.S.: As to an agreed-upon name for this theorem, I think there isn't one (or googling would reveal it). Too much competition from other results of Frobenius! So, other than in the book by Etingof et al. (who innovate by calling it "Frobenius divisibility theorem"), one finds mainly turns of phrase like "Frobenius's theorem that the degrees of the irreducible characters divide the order of the group", as in Curtis (who devotes two pages to this theorem and Burnside's second proof of it).

An interesting byproduct of this archaeology is some light shed on the words "degree" and "irreducible" in representation theory — namely, they initially qualified factors of a polynomial, the group determinant.

-
Thank you very much for your detailed answer. I think I like the name "Frobenius divisibility theorem". About your last comment. Do you mean the determinant described in \S 4.2 of arxiv.org/pdf/0901.0827v5.pdf? Is there a nice way to think of the factors $P_i(x)$? Thanks again –  Rami Jul 25 '13 at 8:19
Yes, that's the determinant in question. I believe loc. cit. gives you the nicest way of thinking about its factors, viz.: $P_i(x) = \det(\rho_i(x)) = \det(\sum_{g\in G} x_g\rho_i(g))$ where $\rho_i$ is the $i$-th irreducible representation of $G$. For more detail see KConrad's lovely paper dx.doi.org/10.5169/seals-63909 –  Francois Ziegler Jul 25 '13 at 13:59

format: plain


text:
1.2k views
State True or False with one line explanation

Expanding opcode instruction formats are commonly employed in RISC. (Reduced Instruction Set Computers) machines.
retagged | 1.2k views

I think the answer is TRUE.

RISC systems use fixed length instruction to simplify pipeline.

eg: MIPS, PowerPC: Instructions are $4$ bytes long.

CISC systems use Variable-length instructions.

eg: Intel $80X86$: Instructions vary from $1$ to $17$ bytes long.

Now the challenge is: How to fit multiple sets of instruction types into same (limited) number of bits (Fixed size instruction)?

Here comes Expanding opcode into the picture.

RISC systems commonly uses Expanding opcode technique to have fixed size instructions.

edited by
0
@bikram sir Please tell a good source to read Expanding Opcodes and their numericals?
+2
0

this is true for more conformation look in below given link.

from 25 minute.

This expanding opcode scheme makes the decoding more complex. Instead of simply looking at a bit pattern and deciding which instruction it is, we need to decode the instruction something like this:

if (leftmost four bits != 1111 ) {
else if (leftmost seven bits != 1111 111 ) {
else if (leftmost twelve bits != 1111 1111 1111 ) {
else {
}

At each stage, one spare code is used to indicate that we should now look at more bits. This is another example of the types of trade-offs hardware designers continually face: Here, we trade opcode space for operand space.

Being more complex and RISC not needing more instructions expanding opcode is not a common RISC technique. But this is there in many RISC machines.

0
@arjun sir and @bikram sir

0

Best answer is chosen already , it is true not always false .

Many RISC machines use expanding opcode technique.

see what question says " Expanding opcode instruction formats are commonly employed in RISC."

this is true , even Arjun said that in last line .

0


text:
# Algebraic functions

Alternatively, an(x)yn + an − 1(x)yn − 1 + a1(x)y + a0(x) = 0, where $a_n(x), a_{n-1}(x), \cdots, a_1(x), a_0(x)$ are themselves polynomials in x.


text:
# E = mc^2: Identity or equality

1. Aug 23, 2004

### pmb_phy

Some people refer to the relationship between inertial mass m (aka "relativistic mass") and inertial energy E as an identity and some refer to it as an equality. Inertial mass has never been defined as m = E/c2.

Inertial mass is always defined as the m in p = mv (e.g. Tolman, Feynman, French etc. etc. etc.). The E in that equation is always defined as the total energy of a particle minus the potential energy of position, V(r) (although some people use different letters for, such as T, for E. E.g. Goldstein - 3rd Ed.). The relationship E = mc2 must then be derived which thereby makes it an equality rather than an identity.

My question is to those who hold it to be an identiy is - Why?

Thanks

Pete

Last edited: Aug 23, 2004
2. Aug 23, 2004

### DW

Inertial mass is not relativistic mass as I have mathematically proven here in the past. Relativistic mass has no place in modern relativity as it is just a redundant name for relativistic energy which is defined as the time element of the momentum four-vector of the first kind. From the definition of the momentum four-vector of the second kind one has
$$P^{0} = p^{0} + (q/c)\phi ^{0}$$
This yields
$$E_{R} = E_{tot} - E_{pot}$$
$$E_{R}$$ is the relativistic energy and what is innapropriately called relativistic mass. You also missname energy parameter by total energy as well which is unfortunate, but even if by that mistake you have identified relativistic mass with the energy parameter instead of the total energy, you have still "identified" it with an energy. That should end your questioning whether it is an identity because even though you have identified it with the wrong energy, you have still "identified" it yourself.
To see more about what I am refering to conserning the different kinds of momentum four-vectors see
http://www.geocities.com/zcphysicsms/chap3.htm

Last edited: Aug 23, 2004
3. Aug 23, 2004

### chroot

Staff Emeritus
Okay, pmb, how many threads do you intend to start that have no purpose other than discussing the semantics of the invariant mass view vs. the relativistic mass view? This same discussion has already been had countless times on this forum. I've given you the opportunity to write an essay supporting your views, which we will happy to host for you. You have ignored that opportunity, and continue to start threads about the same topics. I regard this thread as spamming.

- Warren


text:
# Modes

There are various modes that can be toggled on or off. Modes can be enabled/disabled by stick positions, auxillary receiver channels and other events such as failsafe detection.

ID Short Name Function
0 ARM Enables motors and flight stabilisation
1 ANGLE Legacy auto-level flight mode 真正的自稳模式
2 HORIZON Auto-level flight mode  半自稳模式
4 ANTI GRAVITY Prevents dips and rolls on fast throttle changes
6 HEADFREE Head Free – When enabled yaw has no effect on pitch/roll inputs
8 CAMSTAB Camera Stabilisation
12 PASSTHRU Pass roll, yaw, and pitch directly from rx to servos in airplane mix
13 BEEPERON Enable beeping – useful for locating a crashed aircraft
15 LEDLOW Switch off LED_STRIP output
17 CALIB Start in-flight calibration
19 OSD Enable/Disable On-Screen-Display (OSD)
20 TELEMETRY Enable telemetry via switch
23 SERVO1 Servo 1
24 SERVO2 Servo 2
25 SERVO3 Servo 3
26 BLACKBOX Enable BlackBox logging
27 FAILSAFE Enter failsafe stage 2 manually
28 AIRMODE Alternative mixer and additional PID logic for more stable copter
29 3D Enable 3D mode
30 FPV ANGLE MIX Apply yaw rotation relative to a FPV camera mounted at a preset angle
31 BLACKBOX ERASE Erase the contents of the onboard flash log chip (takes > 30 s)
32 CAMERA CONTROL 1 Control function 1 of the onboard camera (if supported)
33 CAMERA CONTROL 2 Control function 2 of the onboard camera (if supported)
34 CAMERA CONTROL 3 Control function 3 of the onboard camera (if supported)
35 FLIP OVER AFTER CRASH Reverse the motors to flip over an upside down craft after a crash (DShot required)
36 BOXPREARM When arming, wait for this switch to be activated before actually arming
37 BEEP GPS SATELLITE COUNT Use a number of beeps to indicate the number of GPS satellites found
39 VTX PIT MODE Switch the VTX into pit mode (low output power, if supported)
40 USER1 User defined switch 1. Intended to be used to control an arbitrary output with PINIO
41 USER2 User defined switch 2. Intended to be used to control an arbitrary output with PINIO
42 USER3 User defined switch 3. Intended to be used to control an arbitrary output with PINIO
43 USER4 User defined switch 4. Intended to be used to control an arbitrary output with PINIO
44 PID AUDIO Enable output of PID controller state as audio
45 PARALYZE Permanently disable a crashed craft until it is power cycled
46 GPS RESCUE Enable ‘GPS Rescue’ to return the craft to the location where it was last armed
47 ACRO TRAINER Enable ‘acro trainer’ angle limiting in acro mode
48 DISABLE VTX CONTROL Disable the control of VTX settings through the OSD
49 LAUNCH CONTROL Race start assistance system

## Auto-leveled flight

The default flight mode does not stabilize the multicopter around the roll and the pitch axes. That is, the multicopter does not level on its own if you center the pitch and roll sticks on the radio. Rather, they work just like the yaw axis: the rate of rotation of each axis is controlled directly by the related stick on the radio, and by leaving them centered the flight controller will just try to keep the multicopter in whatever orientation it’s in. This default mode is called “Rate” mode, also sometime called “Acro” (from “acrobatic”) or “Manual” mode, and is active whenever no auto-leveled mode is enabled.

If your flight controller is equipped with a 3 axis accelerometer (very likely), then you can enable one of the two available auto leveled flight modes.

## Mode details

### Angle

In this auto-leveled mode the roll and pitch channels control the angle between the relevant axis and the vertical, achieving leveled flight just by leaving the sticks centered.

### Horizon

This hybrid mode works exactly like the previous ANGLE mode with centered roll and pitch sticks (thus enabling auto-leveled flight), then gradually behaves more and more like the default RATE mode as the sticks are moved away from the center position.

In this mode, the “head” of the multicopter is always pointing to the same direction as when the feature was activated. This means that when the multicopter rotates around the Z axis (yaw), the controls will always respond according the same “head” direction.

With this mode it is easier to control the multicopter, even fly it with the physical head towards you since the controls always respond the same. This is a friendly mode to new users of multicopters and can prevent losing the control when you don’t know the head direction.

### Airmode

In the standard mixer / mode, when the roll, pitch and yaw gets calculated and saturates a motor, all motors will be reduced equally. When motor goes below minimum it gets clipped off. Say you had your throttle just above minimum and tried to pull a quick roll – since two motors can’t go any lower, you essentially get half the power (half of your PID gain). If your inputs would asked for more than 100% difference between the high and low motors, the low motors would get clipped, breaking the symmetry of the motor balance by unevenly reducing the gain. Airmode will enable full PID correction during zero throttle and give you ability for nice zero throttle gliding and actobatics. But also the cornering / turns will be much tighter now as there is always maximum possible correction performed. Airmode can also be enabled to work at all times by always putting it on the same switch like your arm switch or you can enable/disable it in air. Additional things and benefits: Airmode will additionally fully enable Iterm at zero throttle. Note that there is still some protection on the ground when throttle zeroed (below min\check) and roll/pitch sticks centered. This is a basic protection to limit motors spooling up on the ground. Also the Iterm will be reset above 70% of stick input in acro mode to prevent quick Iterm windups during finishes of rolls and flips, which will provide much cleaner and more natural stops of flips and rolls what again opens the ability to have higher I gains for some. Note that AIRMODE will also overrule motor stop function! It will basically also act as an idle up switch.

## Auxiliary Configuration

Spare auxillary receiver channels can be used to enable/disable modes. Some modes can only be enabled this way.

Configure your transmitter so that switches or dials (potentiometers) send channel data on channels 5 and upwards (the first 4 channels are usually occupied by the throttle, aileron, rudder, and elevator channels).

e.g. You can configure a 3 position switch to send 1000 when the switch is low, 1500 when the switch is in the middle and 2000 when the switch is high.

Configure your tx/rx channel limits to use values between 1000 and 2000. The range used by mode ranges is fixed to 900 to 2100.

When a channel is within a specifed range the corresponding mode is enabled.

Use the GUI configuration tool to allow easy configuration when channel.

### CLI

There is a CLI command, aux that allows auxillary configuration. It takes 5 arguments as follows:

• AUX range slot number (0 – 39)
• mode id (see mode list above)
• AUX channel index (AUX1 = 0, AUX2 = 1,… etc)
• low position, from 900 to 2100. Should be a multiple of 25.
• high position, from 900 to 2100. Should be a multiple of 25.

If the low and high position are the same then the values are ignored.

e.g.

Configure AUX range slot 0 to enable ARM when AUX1 is withing 1700 and 2100.

You can display the AUX configuration by using the aux command with no arguments.


text:
Sum of (i^2)/(4^i)

1. Jun 21, 2004

Johnny Leong

Sum of (i^2)/(4^i) where i is from 0 to infinity.

2. Jun 21, 2004

turin

If you just want an approximate answer, then consider the convergence of the series.

3. Jun 21, 2004

Johnny Leong

Sum of (i^2)/(4^i) > 1/4 + 1/4 + 9/16 + Sum of 1/(4^i) where 4<=i<=infinity.
Can this be a good approximation?

4. Jun 21, 2004

HallsofIvy

Staff Emeritus
Well, that was what you were told when you posted this under "k-12 homework".

5. Jun 27, 2004

turin

The sequence of partial sums is monotonic, so you definitely know that the infinite series must be greater than any partial series. Then, you know that any number greater than 1 is greater than 1, so that remaining sum also fits the bill.

I actually worked this summation out to about 20 terms, and it appears as though it is a recognizable fraction.

6. Jun 27, 2004

7. Jun 27, 2004

turin

8. Jun 28, 2004

I had no trouble following it and I'm just out of high school.

Alternatively, do you know of another, less advanced way of solving it? I'd be interested in seeing it.

9. Jun 28, 2004

arildno

So would I!
Perhaps I shot a sparrow with a cannon..

10. Jun 28, 2004

turin

Add about twenty of the terms. You can definitely see the series converge. This is "less advanced" (and more straightforward). Though I certainly admit that it does not smack of the elegance provided by arildno.

I would say you fought an armored knight with a rapier.


text:
# Chapter 16 Interpretable Machine Learning

In the previous chapters you learned how to train several different forms of advanced ML models. Often, these models are considered “black boxes” due to their complex inner-workings. However, because of their complexity, they are typically more accurate for predicting nonlinear, faint, or rare phenomena. Unfortunately, more accuracy often comes at the expense of interpretability, and interpretability is crucial for business adoption, model documentation, regulatory oversight, and human acceptance and trust. Luckily, several advancements have been made to aid in interpreting ML models over the years and this chapter demonstrates how you can use them to extract important insights. Interpreting ML models is an emerging field that has become known as interpretable machine learning (IML).

## 16.1 Prerequisites

There are multiple packages that provide robust machine learning interpretation capabilities. Unfortunately there is not one single package that is optimal for all IML applications; rather, when performing IML you will likely use a combination of packages. The following packages are used in this chapter.

# Helper packages
library(dplyr)      # for data wrangling
library(ggplot2)    # for awesome graphics

# Modeling packages
library(h2o)       # for interfacing with H2O
library(recipes)   # for ML recipes
library(rsample)   # for data splitting
library(xgboost)   # for fitting GBMs

# Model interpretability packages
library(pdp)       # for partial dependence plots (and ICE curves)
library(vip)       # for variable importance plots
library(iml)       # for general IML-related functions
library(DALEX)     # for general IML-related functions
library(lime)      # for local interpretable model-agnostic explanations

To illustrate various concepts we’ll continue working with the h2o version of the Ames housing example from Section 15.1. We’ll also use the stacked ensemble model (ensemble_tree) created in Section 15.3.

## 16.2 The idea

It is not enough to identify a machine learning model that optimizes predictive performance; understanding and trusting model results is a hallmark of good science and necessary for our model to be adopted. As we apply and embed ever-more complex predictive modeling and machine learning algorithms, both we (the analysts) and the business stakeholders need methods to interpret and understand the modeling results so we can have trust in its application for business decisions (Doshi-Velez and Kim 2017).

Advancements in interpretability now allow us to extract key insights and actionable information from the most advanced ML models. These advancements allow us to answer questions such as:

• What are the most important customer attributes driving behavior?
• How are these attributes related to the behavior output?
• Do multiple attributes interact to drive different behavior among customers?
• Why do we expect a customer to make a particular decision?
• Are the decisions we are making based on predicted results fair and reliable?

Approaches to model interpretability to answer the exemplar questions above can be broadly categorized as providing global or local explanations. It is important to understand the entire model that you’ve trained on a global scale, and also to zoom in on local regions of your data or your predictions and derive explanations. Being able to answer such questions and provide both levels of explanation is key to any ML project becoming accepted, adopted, embedded, and properly utilized.

### 16.2.1 Global interpretation

Global interpretability is about understanding how the model makes predictions, based on a holistic view of its features and how they influence the underlying model structure. It answers questions regarding which features are relatively influential, how these features influence the response variable, and what kinds of potential interactions are occurring. Global model interpretability helps to understand the relationship between the response variable and the individual features (or subsets thereof). Arguably, comprehensive global model interpretability is very hard to achieve in practice. Any model that exceeds a handful of features will be hard to fully grasp as we will not be able to comprehend the whole model structure at once.

While global model interpretability is usually out of reach, there is a better chance to understand at least some models on a modular level. This typically revolves around gaining understanding of which features are the most influential (via feature importance) and then focusing on how the most influential variables drive the model output (via feature effects). Although you may not be able to fully grasp a model with a hundred features, typically only a dozen or so of these variables are really influential in driving the model’s performance. And it is possible to have a firm grasp of how a dozen variables are influencing a model.

### 16.2.2 Local interpretation

Global interpretability methods help us understand the inputs and their overall relationship with the response variable, but they can be highly deceptive in some cases (e.g., when strong interactions are occurring). Although a given feature may influence the predictive accuracy of our model as a whole, it does not mean that that feature has the largest influence on a predicted value for a given observation (e.g., a customer, house, or employee) or even a group of observations. Local interpretations help us understand what features are influencing the predicted response for a given observation (or small group of observations). These techniques help us to not only answer what we expect a customer to do, but also why our model is making a specific prediction for a given observation.

There are three primary approaches to local interpretation:

• Local interpretable model-agnostic explanations (LIME)
• Shapley values
• Localized step-wise procedures

These techniques have the same objective: to explain which variables are most influential in predicting the target for a set of observations. To illustrate, we’ll focus on two observations. The first is the observation that our ensemble produced the highest predicted Sale_Price for (i.e., observation 1825 which has a predicted Sale_Price of $663,136), and the second is the observation with the lowest predicted Sale_Price (i.e., observation 139 which has a predicted Sale_Price of$47,245.45). Our goal with local interpretation is to explain what features are driving these two predictions.

# Compute predictions
predictions <- predict(ensemble_tree, train_h2o) %>% as.vector()

# Print the highest and lowest predicted sales price
paste("Observation", which.max(predictions),
"has a predicted sale price of", scales::dollar(max(predictions)))
## [1] "Observation 1825 has a predicted sale price of $663,136" paste("Observation", which.min(predictions), "has a predicted sale price of", scales::dollar(min(predictions))) ## [1] "Observation 139 has a predicted sale price of$47,245.45"

# Grab feature values for observations with min/max predicted sales price
high_ob <- as.data.frame(train_h2o)[which.max(predictions), ] %>% select(-Sale_Price)
low_ob  <- as.data.frame(train_h2o)[which.min(predictions), ] %>% select(-Sale_Price)

### 16.2.3 Model-specific vs. model-agnostic

It’s also important to understand that there are model-specific and model-agnostic approaches for interpreting your model. Many of the approaches you’ve seen in the previous chapters for understanding feature importance are model-specific. For example, in linear models we can use the absolute value of the $$t$$–statistic as a measure of feature importance (though this becomes complicated when your linear model involves interaction terms and transformations). Random forests, on the other hand, can record the prediction accuracy on the OOB portion of the data, then the same is done after permuting each predictor variable, and the difference between the two accuracies are then averaged over all trees, and normalized by the standard error. These model-specific interpretation tools are limited to their respective model classes. There can be advantages to using model-specific approaches as they are more closely tied to the model performance and they may be able to more accurately incorporate the correlation structure between the predictors (Kuhn and Johnson 2013).

However, there are also some disadvantages. For example, many ML algorithms (e.g., stacked ensembles) have no natural way of measuring feature importance:

vip(ensemble_tree, method = "model")
## Error in vi_model.default(ensemble_tree, method = "model") :
##  model-specific variable importance scores are currently not available for objects of class "h2o.stackedEnsemble.summary".

Furthermore, comparing model-specific feature importance across model classes is difficult since you are comparing different measurements (e.g., the magnitude of $$t$$-statistics in linear models vs. degradation of prediction accuracy in random forests). In model-agnostic approaches, the model is treated as a “black box”. The separation of interpretability from the specific model allows us to easily compare feature importance across different models.

Ultimately, there is no one best approach for model interpretability. Rather, only by applying multiple approaches (to include comparing model specific and model agnostic results) can we really gain full trust in the interpretations we extract.

An important item to note is that when using model agnostic procedures, additional code preparation is often required. For example, the iml (Molnar 2019), DALEX (Biecek 2019), and LIME (Pedersen and Benesty 2018) packages use purely model agnostic procedures. Consequently, we need to create a model agnostic object that contains three components:

1. A data frame with just the features (must be of class "data.frame", cannot be an "H2OFrame" or other object).
2. A vector with the actual responses (must be numeric—0/1 for binary classification problems).
3. A custom function that will take the features from 1), apply the ML algorithm, and return the predicted values as a vector.

The following code extracts these items for the h2o example:

# 1) create a data frame with just the features
features <- as.data.frame(train_h2o) %>% select(-Sale_Price)

# 2) Create a vector with the actual responses
response <- as.data.frame(train_h2o) %>% pull(Sale_Price)

# 3) Create custom predict function that returns the predicted values as a vector
pred <- function(object, newdata)  {
results <- as.vector(h2o.predict(object, as.h2o(newdata)))
return(results)
}

# Example of prediction output
pred(ensemble_tree, features) %>% head()
## [1] 207144.3 108958.2 164248.4 241984.2 190000.7 202795.8

Once we have these three components we can create our model agnostic objects for the iml43 and DALEX packages, which will just pass these downstream components (along with the ML model) to other functions.

# iml model agnostic object
components_iml <- Predictor$new( model = ensemble_tree, data = features, y = response, predict.fun = pred ) # DALEX model agnostic object components_dalex <- DALEX::explain( model = ensemble_tree, data = features, y = response, predict_function = pred ) ## 16.3 Permutation-based feature importance In previous chapters we illustrated a few model-specific approaches for measuring feature importance (e.g., for linear models we used the absolute value of the $$t$$-statistic). For SVMs, on the other hand, we had to rely on a model-agnostic approach which was based on the permutation feature importance measurement introduced for random forests by Breiman (2001) (see Section 11.6) and expanded on by Fisher, Rudin, and Dominici (2018). ### 16.3.1 Concept The permutation approach measures a feature’s importance by calculating the increase of the model’s prediction error after permuting the feature. The idea is that if we randomly permute the values of an important feature in the training data, the training performance would degrade (since permuting the values of a feature effectively destroys any relationship between that feature and the target variable). The permutation approach uses the difference (or ratio) between some baseline performance measure (e.g., RMSE) and the same performance measure obtained after permuting the values of a particular feature in the training data. From an algorithmic perspective, the approach follows these steps: For any given loss function do the following: 1. Compute loss function for original model 2. For variable i in {1,...,p} do | randomize values | apply given ML model | estimate loss function | compute feature importance (some difference/ratio measure between permuted loss & original loss) End 3. Sort variables by descending feature importance  Algorithm 1: A simple algorithm for computing permutation-based variable importance for the feature set $$X$$. A feature is “important” if permuting its values increases the model error relative to the other features, because the model relied on the feature for the prediction. A feature is “unimportant” if permuting its values keeps the model error relatively unchanged, because the model ignored the feature for the prediction. This type of variable importance is tied to the model’s performance. Therefore, it is assumed that the model has been properly tuned (e.g., using cross-validation) and is not over fitting. ### 16.3.2 Implementation Permutation-based feature importance is available with the DALEX, iml, and vip packages; each providing unique benefits. The iml package provides the FeatureImp() function which computes feature importance for general prediction models using the permutation approach. It is written in R6 and allows the user to specify a generic loss function or select from a pre-defined list (e.g., loss = "mse" for mean squared error). It also allows the user to specify whether importance is measures as the difference or as the ratio of the original model error and the model error after permutation. The user can also specify the number of repetitions used when permuting each feature to help stabilize the variability in the procedure. The DALEX package also provides permutation-based variable importance scores through the variable_importance() function. Similar to iml::FeatureImp(), this function allows the user to specify a loss function and how the importance scores are computed (e.g., using the difference or ratio). It also provides an option to sample the training data before shuffling the data to compute importance (the default is to use n_sample = 1000. This can help speed up computation. The vip package specifically focuses on variable importance plots (VIPs) and provides both model-specific and a number of model-agnostic approaches to computing variable importance, including the permutation approach. With vip you can use customized loss functions (or select from a pre-defined list), perform a Monte Carlo simulation to stabilize the procedure, sample observations prior to permuting features, perform the computations in parallel which can speed up runtime on large data sets, and more. The following executes a permutation-based feature importance via vip. To speed up execution we sample 50% of the training data but repeat the simulations 5 times to increase stability of our estimates (whenever nsim >, you also get an estimated standard deviation for each importance score). We see that many of the same features that have been influential in model-specific approaches illustrated in previous chapters (e.g., Gr_Liv_Area, Overall_Qual, Total_Bsmt_SF, and Neighborhood) are also considered influential in our stacked model using the permutation approach. Permutation-based approaches can become slow as the number of predictors grows. This implementation took 9 minutes. You can speed up execution by parallelizing, reducing the sample size, or reducing the number of simulations. However, note that the last two options also increases the variability of the feature importance estimates. vip( ensemble_tree, train = as.data.frame(train_h2o), method = "permute", target = "Sale_Price", metric = "RMSE", nsim = 5, sample_frac = 0.5, pred_wrapper = pred ) ## 16.4 Partial dependence Partial dependence helps to understand the marginal effect of a feature (or subset thereof) on the predicted outcome. In essence, it allows us to understand how the response variable changes as we change the value of a feature while taking into account the average effect of all the other features in the model. ### 16.4.1 Concept The procedure follows the traditional methodology documented in J. H. Friedman (2001). The algorithm (illustrated below) will split the feature of interest into $$j$$ equally spaced values. For example, the Gr_Liv_Area feature ranges from 334–5095 square feet. Say the user selects $$j = 20$$. The algorithm will first create an evenly spaced grid consisting of 20 values across the distribution of Gr_Liv_area (e.g., $$334.00, 584.58, \dots, 5095.00$$). Then the algorithm will make 20 copies of the original training data (one copy for each value in the grid). The algorithms will then set Gr_Liv_Area for all observations in the first copy to 334, 585 in the second copy, 835 in the third copy, …, and finally to 5095 in the 20-th copy (all other features remain unchanged). The algorithm then predicts the outcome for each observation in each of the 20 copies, and then averages the predicted values for each set. These averaged predicted values are known as partial dependence values and are plotted against the 20 evenly spaced values for Gr_Liv_Area. For a selected predictor (x) 1. Construct a grid of j evenly spaced values across the distribution of x: {x1, x2, ..., xj} 2. For i in {1,...,j} do | Copy the training data and replace the original values of x with the constant xi | Apply given ML model (i.e., obtain vector of predictions) | Average predictions together End 3. Plot the averaged predictions against x1, x2, ..., xj Algorithm 2: A simple algorithm for constructing the partial dependence of the response on a single predictor $$x$$. Algorithm 1 can be quite computationally intensive since it involves $$j$$ passes over the training records (and therefore $$j$$ calls to the prediction function). Fortunately, the algorithm can be parallelized quite easily (see (Brandon Greenwell 2018) for an example). It can also be easily extended to larger subsets of two or more features as well (i.e., to visualize interaction effects). If we plot the partial dependence values against the grid values we get what’s known as a partial dependence plot (PDP) (Figure 16.1) where the line represents the average predicted value across all observations at each of the $$j$$ values of $$x$$. ### 16.4.2 Implementation The pdp package (Brandon Greenwell 2018) is a widely used, mature, and flexible package for constructing PDPs. The iml and DALEX packages also provide PDP capabilities.44 pdp has built-in support for many packages but for models that are not supported (such as h2o stacked models) we need to create a custom prediction function wrapper, as illustrated below. First, we create a custom prediction function similar to that which we created in Section 16.2.3; however, here we return the mean of the predicted values. We then use pdp::partial() to compute the partial dependence values. We can use autoplot() to view PDPs using ggplot2. The rug argument provides markers for the decile distribution of Gr_Liv_Area and when you include rug = TRUE you must also include the training data. # Custom prediction function wrapper pdp_pred <- function(object, newdata) { results <- mean(as.vector(h2o.predict(object, as.h2o(newdata)))) return(results) } # Compute partial dependence values pd_values <- partial( ensemble_tree, train = as.data.frame(train_h2o), pred.var = "Gr_Liv_Area", pred.fun = pdp_pred, grid.resolution = 20 ) head(pd_values) # take a peak ## Gr_Liv_Area yhat ## 1 334 158858.2 ## 2 584 159566.6 ## 3 835 160878.2 ## 4 1085 165896.7 ## 5 1336 171665.9 ## 6 1586 180505.1 # Partial dependence plot autoplot(pd_values, rug = TRUE, train = as.data.frame(train_h2o)) ### 16.4.3 Alternative uses PDPs have primarily been used to illustrate the marginal effect a feature has on the predicted response value. However, Brandon M Greenwell, Boehmke, and McCarthy (2018) illustrate an approach that uses a measure of the relative “flatness” of the partial dependence function as a measure of variable importance. The idea is that those features with larger marginal effects on the response have greater importance. You can implement a PDP-based measure of feature importance by using the vip package and setting method = "pdp". The resulting variable importance scores also retain the computed partial dependence values (so you can easily view plots of both feature importance and feature effects). ## 16.5 Individual conditional expectation Individual conditional expectation (ICE) curves (Goldstein et al. 2015) are very similar to PDPs; however, rather than averaging the predicted values across all observations we observe and plot the individual observation-level predictions. ### 16.5.1 Concept An ICE plot visualizes the dependence of the predicted response on a feature for each instance separately, resulting in multiple lines, one for each observation, compared to one line in partial dependence plots. A PDP is the average of the lines of an ICE plot. Note that the following algorithm is the same as the PDP algorithms except for the last line where PDPs averaged the predicted values. For a selected predictor (x) 1. Construct a grid of j evenly spaced values across the distribution of x: {x1, x2, ..., xj} 2. For i in {1,...,j} do | Copy the training data and replace the original values of x with the constant xi | Apply given ML model (i.e., obtain vector of predictions) End 3. Plot the predictions against x1, x2, ..., xj with lines connecting oberservations that correspond to the same row number in the original training data Algorithm 3: A simple algorithm for constructing the individual conditional expectation of the response on a single predictor $$x$$. So, what do you gain by looking at individual expectations, instead of partial dependencies? PDPs can obfuscate heterogeneous relationships that result from strong interaction effects. PDPs can show you what the average relationship between feature $$x_s$$ and the predicted value ($$\widehat{y}$$) looks like. This works only well in cases where the interactions between features are weak but in cases where interactions exist, ICE curves will help to highlight this. One issue to be aware of, often differences in ICE curves can only be identified by centering the feature. For example, ~ref(fig:ice-illustration) below displays ICE curves for the Gr_Liv_Area feature. The left plot makes it appear that all observations have very similar effects across Gr_Liv_Area values. However, the right plot shows centered ICE (c-ICE) curves which helps to highlight heterogeneity more clearly and also draws more attention to those observations that deviate from the general pattern. You will typically see ICE curves centered at the minimum value of the feature. This allows you to see how effects change as the feature value increases. ### 16.5.2 Implementation Similar to PDPs, the premier package to use for ICE curves is the pdp package; however, the iml package also provides ICE curves. To create ICE curves with the pdp package we follow the same procedure as with PDPs; however, we exclude the averaging component (applying mean()) in the custom prediction function. By default, autoplot() will plot all observations; we also include center = TRUE to center the curves at the first value. Note that we use pred.fun = pred. This is using the same custom prediction function created in Section 16.2.3. # Construct c-ICE curves partial( ensemble_tree, train = as.data.frame(train_h2o), pred.var = "Gr_Liv_Area", pred.fun = pred, grid.resolution = 20, plot = TRUE, center = TRUE, plot.engine = "ggplot2" ) PDPs for classification models are typically plotted on a logit-type scale, rather than on the probability scale (see Brandon Greenwell (2018) for details). This is more important for ICE curves and c-ICE curves, which can be more difficult to interpret. For example, c-ICE curves can result in negative probabilities. The ICE curves will also be more clumped together and harder to interpret when the predicted probabilities are close to zero or one. ## 16.6 Feature interactions When features in a prediction model interact with each other, the influence of the features on the prediction surface is not additive but more complex. In real life, most relationships between features and some response variable are complex and include interactions. This is largely why more complex algorithms (especially tree-based algorithms) tend to perform very well—the nature of their complexity often allows them to naturally capture complex interactions. However, identifying and understanding the nature of these interactions is difficult. One way to estimate the interaction strength is to measure how much of the variation of the predicted outcome depends on the interaction of the features. This measurement is called the $$H$$-statistic and was introduced by Friedman, Popescu, and others (2008). ### 16.6.1 Concept There are two main approaches to assessing interactions with the $$H$$-statistic: 1. The interaction between two features, which tells us how strongly two specific features interact with each other in the model; 2. The interaction between a feature and all other features, which tells us how strongly (in total) the specific feature interacts in the model with all the other features. To measure both types of interactions, we leverage partial dependence values for the features of interest. For the first approach, which measures how a feature ($$x_i$$) interacts with all other features. The algorithm performs the following steps: 1. For variable i in {1,...,p} do | f(x) = estimate predicted values with original model | pd(x) = partial dependence of variable i | pd(!x) = partial dependence of all features excluding i | upper = sum(f(x) - pd(x) - pd(!x)) | lower = variance(f(x)) | rho = upper / lower End 2. Sort variables by descending rho (interaction strength)  Algorithm 4: A simple algorithm for measuring the interaction strength between $$x_i$$ and all other features. For the second approach, which measures the two-way interaction strength of feature $$x_i$$ and $$x_j$$, the algorithm performs the following steps: 1. i = a selected variable of interest 2. For remaining variables j in {1,...,p} do | pd(ij) = interaction partial dependence of variables i and j | pd(i) = partial dependence of variable i | pd(j) = partial dependence of variable j | upper = sum(pd(ij) - pd(i) - pd(j)) | lower = variance(pd(ij)) | rho = upper / lower End 3. Sort interaction relationship by descending rho (interaction strength)  Algorithm 5: A simple algorithm for measuring the interaction strength between $$x_i$$ and $$x_j$$. In essence, the $$H$$-statistic measures how much of the variation of the predicted outcome depends on the interaction of the features. In both cases, $$\rho = \text{rho}$$ represents the interaction strength, which will be between 0 (when there is no interaction at all) and 1 (if all of variation of the predicted outcome depends on a given interaction). ### 16.6.2 Implementation Currently, the iml package provides the only viable implementation of the $$H$$-statistic as a model-agnostic application. We use Interaction$new() to compute the one-way interaction to assess if and how strongly two specific features interact with each other in the model. We find that First_Flr_SF has the strongest interaction (although it is a weak interaction since $$\rho < 0.139$$ ).

Unfortunately, due to the algorithm complexity, the $$H$$-statistic is very computationally demanding as it requires $$2n^2$$ runs. This example of computing the one-way interaction $$H$$-statistic took two hours to complete! However, iml does allow you to speed up computation by reducing the grid.size or by parallelizing computation with parallel = TRUE. See vignette(“parallel”, package = “iml”) for more info.

interact <- Interaction$new(components_iml) interact$results %>%
arrange(desc(.interaction)) %>%
##        .feature .interaction
## 1  First_Flr_SF   0.13917718
## 2  Overall_Qual   0.11077722
## 3  Kitchen_Qual   0.10531653
## 4 Second_Flr_SF   0.10461824
## 5      Lot_Area   0.10389242
## 6   Gr_Liv_Area   0.09833997

plot(interact)

Once we’ve identified the variable(s) with the strongest interaction signal (First_Flr_SF in our case), we can then compute the $$h$$-statistic to identify which features it mostly interacts with. This second iteration took over two hours and identified Overall_Qual as having the strongest interaction effect with First_Flr_SF (again, a weak interaction effect given $$\rho = 0.144$$ ).

interact_2way <- Interaction$new(components_iml, feature = "First_Flr_SF") interact_2way$results %>%
arrange(desc(.interaction)) %>%
top_n(10)
##                      .feature .interaction
## 1   Overall_Qual:First_Flr_SF   0.14385963
## 2     Year_Built:First_Flr_SF   0.09314573
## 3   Kitchen_Qual:First_Flr_SF   0.06567883
## 4      Bsmt_Qual:First_Flr_SF   0.06228321
## 5  Bsmt_Exposure:First_Flr_SF   0.05900530
## 6  Second_Flr_SF:First_Flr_SF   0.05747438
## 7  Kitchen_AbvGr:First_Flr_SF   0.05675684
## 8    Bsmt_Unf_SF:First_Flr_SF   0.05476509
## 9     Fireplaces:First_Flr_SF   0.05470992
## 10  Mas_Vnr_Area:First_Flr_SF   0.05439255

Identifying these interactions can help point us in the direction of assessing how the interactions relate to the response variable. We can use PDPs or ICE curves with interactions to see their effect on the predicted response. Since the above process pointed out that First_Flr_SF and Overall_Qual had the highest interaction effect, the code plots this interaction relationship with predicted Sale_Price. We see that properties with “good” or lower Overall_Qual values tend have their Sale_Prices level off as First_Flr_SF increases moreso than properties with really strong Overall_Qual values. Also, you can see that properties with “very good” Overall_Qual tend to have a much larger increase in Sale_Price as First_Flr_SF increases from 1500–2000 than most other properties. (Although pdp allows more than one predictor, we take this opportunity to illustrate PDPs with the iml package.)

# Two-way PDP using iml
interaction_pdp <- Partial$new( components_iml, c("First_Flr_SF", "Overall_Qual"), ice = FALSE, grid.size = 20 ) plot(interaction_pdp) ### 16.6.3 Alternatives Obviously computational time constraints are a major issue in identifying potential interaction effects. Although the $$H$$-statistic is the most statistically sound approach to detecting interactions, there are alternatives. The PDP-based variable importance measure discussed in Brandon M Greenwell, Boehmke, and McCarthy (2018) can also be used to quantify the strength of potential interaction effects. A thorough discussion of this approach is provided by Greenwell, Brandon M. and Boehmke, Bradley C. (2019) and can be implemented with vip::vint(). Also, Kuhn and Johnson (2019) provide a fairly comprehensive chapter discussing alternative approaches for identifying interactions. ## 16.7 Local interpretable model-agnostic explanations Local Interpretable Model-agnostic Explanations (LIME) is an algorithm that helps explain individual predictions and was introduced by Ribeiro, Singh, and Guestrin (2016). Behind the workings of LIME lies the assumption that every complex model is linear on a local scale (i.e. in a small neighborhood around an observation of interest) and asserting that it is possible to fit a simple surrogate model around a single observation that will mimic how the global model behaves at that locality. ### 16.7.1 Concept To do so, LIME samples the training data multiple times to identify observations that are similar to the individual record of interest. It then trains an interpretable model (often a LASSO model) weighted by the proximity of the sampled observations to the instance of interest. The resulting model can then be used to explain the predictions of the more complex model at the locality of the observation of interest. The general algorithm LIME applies is: 1. Permute your training data to create replicated feature data with slight value modifications. 2. Compute proximity measure (e.g., 1 - distance) between the observation of interest and each of the permuted observations. 3. Apply selected machine learning model to predict outcomes of permuted data. 4. Select m number of features to best describe predicted outcomes. 5. Fit a simple model to the permuted data, explaining the complex model outcome with $$m$$ features from the permuted data weighted by its similarity to the original observation. 6. Use the resulting feature weights to explain local behavior. Algorithm 6: The generalized LIME algorithm. Each of these steps will be discussed in further detail as we proceed. Although the iml package implements the LIME algorithm, the lime package provides the most comprehensive implementation. ### 16.7.2 Implementation The implementation of Algorithm 6 via the lime package is split into two operations: lime::lime() and lime::explain(). The lime::lime() function creates an "explainer" object, which is just a list that contains the fitted machine learning model and the feature distributions for the training data. The feature distributions that it contains includes distribution statistics for each categorical variable level and each continuous variable split into $$n$$ bins (the current default is four bins). These feature attributes will be used to permute data. # Create explainer object components_lime <- lime( x = features, model = ensemble_tree, n_bins = 10 ) class(components_lime) ## [1] "data_frame_explainer" "explainer" "list" summary(components_lime) ## Length Class Mode ## model 1 H2ORegressionModel S4 ## preprocess 1 -none- function ## bin_continuous 1 -none- logical ## n_bins 1 -none- numeric ## quantile_bins 1 -none- logical ## use_density 1 -none- logical ## feature_type 80 -none- character ## bin_cuts 80 -none- list ## feature_distribution 80 -none- list Once we’ve created our lime object (i.e., components_lime), we can now perform the LIME algorithm using the lime::explain() function on the observation(s) of interest. Recall that for local interpretation we are focusing on the two observations identified in Section 16.2.2 that contain the highest and lowest predicted sales prices. This function has several options, each providing flexibility in how we perform Algorithm 6: • x: Contains the observation(s) you want to create local explanations for. (See step 1 in Algorithm 6.) • explainer: Takes the explainer object created by lime::lime(), which will be used to create permuted data. Permutations are sampled from the variable distributions created by the lime::lime() explainer object. (See step 1 in Algorithm 6.) • n_permutations: The number of permutations to create for each observation in x (default is 5,000 for tabular data). (See step 1 in Algorithm 6.) • dist_fun: The distance function to use. The default is Gower’s distance but can also use Euclidean, Manhattan, or any other distance function allowed by the dist() function (see ?dist() for details). To compute similarities, categorical features will be recoded based on whether or not they are equal to the actual observation. If continuous features are binned (the default) these features will be recoded based on whether they are in the same bin as the observation to be explained. Using the recoded data the distance to the original observation is then calculated based on a user-chosen distance measure. (See step 2 in Algorithm 6.) • kernel_width: To convert the distance measure to a similarity score, an exponential kernel of a user defined width (defaults to 0.75 times the square root of the number of features) is used. Smaller values restrict the size of the local region. (See step 2 in Algorithm 6.) • n_features: The number of features to best describe the predicted outcomes. (See step 4 in Algorithm 6.) • feature_select: lime::lime() can use forward selection, ridge regression, lasso, or a decision tree to select the “best” n_features features. In the next example we apply a ridge regression model and select the $$m$$ features with highest absolute weights. (See step 4 in Algorithm 6.) For classification models we need to specify a couple of additional arguments: • labels: The specific labels (classes) to explain (e.g., 0/1, “Yes”/“No”)? • n_labels: The number of labels to explain (e.g., Do you want to explain both success and failure or just the reason for success?) # Use LIME to explain previously defined instances: high_ob and low_ob lime_explanation <- lime::explain( x = rbind(high_ob, low_ob), explainer = components_lime, n_permutations = 5000, dist_fun = "gower", kernel_width = 0.25, n_features = 10, feature_select = "highest_weights" ) If the original ML model is a regressor, the local model will predict the output of the complex model directly. If it is a classifier, the local model will predict the probability of the chosen class(es). The output from lime::explain() is a data frame containing various information on the local model’s predictions. Most importantly, for each observation supplied it contains the fitted explainer model (model_r2) and the weighted importance (feature_weight) for each important feature (feature_desc) that best describes the local relationship. glimpse(lime_explanation) ## Observations: 20 ## Variables: 11 ##$ model_type       <chr> "regression", "regression", "regression", "regr…
## $case <chr> "1825", "1825", "1825", "1825", "1825", "1825",… ##$ model_r2         <dbl> 0.41661172, 0.41661172, 0.41661172, 0.41661172,…
## $model_intercept <dbl> 186253.6, 186253.6, 186253.6, 186253.6, 186253.… ##$ model_prediction <dbl> 406033.5, 406033.5, 406033.5, 406033.5, 406033.…
## $feature <chr> "Gr_Liv_Area", "Overall_Qual", "Total_Bsmt_SF",… ##$ feature_value    <int> 3627, 8, 1930, 35760, 1796, 1831, 3, 14, 1, 3, …
## $feature_weight <dbl> 55254.859, 50069.347, 40261.324, 20430.128, 193… ##$ feature_desc     <chr> "2141 < Gr_Liv_Area", "Overall_Qual = Very_Exce…
## $data <list> [[Two_Story_1946_and_Newer, Residential_Low_De… ##$ prediction       <dbl> 663136.38, 663136.38, 663136.38, 663136.38, 663…

Visualizing the results in Figure 16.6 we see that size and quality of the home appears to be driving the predictions for both high_ob (high Sale_Price observation) and low_ob (low Sale_Price observation). However, it’s important to note the low $$R^2$$ (“Explanation Fit”) of the models. The local model appears to have a fairly poor fit and, therefore, we shouldn’t put too much faith in these explanations.

plot_features(lime_explanation, ncol = 1)

### 16.7.3 Tuning

Considering there are several knobs we can adjust when performing LIME, we can treat these as tuning parameters to try to tune the local model. This helps to maximize the amount of trust we can have in the local region explanation. As an example, the following code block changes the distance function to be Euclidean, increases the kernel width to create a larger local region, and changes the feature selection approach to a LARS-based LASSO model.

The result is a fairly substantial increase in our explanation fits, giving us much more confidence in their explanations.

# Tune the LIME algorithm a bit
lime_explanation2 <- explain(
x = rbind(high_ob, low_ob),
explainer = components_lime,
n_permutations = 5000,
dist_fun = "euclidean",
kernel_width = 0.75,
n_features = 10,
feature_select = "lasso_path"
)

# Plot the results
plot_features(lime_explanation2, ncol = 1)

### 16.7.4 Alternative uses

The discussion above revolves around using LIME for tabular data sets. However, LIME can also be applied to non-traditional data sets such as text and images. For text, LIME creates a new document term matrix with perturbed text (e.g., it generates new phrases and sentences based on existing text). It then follows a similar procedure of weighting the similarity of the generated text to the original. The localized model then helps to identify which words in the perturbed text are producing the strongest signal. For images, variations of the images are created by replacing certain groupings of pixels with a constant color (e.g., gray). LIME then assesses the predicted labels for the given group of pixels not perturbed. For more details on such use cases see Molnar and others (2018).

## 16.8 Shapley values

Another method for explaining individual predictions borrows ideas from coalitional (or cooperative) game theory to produce whats called Shapley values (Lundberg and Lee 2016, 2017). By now you should realize that when a model gives a prediction for an observation, all features do not play the same role: some of them may have a lot of influence on the model’s prediction, while others may be irrelevant. Consequently, one may think that the effect of each feature can be measured by checking what the prediction would have been if that feature was absent; the bigger the change in the model’s output, the more important that feature is. This is exactly what happens with permutation-based variable importance (since LIME most often uses a ridge or lasso model, it also uses a similar approach to identify localized feature importance).

However, observing only single feature effects at a time implies that dependencies between features are not taken into account, which could produce inaccurate and misleading explanations of the model’s internal logic. Therefore, to avoid missing any interaction between features, we should observe how the prediction changes for each possible subset of features and then combine these changes to form a unique contribution for each feature value.

### 16.8.1 Concept

The concept of Shapley values is based on the idea that the feature values of an individual observation work together to cause a change in the model’s prediction with respect to the model’s expected output, and it divides this total change in prediction among the features in a way that is “fair” to their contributions across all possible subsets of features.

To do so, Shapley values assess every combination of predictors to determine each predictors impact. Focusing on feature $$x_j$$, the approach will test the accuracy of every combination of features not including $$x_j$$ and then test how adding $$x_j$$ to each combination improves the accuracy. Unfortunately, computing Shapley values is very computationally expensive. Consequently, the iml package implements an approximate Shapley value.

To compute the approximate Shapley contribution of feature $$x_j$$ on $$x$$ we need to construct two new “Frankenstein” instances and take the difference between their corresponding predictions. This is outlined in the brief algorithm below. Note that this is often repeated several times (e.g., 10–100) for each feature/observation combination and the results are averaged together. See http://bit.ly/fastshap and Štrumbelj and Kononenko (2014) for details.

ob = single observation of interest
1. For variables j in {1,...,p} do
| m = draw random sample(s) from data set
| randomly shuffle the feature names, perm <- sample(names(x))
| Create two new instances b1 and b2 as follows:
| b1 = x, but all the features in perm that appear after
|      feature xj get their values swapped with the
|      corresponding values in z.
| b2 = x, but feature xj, as well as all the features in perm
|      that appear after xj, get their values swapped with the
|      corresponding values in z.
| f(b1) = compute predictions for b1
| f(b2) = compute predictions for b2
| shap_ind = f(b1) - f(b2)
| phi = mean(shap_ind)
End
2. Sort phi in decreasing order

Algorithm 7: A simple algorithm for computing approximate Shapley values.

The aggregated Shapley values ($$\phi =$$ phi) represent the contribution of each feature towards a predicted value compared to the average prediction for the data set. Figure 16.8, represents the first iteration of our algorithm where we focus on the impact of feature $$X_1$$. In step (A) we sample the training data. In step (B) we create two copies of an individually sampled row and randomize the order of the features. Then in one copy we include all values from the observation of interest for the values from the first column feature up to and including $$X_1$$. We then include the values from the sampled row for all the other features. In the second copy, we include all values from the observation of interest for the values from the first column feature up to but not including $$X_1$$. We use values from the sample row for $$X_1$$ and all the other features. Then in step (C), we apply our model to both copies of this row and in step (D) compute the difference between the predicted outputs.

We follow this procedure for all the sampled rows and the average difference across all sampled rows is the Shapley value. It should be obvious that the more observations we include in our sampling procedure the closer our approximate Shapley computation will be to the true Shapley value.

### 16.8.2 Implementation

The iml package provides one of the few Shapley value implementations in R. We use Shapley$new() to create a new Shapley object. The time to compute is largely driven by the number of predictors and the sample size drawn. By default, Shapley$new() will only use a sample size of 100 but you can control this to either reduce compute time or increase confidence in the estimated values.

In this example we increased the sample size to 1000 for greater confidence in the estimated values; it took roughly 3.5 minutes to compute.

Looking at the results we see that the predicted sale price of $663,136.38 is$481,797.42 larger than the average predicted sale price of $181,338.96; Figure 16.9 displays the contribution each predictor played in this difference. We see that Gr_Liv_Area, Overall_Qual, and Second_Flr_SF are the top three features positively influencing the predicted sale price; all of which contributed close to, or over,$75,000 towards the $481.8K difference. # Compute (approximate) Shapley values (shapley <- Shapley$new(components_iml, x.interest = high_ob, sample.size = 1000))
## Interpretation method:  Shapley
## Predicted value: 663136.380000, Average prediction: 181338.963590 (diff = 481797.416410)
##
## Analysed predictor:
## Prediction task: unknown
##
##
## Analysed data:
## Sampling from data.frame with 2199 rows and 80 columns.
##
## Head of results:
##        feature         phi      phi.var
## 1  MS_SubClass  1746.38653 4.269700e+07
## 2    MS_Zoning   -24.01968 3.640500e+06
## 3 Lot_Frontage  1104.17628 7.420201e+07
## 4     Lot_Area 15471.49017 3.994880e+08
## 5       Street     1.03684 6.198064e+03
## 6        Alley    41.81164 5.831185e+05
##                          feature.value
## 2    MS_Zoning=Residential_Low_Density
## 3                     Lot_Frontage=118
## 4                       Lot_Area=35760
## 5                          Street=Pave
## 6                Alley=No_Alley_Access

# Plot results
plot(shapley)

Since iml uses R6, we can reuse the Shapley object to identify the influential predictors that help explain the low Sale_Price observation. In Figure 16.10 we see similar results to LIME in that Overall_Qual and Gr_Liv_Area are the most influential predictors driving down the price of this home.

# Reuse existing object
shapley$explain(x.interest = low_ob) # Plot results shapley$results %>%
top_n(25, wt = abs(phi)) %>%
ggplot(aes(phi, reorder(feature.value, phi), color = phi > 0)) +
geom_point(show.legend = FALSE)

### 16.8.3 XGBoost and built-in Shapley values

True Shapley values are considered theoretically optimal (Lundberg and Lee 2016); however, as previously discussed they are computationally challenging. The approximate Shapley values provided by iml are much more computationally feasible. Another common option is discussed by Lundberg and Lee (2017) and, although not purely model-agnostic, is applicable to tree-based models and is fully integrated in most XGBoost implementations (including the xgboost package). Similar to iml’s approximation procedure, this tree-based Shapley value procedure is also an approximation, but allows for polynomial runtime instead of exponential runtime.

To demonstrate, we’ll use the features used and the final XGBoost model created in Section 12.5.2.

# Compute tree SHAP for a previously obtained XGBoost model
xgb.fit.final <- readr::read_rds("data/xgb-fit-final.rds")

The benefit of this expedient approach is we can reasonably compute Shapley values for every observation and every feature in one fell swoop. This allows us to use Shapley values for more than just local interpretation. For example, the following computes and plots the Shapley values for every feature and observation in our Ames housing example; see Figure 16.11. The left plot displays the individual Shapley contributions. Each dot represents a feature’s contribution to the predicted Sale_Price for an individual observation. This allows us to see the general magnitude and variation of each feature’s contributions across all observations. We can use this information to compute the average absolute Shapley value across all observations for each features and use this as a global measure of feature importance (right plot).

There’s a fair amount of general data wrangling going on here but the key line of code is predict(newdata = X, predcontrib = TRUE). This line computes the prediction contribution for each feature and observation in the data supplied via newdata.

# Try to re-scale features (low to high)
feature_values <- X %>%
as.data.frame() %>%
mutate_all(scale) %>%
gather(feature, feature_value) %>%
pull(feature_value)

# Compute SHAP values, wrangle a bit, compute SHAP-based importance, etc.
shap_df <- xgb.fit.final %>%
predict(newdata = X, predcontrib = TRUE) %>%
as.data.frame() %>%
select(-BIAS) %>%
gather(feature, shap_value) %>%
mutate(feature_value = feature_values) %>%
group_by(feature) %>%
mutate(shap_importance = mean(abs(shap_value)))

# SHAP contribution plot
p1 <- ggplot(shap_df, aes(x = shap_value, y = reorder(feature, shap_importance))) +
ggbeeswarm::geom_quasirandom(groupOnX = FALSE, varwidth = TRUE, size = 0.4, alpha = 0.25) +
xlab("SHAP value") +
ylab(NULL)

# SHAP importance plot
p2 <- shap_df %>%
select(feature, shap_importance) %>%
filter(row_number() == 1) %>%
ggplot(aes(x = reorder(feature, shap_importance), y = shap_importance)) +
geom_col() +
coord_flip() +
xlab(NULL) +
ylab("mean(|SHAP value|)")

# Combine plots
gridExtra::grid.arrange(p1, p2, nrow = 1)

We can also use this information to create an alternative to PDPs. Shapley-based dependence plots (Figure 16.12) show the Shapley values of a feature on the $$y$$-axis and the value of the feature for the $$x$$-axis. By plotting these values for all observations in the data set we can see how the feature’s attributed importance changes as its value varies.

shap_df %>%
filter(feature %in% c("Overall_Qual", "Gr_Liv_Area")) %>%
ggplot(aes(x = feature_value, y = shap_value)) +
geom_point(aes(color = shap_value)) +
scale_colour_viridis_c(name = "Feature value\n(standardized)", option = "C") +
facet_wrap(~ feature, scales = "free") +
scale_y_continuous('Shapley value', labels = scales::comma) +
xlab('Normalized feature value')

## 16.9 Localized step-wise procedure

An additional approach for localized explanation is a procedure that is loosely related to the partial dependence algorithm with an added step-wise procedure. The procedure was introduced by Staniak and Biecek (2018) and is known as the Break Down method, which uses a greedy strategy to identify and remove features iteratively based on their influence on the overall average predicted response.

### 16.9.1 Concept

The Break Down method provides two sequential approaches; the default is called step up. This procedure, essentially, takes the value for a given feature in the single observation of interest, replaces all the observations in the training data set, and identifies how it effects the prediction error. It performs this process iteratively and independently for each feature, identifies the column with the largest difference score, and adds that variable to the list as the most important. This feature’s signal is then removed (via randomization), and the procedure sweeps through the remaining predictors and applies the same process until all variables have been assessed.

existing_data = validation data set used in explainer
new_ob = single observation to perform local interpretation on
p = number of predictors
l = list of predictors
baseline = mean predicted response of existing_data

for variable i in {1,...,p} do
for variable j in {1,...,l} do
| exchange variable j in existing_data with variable j value in new_ob
| predicted_j = mean predicted response of altered existing_data
| diff_j = absolute difference between baseline - predicted
| reset existing_data
end
| t = variable j with largest diff value
| contribution for variable t = diff value for variable t
| remove variable t from l
end

Algorithm 8: A simple algorithm for computing Break Down values with the step up method.

An alternative approach is called the step down method which follows a similar algorithm but rather than remove the variable with the largest difference score on each sweep, it removes the variable with the smallest difference score. Both approaches are analogous to backward stepwise selection where step up removes variables with largest impact and step down removes variables with the smallest impact.

### 16.9.2 Implementation

To perform the Break Down algorithm on a single observation, use the DALEX::prediction_breakdown() function. The output is a data frame with class "prediction_breakdown_explainer" that lists the contribution for each variable. Similar to Shapley values, the results display the contribution that each feature value for the given observation has on the difference between the overall average response (Sale_Price in this example) and the response for the given observation of interest.

The default approach is step up but you can perform step down by specifying direction = “down”.

If you look at the contribution output, realize the feature ordering is in terms of importance. Consequently, Gr_Liv_Area was identified as most influential followed by Second_Flr_SF and Total_Bsmt_SF. However, if you look at the contribution value, you will notice that Second_Flr_SF appears to have a larger contribution to the above average price than Gr_Liv_Area. However, the Second_Flr_SF contribution is based on having already taken Gr_Liv_Area’s contribution into effect.

The break down algorithm is the most computationally intense of all methods discussed in this chapter. Since the number of required iterations increases by $$p \times \left(p-1\right)$$ for every additional feature, wider data sets cause this algorithm to become burdensome. For example, this single application took over 6 hours to compute!

high_breakdown <- prediction_breakdown(components_dalex, observation = high_ob)

# class of prediction_breakdown output
class(high_breakdown)
## [1] "prediction_breakdown_explainer" "data.frame"

# check out the top 10 influential variables for this observation
high_breakdown[1:10, 1:5]
##                                      variable contribution variable_name variable_value cummulative
## 1                                 (Intercept)    181338.96     Intercept              1    181338.9
## Gr_Liv_Area              + Gr_Liv_Area = 4316     46971.64   Gr_Liv_Area           4316    228310.5
## Second_Flr_SF          + Second_Flr_SF = 1872     52997.40 Second_Flr_SF           1872    281307.9
## Total_Bsmt_SF          + Total_Bsmt_SF = 2444     41339.89 Total_Bsmt_SF           2444    322647.8
## Overall_Qual  + Overall_Qual = Very_Excellent     47690.10  Overall_Qual Very_Excellent    370337.9
## First_Flr_SF            + First_Flr_SF = 2444     56780.92  First_Flr_SF           2444    427118.8
## Bsmt_Qual             + Bsmt_Qual = Excellent     49341.73     Bsmt_Qual      Excellent    476460.6
## Neighborhood      + Neighborhood = Northridge     54289.27  Neighborhood     Northridge    530749.8
## Garage_Cars                 + Garage_Cars = 3     41959.23   Garage_Cars              3    572709.1
## Kitchen_Qual       + Kitchen_Qual = Excellent     59805.57  Kitchen_Qual      Excellent    632514.6

We can plot the entire list of contributions for each variable using plot(high_breakdown).

## 16.10 Final thoughts

Since this book focuses on hands-on applications, we have focused on only a small sliver of IML. IML is a rapidly expanding research space that covers many more topics including moral and ethical considerations such as fairness, accountability, and transparency along with many more analytic procedures to interpret model performance, sensitivity, bias identification, and more. Moreover, the above discussion only provides a high-level understanding of the methods. To gain deeper understanding around these methods and to learn more about the other areas of IML (like not discussed in this book) we highly recommend Molnar and others (2018) and Hall, Patrick (2018).

### References

Biecek, Przemyslaw. 2019. DALEX: Descriptive mAchine Learning Explanations. https://CRAN.R-project.org/package=DALEX.

Breiman, Leo. 2001. “Random Forests.” Machine Learning 45 (1). Springer: 5–32.

Doshi-Velez, Finale, and Been Kim. 2017. “Towards a Rigorous Science of Interpretable Machine Learning.” arXiv Preprint arXiv:1702.08608.

Fisher, Aaron, Cynthia Rudin, and Francesca Dominici. 2018. “Model Class Reliance: Variable Importance Measures for Any Machine Learning Model Class, from the" Rashomon" Perspective.” arXiv Preprint arXiv:1801.01489.

Friedman, Jerome H. 2001. “Greedy Function Approximation: A Gradient Boosting Machine.” Annals of Statistics. JSTOR, 1189–1232.

Friedman, Jerome H, Bogdan E Popescu, and others. 2008. “Predictive Learning via Rule Ensembles.” The Annals of Applied Statistics 2 (3). Institute of Mathematical Statistics: 916–54.

Goldstein, Alex, Adam Kapelner, Justin Bleich, and Emil Pitkin. 2015. “Peeking Inside the Black Box: Visualizing Statistical Learning with Plots of Individual Conditional Expectation.” Journal of Computational and Graphical Statistics 24 (1). Taylor & Francis: 44–65.

Greenwell, Brandon. 2018. Pdp: Partial Dependence Plots. https://CRAN.R-project.org/package=pdp.

Greenwell, Brandon M. and Boehmke, Bradley C. 2019. “Quantifying the Strength of Potential Interaction Effects.”

Greenwell, Brandon M, Bradley C Boehmke, and Andrew J McCarthy. 2018. “A Simple and Effective Model-Based Variable Importance Measure.” arXiv Preprint arXiv:1805.04755.

Hall, Patrick. 2018. “Awesome Machine Learning Interpretability: A Curated, but Probably Biased and Incomplete, List of Awesome Machine Learning Interpretability Resources.”

Kuhn, Max, and Kjell Johnson. 2013. Applied Predictive Modeling. Vol. 26. Springer.

Kuhn, Max, and Kjell Johnson. 2019. Feature Engineering and Selection: A Practical Approach for Predictive Models. Chapman & Hall/CRC.

Lundberg, Scott, and Su-In Lee. 2016. “An Unexpected Unity Among Methods for Interpreting Model Predictions.” arXiv Preprint arXiv:1611.07478.

Lundberg, Scott M, and Su-In Lee. 2017. “A Unified Approach to Interpreting Model Predictions.” In Advances in Neural Information Processing Systems, 4765–74.

Molnar, Christoph. 2019. Iml: Interpretable Machine Learning. https://CRAN.R-project.org/package=iml.

Molnar, Christoph, and others. 2018. “Interpretable Machine Learning: A Guide for Making Black Box Models Explainable.” E-Book At< Https://Christophm.github.io/Interpretable-Ml-Book/>, Version Dated 10.

Pedersen, Thomas Lin, and Michaël Benesty. 2018. Lime: Local Interpretable Model-Agnostic Explanations. https://CRAN.R-project.org/package=lime.

Ribeiro, Marco Tulio, Sameer Singh, and Carlos Guestrin. 2016. “Why Should I Trust You?: Explaining the Predictions of Any Classifier.” In Proceedings of the 22nd Acm Sigkdd International Conference on Knowledge Discovery and Data Mining, 1135–44. ACM.

Staniak, Mateusz, and Przemyslaw Biecek. 2018. “Explanations of Model Predictions with Live and breakDown Packages.” arXiv Preprint arXiv:1804.01955.

Štrumbelj, Erik, and Igor Kononenko. 2014. “Explaining Prediction Models and Individual Predictions with Feature Contributions.” Knowledge and Information Systems 41 (3): 647–65. https://doi.org/10.1007/s10115-013-0679-x.

1. Note that the iml package uses the R6 class, which is less common than the normal S3 and S4 classes. For more information on R6 see Wickham (2014), Chapter 14.

2. In fact, previous versions of the DALEX package relied on pdp under the hood.


text:
## Doctoral Dissertations

#### Title

Fabrication of resonant tunneling transistor lasers for optoelectronic integrated circuits

January 1997

#### Keywords

Engineering, Electronics and Electrical

Ph.D.

#### Abstract

Semiconductor laser technology has evolved tremendously during the last decade and there have been relentless efforts toward improved performance. The major part of optoelectronic research has focused on III-V material structures for discrete devices such as detectors, lasers, modulators, high-speed field effect transistors (FETs) and heterojunction bipolar transistors (HBT's). There is simultaneous focus on monolithic integration of the various devices to produce optoelectronic integrated circuits (OEIC's) with greater functionality and speed. A laser diode integrated with heterojunction bipolar transistors (HBTs) can be controlled either electronically or optically.^ This study involves the fabrication of a Resonant Tunneling Transistor Laser, a bistable light emitting device which can be triggered electrically or optically. The structure of the RTTL is made up of a HBT with a resonant tunneling structure (RTS) located in the emitter. The electrical characteristics of RTT have been simulated according to a model developed by LaComb et al., for generic resonant tunneling transistors. The overall characteristics of the RTTL were obtained by dividing it into a resonant tunneling diode (RTD) and a HBT structure connected in series.^ The optical cavity which is formed by the waveguiding structure is designed to lase when the base current density is greater than the threshold current density. The p-base which is the active (light emitting) layer, is made of GaAs whose index of refraction is higher than the surrounding AlGaAs layers thus forming a waveguiding structure. A unique feature of this device is the indirect contacting of the active layer which requires p-type zinc diffusion performed through the windows opened in the SiO$\sb2$ isolation layer. Simulation of p-type diffusion is in close agreement with the experimental measurements. Since the diffusion profile is highly non-linear, we calibrated the process using a ZnAs$\sb2$ source in a diffusion furnace at 700$\sp\circ$C adopting a closed ampoule technique. Low resistance ohmic contacts were obtained using Ti/Pt/Au and Au-Ge/Ni for p and n contacts respectively.^ Results obtained from a light-emitting AlGaAs-GaAs heterojunction bipolar device will be presented. The I-V characteristics of the completely processed samples show the negative differential resistance (NDR) behavior in the samples that have been mesa-etched to expose the RTS in the emitter. The transistor characteristics yield a $\beta$ of $\sim$7-15 which matches the simulated characteristics predicted by the RTT model. Bistability was more pronounced at 77 K, and the transistor current gain doubled, yielding a maximum $\beta$ of $\sim$35. The device was tested for the lasing characteristics under pulsed conditions, which resulted in an emission spectrum centered at 906nm. Several devices tested (in excess of twenty) yielded similar results. ^

COinS