May 22, 2020

Data Measurement and Analysis for Software Engineers

  —A look at measurement and its application in software engineering.

In Data Measurement and Analysis for Software Engineers, I go through Part 1 of a talk by Dennis J. Frailey. Part 1 describes scales of measurement and the importance of understanding which statistical operations make sense on those scales. Scales are important because they define the properties of what is being measured.

Part 2 looks at basic analysis techniques for software engineering and what makes a good measurement process. Importantly,

If you only measure the code, you will probably not really understand your software or its development process.

Why? Because many software products are not code. They include specifications, design models, tests, etc. An error in a software product can result in errors in those that depend upon it.

Measurement smells:

  • Requirements are not measurable.
  • Activities are not measured.
  • Software quality attributes are not measured or modeled.
  • Performance of tools and methods employed are not based on factual data.

The countermeasure to these smells is the measurement process. It

  • establishes a measurement program,
  • implements a measurement program and
  • evaluates the measurements.

The International Standard for Software Measurement Processes (ISO/IEC/IEEE 15939) describes describes a set of criteria for a good measuring process. It does not define a process but tells you what a good process should be like.

A good measurement process requires establishing what your information needs are. Identifying what to measure is the subject of The Goal/Question/Metric (GQM) Paradigm.

The webinar walks through a process for metrics.

  1. Organize the base measures (stuff we measure) by refining or compressing it. This ensures that data comprising base measures is consistent.
  2. Compute derived measures from base measures. This ensures that derived measures are directed at fulfilling information needs.

Base measures must be established with consideration of their scales of measure. This determines the meaningful statistic calculations as part of the derived measures.

The use of probability distributions and statistics is the subject of the third webinar. This includes discrete and continuous functions.

April 29, 2020

Data Measurement and Analysis for Software Engineers

  —A look at measurement and its application in software engineering.

This post is motivated by a series of SIGSOFT webinars by Dennis J. Frailey entitled Fundamentals of Measurement and Data Analysis for Software Engineers. Part I lays out the foundation of measurement theory for software engineering. The first webinar includes a field chart for scales and permitted operations. It’s worth the price of admission.

The ultimate goal for software metrics is to help software professionals … make decisions under uncertainty.

Why do we measure? To make things more visible and controllable. Better information leads to more informed decision making. The key is proper selection, collection, analysis and interpretation of metrics.

In discussing the analysis and interpretation, Frailey references a paper by Stanley S. Stevens entitled On the Theory of Scales of Measurement. This paper weighs in at 3 pages and tells a story of the challeges in creating a definition of measurement. They arrived at

measurement is the assignment of numerals to objects or events according to rules.

The paper sets out to make explicit

  • the rules for assigning numerals,
  • the mathematical properties of the resulting scales and
  • the statistical operations permitted on each scale.

Misunderstanding scales and the statistical analysis on measures in those scales leads to poor decisions.

Frailey refines the definition of measurement using Fenton’s definition:

Measurement is
… the process by which
numbers or symbols
are assigned to
attributes of entities in the real world
in such a way so as to
describe them acording to clearly defined rules.

Importantly,

The assignment of numbers must preserve the intuitive and empirical observations about the attributes and entities.

Entities, Attributes and Values of Attributes

Attributes are features, properties or characteristics that allow us to distinguish entities from each other or compare and evaluate entities.

Attributes are often measured by numbers or symbols–numbers don’t always make sense. They permit distinguishing entities or comparing them. An attribute is a property or characteristic of an entity that can distinguish them quantitatively or qualitatively.

A defect identifier is best represented as a unique symbol (e.g., BUG-1). An estimate and time spent on a defect is represented as a unit of time; severity is a category (e.g., High (H) and Low (L)).

Basic Rules and Principles

Measures should lead to useful information–you should have a purpose for every measure. Alternatively, don’t collect measures if you don’t know how they will be consumed. It’s pointless and distracting.

A consistent set of rules can indicate the type of measurement results. In most cases, formulation of the rules of assignment determines the nature of the scale. If there is any ambiguity the group formed by the scale–and the what ways it be transformed and still serve it’s function? Measurement is never better than the empirical operations by which it is carried out.

If our product backlog comprises stories and defects it is meaningful to count them within their respective categories. It is meaningful to count the defects attributed to a story.

Comparing stories to defects is meaningless unless a comparison can be made with time spent or estimates. Since stories lack a severity attribute they are different from defects. This difference prevents direct comparison.

Good measures rely upon a model that reflects a specific viewpoint.

  • What we are going to measure?
  • What attribute are we collecting data on?

Identifying what to measure is the subject of The Goal/Question/Metric (GQM) Paradigm. It is also the realm of the scientific method.

A measure is a variable to which a value is assigned as a result of measurement. Data is a collection of values assigned to measures. Identifying how to measure something lies in the realm of measurement theory.

Measurement theory differentiates between base and derived or calculated measures.

  • A base measure or direct measure is a direct quantification of an attribute. It is generated through observation of the thing being measured (e.g., time spent on a story or defect).

  • A calculated or derived measure is a measure defined in terms of other measures. They are new measures defined in terms of base measures (e.g., the average number of hours spent on defects).

Measurement involves the assignment of numbers to attributes of the entities being observed. That assignment determines how the entity is classified and what statistical operations have meaning on that object. The analysis of measures requires understanding the scales of measurement.

Scales of Measurement

A scale of measure is also known as a level. They help us understand what we are seeing.

A scale is a collection of symbols or numbers used to classify attributes of entities. It is a system for describing the nature of information.

Different scales have different properties. Those properties determine which forms of analysis are appropriate on them.

Stevens classifies scales into the following groups.

  • nominal
  • ordinal
  • interval
  • ratio

The further down this list the more sophisticated analysis you can perform.

Nominal Scale

Nominal scale enables categorization but does not support ordering. In these scales, numbers and symbols are used only as labels. For example, colour and a football jersey number used to identify a player are both nominal scales. (Colour has a natural order if you look at wavelength, but let’s ignore this for purposes of this example.).

You can count the size or frequency (mode) of each category. There is no average or a median nor is there a natural category ordering.

In a nominal scale you can easily count stories and defects and identify individual objects using the identifier. There is no way to determine which story should be ordered before another.

You can use numbers to categorize a nominal scale but there is no numerical meaning. Changing the shape assigned to stories does not change the scale. Likewise changing the label “Story” does not change the scale-there are still three objects in the category.

In a nominal scale, do not assign the same numeral or symbol to different categories or different numerals and symbols to the same category. For example, Story and Defect are assigned different shape to differentiate them. If they had been assigned the same shape they would be indistinguishable from each other.

Ordinal Scale

Ordinal scales enable ranking or ordering the data. For example, the serverity of defects are often ordered as high, medium and low, so defects can be ranked by severity.

Items in an ordinal scale can be sorted. This permits the middle item to be identified. Ordinal items do not support the notion of average (and hence standard deviation). There is no mathematical relationship between ordinal values–the degree of distance between categories is not defined.

Stevens says that averages and standard deviations computed on ordinals are in error to the extent that successive intervals on the scale are unequal. Percentages are dangerous if interpolating linearity within a class interval. Likewise, interpolating the mid-point in a class interval using linear interpolation is dangerous because linearity in an ordinal scale is an open question.

Interval Scale

Interval scales are ordered and there is a fixed distance between consequtive members. Examples include dates, times and temperatures.

Given any two dates (times or temperatures), you can count the number of intervals between any two points on the scale. You can add or substract values, order them and calculate the distance between any two of them. You cannot multiply or divide or calculate a ratio. There is no true zero (e.g., when time began).

Computing ratios of intervals is a common error–so a ratio of the time start of two stories or the start and end times for a story is meaningless. You can compute ratios between differences. It is fine to say the ratio of time spent on two different stories is double or half of the other.

The zero point on an interval scale is usually a matter of convenience (e.g., Centigrade and Fahrenheit temperatures in comparison with Kelvin).

Ratio Scale

Ratio scales support multiplication and division. They support equality, rank-ordering, equality or intervals and equality of ratios. There is a true zero. They are commonly encountered in physics.

An example of a ratio scale is speed.

Ratio scales are either fundamental or derived. A fundamental scale measures a true value (e.g., speed). A derived scale is a function of one or more values from a fundamental scale (e.g., acceleration) All types of statistical measures are applicable. You can compute an average or mean (and thus standard deviation).

Absolute Scale

An absolute scale is a scale where all mathematical operations (e.g., average and exponentiation) are meaningful. It is a system of measurement that begins at a minimum, or zero point, and progresses in only one direction.

Pressure, length, area and volume are all measured using an absolute scale.

Sample Size

Suppose you have a large number of entities. How many are needed to make a predictions about them? Sample size is the number of entities to measure in ensure meaningful predictions.

To determine a the sample size, how many entities needs to be understood. The total number of entities is the population.

To make meaningful predictions the proportion of sample size relative to the population count is needed. Sampling data includes margin of error and sample size. Sample size depends upon the circumstances (what is the size of your sample as a percentage of total, how well have you selected your sample)?

A sample size of 1% is less useful than one representing 10% or 20% of the population. Need to consider what proportion of the population is included in the sample size–the larger the sample size the better.

Resources

Some of these resources make me wonder if some of the learning in psychology on creating measures is applicable to software metrics. Not thinking Likert but more about methodology and identification.

This thinking contradicts a little of what On the Application of Measurement Theory in Software Engineering says, but not entirely. An interesting question when posed in the context of some discussion in Statistics and the Theory of Measurement and Measurement Theory with Applications to Decisionmaking, Utility, and the Social Sciences.

Suppes thought through measurement on many different levels. Methodology, Probability and Measurement. A great resource but a hard read.

April 23, 2020

Another Look at Base Rate Fallacy for Shared Resources

  —Logical fallacy and broken models.

Here’s another look at the base rate fallacy I discused in Logical Fallacy and Memory Allocation when applied to a shared resource. I’ll use memory allocation again.

This is a contrived example. I am not suggesting this anaylsis is correct. In fact, I’m trying to show the opposite (the fallacy of this approach).

Make sense?

%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

df = dict()

Let \(P(E = n)\) be the probability of the event occurring.

We know that \(P(E = 1) = 1\), because this user initiated event must occur at least once in order to use the system.

Assume most users will have \(n > 1\). Assume that \(P(E = 2) = \frac{1}{2}\), \(P(E = 3) = \frac{1}{3}\) and \(P(E = n) = \frac{1}{n}\), for \(1 \le n \le 300\).

The probability distribution function can be any function showing the probability of an event decreasing as the number of events increases.

def event_pdf(n):
    """Calculate the probability of the event occuring."""
    return 1 / n

df['P(E = n)'] = [ event_pdf(n) for n in range(1, 301) ]
for n in [ 0, 1, 2, 299]:
    print("P(E = {:3}) = {:1.3f}".format(n + 1, df['P(E = n)'][n]))
P(E =   1) = 1.000
P(E =   2) = 0.500
P(E =   3) = 0.333
P(E = 300) = 0.003

Let \(P(C)\) be the probability of system memory being exhausted.

Then \(P(C \vert E = n) = \frac{P(C) \cap P(E = n)}{P(C)}\).

Assume \(P(C \vert E = n) = 0\) for all \(1 \le n < 300\) and \(P(C \vert E = 300) = 1\). That is memory exhaustion only occurs when \(300^{th}\) event occurs.

(The careful reader will note the flaw here. While true the system crashes upon the \(300^{th}\) event, it is wrong to consider this in isolation. But lets continue our argument with this flaw.)

def crash_given_event(n):
    """Calculate the probability of P(C|E = n)."""
    return 0 if n < 299 else 1

df['P(C|E = n)'] = [ crash_given_event(n) for n in range(0, 300) ]

We know \(P(C \vert E = 1) = 0\) and \(P(C \vert E = 300) = 1\).

for n in [0, 1, 2, 299]:
    print("P(C|E = {:3}) = {:1.3f}".format(n, df['P(C|E = n)'][n]))
$$P(C \vert E =   0) = 0.000$$
$$P(C \vert E =   1) = 0.000$$
$$P(C \vert E =   2) = 0.000$$
$$P(C \vert E = 299) = 1.000$$

Let \(M(E = n)\) be the proportion of memory consumed at the completion of the \(n^{th}\) event.

We know that \(M(E = 300) = 1\) and \(M(E = 1) = 0.75\). We know each event consums \(0.0875\)% of remaining memory.

def memory(n):
    """Determine percentage of consumed memory."""
    if 0 == n:
        return 0.75
    elif 299 == n:
        return 1
    else:
        return 0.75 + (n * 0.000875)
    
df['Memory (% Used)'] = [ memory(n) for n in range(0, 300) ]

We know that the system exhausts available memory immediately when the \(300^{th}\) event occurs.

fig,ax = plt.subplots()

for name in ['P(C|E = n)','P(E = n)', 'Memory (% Used)']:
    ax.plot(df[name],label=name)
    
ax.set_ylabel("probability")
ax.set_xlabel("event number")
ax.set_title('system outage')
ax.legend(loc='right')
$$\text{The model} P(C \vert E = n)$$.
$$\text{The model} P(C \vert E = n)$$.

The system outage graph above is our model of the memory leak if we reason about the leak in isolation.

We can improve this model significantly and still make the same error.

def crash1_given_event(n):
    """Calculate the probability of P(C1|E = n)."""
    return 1 / (300 - n)

df['P(C1|E = n)'] = [ crash1_given_event(n) for n in range(0, 300) ]
fig,ax = plt.subplots()

for name in ['P(C1|E = n)','P(E = n)', 'Memory (% Used)']:
    ax.plot(df[name],label=name)
    
ax.set_ylabel("probability")
ax.set_xlabel("event number")
ax.set_title('system outage')
ax.legend(loc='best')

The model \(P(C1|E = n)\) considers the increase in probability of a crash as the number of events increases. Better, but flawed. Flawed because memory is a shared resource.

The model should look something like \(P(C1 \vert E = n, F, G, \ldots)\), where \(F\) and \(G\) are other events affecting memory.

These models are positioned a probability distributions of different events in memory. These make for nice discussion points and reflect the fact that the underlying arguments are probability based.

In my opinion, a better approach is to count the bytes allocated and freed and map this over time and across different use cases.

March 31, 2020

The Goal/Question/Metric (GQM) Paradigm

  —A look at a framework for creating well-aligned software metrics.

In McCall’s Software Quality Model, I discussed a paper tying quality factors to quality criteria. That model takes quality criteria coupled with metrics collected throughout the lifecycle to provide feedback on quality. What’s missing from this model is a discussion on how to arrive at good metrics.

The Goal/Question/Metric (GQM) Paradigm provides a framework published in 1994 for arriving at good measures.

Measurement is a mechanism for creating a corporate memory and an aid in answering a variety of questions associated with the enactment of any software process.

Measurement also helps, during the course of a project, to assess its progress, to take corrective action based on this assessment, and to evaluate the impact of such action.

I like this framework when its coupled with the quality criteria in McCall’s model. What follows is a brief description of GQM and how I think it complements McCall’s model.

GQM must be applied top-down and focus on goals and models. An organization must identify goals and trace those goals to data intended support to those goals operationally. Then provide a framework for interpreting the data with respect to its goals.

An object is the focus of measurement. Objects can be resources, processes or projects.

  • Goals are defined for an object that is to be the focus of measurement. A goal is characterized by a purpose, issue and viewpoint (or perspective). An object is a product (something that is produced), process (an activity) or resource (something consumed).

  • Questions connect the object of measurement to a quality issue. They determine the quality from the viewpoint.

  • Metrics are associated with every question. Metrics are objective if they are the same regardless of viewpoint and are subjective if they depend upon the viewpoint.

A GQM model is developed by identifying a set of quality or productivity goals. Questions are derived for object of measurement to define the goal as completely as possible. Metrics are developed to answer those questions.

Goals are developed from policy and strategy, process and product descriptions and viewpoint to develop the measurement.

Quality factors in McCall’s model affect product operation (fufills specification), translation (ability to adapt software) or revision (ability to change software). These are similar to architectural quality attributes–a measurable or testable property of a system used to indicate how well the system satisfies the needs of its stakeholders. Basili’s GQM cites McCall’s model and identifies it as another means of defining Software Quality Metrics.

The chief contribution of GQM over McCall’s model is the explicit introduction of goals coordinates based upon viewpoint, purpose, issue and object. The explicitness of the goal coordinates creates a wider perspective for goals.

I like the complement between architectural quality attributes, McCall’s quality model, where criteria is identified to measure attributes, and the GQM idea of tying viewpoint to metric.

The Goal/Question/Metric Paradigm overlaps and refines McCall’s Software Quality Model as follows.

Here, goals create quality factors, an extension of the original concept to explicitly include a wider varienty of objects.

I don’t differentiate between the current notion of software architecture quality attributes and quality factors. I see GQM’s notion of goal as a superset because a goal might include resource, time, defects, etc. I view quality attributes as non-behavioural requirements.

Questions aided by goal coordinates motivate quality criterion that connect goals to metrics.

Metrics are an extension over quality measures because they explicitly include subjective and objective measures. Not necessarily missing from McCall’s model but not explicitly called out either.

March 25, 2020

Logical Fallacy and Memory Allocation

  —Sometimes a person's reasoning is flawed. Sometimes that affects a whole team.

I’m astounded that a memory leak was permitted to exist for several years in a product I work on. Furthermore, the history of this leak included discussion, capture, diagnosis and tests to ensure the size didn’t change. Fixing it took four days.

To put this in perspective, the leak consumes 0.0875% of system memory. The event triggering the leak need occur 300 times to bring the system down. The trigger is the result of a user initiated operation.

Okay. These things happen. What I didn’t count on was the response to the rediscovery of this issue. I guess I should have expected the response given the history of this issue. Still it was weird.

Which brings me to the logical fallacy about the reasoning that led to this leak’s long life.

Several arguments were made on why we shouldn’t fix the leak.

  1. Cost: we should work on something “more important”. A reflection of the time this leak existed but not the effort that had been put into managing it thus far.

  2. Use case: no user would ever trigger so many of these events. An arrogant or naive opinion on how real users use the system but no recognition of the lack of concrete data to support this.

  3. Availability: without an availability requirement we can evaluate the trade-off. A variation of the cost argument veiled by a requirements issue (e.g., we don’t know if we need to fix it).

Okay. These are rational arguments on some level. They are irrational on many.

First, cost doesn’t make any sense unless we know the cost to fix the leak. The cost to discover and rediscover this issue was much larger than the cost of correction.

Second, the use case isn’t helpful unless we know how every user uses the system. We don’t.

Third, availability doesn’t make any sense unless we have some way to reason about the second argument.

The biggest issue is that memory is a shared resource. You can’t reason about the memory usage of one component without considering the others.

Reasoning about the behaviour of memory allocation for a system component in isolation is a base rate fallacy. You can’t make a probability judgment based on conditional probabilities, without taking into account the effect of prior probabilities.

Since we don’t know the prior probabilities of events we can’t make a judgement about the impact of this leak on users. We really have no choice except to fix it.

My stakeholders will rejoice.

For another look at the fallacy of reasoning about bugs in isolation: Code Matters.