Note: I did not check whether your code matches the formula correctly and I am not an expert of the mathematical background. I only refer to your code.
Style
[12,11,13,13, 9,10,10,13, 5,10,10,13,10,10, 5, 8, 9, 8, 8, 9, 9,10,11, 5,12]
This looks very inconsistent. You should add a space after each comma.
Naming
Xmean
and X
are unusual names for variables. x_square
is the style you should use for Python, which is lower case with underscores, also known as "snake case".
Your names however make no sense at all semantically. You can name local variables x
and y
if they are e. g. coordinates, or if you use them for iterating. If they represent lists of numbers, why not just call them numbers1
and numbers2
? (This might still not be perfect, but it shows what the variables mean. Edit: Note that this mainly concerns the problem of having two variables that only differ in being lower/upper case, and not nowing what x
is somewhere inside your code, whereas numbers
tells you that it is a collection or sequence of numbers. See below.) Note that I used a lower case x
to refer to your X
. Having another x
later is the next problem. How do you know the difference without reading your whole code again?
x = [var-Xmean for var in X]
This took me some time to understand. You can improve it by using a common iterator variable like i
and adding spaces around operators. With these improvements, and also better variable names, this could be for example:
subtracted_average = [i - mean_x for i in numbers1]
sum_xy = sum(xy)
Saving intermediate results of calculations like this is good, when you need them more than once. But here you don't. So sum(xy)
is more readible if it is inside of another formula than sum_xy
.
sum_x_square_sum_y_square
If you read this, do you know what it means without reading the code next to it? Is it a sum of sums? A product of sums? Or a completely different thing altogether? When trying to find a good variable names, think about "what is this"? The answer might be e. g. "the product of sums of squared numbers". product_of_sums_of_squared_numbers
is long, but it tells you what it is.
Implementing Formulas
Judge for yourself. What is more readible?
1.
sum_x_square = sum(x_square)
sum_y_square = sum(y_square)
sum_x_square_sum_y_square = sum_x_square*sum_y_square
sqrt_sum_x_square_sum_y_square = math.sqrt(sum_x_square_sum_y_square)
or 2.
result = math.sqrt(sum(x_square) * sum(y_square))
The second one is actually how you write formulas in maths. So when implementing a function to represent that formula, go the same way. (Hint: Maybe this code should be a function.)
Using Functions
def pearson_correlation(numbers_x, numbers_y):
mean_x = sum(numbers_x)/len(numbers_x)
mean_y = sum(numbers_y)/len(numbers_y)
subtracted_mean_x = [i - mean_x for i in numbers_x]
subtracted_mean_y = [i - mean_y for i in numbers_y]
x_times_y = [a * b for a, b in list(zip(subtracted_mean_x, subtracted_mean_y))]
x_squared = [i * i for i in numbers_x]
y_squared = [i * i for i in numbers_y]
return sum(x_times_y) / math.sqrt(sum(x_squared) * sum(y_squared))
Call it like this:
# Contrary to what I said above about variables in general,
# the names X and Y are ok here because they match the names in the formula.
X = [12, 11, 13, 13, 9, 10, 10, 13, 5, 10, 10, 13, 10, 10, 5, 8, 9, 8, 8, 9, 9, 10, 11, 5, 12]
Y = [11, 10, 10, 10, 9, 13, 10, 11, 6, 7, 13, 14, 14, 11, 11, 10, 10, 7, 8, 12, 11, 11, 8, 7, 13]
print(pearson_correlation(X, Y))