bundles / scipy 1.17.1 / scipy / stats / _page_trend_test / page_trend_test
function
scipy.stats._page_trend_test:page_trend_test
Signature
def page_trend_test ( data , ranked = False , predicted_ranks = None , method = auto ) Summary
Perform Page's Test, a measure of trend in observations between treatments.
Extended Summary
Page's Test (also known as Page's test) is useful when:
there are treatments,
subjects are observed for each treatment, and
the observations are hypothesized to have a particular order.
Specifically, the test considers the null hypothesis that
where is the mean of the observed quantity under treatment , against the alternative hypothesis that
where at least one inequality is strict.
As noted by [4], Page's test has greater statistical power than the Friedman test against the alternative that there is a difference in trend, as Friedman's test only considers a difference in the means of the observations without considering their order. Whereas Spearman considers the correlation between the ranked observations of two variables (e.g. the airspeed velocity of a swallow vs. the weight of the coconut it carries), Page's is concerned with a trend in an observation (e.g. the airspeed velocity of a swallow) across several distinct treatments (e.g. carrying each of five coconuts of different weight) even as the observation is repeated with multiple subjects (e.g. one European swallow and one African swallow).
Parameters
data: array-likeA array; the element in row and column is the observation corresponding with subject and treatment . By default, the columns are assumed to be arranged in order of increasing predicted mean.
ranked: boolean, optionalBy default,
datais assumed to be observations rather than ranks; it will be ranked with scipy.stats.rankdata alongaxis=1. Ifdatais provided in the form of ranks, pass argumentTrue.predicted_ranks: array-like, optionalThe predicted ranks of the column means. If not specified, the columns are assumed to be arranged in order of increasing predicted mean, so the default
predicted_ranksare .method: {'auto', 'asymptotic', 'exact'}, optionalSelects the method used to calculate the p-value. The following options are available.
'auto': selects between 'exact' and 'asymptotic' to achieve reasonably accurate results in reasonable time (default)
'asymptotic': compares the standardized test statistic against the normal distribution
'exact': computes the exact p-value by comparing the observed statistic against those realized by all possible permutations of ranks (under the null hypothesis that each permutation is equally likely)
Returns
res: PageTrendTestResultAn object containing attributes:
statistic
statistic
pvalue
pvalue
method
method
Notes
As noted in [1], "the 'treatments' could just as well represent objects or events or performances or persons or trials ranked." Similarly, the 'subjects' could equally stand for "groupings by ability or some other control variable, or judges doing the ranking, or random replications of some other sort."
The procedure for calculating the statistic, adapted from [1], is:
"Predetermine with careful logic the appropriate hypotheses concerning the predicted ordering of the experimental results. If no reasonable basis for ordering any treatments is known, the test is not appropriate."
"As in other experiments, determine at what level of confidence you will reject the null hypothesis that there is no agreement of experimental results with the monotonic hypothesis."
"Cast the experimental material into a two-way table of columns (treatments, objects ranked, conditions) and rows (subjects, replication groups, levels of control variables)."
"When experimental observations are recorded, rank them across each row", e.g.
ranks = scipy.stats.rankdata(data, axis=1)."Add the ranks in each column", e.g.
colsums = np.sum(ranks, axis=0)."Multiply each sum of ranks by the predicted rank for that same column", e.g.
products = predicted_ranks * colsums."Sum all such products", e.g.
L = products.sum().
[1] continues by suggesting use of the standardized statistic
"which is distributed approximately as chi-square with 1 degree of freedom. The ordinary use of tables would be equivalent to a two-sided test of agreement. If a one-sided test is desired, as will almost always be the case, the probability discovered in the chi-square table should be halved."
However, this standardized statistic does not distinguish between the observed values being well correlated with the predicted ranks and being _anti_-correlated with the predicted ranks. Instead, we follow [2] and calculate the standardized statistic
where and , "which is asymptotically normal under the null hypothesis".
The p-value for method='exact' is generated by comparing the observed value of against the values generated for all possible permutations of ranks. The calculation is performed using the recursive method of [5].
The p-values are not adjusted for the possibility of ties. When ties are present, the reported 'exact' p-values may be somewhat larger (i.e. more conservative) than the true p-value [2]. The 'asymptotic'` p-values, however, tend to be smaller (i.e. less conservative) than the 'exact' p-values.
Array API Standard Support
page_trend_test has experimental support for Python Array API Standard compatible backends in addition to NumPy. Please consider testing these features by setting an environment variable SCIPY_ARRAY_API=1 and providing CuPy, PyTorch, JAX, or Dask arrays as array arguments. The following combinations of backend and device (or other capability) are supported.
==================== ==================== ==================== Library CPU GPU ==================== ==================== ==================== NumPy ✅ n/a CuPy n/a ⛔ PyTorch ⛔ ⛔ JAX ⛔ ⛔ Dask ⛔ n/a ==================== ==================== ====================
See
dev-arrayapifor more information.
Examples
We use the example from [3]_: 10 students are asked to rate three teaching methods - tutorial, lecture, and seminar - on a scale of 1-5, with 1 being the lowest and 5 being the highest. We have decided that a confidence level of 99% is required to reject the null hypothesis in favor of our alternative: that the seminar will have the highest ratings and the tutorial will have the lowest. Initially, the data have been tabulated with each row representing an individual student's ratings of the three methods in the following order: tutorial, lecture, seminar.table = [[3, 4, 3], [2, 2, 4], [3, 3, 5], [1, 3, 2], [2, 3, 2], [2, 4, 5], [1, 2, 4], [3, 4, 4], [2, 4, 5], [1, 3, 4]]✓
from scipy.stats import page_trend_test res = page_trend_test(table)✓
res
✗from scipy.stats import rankdata ranks = rankdata(table, axis=1) ranks✓
import numpy as np m, n = ranks.shape predicted_ranks = np.arange(1, n+1) L = (predicted_ranks * np.sum(ranks, axis=0)).sum()✓
res.statistic == L
✗from scipy.stats import norm E0 = (m*n*(n+1)**2)/4 V0 = (m*n**2*(n+1)*(n**2-1))/144 Lambda = (L-E0)/np.sqrt(V0) p = norm.sf(Lambda)✓
p
✗res = page_trend_test(table, method="asymptotic")
✓res
✗res = page_trend_test(ranks, # ranks of data ranked=True, # data is already ranked )✓
res
✗table = np.asarray(table)[:, [1, 2, 0]]
✓res = page_trend_test(table, # data as originally tabulated predicted_ranks=[2, 3, 1], # our predicted order )✓
res
✗See also
- friedmanchisquare
- rankdata
- spearmanr
Aliases
-
scipy.stats.page_trend_test