Classification Textuelle avec Oracle Text #2
Dans la continuité de l’article précédent, la classification est réalisée cette fois-ci à l’aide d’un arbre de décision – RULE_CLASSIFIER
Je ne reprends pas les premières étapes du processus – elles sont identiques à la classification SVM.
Une table est créée pour recevoir les règles produites par le classifieur:
SQL> CREATE TABLE rules
2 (
3 rule_cat_id NUMBER,
4 rule_text VARCHAR2 (4000),
5 rule_confidence NUMBER
6 );
Table created.
SQL> EXEC ctx_ddl.drop_preference('WINE_CLASSIFIER');
PL/SQL procedure successfully completed.
SQL> EXEC ctx_ddl.create_preference('WINE_CLASSIFIER','RULE_CLASSIFIER');
PL/SQL procedure successfully completed.
SQL> BEGIN
2 ctx_cls.train (index_name => 'train_set_wines_ctxidx',
3 docid => 'wine#',
4 cattab => 'train_set_variety',
5 catdocid => 'wine#',
6 catid => 'cat#',
7 restab => 'rules',
8 rescatid => 'rule_cat_id',
9 resquery => 'rule_text',
10 resconfid => 'rule_confidence',
11 pref_name => 'wine_classifier');
12 END;
13 /
PL/SQL procedure successfully completed.
SQL>
Un index de routage (CTXRULE) est alors construit à partir des règles stockées dans la table RULES:
SQL> CREATE INDEX rules_idx 2 ON rules (rule_text) 3 INDEXTYPE IS ctxsys.ctxrule; Index created. SQL>
L’opérateur MATCHES permet alors de détecter la catégorie prédite en fonction des règles inférées précédemment. Le vin #6 est associé à la catégorie 4:
SQL> SELECT b.wine#, a.rule_cat_id pred_cat#
2 FROM rules a, test_set_wines b
3 WHERE matches (rule_text, description, 1) > 0 AND b.wine# = 6;
WINE# PRED_CAT#
---------- ----------
6 4
SQL>
On réalise le scoring pour l’ensemble des échantillons de test:
SQL> CREATE TABLE res
2 AS
3 SELECT *
4 FROM (SELECT wine#,
5 pred_cat#,
6 cat#,
7 ROW_NUMBER () OVER (PARTITION BY wine# ORDER BY scr DESC)
8 rn
9 FROM (SELECT b.wine#,
10 a.rule_cat_id pred_cat#,
11 b.cat#,
12 match_score (1) scr
13 FROM rules a, test_set_wines b
14 WHERE matches (rule_text, description, 1) > 0))
15 WHERE rn = 1;
Table created.
SQL> WITH
2 badpred
3 AS
4 (SELECT COUNT (*) c1
5 FROM res
6 WHERE pred_cat# != cat#),
7 totpop AS (SELECT COUNT (*) c2 FROM res)
8 SELECT ROUND (100 * (c2 - c1) / c2, 2) pct_good
9 FROM badpred, totpop;
PCT_GOOD
----------
86.2
SQL>
Le taux de prédictions correctes est de 86%.