ML model "Parse issue" expected ;

I built an ML model "PatientFlowModel.mlmodel" using MLClassifier to import a data table in a Swift playground.


I am trying to integrate the model it built into an objective C app in xcode 10 beta 4. When I add the model to the app I am getting an error. The error is a "Parse issue" saying it expected a ; in the PatientFlowModel.m file. The header file is automatically generated so I am assuming that this file is automatically generated by the model too.


The application won't build and I can't figure out what is causing this error or how to fix it.


Is this a bug with the xcode 10 beta 4?


I'm stuck. Any help is appreciated.

Accepted Reply

After looking at this some more this moring I found a work around. I went back to the table of data and removed the spaces from the column heading Day of Week (it was the first column in the CSV file) so that it was DayOfWeek and the code generated correctly. The funny thing is that the other column headings in the table have spaces and it inserts the underscore for them fine.


I think it may be a bug with the automatic code generator. Either fix the generator to consistently insert the underscore in all column headers or change the documentation to indicate column headers should contain no spaces.


Anyway the workaround worked and everything is now working now.


Thanks for looking at this you got me thinking!

Replies

Could you post the PatientFlowModel.m ?

Here it is. There error is on this line. It wants a ; before the o in Day of Week:


PatientFlowMLInput *input_ = [[PatientFlowMLInput alloc] initWithDay of Week:Day_of_Week


//

// PatientFlowML.m

//

// This file was automatically generated and should not be edited.

//


#import "PatientFlowML.h"


@implementation PatientFlowMLInput


- (instancetype)initWithDay_of_Week:(double)Day_of_Week ED_Arrival_Time:(NSString *)ED_Arrival_Time ED_Arrival_To_Triage:(double)ED_Arrival_To_Triage ED_Triage_To_ED_Room:(double)ED_Triage_To_ED_Room ED_Room_To_ED_Doctor:(double)ED_Room_To_ED_Doctor EDDoctor_Time:(NSString *)EDDoctor_Time ED_Doctor_To_Bed_Request_Start:(NSString *)ED_Doctor_To_Bed_Request_Start EDBed_Req_Start_Time:(NSString *)EDBed_Req_Start_Time Bed_Request_Start_To_Complete:(double)Bed_Request_Start_To_Complete Total_ED_Time:(NSString *)Total_ED_Time Bed_Request_Complete_To_IP_Conversion:(double)Bed_Request_Complete_To_IP_Conversion Bed_Request_Complete_To_Bed_Assignment:(double)Bed_Request_Complete_To_Bed_Assignment TTBed_Assignment_Time:(NSString *)TTBed_Assignment_Time Bed_Assign_To_Previous_Patient_Discharge:(double)Bed_Assign_To_Previous_Patient_Discharge Bed_Assign_To_Bed_Clean:(double)Bed_Assign_To_Bed_Clean Bed_Clean_To_IP_Bed_Check_in:(double)Bed_Clean_To_IP_Bed_Check_in Bed_Checkin_Time:(NSString *)Bed_Checkin_Time Total_TeleTTrack_Time:(NSString *)Total_TeleTTrack_Time Total_Time:(NSString *)Total_Time {

if (self) {

_Day_of_Week = Day_of_Week;

_ED_Arrival_Time = ED_Arrival_Time;

_ED_Arrival_To_Triage = ED_Arrival_To_Triage;

_ED_Triage_To_ED_Room = ED_Triage_To_ED_Room;

_ED_Room_To_ED_Doctor = ED_Room_To_ED_Doctor;

_EDDoctor_Time = EDDoctor_Time;

_ED_Doctor_To_Bed_Request_Start = ED_Doctor_To_Bed_Request_Start;

_EDBed_Req_Start_Time = EDBed_Req_Start_Time;

_Bed_Request_Start_To_Complete = Bed_Request_Start_To_Complete;

_Total_ED_Time = Total_ED_Time;

_Bed_Request_Complete_To_IP_Conversion = Bed_Request_Complete_To_IP_Conversion;

_Bed_Request_Complete_To_Bed_Assignment = Bed_Request_Complete_To_Bed_Assignment;

_TTBed_Assignment_Time = TTBed_Assignment_Time;

_Bed_Assign_To_Previous_Patient_Discharge = Bed_Assign_To_Previous_Patient_Discharge;

_Bed_Assign_To_Bed_Clean = Bed_Assign_To_Bed_Clean;

_Bed_Clean_To_IP_Bed_Check_in = Bed_Clean_To_IP_Bed_Check_in;

_Bed_Checkin_Time = Bed_Checkin_Time;

_Total_TeleTTrack_Time = Total_TeleTTrack_Time;

_Total_Time = Total_Time;

}

return self;

}


- (NSSet<NSString *> *)featureNames {

return [NSSet setWithArray:@[@"Day of Week", @"ED Arrival Time", @"ED Arrival To Triage", @"ED Triage To ED Room", @"ED Room To ED Doctor", @"EDDoctor Time", @"ED Doctor To Bed Request Start", @"EDBed Req Start Time", @"Bed Request Start To Complete", @"Total ED Time", @"Bed Request Complete To IP Conversion", @"Bed Request Complete To Bed Assignment", @"TTBed Assignment Time", @"Bed Assign To Previous Patient Discharge", @"Bed Assign To Bed Clean", @"Bed Clean To IP Bed Check-in", @"Bed Checkin Time", @"Total TeleTTrack Time", @"Total Time"]];

}


- (nullable MLFeatureValue *)featureValueForName:(NSString *)featureName {

if ([featureName isEqualToString:@"Day of Week"]) {

return [MLFeatureValue featureValueWithDouble:_Day_of_Week];

}

if ([featureName isEqualToString:@"ED Arrival Time"]) {

return [MLFeatureValue featureValueWithString:_ED_Arrival_Time];

}

if ([featureName isEqualToString:@"ED Arrival To Triage"]) {

return [MLFeatureValue featureValueWithDouble:_ED_Arrival_To_Triage];

}

if ([featureName isEqualToString:@"ED Triage To ED Room"]) {

return [MLFeatureValue featureValueWithDouble:_ED_Triage_To_ED_Room];

}

if ([featureName isEqualToString:@"ED Room To ED Doctor"]) {

return [MLFeatureValue featureValueWithDouble:_ED_Room_To_ED_Doctor];

}

if ([featureName isEqualToString:@"EDDoctor Time"]) {

return [MLFeatureValue featureValueWithString:_EDDoctor_Time];

}

if ([featureName isEqualToString:@"ED Doctor To Bed Request Start"]) {

return [MLFeatureValue featureValueWithString:_ED_Doctor_To_Bed_Request_Start];

}

if ([featureName isEqualToString:@"EDBed Req Start Time"]) {

return [MLFeatureValue featureValueWithString:_EDBed_Req_Start_Time];

}

if ([featureName isEqualToString:@"Bed Request Start To Complete"]) {

return [MLFeatureValue featureValueWithDouble:_Bed_Request_Start_To_Complete];

}

if ([featureName isEqualToString:@"Total ED Time"]) {

return [MLFeatureValue featureValueWithString:_Total_ED_Time];

}

if ([featureName isEqualToString:@"Bed Request Complete To IP Conversion"]) {

return [MLFeatureValue featureValueWithDouble:_Bed_Request_Complete_To_IP_Conversion];

}

if ([featureName isEqualToString:@"Bed Request Complete To Bed Assignment"]) {

return [MLFeatureValue featureValueWithDouble:_Bed_Request_Complete_To_Bed_Assignment];

}

if ([featureName isEqualToString:@"TTBed Assignment Time"]) {

return [MLFeatureValue featureValueWithString:_TTBed_Assignment_Time];

}

if ([featureName isEqualToString:@"Bed Assign To Previous Patient Discharge"]) {

return [MLFeatureValue featureValueWithDouble:_Bed_Assign_To_Previous_Patient_Discharge];

}

if ([featureName isEqualToString:@"Bed Assign To Bed Clean"]) {

return [MLFeatureValue featureValueWithDouble:_Bed_Assign_To_Bed_Clean];

}

if ([featureName isEqualToString:@"Bed Clean To IP Bed Check-in"]) {

return [MLFeatureValue featureValueWithDouble:_Bed_Clean_To_IP_Bed_Check_in];

}

if ([featureName isEqualToString:@"Bed Checkin Time"]) {

return [MLFeatureValue featureValueWithString:_Bed_Checkin_Time];

}

if ([featureName isEqualToString:@"Total TeleTTrack Time"]) {

return [MLFeatureValue featureValueWithString:_Total_TeleTTrack_Time];

}

if ([featureName isEqualToString:@"Total Time"]) {

return [MLFeatureValue featureValueWithString:_Total_Time];

}

return nil;

}


@end


@implementation PatientFlowMLOutput


- (instancetype)initWithResult:(int64_t)Result ResultProbability:(NSDictionary<NSNumber *, NSNumber *> *)ResultProbability {

if (self) {

_Result = Result;

_ResultProbability = ResultProbability;

}

return self;

}


- (NSSet<NSString *> *)featureNames {

return [NSSet setWithArray:@[@"Result", @"ResultProbability"]];

}


- (nullable MLFeatureValue *)featureValueForName:(NSString *)featureName {

if ([featureName isEqualToString:@"Result"]) {

return [MLFeatureValue featureValueWithInt64:_Result];

}

if ([featureName isEqualToString:@"ResultProbability"]) {

return [MLFeatureValue featureValueWithDictionary:_ResultProbability error:nil];

}

return nil;

}


@end


@implementation PatientFlowML


- (nullable instancetype)initWithContentsOfURL:(NSURL *)url error:(NSError * _Nullable * _Nullable)error {

self = [super init];

if (!self) { return nil; }

_model = [MLModel modelWithContentsOfURL:url error:error];

if (_model == nil) { return nil; }

return self;

}


- (nullable instancetype)init {

NSString *assetPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"PatientFlowML" ofType:@"mlmodelc"];

return [self initWithContentsOfURL:[NSURL fileURLWithPath:assetPath] error:nil];

}


- (nullable PatientFlowMLOutput *)predictionFromFeatures:(PatientFlowMLInput *)input error:(NSError * _Nullable * _Nullable)error {

return [self predictionFromFeatures:input options:[[MLPredictionOptions alloc] init] error:error];

}


- (nullable PatientFlowMLOutput *)predictionFromFeatures:(PatientFlowMLInput *)input options:(MLPredictionOptions *)options error:(NSError * _Nullable * _Nullable)error {

id<MLFeatureProvider> outFeatures = [_model predictionFromFeatures:input options:options error:error];

return [[PatientFlowMLOutput alloc] initWithResult:[outFeatures featureValueForName:@"Result"].int64Value ResultProbability:(NSDictionary<NSNumber *, NSNumber *> *)[outFeatures featureValueForName:@"ResultProbability"].dictionaryValue];

}


- (nullable PatientFlowMLOutput *)predictionFromDay_of_Week:(double)Day_of_Week ED_Arrival_Time:(NSString *)ED_Arrival_Time ED_Arrival_To_Triage:(double)ED_Arrival_To_Triage ED_Triage_To_ED_Room:(double)ED_Triage_To_ED_Room ED_Room_To_ED_Doctor:(double)ED_Room_To_ED_Doctor EDDoctor_Time:(NSString *)EDDoctor_Time ED_Doctor_To_Bed_Request_Start:(NSString *)ED_Doctor_To_Bed_Request_Start EDBed_Req_Start_Time:(NSString *)EDBed_Req_Start_Time Bed_Request_Start_To_Complete:(double)Bed_Request_Start_To_Complete Total_ED_Time:(NSString *)Total_ED_Time Bed_Request_Complete_To_IP_Conversion:(double)Bed_Request_Complete_To_IP_Conversion Bed_Request_Complete_To_Bed_Assignment:(double)Bed_Request_Complete_To_Bed_Assignment TTBed_Assignment_Time:(NSString *)TTBed_Assignment_Time Bed_Assign_To_Previous_Patient_Discharge:(double)Bed_Assign_To_Previous_Patient_Discharge Bed_Assign_To_Bed_Clean:(double)Bed_Assign_To_Bed_Clean Bed_Clean_To_IP_Bed_Check_in:(double)Bed_Clean_To_IP_Bed_Check_in Bed_Checkin_Time:(NSString *)Bed_Checkin_Time Total_TeleTTrack_Time:(NSString *)Total_TeleTTrack_Time Total_Time:(NSString *)Total_Time error:(NSError * _Nullable * _Nullable)error {

PatientFlowMLInput *input_ = [[PatientFlowMLInput alloc] initWithDay of Week:Day_of_Week ED_Arrival_Time:ED_Arrival_Time ED_Arrival_To_Triage:ED_Arrival_To_Triage ED_Triage_To_ED_Room:ED_Triage_To_ED_Room ED_Room_To_ED_Doctor:ED_Room_To_ED_Doctor EDDoctor_Time:EDDoctor_Time ED_Doctor_To_Bed_Request_Start:ED_Doctor_To_Bed_Request_Start EDBed_Req_Start_Time:EDBed_Req_Start_Time Bed_Request_Start_To_Complete:Bed_Request_Start_To_Complete Total_ED_Time:Total_ED_Time Bed_Request_Complete_To_IP_Conversion:Bed_Request_Complete_To_IP_Conversion Bed_Request_Complete_To_Bed_Assignment:Bed_Request_Complete_To_Bed_Assignment TTBed_Assignment_Time:TTBed_Assignment_Time Bed_Assign_To_Previous_Patient_Discharge:Bed_Assign_To_Previous_Patient_Discharge Bed_Assign_To_Bed_Clean:Bed_Assign_To_Bed_Clean Bed_Clean_To_IP_Bed_Check_in:Bed_Clean_To_IP_Bed_Check_in Bed_Checkin_Time:Bed_Checkin_Time Total_TeleTTrack_Time:Total_TeleTTrack_Time Total_Time:Total_Time];

return [self predictionFromFeatures:input_ error:error];

}


- (nullable NSArray<PatientFlowMLOutput *> *)predictionsFromInputs:(NSArray<PatientFlowMLInput*> *)inputArray options:(MLPredictionOptions *)options error:(NSError * _Nullable * _Nullable)error {

id<MLBatchProvider> inBatch = [[MLArrayBatchProvider alloc] initWithFeatureProviderArray:inputArray];

id<MLBatchProvider> outBatch = [_model predictionsFromBatch:inBatch options:options error:error];

NSMutableArray<PatientFlowMLOutput*> *results = [NSMutableArray arrayWithCapacity:(NSUInteger)outBatch.count];

for (NSInteger i = 0; i < outBatch.count; i++) {

id<MLFeatureProvider> resultProvider = [outBatch featuresAtIndex:i];

PatientFlowMLOutput * result = [[PatientFlowMLOutput alloc] initWithResult:[resultProvider featureValueForName:@"Result"].int64Value ResultProbability:(NSDictionary<NSNumber *, NSNumber *> *)[resultProvider featureValueForName:@"ResultProbability"].dictionaryValue];

[results addObject:result];

}

return results;

}


@end

That's automatically generated code ?


What seems curious is to see

initWithDay of Week

instead of

initWithDay_of_Week

with underscores.


Could you try to manually edit this ?

After looking at this some more this moring I found a work around. I went back to the table of data and removed the spaces from the column heading Day of Week (it was the first column in the CSV file) so that it was DayOfWeek and the code generated correctly. The funny thing is that the other column headings in the table have spaces and it inserts the underscore for them fine.


I think it may be a bug with the automatic code generator. Either fix the generator to consistently insert the underscore in all column headers or change the documentation to indicate column headers should contain no spaces.


Anyway the workaround worked and everything is now working now.


Thanks for looking at this you got me thinking!

Great, happy to have helped and thanks for feedback.


Don't forget to close the thread.

I'm not sure how to close the thread...

Just mark as Correct answer the one that is correct or helped most.