Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new phase updateLabel implementation #58 #102

Merged
merged 1 commit into from
Jan 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion client/src/main/java/zingg/client/ZinggOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ public enum ZinggOptions {
FIND_TRAINING_DATA("findTrainingData"),
LABEL("label"),
LINK("link"),
GENERATE_DOCS("generateDocs");
GENERATE_DOCS("generateDocs"),
UPDATE_LABEL("updateLabel");

private String value;

Expand Down
129 changes: 129 additions & 0 deletions core/src/main/java/zingg/LabelUpdater.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package zingg;

import java.util.List;
import java.util.Scanner;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.spark.sql.Column;
import org.apache.spark.sql.Dataset;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.SaveMode;

import zingg.client.ZinggClientException;
import zingg.client.ZinggOptions;
import zingg.client.pipe.Pipe;
import zingg.client.util.ColName;
import zingg.client.util.ColValues;
import zingg.util.DSUtil;
import zingg.util.PipeUtil;

public class LabelUpdater extends Labeller {
protected static String name = "zingg.LabelUpdater";
public static final Log LOG = LogFactory.getLog(LabelUpdater.class);

public LabelUpdater() {
setZinggOptions(ZinggOptions.UPDATE_LABEL);
}

public void execute() throws ZinggClientException {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rename getUnmarkedRecords in labeller to getRecordsToProcess, call that in execute. In this class, override that method so that you do not have to override execute here

try {
LOG.info("Reading inputs for updateLabelling phase ...");
Dataset<Row> markedRecords = PipeUtil.read(spark, false, false, PipeUtil.getTrainingDataMarkedPipe(args));
processRecordsCli(markedRecords);
LOG.info("Finished updataLabelling phase");
} catch (Exception e) {
e.printStackTrace();
throw new ZinggClientException(e.getMessage());
}
}

public void processRecordsCli(Dataset<Row> lines) throws ZinggClientException {
LOG.info("Processing Records for CLI updateLabelling");
getMarkedRecordsStat(lines);
printMarkedRecordsStat();
if (lines == null || lines.count() == 0) {
LOG.info("There is no marked record for updating. Please run findTrainingData/label jobs to generate training data.");
return;
}

List<Column> displayCols = DSUtil.getFieldDefColumns(lines, args, false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

displaycols is redundant, we use df.show so i doubt if it being used. please check

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, overall is there a way to abstract the logic - reading and quitting at 9, displaying some stuff, accepting user input, doing some action(update/mark) in the base class and only override the relevant methods in the update labeller class?

try {
int matchFlag;
Dataset<Row> updatedRecords = null;
Dataset<Row> recordsToUpdate = lines;
int selectedOption = -1;
String postMsg;

Scanner sc = new Scanner(System.in);
do {
System.out.print("\tPlease enter the cluster id (or '9' to exit): ");
String cluster_id = sc.next();
if (cluster_id.equals("9")) {
LOG.info("User has exit in the middle. Updating the records.");
break;
}
Dataset<Row> currentPair = lines.filter(lines.col(ColName.CLUSTER_COLUMN).equalTo(cluster_id));
if (currentPair.isEmpty()) {
System.out.println("\tInvalid cluster id. Enter '9' to exit");
continue;
}

matchFlag = currentPair.head().getAs(ColName.MATCH_FLAG_COL);
postMsg = String.format("\tCurrent Match type for the above pair is %d\n", matchFlag);
selectedOption = displayRecordsAndGetUserInput(DSUtil.select(currentPair, displayCols), "", postMsg);
updateLabellerStat(selectedOption, matchFlag);
printMarkedRecordsStat();
if (selectedOption == 9) {
LOG.info("User has quit in the middle. Updating the records.");
break;
}
recordsToUpdate = recordsToUpdate
.filter(recordsToUpdate.col(ColName.CLUSTER_COLUMN).notEqual(cluster_id));
if (updatedRecords != null) {
updatedRecords = updatedRecords
.filter(updatedRecords.col(ColName.CLUSTER_COLUMN).notEqual(cluster_id));
}
updatedRecords = updateRecords(selectedOption, currentPair, updatedRecords);
} while (selectedOption != 9);

if (updatedRecords != null) {
updatedRecords = updatedRecords.union(recordsToUpdate);
}
writeLabelledOutput(updatedRecords, SaveMode.Overwrite);
sc.close();
LOG.info("Processing finished.");
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
e.printStackTrace();
}
LOG.warn("An error has occured while Updating Label. " + e.getMessage());
throw new ZinggClientException(e.getMessage());
}
return;
}

private void updateLabellerStat(int selectedOption, int existingType) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have one method updateLabellerstat(selectedOption, existingType, increment) in base class and call that with increment +1 there or -1 here

--totalCount;
if (existingType == ColValues.MATCH_TYPE_MATCH) {
--positivePairsCount;
}
else if (existingType == ColValues.MATCH_TYPE_NOT_A_MATCH) {
--negativePairsCount;
}
else if (existingType == ColValues.MATCH_TYPE_NOT_SURE) {
--notSurePairsCount;
}
updateLabellerStat(selectedOption);
}

void writeLabelledOutput(Dataset<Row> records, SaveMode mode) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

define method getPipeForRecordsTowrite in base class. override it here with SaveMode. call it in writeLAbelledOutput in base class.

if (records == null) {
LOG.warn("No marked record has been updated.");
return;
}
Pipe p = PipeUtil.getTrainingDataMarkedPipe(args);
p.setMode(mode);
PipeUtil.write(records, args, ctx, p);
}
}
22 changes: 13 additions & 9 deletions core/src/main/java/zingg/Labeller.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,21 @@ public Dataset<Row> getUnmarkedRecords() throws ZinggClientException {
unmarkedRecords = unmarkedRecords.join(markedRecords,
unmarkedRecords.col(ColName.CLUSTER_COLUMN).equalTo(markedRecords.col(ColName.CLUSTER_COLUMN)),
"left_anti");
positivePairsCount = markedRecords.filter(markedRecords.col(ColName.MATCH_FLAG_COL).equalTo(ColValues.MATCH_TYPE_MATCH)).count() / 2;
negativePairsCount = markedRecords.filter(markedRecords.col(ColName.MATCH_FLAG_COL).equalTo(ColValues.MATCH_TYPE_NOT_A_MATCH)).count() / 2;
notSurePairsCount = markedRecords.filter(markedRecords.col(ColName.MATCH_FLAG_COL).equalTo(ColValues.MATCH_TYPE_NOT_SURE)).count() / 2;
totalCount = markedRecords.count() / 2;
getMarkedRecordsStat(markedRecords);
}
} catch (Exception e) {
LOG.warn("No unmarked record for labelling");
}
return unmarkedRecords;
}

protected void getMarkedRecordsStat(Dataset<Row> markedRecords) {
positivePairsCount = markedRecords.filter(markedRecords.col(ColName.MATCH_FLAG_COL).equalTo(ColValues.MATCH_TYPE_MATCH)).count() / 2;
negativePairsCount = markedRecords.filter(markedRecords.col(ColName.MATCH_FLAG_COL).equalTo(ColValues.MATCH_TYPE_NOT_A_MATCH)).count() / 2;
notSurePairsCount = markedRecords.filter(markedRecords.col(ColName.MATCH_FLAG_COL).equalTo(ColValues.MATCH_TYPE_NOT_SURE)).count() / 2;
totalCount = markedRecords.count() / 2;
}

public void processRecordsCli(Dataset<Row> lines) throws ZinggClientException {
LOG.info("Processing Records for CLI Labelling");
printMarkedRecordsStat();
Expand Down Expand Up @@ -105,6 +109,7 @@ public void processRecordsCli(Dataset<Row> lines) throws ZinggClientException {

selected_option = displayRecordsAndGetUserInput(DSUtil.select(currentPair, displayCols), msg1, msg2);
updateLabellerStat(selected_option);
printMarkedRecordsStat();
if (selected_option == 9) {
LOG.info("User has quit in the middle. Updating the records.");
break;
Expand All @@ -124,7 +129,7 @@ public void processRecordsCli(Dataset<Row> lines) throws ZinggClientException {
}


private int displayRecordsAndGetUserInput(Dataset<Row> records, String preMessage, String postMessage) {
protected int displayRecordsAndGetUserInput(Dataset<Row> records, String preMessage, String postMessage) {
//System.out.println();
System.out.println(preMessage);
records.show(false);
Expand All @@ -134,7 +139,7 @@ private int displayRecordsAndGetUserInput(Dataset<Row> records, String preMessag
return selection;
}

private Dataset<Row> updateRecords(int matchValue, Dataset<Row> newRecords, Dataset<Row> updatedRecords) {
protected Dataset<Row> updateRecords(int matchValue, Dataset<Row> newRecords, Dataset<Row> updatedRecords) {
newRecords = newRecords.withColumn(ColName.MATCH_FLAG_COL, functions.lit(matchValue));
if (updatedRecords == null) {
updatedRecords = newRecords;
Expand Down Expand Up @@ -200,7 +205,7 @@ int readCliInput() {
return selection;
}

private void updateLabellerStat(int selected_option) {
protected void updateLabellerStat(int selected_option) {
++totalCount;
if (selected_option == ColValues.MATCH_TYPE_MATCH) {
++positivePairsCount;
Expand All @@ -211,10 +216,9 @@ else if (selected_option == ColValues.MATCH_TYPE_NOT_A_MATCH) {
else if (selected_option == ColValues.MATCH_TYPE_NOT_SURE) {
++notSurePairsCount;
}
printMarkedRecordsStat();
}

private void printMarkedRecordsStat() {
protected void printMarkedRecordsStat() {
String msg = String.format(
"\tLabelled pairs so far : %d/%d MATCH, %d/%d DO NOT MATCH, %d/%d NOT SURE", positivePairsCount, totalCount,
negativePairsCount, totalCount, notSurePairsCount, totalCount);
Expand Down
1 change: 1 addition & 0 deletions core/src/main/java/zingg/ZFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public ZFactory() {}
zinggers.put(ZinggOptions.TRAIN_MATCH, TrainMatcher.name);
zinggers.put(ZinggOptions.LINK, Linker.name);
zinggers.put(ZinggOptions.GENERATE_DOCS, Documenter.name);
zinggers.put(ZinggOptions.UPDATE_LABEL, LabelUpdater.name);
}

public IZingg get(ZinggOptions z) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
Expand Down