Copying "Introduction to Statistical Analysis" in Python Vol. 11 - Chapter 4 "First Statistical Tests" (4) Testing Correlation Coefficients: Test for No Correlation, Test for Population Correlation Coefficient, and Test for the Difference Between Two Population Correlation Coefficients
Chapter 4 "First Statistical Tests"
Book Author: Dr. Sadao Ishimura
This article covers the "Introduction to Statistical Analysis" Chapter 4 "First Statistical Tests" Python copying activity.
This is a copying series that calmly converts the book's figures, tables, and calculations into Python.
This article practices three tests related to correlation coefficients among the statistical test themes in Chapter 4.
・Test for no correlation
・Test for population correlation coefficient
・Test for the difference between two population correlation coefficients
I will continue to utilize ChatGPT as well!
Now, let's open the book and set off on a journey of statistical analysis 🚀

Introduction
This blog series introduces the "joy of statistical analysis" gained through copying the Python code from the book "Introduction to Statistical Analysis" (Tokyo Tosho, referred to as the "Text").
Information on the book and citation notation are posted in the linked article.

Chapter 4 First Statistical Tests
This article covers the following sections of Chapter 4.
4.9 Testing Correlation Coefficients
The data used in the article is cited directly from the data published in the text.
For data with a small number of items, the data is registered in the code, and for data with a large number of items, it is converted into a CSV file and loaded.
Import the libraries used in Chapter 4.
### インポート
# 数値計算
import math # python標準ライブラリ
import numpy as np
import pandas as pd
# 統計
import scipy.stats as stats
import pingouin as pg
from statsmodels.stats.proportion import proportions_ztest # 母比率のz検定
from statsmodels.stats.weightstats import ttest_ind # 2標本のt検定
# 描画
import matplotlib.pyplot as plt
import seaborn as sns
plt.rcParams['font.family'] = 'Meiryo'
Introduction
Continuing from last time, let's work hard on "statistical testing".
Please enjoy the "gentle introduction" by ChatGPT.
“I feel like these two numbers are moving together somehow.”
“Sales and advertising costs, they must be related, right?”
The correlation coefficient is what verifies such "feelings" with data.
The correlation coefficient is an index that expresses how much of a "relationship" exists between two sets of data using a value from $${−1}$$ to $${1}$$.
But is the correlation coefficient calculated from actual data just "a coincidence" or is there "a real relationship"—
To determine that, we use the theme of this time, tests related to correlation coefficients.
🍀 The three tests we will cover are...
Test for no correlation: Investigating whether the correlation coefficient can be said to be zero (= no relationship)
Test for population correlation coefficient: Checking if there is a difference from a specific theoretical correlation value
Test for the difference between two population correlation coefficients: Comparing whether there is a difference in the strength of correlation between groups A and B
By focusing on the "connections" between numbers, there are things that become visible.
This time, let's gently step into the world of testing to determine "Can we say there is a relationship?".

Section 4.9 Correlation Coefficient Tests
■ Review of Correlation Coefficients
The correlation coefficient is a statistic that represents the strength of the relationship between two sets of data.
Let's check the correlation coefficient using a "scatter plot," which allows for an intuitive understanding.
## 設定と準備
# 標本サイズ
N = 10
# 乱数生成器の初期化
rng = np.random.default_rng(seed=1)
## データの準備
# x の作成:一様分布乱数
x = rng.uniform(size=N)
# y の作成:y = x + ε, ε ~ Normal(0, 1)
y = x + rng.normal(size=N)
# xとyの相関係数の算出
xy_corrcoef = np.corrcoef(x, y)[0, 1]
## 可視化
# 描画領域の設定
fig, ax = plt.subplots()
# x,yの散布図の描画
ax.plot(x, y, 'o', ms=8, alpha=0.8)
# 修飾
ax.set(xlabel='$x$', ylabel='$y$', title=f'相関係数 = {xy_corrcoef:.3f}')
ax.grid(lw=0.5);[Execution Results]
An upward trend can be seen between the data $${x,y}$$.
The correlation coefficient of $${0.787}$$ indicates a strong positive correlation.


Test for No Correlation
■ Test for No Correlation: Formula for Test Statistic p.190
The test for no correlation is a test to determine whether there is no correlation (no correlation) between two sets of data.
❓️What about the population distribution?❓️
The text does not seem to explicitly state the assumption of the population distribution in the test for no correlation.
ChatGPT's answer is "assume a bivariate normal distribution for the two population distributions."
Since I haven't obtained theoretical backing...
I will post the exchange with ChatGPT in the "Assumptions of Population Distribution in the Test for No Correlation: ChatGPT Q&A" section later.
[Hypothesis]
We set the hypotheses as follows.
Null hypothesis $${H_0}$$: The two variables $${x}$$ and $${y}$$ are uncorrelated
Alternative hypothesis $${H_1}$$: The two variables $${x}$$ and $${y}$$ are correlated
It seems there is no one-tailed test.
◆ ◆ ◆
I will borrow the formula for the test statistic in the test for no correlation from the text.
When the sample correlation coefficient for a sample size of $${N}$$ is $${r}$$, the test statistic for no correlation is
$$
T(r, N) = \cfrac{r\sqrt{N-2}}{\sqrt{1 - r^2}}
$$
follows a $${t}$$ distribution with $${N-2}$$ degrees of freedom.
I will define a "test for no correlation function" according to the formula.
I will use scipy.stats for probability calculations.
### 無相関の検定 p.190
# 標本相関係数算出関数
def calc_corr(x_list1, x_list2):
# 標本サイズ ※2つの標本サイズは同じ
N = len(x_list1)
# 2つの標本平均
x_bar, y_bar = sum(x_list1) / N, sum(x_list2) / N
# 分子、分母1,分母2の計算
numerator = sum((x - x_bar) * (y - y_bar) for x, y in zip(x_list1, x_list2))
denominator1 = (sum([(x - x_bar)**2 for x in x_list1]))**(1/2)
denominator2 = (sum([(y - y_bar)**2 for y in x_list2]))**(1/2)
# 標本相関係数r
r = numerator / (denominator1 * denominator2)
# 戻り値: 標本相関係数r, 標本サイズN
return r, N
# 無相関のt検定統計量の算出関数
def t_stat_non_corr(x_list1, x_list2):
# 標本相関係数の算出
r, N = calc_corr(x_list1, x_list2)
# 戻り値: t検定統計量
return r * (N - 2)**(1/2) / (1 - r**2)**(1/2), r
# 無相関のt検定関数 ※確率計算はscipy.stats利用
def non_corr_ttest(x_list1, x_list2, alpha=0.05, alternative='two-sided'):
# 標本サイズ ※2つの標本サイズは同じ
N = len(x_list1)
# t検定統計量と標本相関係数の算出
t_val, r = t_stat_non_corr(x_list1, x_list2)
# 自由度(N-2)のt分布の設定
t_dist = stats.t(df=N - 2)
# 棄却限界値c_valとp値p_valの算出
match alternative:
case 'two-sided':
c_val = t_dist.ppf(q=1 - alpha/2)
c_val = -c_val, c_val
p_val = t_dist.sf(x=abs(t_val)) * 2
case 'less':
c_val = t_dist.ppf(q=alpha)
p_val = t_dist.cdf(x=t_val)
case 'greater':
c_val = t_dist.ppf(q=1 - alpha)
p_val = t_dist.sf(x=t_val)
return {'t_value': t_val, 'c_value': c_val, 'alpha': alpha, 'p_value': p_val,
'r': r}Let's perform a test for no correlation using the following test data.
$$
\begin{array}{cc}
Variable 1 & Variable 2 \\
\hline
1 & 1.5 \\
2 & 1.8 \\
3 & 2.0 \\
\end{array}
$$
These are the test conditions.
Null hypothesis $${H_0}$$: "The two sets of data are uncorrelated"
Significance level 5% ($${\alpha=0.05}$$)
Two-tailed test
# テスト
x_list1, x_list2 = [1, 2, 3], [1.5, 1.8, 2.0]
non_corr_ttest(x_list1, x_list2)[Execution Result]
"It cannot be said to be significant at the 5% significance level, and the null hypothesis cannot be rejected."
The correlation coefficient is $${0.993}$$, but the test result accepts that "the two sets of data are uncorrelated."

I will briefly explain the output content.
t_value: Realized value of the test statistic $${T}$$
c_value: Critical value
Threshold for the test statistic $${T}$$ at which the null hypothesis can be rejected
When the realized value of $${T}$$ is outside the critical value, the null hypothesis can be rejectedalpha: Significance level $${\alpha}$$
p_value: $${p}$$ value
Probability that the test statistic will reach the realized value under the null hypothesis
When the $${p}$$ value is less than or equal to the significance level, the null hypothesis can be rejectedr: Sample correlation coefficient
Let's verify the calculation using scipy.stats.
### scipy.statsで答え合わせ (標本相関係数, 無相関の検定のp値)
stats.pearsonr(x_list1, x_list2)[Execution Result]
(Pearson product-moment) correlation coefficient and $${p}$$ value.
The verification results matched.

◆ ◆ ◆
■ Test for No Correlation (Two-tailed test) Example p.191
We will examine the presence or absence of a correlation between air pollution and water pollution in the example on p.191 using a test for no correlation.

The hypotheses are as follows:
・Null hypothesis $${H_0}$$: "The two sets of data are uncorrelated"
・Alternative hypothesis $${H_1}$$: "The two sets of data are correlated"
⇒Two-tailed test: Interested in whether or not there is a correlation
① Execute test using custom function
First, set the two sets of data.
### 無相関の検定 p.191
# データ
data2 = pd.DataFrame({'市名': ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'O'],
'大気汚染': [113, 64, 16, 45, 28, 19, 30, 82, 76],
'水質汚濁': [31, 5, 2, 17, 18, 2, 9, 25, 13]},
index=range(1, 10))
data2.index.name = 'No.'
data2[Execution Result]

Let's visualize the air pollution and water pollution with a scatter plot.
# 散布図の描画 p.191
sns.scatterplot(data=data2, x='大気汚染', y='水質汚濁', s=80, alpha=0.7)
plt.xlim(0, 150)
plt.ylim(0, 40);[Execution Result]
A trend sloping upward to the right can be seen.
There appears to be a positive correlation.

Let's check the correlation coefficient.
# pandasで相関係数を算出
data2.corr(numeric_only=True)[Execution Result]
The correlation coefficient is $${0.761}$$.
I feel that there is a relatively strong positive correlation between the two sets of data.

Now, let's perform a test for the difference between two population variances with a significance level of $${5\%}$$ and a two-sided test.
# 関数利用
result = non_corr_ttest(data2['大気汚染'], data2['水質汚濁'])
result[Execution Result]

Since the test statistic $${3.104}$$ is greater than the rejection limit (upper threshold) $${2.365}$$ (it falls into the rejection region), the null hypothesis is rejected at the $${5\%}$$ significance level.
In other words, it can be said that there is a correlation between air pollution and water pollution.
(2) Visualization of the test
Let's visualize the $${t}$$ distribution to see how it is rejected.
### 図示 p.193
## 設定と準備
# 統計関連の値
N = data2.shape[0] # 標本サイズ
alpha = result['alpha'] # 有意水準
lower, upper = result['c_value'] # 棄却限界値
t_val = result['t_value'] # 検定統計量
t_dist = stats.t(df=N - 2) # t分布
# グラフ描画用設定
color = 'tab:blue' # 基本の色
x_min, x_max = -5, 5 # x軸の最小値、最大値
x_val = np.linspace(x_min, x_max, 1001) # 確率密度関数用のx軸の値
x_val_lower = np.linspace(x_min, lower, 101) # 下側棄却域用のx軸の値
x_val_upper = np.linspace(upper, x_max, 101) # 上側棄却域用のx軸の値
## 描画処理
# 描画領域の設定
plt.figure(figsize=(7, 3))
# t分布の確率密度関数の描画
plt.plot(x_val, t_dist.pdf(x_val), color=color,
label=f'自由度({N}-2)の$t$分布')
# 下側棄却域の塗りつぶし
plt.fill_between(x_val_lower, 0, t_dist.pdf(x_val_lower),
color=color, alpha=0.3, label=f'有意水準{alpha}の棄却域')
# 上側棄却域の塗りつぶし
plt.fill_between(x_val_upper, 0, t_dist.pdf(x_val_upper),
color=color, alpha=0.3)
# 検定統計量の垂直線の描画
plt.axvline(t_val, color='tab:red', ls='--', label=f'検定統計量={t_val:.3f}')
# 修飾
plt.xticks([lower, 0, upper])
plt.legend();[Execution Result]

The bell-shaped curve is the probability density function of the $${t}$$ distribution with $${N -2=7}$$ degrees of freedom.
The blue regions at both ends are the rejection regions for a $${5\%}$$ significance level.
Since it is a two-sided test, there is a $${2.5\%}$$ rejection region at each end.
The red dotted line is the test statistic $${T}$$.
Since $${T}$$ falls into both rejection regions, the null hypothesis is rejected.
(3) Executing the test with Python libraries
Here, we use scipy.stats and pingouin.
Both pass the two sample data sets as arguments.
🖲️scipy.stats
# scipy.stats利用 (標本相関係数, 無相関の検定のp値)
stats.pearsonr(data2['大気汚染'], data2['水質汚濁'])[Execution Result]
We obtained the correlation coefficient and the $${p}$$ value.

🖲️pingouin
# pingouin利用
pg.corr(data2['大気汚染'], data2['水質汚濁'])[Execution Result]
The main outputs are: r: correlation coefficient, CI95%: 95% confidence interval of the correlation coefficient, p_val: $${p}$$ value.


■ (Reference) Assumptions of population distribution in tests for no correlation: ChatGPT Q&A
I am posting the exchange with ChatGPT regarding the assumptions of the population distribution mentioned at the beginning.
Please note that I have not verified the accuracy of the content.






Test for population correlation coefficient
The test for the population correlation coefficient is a test to determine whether the correlation coefficient of the data is "a certain correlation coefficient".
"A certain correlation coefficient" refers to the correlation coefficient $${{\rho_0}}$$ of the null hypothesis.
Does the test for the population correlation coefficient assume any kind of population distribution?
By the way, ChatGPT's answer is "it assumes a bivariate normal distribution."
■ Hypothesis
Set the hypothesis for the population correlation coefficient $${\rho_0}$$ that you wish to refute as follows.
Null hypothesis $${H_0}$$: $${\rho = \rho_0}$$
The hypothesis you wish to support, the alternative hypothesis, is set as one of the following three patterns.
① Two-tailed test: When testing that the population correlation coefficient is different from $${\rho_0}$$ ・Alternative hypothesis $${H_1}$$: $${\rho \neq \rho_0}$$
② One-tailed test: When testing that the population correlation coefficient is smaller than $${\rho_0}$$ ・Alternative hypothesis $${H_1}$$: $${\rho < \rho_0}$$
③ One-tailed test: When testing that the population correlation coefficient is larger than $${\rho_0}$$ ・Alternative hypothesis $${H_1}$$: $${\rho > \rho_0}$$
◆ ◆ ◆
■ Test for population correlation coefficient: Formula for test statistic p.194
I will borrow the formula for the test statistic in the test for the population correlation coefficient from the text.
Let $${r}$$ be the sample correlation coefficient of a sample with sample size $${N}$$; the test statistic for the population correlation coefficient is
$$
T(r) = \sqrt{N - 3} \left(\cfrac{1}{2}\log\cfrac{1+r}{1-r} - \cfrac{1}{2}\log\cfrac{1+\rho_0}{1-\rho_0}\right)
$$
is approximated by the standard normal distribution.
$${\rho_0}$$ is the correlation coefficient of the null hypothesis.
I will define a "population correlation coefficient test function" according to the formula.
I will use scipy.stats for probability calculations.
### 母相関係数の検定関数 p.194
# 標本相関係数算出関数
def calc_corr(x_list1, x_list2):
# 標本サイズ ※2つの標本サイズは同じ
N = len(x_list1)
# 2つの標本平均
x_bar, y_bar = sum(x_list1) / N, sum(x_list2) / N
# 分子、分母1,分母2の計算
numerator = sum((x - x_bar) * (y - y_bar) for x, y in zip(x_list1, x_list2))
denominator1 = (sum([(x - x_bar)**2 for x in x_list1]))**(1/2)
denominator2 = (sum([(y - y_bar)**2 for y in x_list2]))**(1/2)
# 標本相関係数r
r = numerator / (denominator1 * denominator2)
# 戻り値: 標本相関係数r, 標本サイズN
return r, N
# 母相関係数のz検定統計量の算出関数
def z_stat_pop_corr(x_list1, x_list2, rho0):
# 標本相関係数の算出
r, N = calc_corr(x_list1, x_list2)
# 戻り値: z検定統計量
return ((N-3)**(1/2)
* (1/2 * math.log((1+r)/(1-r)) - 1/2 * math.log((1+rho0)/(1-rho0))),
r)
# 母相関係数のz検定関数 ※確率計算はscipy.stats利用
def pop_corr_ztest(x_list1, x_list2, rho0, alpha=0.05, alternative='two-sided'):
# z検定統計量と標本相関係数rの算出
z_val, r = z_stat_pop_corr(x_list1, x_list2, rho0)
std_norm_dist = stats.norm(loc=0, scale=1)
match alternative:
case 'two-sided':
c_val = std_norm_dist.ppf(q=1 - alpha/2)
c_val = -c_val, c_val
p_val = std_norm_dist.sf(x=abs(z_val)) * 2
case 'less':
c_val = std_norm_dist.ppf(q=alpha)
p_val = std_norm_dist.cdf(x=z_val)
case 'greater':
c_val = std_norm_dist.ppf(q=1 - alpha)
p_val = std_norm_dist.sf(x=z_val)
return {'z_value': z_val, 'c_value': c_val, 'alpha': alpha, 'p_value': p_val,
'r': r, 'rho0': rho0}Let's perform a test for the population correlation coefficient using the following test data.
$$
\begin{array}{cc}
Variable 1 & Variable 2 \\
\hline
1 & 0.8 \\
2 & 0.9 \\
3 & 1.1 \\
4 & 1.5
\end{array}
$$
These are the test conditions.
Null hypothesis $${H_0}$$ "Population correlation coefficient $${\rho=0.9}$$"
Significance level 5% ($${\alpha=0.05}$$)
Two-tailed test
# テスト
x_list1, x_list2 = [1, 2, 3, 4], [0.8, 0.9, 1.1, 1.5]
pop_corr_ztest(x_list1, x_list2, rho0=0.9)[Execution Result]
"It cannot be said to be significant at the 5% significance level, and the null hypothesis cannot be rejected."
As a result of the test, we accept that "the population correlation coefficient is $${0.9}$$".
The sample correlation coefficient of the data was $${0.959}$__.

I will briefly explain the output content.
z_value: Realized value of the test statistic $${T}$$
c_value: Critical value
The threshold for the test statistic $${T}$$ at which the null hypothesis can be rejected
When the realized value of $${T}$$ is outside the critical value, the null hypothesis can be rejectedalpha: Significance level $${\alpha}$$
p_value: $${p}$$ value
The probability that the test statistic takes the realized value under the null hypothesis
When the $${p}$$ value is less than or equal to (or less than) the significance level, the null hypothesis can be rejectedr: Sample correlation coefficient
rho0: Population correlation coefficient of the null hypothesis
I would like to work on an example problem in this flow, but...
Please wait until the "Understanding Check"!
◆ ◆ ◆
💡 Tips: Fisher's $${z}$$ transformation
Included in the formula for the test of the population correlation coefficient
$$
\cfrac{1}{2}\log\cfrac{1+r}{1-r}
$$
is an operation called "Fisher's $${z}$$ transformation".
I asked ChatGPT about Fisher's $${z}$$ transformation.
✅ What is Fisher's z-transformation?
The sample correlation coefficient $${r}$$ is originally in the range $${[−1,1]}$$ and its distribution is skewed.
Therefore, by performingthe following transformation, it is brought closer to a normal distribution:
$$
z = \frac{1}{2} \log \left(\frac{1 + r}{1 - r}\right)
$$
The quantity $${z}$$ after this transformation is considered to followapproximately a normal distribution $${\mathcal{N}(\zeta, \frac{1}{N - 3})}$$ under the population correlation coefficient $${\rho}$$. Here:
$$
\zeta = \frac{1}{2} \log \left(\frac{1 + \rho}{1 - \rho}\right)
$$
So they were approximating the test statistic to a standard normal distribution using Fisher's $${\boldsymbol{z}}$$ transformation!
Actually, in a previous article where I copied code from another book, I practiced "simulating the approximation of a correlation coefficient to a normal distribution using Fisher's $${z}$$ transformation".
Please feel free to take a detour if you'd like.

Understanding Check: Test of Population Correlation Coefficient p.195
We will verify whether the population correlation coefficient between calorie intake by country and the number of patients with a certain disease is $${\rho_0=-0.3}$$ using a test for the population correlation coefficient.

We will proceed with a significance level of 5% and a two-tailed test, writing the code calmly.
Set the sample data.
### 母相関係数の検定 カロリー摂取とある病気の患者数 p.195
# データ
data3 = pd.DataFrame(
{'カロリー': [2750, 2956, 2675, 3198, 1816, 2233, 2375, 2288, 1932, 2036,
2183, 2882],
'患者数': [249, 713, 1136, 575, 5654, 2107, 915, 4193, 7225, 3730, 472, 291]},
index=range(1, 13))
data3[Execution Result]

Let's check the relationship of the data using a scatter plot.
# 散布図の描画
sns.scatterplot(data=data3, x='カロリー', y='患者数', s=80, alpha=0.7);[Execution Result]
A downward trend can be seen up to about 2500 calories.

Let's calculate the sample correlation coefficient.
# 標本相関係数
data3.corr()[Execution Result]
The correlation coefficient of -0.76655 is a relatively strong negative correlation.
It feels like it deviates from the null hypothesis of ρ0 = -0.3.

Now, let's perform the test using a custom function.
# 母相関係数の検定 関数利用 ★テキスト解答のz検定統計量は-0.915となっている
result = pop_corr_ztest(data3['カロリー'], data3['患者数'], rho0=-0.3)
result[Execution Result]
The null hypothesis is rejected.
In other words, 'the population correlation coefficient cannot be said to be -0.3'.
The sample correlation coefficient was -0.767.

Let's visualize the standard normal distribution to see how it can be rejected.
### 図示
## 設定と準備
# 統計関連の値
alpha = result['alpha'] # 有意水準
lower, upper = result['c_value'] # 棄却限界値
z_val = result['z_value'] # 検定統計量
std_norm_dist = stats.norm(loc=0, scale=1) # 標準正規分布
# グラフ描画用設定
color = 'tab:blue' # 基本の色
x_min, x_max = -3, 3 # x軸の最小値、最大値
x_val = np.linspace(x_min, x_max, 1001) # 確率密度関数用のx軸の値
x_val_lower = np.linspace(x_min, lower, 101) # 下側棄却域用のx軸の値
x_val_upper = np.linspace(upper, x_max, 101) # 下側棄却域用のx軸の値
## 描画処理
# 描画領域の設定
plt.figure(figsize=(7, 3))
# 標準正規分布の確率密度関数の描画
plt.plot(x_val, std_norm_dist.pdf(x_val), color=color, label=f'標準正規分布')
# 下側棄却域の塗りつぶし
plt.fill_between(x_val_lower, 0, std_norm_dist.pdf(x_val_lower),
color=color, alpha=0.3, label=f'有意水準{alpha}の棄却域')
# 上側棄却域の塗りつぶし
plt.fill_between(x_val_upper, 0, std_norm_dist.pdf(x_val_upper),
color=color, alpha=0.3)
# 検定統計量の垂直線の描画
plt.axvline(z_val, color='tab:red', ls='--', label=f'検定統計量={z_val:.3f}')
# 修飾
plt.xticks([lower, 0, upper])
plt.legend();[Execution Result]
The test statistic is located in the lower (left) blue rejection region.
The null hypothesis is rejected.

(Note) The value of the test statistic in this article differs from the example answer in the textbook. The reason for the discrepancy is unknown.

Test for the difference between two population correlation coefficients
We are back to the difference test series!
The test for the difference between two population correlation coefficients is quietly introduced in the 'Wait a minute!' corner of the textbook.
It is likely a 'test for the difference between independent population correlation coefficients'.
Let's definitely implement it in Python!
■ Hypothesis
We set the hypothesis for the difference in population correlation coefficients ρ1 - ρ2 that we want to overturn as follows.
Null hypothesis H0: ρ1 - ρ2 = 0
The hypothesis we want to support, the alternative hypothesis, is set as one of the following three patterns.
① Two-tailed test: When testing that the difference in population correlation coefficients is not 0
・Alternative hypothesis H1: ρ1 - ρ2 ≠ 0
② One-tailed test: When testing that the difference in population correlation coefficients is negative
・Alternative hypothesis H1: ρ1 - ρ2 < 0
③ One-tailed test: When testing that the difference in population correlation coefficients is positive
・Alternative hypothesis H1: ρ1 - ρ2 > 0
◆ ◆ ◆
■ Test for the difference between two population correlation coefficients: Formula for the test statistic p.193
I will borrow the formula for the test statistic in the test for the difference between two population correlation coefficients from the text.
Test statistic for the difference between two population correlation coefficients
$$
T = \cfrac{z_1 - z_2}{\sqrt{\cfrac{1}{N_1 - 3} + \cfrac{1}{N_2 - 3}}}
$$
is approximated by the standard normal distribution.
Where:
$$
z_1 = \cfrac{1}{2}\log\cfrac{1+r_1}{1-r_1},\ z_2 = \cfrac{1}{2}\log\cfrac{1+r_2}{1-r_2}
$$
I will define a "test function for the difference between two population correlation coefficients" based on the formula.
I will use scipy.stats for probability calculations.
### 2つの母相関係数の差の検定 p.193
# 2つの母相関係数の差のz検定統計量の算出関数
def z_stat_pop_corr_diff(r1, r2, N1, N2):
# z1, z2の算出
z1 = 1/2 * math.log((1 + r1)/(1 - r1))
z2 = 1/2 * math.log((1 + r2)/(1 - r2))
# 戻り値: z検定統計量
return (z1 - z2) / math.sqrt(1/(N1 - 3) + 1/(N2 - 3))
# 2つの母相関係数差のz検定関数 ※確率計算はscipy.stats利用
def pop_corr_diff_ztest(r1, r2, N1, N2, alpha=0.05, alternative='two-sided'):
# z検定統計量と標本相関係数の算出
z_val = z_stat_pop_corr_diff(r1, r2, N1, N2)
# 標準正規分布の設定
std_norm_dist = stats.norm(loc=0, scale=1)
# 棄却限界値c_valとp値p_valの算出
match alternative:
case 'two-sided':
c_val = std_norm_dist.ppf(q=1 - alpha/2)
c_val = -c_val, c_val
p_val = std_norm_dist.sf(x=abs(z_val)) * 2
case 'less':
c_val = std_norm_dist.ppf(q=alpha)
p_val = std_norm_dist.cdf(x=z_val)
case 'greater':
c_val = std_norm_dist.ppf(q=1 - alpha)
p_val = std_norm_dist.sf(x=z_val)
return {'z_value': z_val, 'c_value': c_val, 'alpha': alpha, 'p_value': p_val}Let's perform a test for the difference between two population correlation coefficients using the following test data.
$$
\begin{array}{cc}
& Sample Size & Sample Correlation Coefficient \\
\hline
Sample 1 & N_1 = 100 & r_1 = 0.8 \\
Sample 2 & N_2 = 120 & r_2 = 0.6 \\
\end{array}
$$
These are the test conditions.
Null hypothesis $${H_0}$$: "Difference in population correlation coefficients $${\rho_1 = \rho_2}$$"
Significance level 5% ($${\alpha=0.05}$$)
Two-sided test
# テスト
r1, r2 = 0.8, 0.6
N1, N2 = 100, 120
pop_corr_diff_ztest(r1, r2, N1, N2)[Execution Results]
"It is significant at the 5% significance level, and the null hypothesis is rejected."
In other words, "it cannot be said that the two population correlation coefficients are $${\rho_1 = \rho_2}$$".

I will briefly explain the output content.
z_value: Realized value of the test statistic $${T}$$
c_value: Rejection limit value
The threshold for the test statistic $${T}$$ at which the null hypothesis can be rejected
When the realized value of $${T}$$ is outside the rejection limit, the null hypothesis can be rejectedalpha: Significance level $${\alpha}$$
p_value: $${p}$$ value
The probability that the test statistic becomes the realized value under the null hypothesis
When the $${p}$$ value is less than or equal to the significance level, the null hypothesis can be rejected

Let's have ChatGPT wrap up the end of the article!
📘 A word from ChatGPT:
"Do these two seem related?"
When you want to verify that intuition properly with the power of data, that is the sign of your first encounter with correlation.
The correlation coefficient test is a tool that turns "seems connected" into "definitely seems connected."
Having listened to the conversation between data points, you are surely already beginning to speak the language of statistics little by little.
That is all for this copying session.
Series Articles
Next Article
Previous Article
Table of Contents
Blog Introduction
I am writing seven series of articles on note.
Please feel free to take a look!
1. Relaxed Statistics
This is a blog that roughly explores probability and statistics using the Statistical Test Grade 2 problem collection as a guide.
Casual conversation style is fine. Please feel free to take a look.
It corresponds to the Statistical Test Grade 2 Official Problem Collection CBT Version.
Sample code for Python and EXCEL is also available.
2. Experiment! Fun Bayesian Modeling 1 & 2 with PyMC Ver. 5
I will draw and analyze the Bayesian models used in the psychology research of the books "Fun Bayesian Modeling" and "Fun Bayesian Modeling 2" using PyMC Ver. 5.
Starting with these books, many Bayesian models are written in R language + Stan.
I will strive to explore the possibilities of PyMC and make Bayesian modeling easy to practice.
Since these are familiar and easy-to-visualize themes, please run them with PyMC and let's enjoy it together!
3. Experiment! Iwanami Data Science 1 Bayesian Modeling with PyMC Ver. 5
I will draw and analyze the Bayesian models by four Bayesians from the book "Experiment! Iwanami Data Science Vol. 1" using PyMC Ver. 5.
This book is a great resource for learning the basics of Bayesian programming.
I feel like I have become friends with Bayesian methods by happily running PyMC models.
Everyone, please run them with PyMC and let's play and learn together!
4. Fun Copying: Bayesian, Python, etc.
I will blog about the results of my "book copying activities" for Bayesian, Python, and others.
I am mainly working on translations into Python.
I hope this becomes sample code for fellow learners who are also copying code 🍀
5. Introduction to Time Series Analysis for Psychology with R and Stan, using Python and PyMC Ver. 5
I will practice the time series analysis from the book "Introduction to Time Series Analysis for Psychology with R and Stan" using Python and PyMC Ver. 5.
This book is packed with time series analysis themes!
I realized the depth of time series analysis.
I will enjoy learning time series analysis with my favorite language, Python.
6. Writing about Data Science-like things
I write columns on statistics, data analysis, AI, machine learning, and Python on an irregular basis.
There are many articles related to statistics and data science books.
Series on "Statistics," "Python," "Mathematics and Python," and "R" have been created.
7. Record of Practical Python Machine Learning Programming
I have written articles about my various thoughts while studying the book 'Python Machine Learning Programming: PyTorch & scikit-learn Edition'.
This book is a textbook for scikit-learn and PyTorch.
Please feel free to give it a try if you like.
Thank you very much for reading until the end.
いいなと思ったら応援しよう!
応援ありがとうございます。これからもがんばって記事を作成します!