Industry Insights

Using the Right Weather Data

July 09, 2014

I recently reviewed a customer’s monthly weather normalization model. The regression model included cooling degree days (CDD), heating degree days (HDD), and a few other minor variables. The monthly CDD and HDD variables were summed from the daily CDD and HDD variables, which were calculated from daily average temperature. In this case, the daily average temperature was calculated as the average of the maximum and minimum values. Further, the CDD and HDD variables were both specified with a single breakpoint of 65 degrees. The model’s Mean Absolute Percent Error (MAPE) was 1.08%. (Remember, a lower MAPE is preferable to a higher MAPE.)

Because the hourly temperature data were available (and because I am a curious person), I modified the calculation of the average temperature to be the average of the 24 hourly values, rather than the average of the maximum and minimum values. When I did this, the MAPE dropped from 1.08% to 1.03%. The improvement is not tremendous, but it is something.

By reviewing a scatter plot that related the daily energy to the daily average temperature, I determined that heating in this area starts at 55 degrees, rather than 65 degrees. When I changed the HDD breakpoint from 65 to 55, the MAPE dropped to 0.72%. I also determined that cooling in this area starts at 70 degrees. When I changed the CDD breakpoint from 65 to 70 degrees, the MAPE dropped to 0.63%.

In total, I reduced the model’s MAPE from 1.08% to 0.63% by using more appropriate weather data and without making any changes to the model structure.

There are two lessons here. First, we cannot assume that 65 degrees is the correct breakpoint just because it is used by the National Oceanic and Atmospheric Administration (NOAA). The best and easiest way to identify the breakpoints is to view them in a scatter plot. Second, the model informs us about the data. Specifically, if the model improves when we make a particular change, that change is probably a good idea.

Kesalahan terjadi ketika Memproses Template.
The following has evaluated to null or missing:
==> authorContent.contentFields  [in template "44616#44647#114455" at line 9, column 17]

----
Tip: It's the step after the last dot that caused this error, not those before it.
----
Tip: If the failing expression is known to legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing</#if>. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??
----

----
FTL stack trace ("~" means nesting-related):
	- Failed at: contentFields = authorContent.content...  [in template "44616#44647#114455" at line 9, column 1]
----
1<#assign 
2	webContentData = jsonFactoryUtil.createJSONObject(author.getData()) 
3	classPK = webContentData.classPK 
4/> 
5 
6<#assign 
7authorContent = restClient.get("/headless-delivery/v1.0/structured-contents/" + classPK + "?fields=contentFields%2CfriendlyUrlPath%2CtaxonomyCategoryBriefs") 
8contentFields = authorContent.contentFields 
9categories=authorContent.taxonomyCategoryBriefs 
10authorContentData = jsonFactoryUtil.createJSONObject(authorContent) 
11friendlyURL = authorContentData.friendlyUrlPath 
12authorCategoryId = "0" 
13/> 
14 
15<#list contentFields as contentField > 
16   <#assign  
17	 contentFieldData = jsonFactoryUtil.createJSONObject(contentField)  
18	 name = contentField.name 
19	 /> 
20	 <#if name == 'authorImage'> 
21	    <#if (contentField.contentFieldValue.image)??> 
22	        <#assign authorImageURL = contentField.contentFieldValue.image.contentUrl />	 
23			</#if> 
24	 </#if> 
25	 <#if name == 'authorName'> 
26	    <#assign authorName = contentField.contentFieldValue.data /> 
27			<#list categories as category > 
28         <#if authorName == category.taxonomyCategoryName> 
29				     <#assign authorCategoryId = category.taxonomyCategoryId /> 
30				 </#if> 
31      </#list> 
32	 </#if> 
33	 <#if name == 'authorDescription'> 
34	    <#assign authorDescription = contentField.contentFieldValue.data /> 
35			 
36	 </#if> 
37	  
38	 <#if name == 'authorJobTitle'> 
39	    <#assign authorJobTitle = contentField.contentFieldValue.data /> 
40			 
41	 </#if> 
42 
43</#list> 
44 
45<div class="blog-author-info"> 
46	<#if authorImageURL??> 
47		<img class="blog-author-img" id="author-image" src="${authorImageURL}" alt="" /> 
48	</#if> 
49	<#if authorName??> 
50		<#if authorName != ""> 
51			<p class="blog-author-name">By <a id="author-detail-page" href="/w/${friendlyURL}?filter_category_552298=${authorCategoryId}"><span id="author-full-name">${authorName}</span></a></p> 
52			<hr /> 
53		</#if> 
54	</#if> 
55	<#if authorJobTitle??> 
56		<#if authorJobTitle != ""> 
57			<p class="blog-author-title" id="author-job-title" >${authorJobTitle}</p> 
58			<hr /> 
59		</#if> 
60	</#if> 
61	<#if authorDescription??> 
62		<#if authorDescription != "" && authorDescription != "null" > 
63			<p class="blog-author-desc" id="author-job-desc">${authorDescription}</p> 
64			<hr /> 
65		</#if> 
66	</#if> 
67</div>