📄 hooks.c
字号:
case ELTSP: C->Subset = MakeSubset(C->Tested); C->TestValue = 1; break; } } while ( Delim == ' ' ); return C;}void FreeCttee(RRuleSet *Cttee)/* --------- */{ int m, r; RRuleSet RS; ForEach(m, 0, MEMBERS-1) { if ( ! (RS = Cttee[m]) ) continue; ForEach(r, 1, RS->SNRules) { ReleaseRule(RS->SRule[r]); } Free(RS->SRule); Free(RS); } Free(Cttee);}/*************************************************************************//* *//* ASCII reading utilities *//* *//*************************************************************************/int ReadProp(char *Delim)/* -------- */{ int c, i; char *p; Boolean Quote=false; for ( p = PropName ; (c = fgetc(Mf)) != '=' ; ) { if ( p - PropName >= 19 || c == EOF ) { Error(MODELFILE, E_MFEOF, ""); PropName[0] = PropVal[0] = *Delim = '\00'; return 0; } *p++ = c; } *p = '\00'; for ( p = PropVal ; ((c = fgetc(Mf)) != ' ' && c != '\n') || Quote ; ) { if ( c == EOF ) { Error(MODELFILE, E_MFEOF, ""); PropName[0] = PropVal[0] = '\00'; return 0; } if ( (i = p - PropVal) >= PropValSize ) { Realloc(PropVal, (PropValSize += 10000) + 3, char); p = PropVal + i; } *p++ = c; if ( c == '\\' ) { *p++ = fgetc(Mf); } else if ( c == '"' ) { Quote = ! Quote; } } *p = '\00'; *Delim = c; return Which(PropName, Prop, 1, PROPS);}String RemoveQuotes(String S)/* ------------ */{ char *p, *Start; p = Start = S; for ( S++ ; *S != '"' ; S++ ) { if ( *S == '\\' ) S++; *p++ = *S; *S = '-'; } *p = '\00'; return Start;}Set MakeSubset(Attribute Att)/* ---------- */{ int Bytes, b; char *p; Set S; Bytes = (MaxAttVal[Att]>>3) + 1; S = AllocZero(Bytes, unsigned char); for ( p = PropVal ; *p ; ) { p = RemoveQuotes(p); b = Which(p, AttValName[Att], 1, MaxAttVal[Att]); if ( ! b ) Error(MODELFILE, E_MFATTVAL, p); SetBit(b, S); for ( p += strlen(p) ; *p != '"' ; p++ ) ; p++; if ( *p == ',' ) p++; } return S;}/*************************************************************************//* *//* Recover attribute values read with "discrete N" *//* *//*************************************************************************/void BinRecoverDiscreteNames()/* ----------------------- */{ Attribute Att; DiscrValue v; int Length; ForEach(Att, 1, MaxAtt) { if ( ! StatBit(Att, DISCRETE) ) continue; StreamIn((char *) &MaxAttVal[Att], sizeof(int)); ForEach(v, 1, MaxAttVal[Att]) { StreamIn((char *) &Length, sizeof(int)); AttValName[Att][v] = Alloc(Length, char); StreamIn(AttValName[Att][v], Length); } /* Invisible name for undefined values */ AttValName[Att][MaxAttVal[Att]+1] = "<other>"; }}/*************************************************************************//* *//* Recover a ruleset *//* *//*************************************************************************/RRuleSet BinInRules()/* ----------- */{ int ri, d, Bytes; RRuleSet RS; CRule R; Condition C; OldRuleRec OR; Set S; DiscrValue vv; Attribute Att; float Xf; MEMBERS = 1; RS = Alloc(1, RuleSetRec); StreamIn((char *) &RS->SNRules, sizeof(RuleNo)); RS->SRule = Alloc(RS->SNRules+1, CRule); ForEach(ri, 1, RS->SNRules) { R = RS->SRule[ri] = Alloc(1, RuleRec); StreamIn((char *) &OR, sizeof(OldRuleRec)); R->RNo = OR.RNo; R->Size = OR.Size; R->Cover = OR.Cover; R->Mean = OR.Mean; R->LoVal = OR.LoVal; R->HiVal = OR.HiVal; R->LoLim = OR.LoLim; R->HiLim = OR.HiLim; R->EstErr = OR.EstErr; R->Lhs = Alloc(R->Size+1, Condition); ForEach(d, 1, R->Size) { C = R->Lhs[d] = Alloc(1, CondRec); StreamIn((char *) C, sizeof(CondRec)); if ( C->NodeType == BrSubset ) { Bytes = ((MaxAttVal[C->Tested] - 1) >> 3) + 1; S = AllocZero(Bytes, unsigned char); C->Subset = AllocZero(Bytes, unsigned char); StreamIn((char *) S, Bytes); ForEach(vv, 1, MaxAttVal[C->Tested]-1) { if ( In(vv, S) ) SetBit(vv+1, C->Subset); } Free(S); } C->TestValue++; /* to allow for N/A values */ } R->Rhs = Alloc(MaxAtt+1, double); StreamIn((char *) R->Rhs, (MaxAtt+1) * sizeof(double)); } StreamIn((char *) &USEINSTANCES, sizeof(Boolean)); /* Now recover the information for replacing missing values */ AttMean = Alloc(MaxAtt+1, ContValue); AttSD = Alloc(MaxAtt+1, ContValue); Modal = Alloc(MaxAtt+1, DiscrValue); ForEach(Att, 0, MaxAtt) { StreamIn((char *) &Xf, sizeof(float)); AttMean[Att] = Xf; } ForEach(Att, 0, MaxAtt) { StreamIn((char *) &Xf, sizeof(float)); AttSD[Att] = Xf; } StreamIn((char *) Modal, (MaxAtt+1) * sizeof(DiscrValue)); StreamIn((char *) &Precision, sizeof(int)); StreamIn((char *) &GlobalMean, sizeof(float)); /* Miscellaneous global stuff */ StreamIn((char *) &SAMPLE, sizeof(float)); StreamIn((char *) &KRInit, sizeof(int)); StreamIn((char *) &EXTRAP, sizeof(float)); return RS;}void StreamIn(String S, int n)/* -------- */{ int c; while ( n-- ) { if ( (c = getc(Mf)) == EOF ) return; *S++ = c; }}/*=======================================================================*//* *//* Miscellaneous routines for rule handling *//* *//*=======================================================================*//*************************************************************************//* *//* Free space occupied by a rule *//* *//*************************************************************************/void ReleaseRule(CRule R)/* ----------- */{ int d; ForEach(d, 1, R->Size) { if ( R->Lhs[d]->NodeType == BrSubset ) { FreeUnlessNil(R->Lhs[d]->Subset); } FreeUnlessNil(R->Lhs[d]); } FreeUnlessNil(R->Lhs); FreeUnlessNil(R->Rhs); FreeUnlessNil(R);}/*************************************************************************//* *//* Print a ruleset *//* *//*************************************************************************/void PrintRules(RRuleSet RS, String Msg)/* ---------- */{ int r; fprintf(Of, "\n%s\n", Msg); ForEach(r, 1, RS->SNRules) { PrintRule(RS->SRule[r]); }}/*************************************************************************//* *//* Print the rule R *//* *//*************************************************************************/void PrintRule(CRule R)/* --------- */{ int c, d, dd, id, LineLen, EntryLen, Indent, NCoeff=0; Attribute Att; char Entry[1000]; double *Model; float *Importance; if ( MEMBERS > 1 ) { fprintf(Of, "\n " T_Rule " %d/%d", R->MNo+1, R->RNo); } else { fprintf(Of, "\n " T_Rule " %d", R->RNo); } fprintf(Of, TX_RInfo(R->Cover, Precision+1, R->Mean, R->LoVal, R->HiVal, R->EstErr)); if ( R->Size ) { fprintf(Of, " " T_If "\n"); /* Mark all conditions as unprinted or-ing flag to NodeType */ ForEach(d, 1, R->Size) { R->Lhs[d]->NodeType |= 8; } ForEach(d, 1, R->Size) { dd = 0; ForEach(id, 1, R->Size) { if ( (R->Lhs[id]->NodeType & 8) && ( ! dd || Before(R->Lhs[id], R->Lhs[dd]) ) ) { dd = id; } } R->Lhs[dd]->NodeType &= 7; PrintCondition(R->Lhs[dd]); } fprintf(Of, " " T_Then "\n"); } /* Print the model. First estimate the importance of the coefficients */ Model = R->Rhs; Importance = AllocZero(MaxAtt+1, float); ForEach(Att, 1, MaxAtt) { if ( Att != ClassAtt && Model[Att] ) { Importance[Att] = fabs(Model[Att]) * AttSD[Att]; NCoeff++; } } sprintf(Entry, "%s =", AttName[ClassAtt]); Indent = CharWidth(Entry); sprintf(Entry + Indent, " %.14g", Model[0]); fprintf(Of, "\t%s", Entry); LineLen = CharWidth(Entry); ForEach(c, 1, NCoeff) { /* Select the next attribute to print */ Att = 1; ForEach(d, 2, MaxAtt) { if ( Importance[d] > Importance[Att] ) Att = d; } Importance[Att] = 0; /* Print, breaking lines when necessary */ sprintf(Entry, " %c %.14g %s", ( Model[Att] > 0 ? '+' : '-' ), fabs(Model[Att]), AttName[Att]); EntryLen = CharWidth(Entry); if ( LineLen + EntryLen > 72 ) { fprintf(Of, "\n\t%*s", Indent, " "); LineLen = Indent; } fprintf(Of, "%s", Entry); LineLen += EntryLen; } fprintf(Of, "\n"); Free(Importance);}/*************************************************************************//* *//* Print a condition C of a rule *//* *//*************************************************************************/void PrintCondition(Condition C)/* -------------- */{ DiscrValue v, pv, Last, Values=0; Boolean First=true; Attribute Att; int Col, Base, Entry; char CVS[20]; v = C->TestValue; Att = C->Tested; fprintf(Of, "\t%s", AttName[Att]); if ( v < 0 ) { fprintf(Of, T_IsUnknown); return; } switch ( C->NodeType ) { case BrDiscr: fprintf(Of, " = %s\n", AttValName[Att][v]); break; case BrThresh: if ( v == 1 ) { fprintf(Of, " = N/A\n"); } else { CValToStr(C->Cut, Att, CVS); fprintf(Of, " %s %s\n", ( v == 2 ? "<=" : ">" ), CVS); } break; case BrSubset: /* Count values at this branch */ ForEach(pv, 1, MaxAttVal[Att]) { if ( In(pv, C->Subset) ) { Last = pv; Values++; } } if ( Values == 1 ) { fprintf(Of, " = %s\n", AttValName[Att][Last]); break; } if ( Ordered(Att) ) { /* Find first value */ for ( pv = 1 ; ! In(pv, C->Subset) ; pv++ ) ; fprintf(Of, " " T_InRange " [%s-%s]\n", AttValName[Att][pv], AttValName[Att][Last]); break; } /* Must keep track of position to break long lines */ fprintf(Of, " %s {", T_ElementOf); Col = Base = CharWidth(AttName[Att]) + CharWidth(T_ElementOf) + 11; ForEach(pv, 1, MaxAttVal[Att]) { if ( In(pv, C->Subset) ) { Entry = CharWidth(AttValName[Att][pv]); if ( First ) { First = false; } else if ( Col + Entry + 2 >= Width ) { Col = Base; fprintf(Of, ",\n%*s", Col, ""); } else { fprintf(Of, ", "); Col += 2; } fprintf(Of, "%s", AttValName[Att][pv]); Col += Entry; } } fprintf(Of, "}\n"); }}/*************************************************************************//* *//* Check whether a case satisfies a condition *//* *//*************************************************************************/Boolean Satisfies(Description CaseDesc, Condition OneCond)/* --------- */{ DiscrValue v; ContValue cv; DiscrValue Outcome; Attribute Att; Att = OneCond->Tested; /* Determine the outcome of this test on this item */ switch ( OneCond->NodeType ) { case BrDiscr: /* test of discrete attribute */ v = DVal(CaseDesc, Att); Outcome = ( v == 0 ? -1 : v ); break; case BrThresh: /* test of continuous attribute */ cv = CVal(CaseDesc, Att); Outcome = ( NotApplic(CaseDesc, Att) ? 1 : cv <= OneCond->Cut ? 2 : 3 ); break; case BrSubset: /* subset test on discrete attribute */ v = DVal(CaseDesc, Att); Outcome = ( v <= MaxAttVal[Att] && In(v, OneCond->Subset) ? OneCond->TestValue : 0 ); } return ( Outcome == OneCond->TestValue );}/*=======================================================================*//* *//* Predict the value of a case from a ruleset *//* *//*=======================================================================*//*************************************************************************//* *//* Find rules that apply to case and form average *//* *//*************************************************************************/float PredictValue(RRuleSet *Cttee, Description CaseDesc)/* ------------ */{ double PredSum=0; int m; double SumErrLim=0; ForEach(m, 0, MEMBERS-1) { PredSum += RuleSetPrediction(Cttee[m], CaseDesc); SumErrLim += ErrLim; } if ( MEMBERS > 1 ) ErrLim = 0.8 * SumErrLim / MEMBERS; return PredSum / MEMBERS;}float RuleSetPredicti
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -