Analysing a dataset using bar plots and scatter plots

This page is under development.

This project is about analyzing data on movie review scores.

FiveThirtyEight (http://fivethirtyeight.com/) compiled data for 147 films from 2015 that have substantive reviews from both critics and consumers. Every time Hollywood releases a movie, critics from Metacritic, Fandango, Rotten Tomatoes, and IMDB review and rate the film.

https://raw.githubusercontent.com/fivethirtyeight/data/master/fandango/fandango_score_comparison.csv

import pandas as pd
import matplotlib.pyplot as plt
import numpy
import scipy.stats as stats


movies = pd.read_csv('data/fandango.csv')
movies.head(3)
                             FILM         ...           Fandango_Difference
0  Avengers: Age of Ultron (2015)         ...                           0.5
1               Cinderella (2015)         ...                           0.5
2                  Ant-Man (2015)         ...                           0.5

[3 rows x 22 columns]

Each row represents a single movie. Each column contains information about how the online moview review services RottenTomatoes, Metacritic, IMDB, and Fandango rated the movie.

To make it easier to compare scores across services, the columns were normalized so their scale and rounding matched the Fandango ratings. Any column with the suffix _norm is the corresponding column changed to a 0-5 scale.

Let’s focus on the Metacritic_norm_round and the Fandango_Stars columns to see how Fandango and Metacritic differ in terms of review scores.

movies.hist(column = 'Metacritic_norm_round')
array([[<matplotlib.axes._subplots.AxesSubplot object at 0x7fe2e8d11208>]],
      dtype=object)
movies.hist(column = 'Fandango_Stars')
array([[<matplotlib.axes._subplots.AxesSubplot object at 0x7fe2e8d11668>]],
      dtype=object)

The scores in Metacritic spread over a larger range (from 0.5 up to 4.5) than the scores from Fandango Stars which start from 3.0 to 5.0. Low scores do not exist in Fandango Stars. To compare the highest frequency score, we can see that in Metacritic, it is 3 which is lower than Fandango’s which is 4.5.

Quantifying these differences with metrics

Metrics include the mean, median and standard deviation.

mean_Meta = movies['Metacritic_norm_round'].mean()
mean_Fandango = movies['Fandango_Stars'].mean()
print('Mean of Metacritics scores', mean_Meta)
Mean of Metacritics scores 2.9726027397260273
print('Mean of Fandango scores', mean_Fandango)
Mean of Fandango scores 4.089041095890411
median_Meta = movies['Metacritic_norm_round'].median()
median_Fandango = movies['Fandango_Stars'].median()
print('Median of Metacritic scores', median_Meta)
Median of Metacritic scores 3.0
print('Median of Fandango scores', median_Fandango)
Median of Fandango scores 4.0

The median metacritic score appears higher than the mean metacritic score because a few very low reviews “drag down” the mean.

The median fandango score is lower than the mean fandango score because a few very high ratings “drag up” the mean.

std_Meta = movies['Metacritic_norm_round'].std()
std_Fandango = movies['Fandango_Stars'].std()
print('Standard deviation of Metacritics', std_Meta)
Standard deviation of Metacritics 0.9909605613743359
print('Standard deviation of Fandango', std_Fandango)
Standard deviation of Fandango 0.5403859779787334

The standard deviation (for a sample or population) is an indicator of how “near/dense” the data are relative to the mean. A small standard deviation indicates that the data are near the mean, large standard deviation indicates that the data are more dispersed.

Fandango ratings appear clustered between 3 and 5, and have a much narrower standard deviation than Metacritic reviews, which go from 0 to 5. The data are more dispersed in Metacritics.

Fandango ratings in general appear to be higher than metacritic ratings. These may be due to movie studio influence on Fandango ratings, and the fact that Fandango calculates its ratings in a hidden way.

Findind which movies tend to be the largest outliers.

movies.plot.scatter(x='Metacritic_norm_round', y='Fandango_Stars')

Several movies appear to have low ratings in Metacritic and high ratings in Fandango, or vice versa. E.g., the movie rated with the lowest score in Metacritic, i.e. 0.5, is rated 3.5 in Fandango…

Let us explore this further, finding the differences between the columns.

fm_diff = movies['Metacritic_norm_round'] - movies['Fandango_Stars']
movies['fm_diff'] = numpy.abs(fm_diff)

Getting the absolute value will ensure that we look at any extreme case where Metacritic_norm_round is much greater or much lower than Fandango_Stars.

movies = movies.sort_values(by='fm_diff', ascending=False)
movies[['FILM', 'Fandango_Stars', 'Metacritic_norm_round', 'fm_diff']].head(5)
                        FILM   ...     fm_diff
3     Do You Believe? (2015)   ...         4.0
85         Little Boy (2015)   ...         3.0
47              Annie (2014)   ...         3.0
19             Pixels (2015)   ...         3.0
134  The Longest Ride (2015)   ...         3.0

[5 rows x 4 columns]

Measuring the correlation between Fandango_Stars and Metacritic_norm_round

Let’s see what the correlation coefficient between Fandango_Stars and Metacritic_norm_round is. This will help to determine if Fandango consistently has higher scores than Metacritic, or if only a few movies were assigned higher ratings.

r, p = stats.pearsonr(movies['Fandango_Stars'], movies['Metacritic_norm_round'])
print(r)
0.17844919073895885

The low correlation between Fandango and Metacritic scores indicates that Fandango scores aren’t just inflated, they are fundamentally different. For whatever reason, it appears like Fandango both inflates scores overall, and inflates scores differently depending on the movie.

movies.plot.scatter(x='Metacritic_norm_round', y='Fandango_Stars')
plot of chunk Figure-12
plot of chunk Figure-12

Several movies appear to have low ratings in Metacritic and high ratings in Fandango, or vice versa. E.g., the movie rated with the lowest score in Metacritic, i.e. 0.5, is rated 3.5 in Fandango… The low correlation between Fandango and Metacritic scores and the scatter plot above, indicates that Fandango scores aren’t just inflated, they are fundamentally different. For whatever reason, it appears like Fandango both inflates scores overall, and inflates scores differently depending on the movie.

Creating a linear regression. Plotting using Seaborn: Comparing IMDB scores and Metacritic scores:

import seaborn as sns
sns.regplot(x='Metacritic_norm_round', y='IMDB_norm_round', data=movies);
plt.show()

In the simplest invocation, both functions draw a scatterplot of two variables, x and y, and then fit the regression model and plot the resulting regression line and a 95% confidence interval for that regression.

A few other seaborn functions use regplot() in the context of a larger, more complex plot including the jointplot() function. In addition to the plot styles, jointplot() can use regplot() to show the linear regression fit on the joint axes by passing kind=“reg” as

sns.jointplot(x='Metacritic_norm_round', y='IMDB_norm_round', data=movies, kind="reg");
plt.show()

We can see IMDB scores are much more correlated to Metacritic scores than Fandango’s. Thus, predicting IMDB scores from Metacritic scores using the linear regression makes sense.