-
Notifications
You must be signed in to change notification settings - Fork 15
utility_weather_sensitivity
Weather sensitivity refers to the strength of the correlation between building load and outside air temperature. The weather sensitivity metric described here uses the Spearman rank correlation coefficient:
- A value of +1 indicates that the load increases as a monotone function of outside air temperature.
- A value of 0 indicates no rank-order correlation between load and outdoor temperature.
- A value of -1 is unexpected value, as it indicates that load continously decreases with temperature.
Note this is not a stand-alone application. Rather, it is calculated for display along with the energy signature plot.
Find the Spearman coefficient by finding the correlation between the ranks of the loads and temperatures.
Sample explanatory text: "If weather sensitivity > 0.7 the building energy use is "highly" sensitive to outside air temperature. There may be opportunities to improve building insulation and ventilation."
Program findSpearmanRank
- Get inputs:
-
xValues
andyValues
, two vectors of values (float). For weather sensitivity,xValues
are the outside air temperatures, andyValues
are the corresponding loads. However, note that interchangingxValues
andyValues
will still give the same correlation coefficient.
-
- Assume:
- Both
xValues
andyValues
have the same number of entries. - Any missing or corrupted entries in
xValues
andyValues
have been marked asNAN
(not-a-number). These entries will be excluded from the analysis.
- Both
- Identify the data of interest:
- Take the last year of data. This ensures that the data are representative.
- Remove invalid pairs of entries:
- Set
xValuesClean
to an empty list. - Set
yValuesClean
to an empty list. - For each matched pair
x, y
taken fromxValues
andyValues
:- If either
x
ory
is aNAN
, discard the pair. - Otherwise, append
x
toxValuesClean
, and appendy
toyValuesClean
.
- If either
- Here, both
xValuesClean
andyValuesClean
should have the same number of entries, call itvalCt
.
- Set
- Rank the remaining entries:
- Set
xRanks
= rankForSpearman(xValuesClean
). - Set
yRanks
= rankForSpearman(yValuesClean
). - Note the pseudo-code for subprogram rankForSpearman() appears below.
- Note both
xRanks
andyRanks
are vectors containingvalCt
ranks. For any valid indexii
, the entryxRanks[ii]
gives the ranking thatxValuesClean[ii]
would have if sorted into ascending order. However, duplicate entries are assigned the mean rank of all the duplicates. Therefore the entries are not necessarily integers.
- Set
- Subtract out the mean ranks:
- Set
xRanksZeroMean
toxRanks
minus the mean of all entries inxRanks
. - Set
yRanksZeroMean
toyRanks
minus the mean of all entries inyRanks
.
- Set
- Find the Spearman rank correlation coefficient:
- Set
cosineFactor
to the inner (dot) product ofxRanksZeroMean
withyRanksZeroMean
. - Set
xMagSq
to the inner (dot) product ofxRanksZeroMean
with itself. - Set
yMagSq
to the inner (dot) product ofyRanksZeroMean
with itself. - Find the Spearman coefficient using:
spearmanCoeff
=cosineFactor
/ sqrt(xRanks
*yMagSq
) - Note that the Spearman coefficient is the Pearson coefficient of the rank vectors
xRanks
andyRanks
. - Note that expect
-1 <= spearmanCoeff <= 1
.
- Set
- Return
spearmanCoeff
.
Subprogram rankForSpearman
ranks the entries of a vector values
, using the average rank to break ties:
Subprogram rankForSpearman
- Get inputs:
-
values
, vector containingvalCt
numbers (float).
-
- Assume:
- All entries in
values
are numeric, i.e., the vector does not contain anyNAN
entries.
- All entries in
- Find the sorted order of entries in
values
:- Set
srtdToActIdx
to a vector ofvalCt
indices that would sortvalues
, from smallest to largest. That is,srtdToActIdx[ii]
should give the index of theii
th entry in a sorted version ofvalues
. - Duplicate entries in
values
may be sorted in any order. That is, it is not necessary to perform a "stable sort" that preserves the original order of duplicate entries invalues
. - For example, if
values = (6.6, 1.1, 3.3, 1.1)
thensrtdToActIdx = (1, 3, 2, 0)
is a possible ranking. Considerii = 3
. SincesrtdToActIdx[3] = 0
, it follows thatvalues[0] = 6.6
would be at index 3 in a sorted version ofvalues
. Note that there is one other possible ranking, due to the duplicated entry 1.1 invalues
. Also note that, in programming languages that index arrays from 1 (such as R or Fortran), the entries insrtdToActIdx
should be one greater than shown in the example. - Note that merely sorting
values
is not helpful, because the simple act of sorting does not retain information about which index of the originalvalues
vector provided each entry in the sorted vector. - In practice, some high-level programming environments provide sorting routines that return the indices needed to sort a vector.
This is exactly the required
srtdToActIdx
.
- Set
- Find the average rank order of each entry in
values
:- Initialize
ranks
as a vector ofvalCt
entries, all equal to 0. - Set
lastVal
tovalues[srtdToActIdx[0]]
. Note this should be the smallest entry invalues
. - Set
startRunIdx
to 0. - For
currIdx
running from 1 tovalCt-1
(i.e., for every entry after the first):- Set
currVal
to the corresponding entry in the sorted vector, i.e., tovalues[srtdToActIdx[currIdx]]
. - If(
currVal
is different fromlastVal
):- Find the mean rank that should be assigned to indices
startRunIdx
throughcurrIdx-1
, inclusive. The sorted rank atcurrIdx-1
iscurrIdx
, so find the mean rank asmeanRank = 0.5 * (startRunIdx + currIdx + 1)
- Note that in a language that indexes arrays from 1, the sorted rank at
currIdx-1
iscurrIdx-1
, so the mean rank ismeanRank = 0.5 * (startRunIdx + currIdx - 1)
- while(
startRunIdx
<currIdx
):- Set
ranks[srtdToActIdx[startRunIdx]]
tomeanRank
. - Increment
startRunIdx
by 1.
- Set
- Set
lastVal
tocurrVal
, in order to mark the start of a new run of equal values. Note thatstartRunIdx
should already be equal tocurrIdx
, due to the while-loop above.
- Find the mean rank that should be assigned to indices
- Set
- Assign ranks to the last entries inspected in the loop above:
- Set
meanRank
to the mean rank, using the same formula shown above. - while( startRunIdx < currIdx ):
- Set
ranks[srtdToActIdx[startRunIdx]]
tomeanRank
. - Increment
startRunIdx
by 1.
- Set
- Set
- Here, every entry of
ranks
should have the rank of the corresponding entry invalues
, with equal values assigned their mean rank, and with NAN values assigned a rank of 0. Continuing the example above, ifvalues = (6.6, 1.1, 3.3, 1.1)
thenranks = (4, 1.5, 3, 1.5)
Note that, unlike the entries insrtdToActIdx
,ranks
does not depend on whether the programming language indexes arrays from 0 or from 1. Ranks always range from 1 (or larger, for the smallest non-NAN entry invalues
) tovalCt
(or less, for the largest non-NAN entry invalues
).
- Initialize
- Return
ranks
.