0. Introduction 
The code can be compiled in Linux or Mac by ‘make’ cmd. Our code supports multiple dependent-variable classification by modeling the interrelations among different dependent variables. In our paper, we use it as a Double Dependent-Variable Factor Graph model for inferring users’ gender and age simultaneously. Please see our paper for details.

If using this code for publications, please kindly cite the following paper:
@inproceedings{Dong:KDD14,
    author = {Yuxiao Dong and Yang Yang and Jie Tang and Yang Yang and Nitesh V. Chawla},
    title = {Inferring User Demographics and Social Strategies in Mobile Social Networks},
    booktitle = {KDD'14},
    year = {2014}
}

If using the code as a general factor graph or conditional random field, please kindly cite the following paper:
@inproceedings{Tang:11PKDD,
 author    = {Wenbin Tang and
               Honglei Zhuang and
               Jie Tang},
  title     = {Learning to Infer Social Ties in Large Networks},
  booktitle = {Proceedings of the ECML/PKDD 2011},
  year      = {2011},
  pages     = {381-397}
}


1. Implementation
./OpenCRF [-est\-estc] -niter [maximum_iteration] -gradientstep [gradient step] -trainfile [train file name] -dstmodel [model file to save] srcmodel [model file to load, only for -estc mode].
----------
example:
OpenCRF -est -niter 100 -gradientstep 0.001 -trainfile example.txt -dstmodel model.txt
OpenCRF -estc -niter 100 -gradientstep 0.001 -trainfile example.txt -dstmodel model_1.txt -srcmodel model.txt
----------
-est : Estimation mode. OpenCRF will read the train file and train the model from the first iteration.
-estc: Estimation continue mode. OpenCRF will read the train file and construct the model according to srcmodel file. Based on the model read, continue the training process.

2. Data preparation
-----------
First n line describes n variable nodes and their attribute factors in the factor graph mode. 

A line starts with character ‘g’ or ‘a’, where ‘g’ indicates the type of dependent variable (gender), and ‘a’ indicates the other type of dependent variable (age). ‘g’ or ‘a’ can be replaced by any character for your application. The number of dependent variables are not limited to 2. 

If you have only one kind of dependent variable, for example, you want to infer the gender of one user, each line should start with the same character ‘g’ (any character works). In this case, this model can be used as a general factor graph model or conditional random field.

The following character starts with '?' or '+', where '?' indicates the label of this node is UNKNOWN, while '+' implies a known label. The following character is the label of this node. Note that even if we assume the label is unknown for the model, you can still give the label here, if it is actually available. The model will ignore the label of '?' sample during the training process, but it can be used in the evaluation. Separated by space, the rest tokens in a line are organized as "[feature name]:[feature value]", depicting the attributes of the node. The feature format is similar to the input of LibSVM The feature value can be a real number, and the feature name should be a string without space. 

-----------
After the first n lines, the following lines are starts with ‘#edge’. They establish the factors between nodes. The factors can only be established in two nodes. A line started by "#edge", followed by two positive integers i and j, indicates a factor between node i and node j. (Node described in the i-th line of this file is node i) At the end of this line is a string, indicating the name of this factor. Factors with the same name share the same form of function g(yi, yj). 

-----------
The following lines starting with ‘#triangle’ establish the factors between triads. The factors can only be established in three nodes. A line started by “#triangle”, followed by three positive integers i, j, and k, indicates a factor among node i, node j, and node k. (Node described in the i-th line of this file is node i) At the end of this line is a string, indicating the name of this factor. Factors with the same name share the same form of function h(yi, yj, yk). 

The lines starting with ‘#edge’ or ‘#triangle’ are not necessary for our model.

-----------
example:
g       +1	10003:1 20000:1 30010:1 40008:1 50004:1
a       ?0      10003:1 20000:1 30010:1 40008:1 50004:1
g       ?1      10011:1 20002:1 30000:1 40031:1 50002:1
a       +1      10011:1 20002:1 30000:1 40031:1 50002:1
g       +0      10005:1 20000:1 30020:1 40011:1 50001:1
a       +1      10005:1 20000:1 30020:1 40011:1 50001:1
#edge 1 2 1circle1
#edge 1 3 1circle1
#edge 2 3 2circle1
#edge 1 4 1circle2
#edge 5 6 5circle1
#triangle 1 2 3 mmm


3. Output
The accuracy, precision, recall, and F1-score are calculated in each iteration, over both the sets of All nodes and Unlabeled nodes. Note that the result is only valid for binary classification. OpenCRF will take the label of the first line as "positive" label. 
"pred.txt" gives the prediction result of all the nodes (including known nodes). The result is presented by the label id. 0 represents the first kind of label detected in the train file, 1 represents the second kind of label encountered in the file, 2 for the third kind of label, etc. 
"marginal.txt" gives the marginal probability of each label for every node. Each line, the marginal probability is presented in the order of label id (p(y=label0), p(y=labe1), p(y=label2)....) 