Feature | Score |
---|---|

str | list[i64] |

"2MP Camera" | [7, 6, 7, 8, 7] |

"Bluetooth" | [6, 5, 7, 7, 6] |

"Browser" | [8, 9, 9, 9, 9] |

"Touchscreen" | [8, 9, 8, 9, 8] |

"Wifi" | [6, 5, 7, 4, 5] |

### The business scenario

Imagine you’re part of the team that launched the first iPhone with Steve Jobs in 2007. You want to measure the customer satisfaction of consumers who have used the demo version of the iPhone by testing how they like the features you have included in this revolutionary device. So you ask them to score their likeability of using the iPhone by focusing on five features.

1 = I don’t like this feature.

10 = I really like this feature.

Suppose you ask five people and they each give a score for each of the five features of the iPhone you’ve presented to them. Below are the scores.

To determine the potentiality of each feature for these customers, you have to know how these customer satisfaction scores vary. This leads to calculating the variance of these scores.

### What is variance?

You can think of variance as the average of each score’s distance from the average (mean). It tells you how much the different scores vary or are spread out from the average. If the variance is large, it means the scores are spread out widely from the average. If it’s small, the scores are closer to the average.

It’s important to note that variance is measured in the square of the unit used. The farther the satisfaction score is from the average, the higher the volatility. This can suggest instability, unreliability, or inconsistency, depending on the type of data and how you’re analyzing it.

Let’s pick one feature, Bluetooth, and see how the scores compare to the average.

```
= (df
bluetooth_df 'Score')
.explode(filter(pl.col('Feature') == "Bluetooth")
.=pl.col('Score').mean())
.with_columns(Mean=pl.col('Score') - pl.col('Mean'))
.with_columns(Difference
) bluetooth_df
```

Feature | Score | Mean | Difference |
---|---|---|---|

str | i64 | f64 | f64 |

"Bluetooth" | 6 | 6.2 | -0.2 |

"Bluetooth" | 5 | 6.2 | -1.2 |

"Bluetooth" | 7 | 6.2 | 0.8 |

"Bluetooth" | 7 | 6.2 | 0.8 |

"Bluetooth" | 6 | 6.2 | -0.2 |

We can see that the largest variation is on the score of 5 with a -1.2 variation (not variance). This is even clearer when presented as a plot.

```
import plotly.graph_objects as go
from plotly_customizations import customize_plotly_figure
from pathlib import Path
# Extract necessary data
= bluetooth_df["Score"].to_list()
scores = bluetooth_df["Mean"][0] # Mean is constant, so we take the first element
mean_value = bluetooth_df['Difference'].abs().to_list() # Absolute deviations for error bars
deviations
# Create the scatter plot using Plotly with error bars
= go.Figure()
fig f"{Path('../../../')}/images/logo.png")
customize_plotly_figure(fig,
# Add a scatter plot with error bars (no connecting lines)
fig.add_trace(go.Scatter(=list(range(1, len(scores) + 1)), # Use index or range as x-axis
x=scores, # Scores as y-axis
y='markers+text', # Markers and text
mode=[str(score) for score in scores], # Display score values next to dots
text="middle right", # Position text to the right of the markers
textposition='Scores',
name=dict(size=8, color='#0000FF'),
marker=dict( # Add error bars showing deviation from the mean
error_ytype='data',
=deviations,
array=True,
visible='#0000FF'
color
)
))
# Add a horizontal solid line for the mean
fig.add_trace(go.Scatter(=list(range(1, len(scores) + 1)), # Use the same x-axis values
x=[mean_value] * len(scores), # The mean is a horizontal line
y='lines+text', # Line and text
mode
))
# Add titles and labels
fig.update_layout(="<b>Customer satisfaction score variation<br>(Bluetooth)",
title=dict(size=22),
title_font="Score",
yaxis_title=False, # Remove the legend
showlegend=740,
width= dict(
xaxis = 'array',
tickmode = list(range(1, len(scores) + 1)),
tickvals = ['Score 1', 'Score 2', 'Score 3', 'Score 4', 'Score 5']
ticktext
),=[
annotationsdict(
='paper',
xref=1,
x=6,
y='center',
xanchor='bottom',
yanchor='Mean', # Escape double quotes within f-string
text=False,
showarrow=dict(size=13, color='red', family="Inter") # Apply font family
font
)]
)
fig.show()
```

Now let’s calculate the variance on the customer satisfaction scores for Bluetooth. Since the variance is the average of the variations for all Bluetooth scores, it will be the same, which in this case is 0.7.

```
(df'Score')
.explode(filter(pl.col('Feature') == "Bluetooth")
.=pl.col('Score').mean(),
.with_columns(Mean=pl.col('Score').var())
Variance )
```

Feature | Score | Mean | Variance |
---|---|---|---|

str | i64 | f64 | f64 |

"Bluetooth" | 6 | 6.2 | 0.7 |

"Bluetooth" | 5 | 6.2 | 0.7 |

"Bluetooth" | 7 | 6.2 | 0.7 |

"Bluetooth" | 7 | 6.2 | 0.7 |

"Bluetooth" | 6 | 6.2 | 0.7 |

The Bluetooth feature has a customer satisfaction score variance of 0.7, relative to a mean score of 6.2. This suggests that customer ratings for this feature tend to cluster around the average.

However, variance is not a good representation of what is going on because we’re using square units. To determine the potentiality that is a lot more representative, we need to calculate standard deviation.

### What is standard deviation?

Standard deviation is simply the square root of the variance. It’s a measure of how much the scores deviate from the mean. So, if the standard deviation is large, there’s a lot of variability among the data points. If it’s small, the data points are more clustered around the mean. Standard deviation is more interpretable because it’s in the same units as the original data, making it easier to understand how spread out the data is.

```
(df'Score')
.explode(filter(pl.col('Feature') == "Bluetooth")
.=pl.col('Score').mean(),
.with_columns(Mean=pl.col('Score').var())
Variance'Variance').sqrt())
.with_columns(pl.col( )
```

Feature | Score | Mean | Variance |
---|---|---|---|

str | i64 | f64 | f64 |

"Bluetooth" | 6 | 6.2 | 0.83666 |

"Bluetooth" | 5 | 6.2 | 0.83666 |

"Bluetooth" | 7 | 6.2 | 0.83666 |

"Bluetooth" | 7 | 6.2 | 0.83666 |

"Bluetooth" | 6 | 6.2 | 0.83666 |

The standard deviation on Bluetooth scores is 0.83, which means that most of the scores vary between -0.83 and +0.83 from the mean. Considering that the mean is 6.2, a standard deviation of 0.83 is not very large – in other words, it doesn’t change the mean score significantly. We can conclude that the customers have a consistence experience with the Bluetooth feature.

Now that we have a better understanding of our customers’ experience with the Bluetooth feature, let’s repeat the process for all the features, but this time we’ll go straight to the standard deviation because that’s the value we’re interested in.

### Interpreting the scores

```
(df'Score')
.explode('Feature')
.group_by('Score').alias('Std_Dev'))
.agg(pl.std(='Feature', how='inner')
.join(df, on'Std_Dev')
.sort( )
```

Feature | Std_Dev | Score |
---|---|---|

str | f64 | list[i64] |

"Browser" | 0.447214 | [8, 9, 9, 9, 9] |

"Touchscreen" | 0.547723 | [8, 9, 8, 9, 8] |

"2MP Camera" | 0.707107 | [7, 6, 7, 8, 7] |

"Bluetooth" | 0.83666 | [6, 5, 7, 7, 6] |

"Wifi" | 1.140175 | [6, 5, 7, 4, 5] |

The values in the table above show that the features Browser and Touchscreen have the lowest standard deviation (the scores don’t deviate much from the mean score). These features also have consistent and generally higher customer satisfaction scores. This suggests customers had a better experience with these two features as there is less variability in their scores. These are the features that must be highlighted to sell more iPhones!

Wifi has the largest standard deviation, and the scores are mostly low. Clearer, customers did not have a better experience with the Wifi feature. Thus, in the later versions of the phone, more resources should be put towards improving this feature.

In July 2023, an unopened, first edition model of the 2007 iPhone was sold at auction in the US for $190,372.80 This is about 400 times the original price.

### Conclusion

Variance is a key concept in statistics that measures how spread out or varied the data is in a set. It’s important for analyzing information, understanding risks, and making smart choices in product management.

By properly calculating and understanding variance, you can better recognize trends in the data, spot areas that need improvement, and make more informed decisions.

Check out my Polars course to improve your data analysis skills.