Detect sales chasing in a vector of sales ratios#
- assesspy.is_sales_chased(x: list[int] | list[float] | Series, method='both', bounds: tuple[float, float] = (0.98, 1.02), gap: float = 0.05) bool #
Sales chasing is when a property is selectively reappraised to shift its assessed value toward its recent sale price. Sales chasing is difficult to detect. This function is NOT a statistical test and does not provide the probability of the given result. Rather, it combines two heuristic methods to roughly estimate if sales chasing has occurred.
The first method (cdf) detects discontinuities in the cumulative distribution function (CDF) of the ratios of input values. Sales ratios that are not sales chased should have a fairly smooth CDF. Discontinuous jumps in the CDF, particularly around 1, may indicate sales chasing. This can usually be seen visually as a “flat spot” on the CDF.
The second method (dist) uses the technique outlined in the IAAO Standard on Ratio Studies Appendix E, Section 4. It compares the percentage of real data within +-2% of the mean ratio to the percentage of data within the same bounds given a constructed normal distribution with the same mean and standard deviation. The intuition here is that ratios that are sales chased may be more “bunched up” in the center of the distribution.
- Parameters:
x (Array-like numeric values) – A list or
pd.Series
of numeric values. Must be longer than 2 and cannot containInf
orNaN
values.method (str) – Default
both
. String indicating sales chasing detection method. Options arecdf
,dist
, orboth
.bounds (tuple[float, float]) – Default
(0.98, 1.02)
. Tuple of two floats indicating the lower and upper bounds of the range of ratios to consider when detecting sales chasing. Setting this to a narrow band at the center of the ratio distribution prevents detecting false positives at the tails.gap (float) – Default
0.05
. Float tuning factor. For the CDF method, it sets the maximum percentage difference between two adjacent ratios. For the distribution method, it sets the maximum percentage point difference between the percentage of the data between thebounds
in the real distribution compared to the ideal distribution.
- Returns:
A boolean value indicating whether or not the input values may have been sales chased.
- Return type:
bool
- Example:
import assesspy as ap import numpy as np from statsmodels.distributions.empirical_distribution import ECDF from matplotlib import pyplot # Generate fake data with normal vs chased ratios normal_ratios = np.random.normal(1, 0.15, 10000).tolist() chased_ratios = list(np.random.normal(1, 0.15, 900)) + [1] * 100 # Plot to view discontinuity ecdf = ECDF(normal_ratios) pyplot.plot(ecdf.x, ecdf.y) pyplot.show() ap.is_sales_chased(normal_ratios) ecdf = ECDF(chased_ratios) pyplot.plot(ecdf.x, ecdf.y) pyplot.show() ap.is_sales_chased(chased_ratios)