Як класифікувати текстові документи в Oracle

Письмо ж твоє прияти бисть і разумлено внятельно.
Перше послання Івана Грозного КурбсьКому


Анотація


Вбудована в СУБД Oracle текстова пошукова машина Oracle Text здатна не тільки виконувати повнотекстовий пошук в документах і за коротким описам, але і робити перевірку на відповідність заданим за бажанням умов. Для цього застосовується різновид CTXSYS.CTXRULE текстового індексу і оператор MATCHES. У статті показані приклади їх застосування. Статтю зручно розглядати як продовження публікувалися раніше «Oracle: працювати з текстовими документами дуже просто», «Текстові документи в Oracle: різноманітність джерел, форматів, запитів» і «Як працювати з картотекою (набором даних з короткими описами)?».


Введення


В даний час вбудована в СУБД Oracle Пошукова текстова машина Oracle Text підтримує роботу з трьома різновидами предметного (DOMAIN), текстового індексу: типів CTXSYS.CONTEXT, CTXSYS.CTXCAT і CTXSYS.CTXRULE. Перші два забезпечують пошук, відповідно, повнотекстовий – в повноцінних документах, і в «картотеці» з короткими описами (так би мовити, в «каталозі») – за пред'явленим до тексту запитом. Тип ж індексу CTXSYS.CTXRULE по відношенню до них не зовсім звичайний і може розглядатися як «оборотний» до типу CTXSYS.CONTEXT. Він будується по набору запитів, а не за документами, і його призначення – Визначити результативність кожного запиту з цього стосовно висунутій документу. Запити в наборі, за яким будується індекс, вільно інакше назвати «правилами» (звідси слово rule в назві індексу1), І перевірку відповідності певного документа того чи іншого правилом вільно, знову-таки, розглядати як класифікування документа.


Деякі основні можливості використання індексу типу CTXSYS.CTXRULE будуть розглянуті нижче на двох прикладах: простому і більш реалістичному.


Простий приклад


Істотним технологічним відзнакою «оборотного» індексу CTXSYS.CTXRULE від CTXSYS.CONTEXT є те, що останній можна будувати для документів як всередині БД, так і поза нею (файлова система, інтернет), а перший – тільки для документів, «всередині», тобто що зберігаються або у змінній програми, або в стовпці типу VARCHAR2 або ж CLOB таблиці БД (тільки ці два типи і допускає оператор MATCHES). Причина такого обмеження розробниками не розкривається. У цьому простому прикладі будемо вважати, що документи зберігаються в програмі, в рядку типу VARCHAR2.


Підготовка та проведення досліду з запитами


Побудуємо таблицю з набором запитів, яку потім будемо використовувати як таблиці «правил», або ж «таблиці класифікації» документів. Видамо в SQL * Plus:


CREATE TABLE rules (id NUMBER PRIMARY KEY, query VARCHAR2 (1000));


INSERT INTO rules VALUES ( 1, “lamb” );


INSERT INTO rules VALUES ( 2, “little OR lamb” );


INSERT INTO rules VALUES ( 3, “lamb NOT mary” );


INSERT INTO rules VALUES ( 4, “little lamb” );


INSERT INTO rules VALUES ( 5, “lamb little” );


INSERT INTO rules VALUES ( 6, “lamb NEAR mary” ); 


Будуємо індекс і готуємо сценарний файл для дослідів:


CREATE INDEX rules_idx ON rules ( query ) INDEXTYPE IS CTXSYS.CTXRULE; 


COLUMN category FORMAT 99999


COLUMN query    FORMAT A50


SELECT id category, query FROM rules WHERE MATCHES (query, "& 1")> 0.


SAVE matches REPLACE


SET VERIFY OFF 


Перевіряємо відповідність трьох «документів» шести заведеним «класифікаційними ознаками»:


CTX> @matches “Mary had a little lamb” 


CATEGORY QUERY


——– ————————————————–


       1 lamb


       6 lamb NEAR mary


       2 little OR lamb


       4 little lamb 


CTX> @matches “Twinkle, twinkle little star” 


CATEGORY QUERY


——– ————————————————–


       2 little OR lamb 


CTX> @matches “This Lamb is my lamb” 


CATEGORY QUERY


——– ————————————————–


       1 lamb


       2 little OR lamb


       3 lambNOTmary 


Подальші досліди рекомендується провести самостійно. При необхідності слід скористатися відомою з попереднього матеріалу процедурою CTX_DDL.SYNC_INDEX перебудови індексу. Також рекомендується упевнитися, що в плані обробки наших запитів варто звернення до індексу RULES_IDX (наявний там крок звернення до таблиці RULES викликаний нашим бажанням видати значення поля ID рядки з цієї таблиці; якщо цього не зробити, звернення до таблиці RULES пропаде).


Технічна організація індексу


Звернення до таблиць USER_OBJECTS і USER_SEGMENTS дозволяє уточнити техніку реалізації індексу типу CTXSYS.CTXRULE. Ось приблизно яким у нашому випадку буде список логічних об'єктів, що виникли в результаті видачі команди CREATE INDEX rules_idx …:


OBJECT_NAME                    OBJECT_TYPE


—————————— ———————–


DR$RULES_IDX$I                 TABLE


DR$RULES_IDX$K                 TABLE


DR$RULES_IDX$N                 TABLE


DR$RULES_IDX$R                 TABLE


RULES                          TABLE


DR$RULES_IDX$X                 INDEX


RULES_IDX                      INDEX


SYS_IOT_TOP_53386              INDEX


SYS_IOT_TOP_53391              INDEX


SYS_LOB0000053383C00006$$      LOB


SYS_LOB0000053388C00002$$      LOB 


А ось приблизно які з'являться структури зберігання:


SEGMENT_NAME                   SEGMENT_TYPE


—————————— —————————–


DR$RULES_IDX$X                 INDEX


SYS_C005906                    INDEX


SYS_IOT_TOP_53386              INDEX


SYS_IOT_TOP_53391              INDEX


SYS_IL0000053383C00006$$       LOBINDEX


SYS_IL0000053388C00002$$       LOBINDEX


SYS_LOB0000053383C00006$$      LOBSEGMENT


SYS_LOB0000053388C00002$$      LOBSEGMENT


DR$RULES_IDX$I                 TABLE


DR$RULES_IDX$R                 TABLE


RULES                          TABLE 


Очевидно, технічна організація індексу типу CTXSYS.CTXRULE майже та ж, що й для типу CTXSYS.CONTEXT, тобто це чотири таблиці та необхідні для них службові структури. (Майже – тому що в таблиці DR $ RULES_IDX $ I в нашому випадку з'явилося додаткове поле TOKEN_EXTRA. Подальше вивчення пропонується зробити самостійно).


У наборах з декількох запитів-«правил», подібно нашому випадку, це призводить до жахливого перевитрати дискової пам'яті; очевидно, сама можливість розрахована на великі набори.


Приклад з реальними документами


Простий приклад вище дозволяє зрозуміти логіку класифікації та технічні моменти. Тепер спробуємо розглянути більш життєвий приклад. Життєвої буде ситуація, в той час як технологічно для кращого розуміння істотного далі все ж таки буде зроблено ряд припущень і технічних спрощень.


У статті «Як працювати з картотекою (набором даних з короткими описами)?» Розглядалося заклад в БД і індексування «картотеки» з короткими описами новин, отриманих з каналу RSS в інтернеті для Oracle Technology Network, і з посиланнями на джерело. Візьмемо одну таку посилання:


CTX> COLUMN link FORMAT A75


CTX> SELECT link FROM otnnews WHERE ROWNUM = 1; 


LINK


————————————————– ————————-


http://www.oracle.com/technology/pub/articles/hunter_rac10gr2_iscsi.html?rs


sid=rss_otn_news 


Ось початок документа HTML, розташованого за цим посиланням:



Проробимо наступне:


– Витягти з цієї посилання документ у БД.


– Побудуємо більш реальний набір класифікаційних правил.


– Перевіримо документ на відповідність правилам.


Одержуємо документ з інтернету


Якщо звернення в інтернет буде здійснюватися через наближений (proxy) сервер, потрібно попередньо видати щось на кшталт:


EXECUTE UTL_HTTP.SET_PROXY ("http:// ім'я: пароль @ адреса: порт")


Для вилучення документа з інтернету мені дуже хотілося б скористатися типом HTTPURITYPE, але перевірка показує, що цей тип не здатний посилати запити HTTP методом POST, а для нашої сторінки, знову-таки показує перевірка, потрібно саме це. Притому, сторінка динамічна: зверніть увагу на завершення адреси текстом? Rssid = rss_otn_news. (Нескладна перевірка параметрів відповіді при зверненні за цією адресою показує, що одержувачем запиту є сервлет на Oracle Application Server). Тому доведеться вдатися до пакету UTL_HTTP та програмування.


Для зручності занесемо основну частину адреси і параметри в змінні SQL * Plus:


VARIABLE url         VARCHAR2 ( 1000 )


VARIABLE parameters  VARCHAR2 ( 1000 )


VARIABLE length      VARCHAR2 ( 1000 ) 


EXECUTE :url := –


http://www.oracle.com/technology/pub/articles/hunter_rac10gr2_iscsi.html


EXECUTE :parameters := “rssid=rss_otn_news


EXECUTE :length := “18” 


Для простоти кількість символів в подстроке параметрів (18) я порахував вручну.


Заведемо змінну SQL * Plus для зберігання документа:


VARIABLE htmlclob CLOB


EXECUTE :htmlclob := EMPTY_CLOB ( ) 


При роботі врахуйте, що значення змінної SQL * Plus типу CLOB загубиться, як тільки ви завершіть сеанс зв'язку з СУБД, наприклад в результаті видачі CONNECT. (Насправді, мінлива HTMLCLOB є змінна-«локатор», що вказує на тимчасовий LOB-об'єкт з часом життя сеансу; цей-то LOB-об'єкт і пропадає без нашої волі по завершенню сеансу, після чого локатор почне вказувати «в нікуди»).


Наступний блок на PL / SQL прочитає за потрібною адресою в інтернеті документ і розмістить його в змінній SQL * Plus:


DECLARE


req      UTL_HTTP.REQ;


resp     UTL_HTTP.RESP;


name     VARCHAR2 ( 256 );


value    VARCHAR2 ( 4000 ); 


BEGIN


req := UTL_HTTP.BEGIN_REQUEST ( :url, method => “POST” );


UTL_HTTP.SET_HEADER (r => req, name => "Content-Type", value => "text / html");


UTL_HTTP.SET_HEADER (r => req, name => "Content-Length", value => :length );


UTL_HTTP.WRITE_LINE ( r => req, data => :parameters );


resp := UTL_HTTP.GET_RESPONSE ( req ); 


DBMS_OUTPUT.PUT_LINE ("HTTP response status code:" / / resp.status_code);


DBMS_OUTPUT.PUT_LINE ("HTTP response reason:" / / resp.reason_phrase);


LOOP


  UTL_HTTP.READ_LINE ( resp, value, TRUE );


  :htmlclob := :htmlclob // value;


END LOOP; 


EXCEPTION


  WHEN UTL_HTTP.END_OF_BODY


  THEN UTL_HTTP.END_RESPONSE ( resp );


END;



Видача на екран додана для контролю. Перевірити, що документ дійсно читався, можна, наприклад, так:


CTX> EXECUTE DBMS_OUTPUT.PUT_LINE ( DBMS_LOB.GETLENGTH ( :htmlclob ) )


166426 


PL/SQL procedure successfully completed. 


При бажанні можна було позначити документ в таблицю, але тут досить і залишити його в змінній SQL * Plus.


Проводимо класифікацію


Створимо таблицю класифікації, заповнимо її правилами і побудуємо індекс:


CREATE TABLE category ( id NUMBER, query VARCHAR2 ( 2000 ) ); 


INSERT INTO category VALUES (1, "rac /" real application clusters "");


INSERT INTO category VALUES ( 2, “linux / unix” );


INSERT INTO category VALUES (3, "installation / configuration");


INSERT INTO category VALUES (4, "ms windows OR microsoft NEAR windows");


INSERT INTO category VALUES ( 5, “standby AND switchover” ); 


CREATE INDEX category_idx ON category (query) INDEXTYPE IS CTXSYS.CTXRULE;


Перевірка:


CTX> COLUMN query FORMAT A60


CTX> SELECT id, query FROM category WHERE MATCHES ( query, :htmlclob ) > 0; 


        ID QUERY


———- —————————————-


         1 rac / “real application clusters”


         2 linux / unix


         3 installation / configuration


         4 ms windows OR microsoft NEAR windows 


У даному випадку документ задовольняє чотирьом категоріям наявної класифікації під номерами 1 – 4 і не задовольняє категорії під номером 5.


У житті може бути складніше


Реальність нерідко виявляється складніше, ніж хотілося б. Ось приклади.


Складовою документ


Повернемося на власні очі до документа, який тільки що проаналізували. Зверніть увагу на його завершення:



Інтерес приваблює фрагмент в кінці сторінки, який я обвів еліпсом. Судячи з усього, наш документ не вичерпується однією сторінкою HTML і складається на ділі з трьох сторінок! Фактичний перехід по посиланнях Page 2 і Page 3 підтверджує це припущення. Це – одна зі складностей, яка може нас підстерігати при організації автоматичного класифікування.


Технічно проблему документа, логічно єдиного, але рознесеного по декількох сторінках, можна врахувати додатковим програмуванням, що включає виявлення подібного роду продовжень, але при цьому ми змушені будемо враховувати особливості цілком конкретного каналу новин RSS, так як в іншому каналі посилання на продовження документа можуть виявитися організовані зовсім інакше. Це позбавить створювану програму автоматичного класифікування спільності.


«Словесний шум»


Якщо документ, як у нашому випадку, представлений сторінкою HTML в інтернеті, він як правило містить не стосується справи (тобто, для нас – шум), в тому числі у вигляді тексту. Непотрібні нам слова можуть з'явитися внаслідок бажання розробників місця в інтернеті показати на сторінці напрямки подальшої навігації, або ж просто можуть ставитися до реклами. Розглянутий спосіб фактично аналізує текст сторінки HTML, а не документа, і як відфільтрувати не відносяться до справи слова, мені невідомо. Залишається тільки сподіватися, що подібне словесне супровід документа, як це нерідко буває, буде породжуватися засобами JavaScript і програмою читання «документа» (сторінки) залишиться непоміченим.


Якщо документ представлений файлом формату PDF, RTF, простого тексту або іншим, проблема потрапляння в поле зору не відносяться до даного документу слів не виникає.


Інші формати


Використаний вище спосіб класифікації можна застосовувати тільки до документів, представленим простим текстом (plain text), або у форматі HTML. До інших форматів надання документа оператор MATCHES безпосередньо не застосуємо. Якщо з'ясовується, що новинна посилання вказує на документ в іншому форматі (наприклад, PDF, – а з'ясування цього вже вимагає додаткового програмування), залишається тільки привести документ перед аналізом у текстовий вигляд за допомогою процедури CTX_DOC.IFILTER. (Неявно якраз ця процедура виконує перетворення документа при повнотекстовому індексуванні і при використанні в індексі типу CTXSYS.CONTEXT фільтра CTXSYS.AUTO_FILTER). Це технічно можливо, але потребує подальшого додаткового програмування і збільшить витрачання ресурсів СУБД на виконання аналізу.


Висновок


Матеріалу цієї статті, а також трьох попередніх, присвячених можливостям Oracle Text, достатньо для розуміння того, як запрограмувати автоматичний збір новин з інтернету і виконувати автоматичну класифікацію.


Виконувати повнотекстовий пошук, а також класифікацію, можна до того ж стосовно документів, які є не тільки в інтернеті, але і в БД, і у файловій системі.


У той же час порушені можливості є базовими, початковими, і не вичерпують зміст Oracle Text. Наприклад, за рамками розгляду опинилися засоби «інтелектуального аналізу» документів, які за аналогією з Data Mining отримали назву Text Mining. Описувати ці кошти мимохідь нереально.

1Можливо, доречніше тут було б привести для слова rule інший, більш специфічний переклад «спрямовуюча».

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*