Analyzing Conjoints
After finishing data collection, the data needs to be modeled and subsequently analyzed. While there are many ways (e.g., Sawtooth, Qualtrics or DisplayR software), we like to have control of the process and analyze it all directly in our own R environment. In fact, we’ve built an entire package dedicated to analyzing conjoint data:
g6tr.cjt
Before we dive into our package, it’s important to understand the math and methodology behind the conjoint estimation process.
There are different ways to analyze the data collected in a conjoint study. The most important methods are Aggregate Logit, Latent Class and CBC HB. They respectively provide utilities for the whole respondents population, for homogeneous groups in the population and for each component of the population.
In this model the whole population of respondents is considered in its integrity. The result is a single set of utilities for the whole population. Intuitively, the resulting utilities describe an average of the population preferences. Aggregate estimation assumes that the respondent utility is equal to the average utility, which is a quite restrictive assumption and does not allow for idiosyncratic, individual effects in the sample, meaning that heterogeneity in the sample is simply not considered. This was the first model ever implemented to analyze conjoint data.
Cluster analysis is, historically speaking, the evolution of aggregate estimation. It was developed to allow for some form of respondents heterogeneity. Clustering algorithms find groups of individuals with similar tastes among the whole sample. The preferences of the individuals are estimated in a ”semi individual” way by assuming that the respondent utility is equal to the cluster utility, allowing for heterogeneities across segments of respondents but not within the cluster. To allow for heterogeneity between single respondents, HB models were created. Clustering models are still very important in their own respect. From a commercial point of view it is very important to divide the market in segments that have similar tastes.
Latent Class estimation detects subgroups of respondents with similar preferences and estimates utilities for each segment. Each respondent is given a probability to being part of a certain group. It is possible to specify how many groups are to be considered. There are criteria (notably the Akaike criterion) to decide the optimal number of groups to consider.
HB methods are the newest and currently most used estimation methods in quantitative marketing research. The name CBC HB means ”Choice Based Conjoint - Hierarchical Bayes”. The mathematical specification of these model is a Bayesian hierarchical model in which, broadly speaking, a different vector of utility is define for each respondent. The distribution of these utilities in the whole population has some specified form, usually normal. CBC HB allows for heterogeneity at a respondent’s level by specifying different utilities for each respondent. This leads to a greater improvement in simulation techniques: simulation conducted using aggregate or clusterized models often lead to biased results. At Gradient, most of our models will be estimates using HB methods
There is way to much information to summarize on this page, but if you want to learn more about Conjoints and the methodologies, please refer to the links below:
As mentioned before, we have built our own package, called
g6tr.cjt which allows you to use both R’s ChoiceModelR or a STAN (Bayesian Models) interface to estimating utilities. Below, we’ve laid out a few simple steps on how to use our package, but for more detail we refer you to the
Conjoint Analysis Workflow Vignette that has a lot more detail.
This package contains a set of functions to help you analyze the survey responses. The functions follow a straightforward path and should be used in succession, they are nigh useless on their own. For a complete overview, please take a look at the vignette.
The path of functions goes like this:
cjt_data <- cjt_read_data(data)
Read conjoint data and return a list with Design and Answers data frames, suitable for the rest of the cjt_ functions family. Check ?cjt_read_data for more information.
cjt_data_asserted <- cjt_assert_data(cjt_data)
This function takes the cjt_read_data() object as input and will assert if the data is correct. If it’s not, it will tell you where changes need to be made to the initial dataframe, or make the changes automatically. E.g. filtering respondents and checking if all design elements are correct. Check ?cjt_assert_data for more information.
cjt_data_tidied <- cjt_tidy_data(cjt_data_asserted)
This function takes the output from cjt_assert_data() and tidies the design and answers data frame so that we can use it for modeling. This is the most important piece, and is also likely the cause of any issues if modeling doesn’t work as intented. Check ?cjt_tidy_data for more information.
cjt_data_model <- cjt_model_data(cjt_data_tidied)
This function takes the output from cjt_tidy_data() and puts the model_data into the specified model. There are currently two options for model; the base ChoiceModelR and a custom-made STAN model. Check ?cjt_model_data for more information.
cjt_stats <- cjt_summary_stats(cjt_data_model)
What we care about. This function calculates individual importance scores and choice utilities from the model.