Міністерство освіти та науки України
Національний університет «Львівська політехніка»
кафедра САПР
ЗВІТ
до лабораторної роботи № 3
ВИВЧЕННЯ БІБЛІОТЕКИ ПРИКЛАДНИХ ПРОГРАМ NLTK, ДЛЯ ОПРАЦЮВАННЯ ТЕКСТІВ ПРИРОДНОЮ МОВОЮ.
ОБРОБКА ОКРЕМИХ СЛІВ (токенізація та нормалізація).
МЕТА РОБОТА
Вивчення основ програмування на мові Python.
Ознайомлення з токенізацією та нормалізацією.
КОРОТКІ ТЕОРЕТИЧНІ ВІДОМОСТІ
Мова (мовлення) може бути представлена розділена на частини різного розміру: від морфем до параграфів. Ця лабораторна робота присвячена словам, як дуже важливому рівню опрацювання текстів природною мовою (NLP). Тільки що вважати словом і як вони повинні бути представити в РС? Це просте питання, але проблеми у самому визначенні слова і його представленні залишаються актуальним. В лабораторній роботі буде розглянуто питання розділення тексту на слова, розбіжності між типами і лексемами (tokens), джерела текстових даних, включаючи файли, веб-сторінки, лінгвістичні корпуси, які використовує Python і NLTK, стемінг і нормалізацію
1.1 Tokens, Types і тексти
В одній з попередніх лабораторних робіт розглядався приклад яким чином стрічка може бути розділена (перетворена) на список слів. Цей процес сегментування стрічки символів у слова відомий як токенізація. Токенізація – початковий етап всього того. що відбувається з текстом при його автоматичному опрацюванні. Розглянемо токенізацію більш докладно.
З попередніх лабораторних робіт відомо, як зібрати список унікальних елементів словника у стрічці, використовуючи set ( ) для видалення дублікатів.
Якщо запитати скільки слів у sentence, то отримано два різні значення в залежності від того, враховувалося дублювання чи ні. Отже, „слово” в цих двох прикладах має різні значення. Щоб розрізнити ці значення вводяться поняття token (лексема) і type (тип). Слово token є індивідуальний окремий випадок вживання слова у конкретному визначеному контексті, він існує в часі і просторі. Слово type є більш абстрактним, це те, коли ми говоримо, що „the” зустрічається у sentence три рази „те саме слово”. Але такий підхід не завжди приводить до потрібних результатів. Крім того, ідентичність стрічок не завжди є хорошим критерієм для встановлення відповідності tokens і type. Тому потрібно вивчити два питання більш детально. Перше з них: токенізація – які підстрічки оригінального тексту повинні бути оброблені як tokens слова. Друге: визначення type – як визначити чи мають два різні tokens той самий type.
Терміни token і type можуть бути застосовані і до інших лінгвістичних об’єктів. Наприклад, sentence token є окремим реченням, але sentence type є абстрактним реченням без врахування контексту. Якщо повторити одне речення двічі, то прозвучали два token речення, але використовувався лише один type.
Підсумовуючи, не можна сказати, що два token слова мають той самий type, якщо вони є однаковими стрічками символів. Потрібно враховувати множину інших факторів при визначенні, що рахувати тим самим словом. Крім того, слід бути обережними при першій ідентифікації token.
1.1.1 Отримання тексту з файлу
Переконайтеся, що це звичайний текстовий файл. Зберегти його потрібно в тій самій директорії або папці, з якої запускається інтерпретатор Python.
Наступний крок для того, щоб відкрити файл – використання вбудованої функції open(), яка містить два аргументи: ім’я файла і метод (mode) відкривання файла („r” файл для читання, ”U” universal дозволяє ігнорувати різні домовленості (методи), які використовуються для маркування нової стрічки). Для читання вмісту файлу можна використати багато різних методів. Метод read , використаний до об’єкта файл (f), читає вміст файлу і представляє стрічкою.
1.1.2 Отримання тексту з Інтернет сторінок
Для читання web-сторінки ми використаємо функцію url open
1.1.3 Отримання тексту з корпусі, які розповсюджуються разом з NLTK.
NLTK розповсюджується з деякими корпусами і прикладами корпусів і багато з них підтримуються пакетом corpora. Розглянемо приклад використання вибраних текстів з електронного архіву текстів Project Gutenberg. Можна доступитися, отримати з цього корпуса окремі речення (як список слів), використовуючи функцію read( ).
1.2 Токенізація і нормалізація
Токенізація – це задача екстракції (вилучення) послідовності елементарних tokens, які є складовою частиною лінгвістичних даних. Перші спроби це здійснити починалися зі стрічки символів і використовувався метод split для розбиття стрічки за пробілами (під пробілом ми розуміємо проміжок між словами, знаки табуляції нової стрічки). Токенізація, яка базується на розбитті за пробілами, є дуже спрощеним підходом, але його використовують у багатьох програмах. Потрібно розглянути більш складний підхід, який використовує регулярні вирази для визначення послідовностей символів, які повинні опрацьовуватися як слова. Також потрібно розглянути способи нормалізації tokens.
1.2.2 Лематизація і нормалізація.
В попередніх прикладах здійснювався підрахунок tokens слів і повністю ігнорувалася решта речення в якому зустрічаються ці tokens . Таким чином, наприклад при обробці I saw the saw, обидва tokens розглядаються як випадки одного і того самого типу. Але одна форма дієслова а інша іменник (пристрій для різання). Як дізнатися що ці дві форми непов’язані . Відповідь одна – це є окремі записи у словнику. З іншого боку більш емпірично якщо переглянути більшу кількість текстів то стало б зрозуміло що ці дві форми мають різне розповсюдження. Наприклад тільки іменник saw може йти після артикля the. Різні слова, які мають таку саму форму написання називаються омонімами. Можна розрізнити омоніми з допомогою контексту - дуже часто достатньо попереднього слова.
Лематизація доволі складний процес, який потребує поєднання правил для регулярних флексій і таблиць пошуку для нерегулярних морфологічних варіантів.
В межах NLTK більш простий підхід пропонує Porter Stemmer, який виділяє флективні суфікси від слів і поєднує (згортає) різні форми. Враховуючи простоту алгоритму цей лематизатор не пробує ідентифікувати were як форму леми be.
1.2.3 List Comprehensions
Лематизація і нормалізація передбачає виконання тих самих дій до кожного слова в тексті. List Comprehensions це є корисна конструкція Python для виконання цих дій. List Comprehensions також дозволяє будувати вкладені структури.
Варіант 8
3.1 Створіть невеликий текстовий файл з текстом, який містить декілька стрічок (ім’я, по батькові та прізвище студента). Напишіть програму, яка читає і виводить вміст файлу на екран стрічка за стрічкою з вказанням номера стрічки.
>>> f=open('Hello everybody.txt','rU')
>>> f.read()
'Hello everybody!\nThis is Iryna Maksymiv.\n'
>>> f=open('Hello everybody.txt','rU')
>>> i=0
>>> for line in f:
i+=1
print i, line[:-1]
1 Hello everybody!
2 This is Iryna Maksymiv.
3.3 Використовуючи модуль corpus прочитайте текст austin-persuasion.txt. Визначіть скільки tokens (слів) і type (унікальних слів)містить ця книжка.
>>> from nltk import corpus
>>> corpus.gutenberg.items
['austen-emma', 'austen-persuasion', 'austen-sense', 'bible-kjv', 'blake-poems', 'blake-songs', 'chesterton-ball', 'chesterton-brown', 'chesterton-thursday', 'milton-paradise', 'shakespeare-caesar', 'shakespeare-hamlet', 'shakespeare-macbeth', 'whitman-leaves']
>>> count=0
>>> for word in corpus.gutenberg.read('austen-persuasion'):
count+=1
>>> print count
98191
>>> len(set(corpus.gutenberg.read('austen-persuasion')))
6134
3.7 Напишіть програму доступу до будь-якої web-сторінки і вилучення з неї певного фрагмену.
>>> from urllib import urlopen
>>> page = urlopen("http://news.bbc.co.uk/").read()
>>> print page[:60]
<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN
>>> line = ’<title>BBC NEWS | News Front Page</title>’
>>> new = re.sub(r’<.*>’, ’’, line)
>>>new
' '
>>> page = re.sub(’<.*?>’, ’’, page)
>>> page = re.sub(’\s+’, ’ ’, page)
>>> print page[:60]
BBC NEWS | News Front Page News Sport Weather World Service
3.8 Прочитайте будь-який текст з корпусу, здійсніть його токенізацію і виведіть на екран список всіх wh- слів (who, which, what….) впорядкований за абеткою. Чи дублюються слова в цьому списку і якщо так, то чому?
>>> from nltk import corpus
>>> res=[]
>>> for word in corpus.state_union.tokenized('1945-Truman'):
if word.startswith('wh'):
res.append(word)
res.sort()
print res
['what', 'what', 'when', 'when', 'which', 'which', 'which', 'which', 'which', 'which', 'who', 'who', 'who', 'who']
Використовуючи демонстраційний приклад NLTK nltk.chat.demo() оцініть якість роботи різних програм генерації тексту. Перегляньте тексти програм і опишіть основні принципи їх роботи.
>>> nltk.chat.demo()
Which chatbot would you like to talk to?
1: Eliza (psycho-babble)
2: Iesha (teen anime junky)
3: Rude
4: Suntsu (Chinese sayings)
5: Zen (gems of wisdom)
Please enter 1-5 4
Talk to the program by typing in plain English, using normal upper-
and lower-case letters and punctuation. Enter "quit" when done.
===================================================================
You seek enlightenment?
>yes
Do not repeat the tactics which have gained you one victory, but let your methods be regulated by the infinite variety of circumstances.
>not bad
If you know neither the enemy nor yourself, you will succumb in every battle.
>I agree
One may know how to conquer without being able to do it.
>Am I able?
Ask me no questions!
>Why?
Ask me no questions!
>Ok.
If you know yourself but not the enemy, for every victory gained you will also suffer a defeat.
>what about money
All men can see the tactics whereby I conquer, but what none can see is the strategy out of which victory is evolved.
>quit
May victory be your future
>>> nltk.chat.demo()
Which chatbot would you like to talk to?
1: Eliza (psycho-babble)
2: Iesha (teen anime junky)
3: Rude
4: Suntsu (Chinese sayings)
5: Zen (gems of wisdom)
Please enter 1-5 2
Iesha the TeenBoT
Talk to the program by typing in plain English, using normal upper-
and lower-case letters and punctuation. Enter "quit" when done.
=====================================================================
hi!! i'm iesha! who r u??!
>ill-timed problem
do u watch anime? i like sailor moon! ^_^
>I liked. In the age of 12
do u like anime?
>whatever
ur funny! kekeke
>you are not
ur funny! kekeke
>you are not
do u like anime?
>you are stupied
i wish i was a kitty!! kekekeke ^_^
>quit
awww u have to go?? see u next time!!
>>> nltk.chat.demo()
Which chatbot would you like to talk to?
1: Eliza (psycho-babble)
2: Iesha (teen anime junky)
3: Rude
4: Suntsu (Chinese sayings)
5: Zen (gems of wisdom)
Please enter 1-5 3
Talk to the program by typing in plain English, using normal upper-
and lower-case letters and punctuation. Enter "quit" when done.
=====================================================================
I suppose I should say hello.
>no, you shouldn't
Either become more thrilling or get lost, buddy.
>whatever
I'm getting bored here. Become more interesting.
>You have some problems with your head
I'm getting bored here. Become more interesting.
>not just with head
Either become more thrilling or get lost, buddy.
>get away
Change the subject before I die of fatal boredom.
>quit
Change the subject before I die of fatal boredom.
3.10 Збережіть текст, який містить прізвище, ім’я та по-батькові студента у файл. Напишіть функцію load(f), яка читає файл, назва якого є її аргументом, і повертає стрічку, яка містить текст з файлу.
>>> def load(f):
f=open(f).read()
return f
>>> load('Hello everybody.txt')
'Hello everybody!\nThis is Iryna Maksymiv.\n'
3.12 Використовуючи nltk.tokenize.regexp_tokenize() створіть токенізатор, який буде виділяти наступні види виразів: дати, імена людей, назви компаній, грошові суми.
>>> from nltk import tokenize
>>> import re
>>> text='Cavalli price is $200.350 sold 19.06.08 to Iryna'
>>> pattern = re.compile(r'''\d+(\.\d+)?(\.\d+)?(?#date)|\$?\d+(\.\d+)?(?#monetary amounts)|[A-Z][a-z]*(?#names of people and companies)''', re.VERBOSE)
>>> print list(tokenize.regexp(text, pattern))
['Cavalli', '$200.350', '19.06.08', 'Iryna']
3.13 Перепишіть наступний цикл як list comprehensions
>>> sent = ['The', 'dog', 'gave', 'John', 'the', 'newspaper']
>>> result = []
>>> [result.append((word,len(word))) for word in sent]
>>> result
[('The', 3), ('dog', 3), ('gave', 4), ('John', 4), ('the', 3), ('newspaper', 9)]
3.14 Використайте Porter Stemmer для нормалізації будь-якого токенізованого тексту (необхідно обробити кожне слово). Повторіть експеримент з використанням Lancaster Stemmer . Результати порівняйте і поясніть.
>>> sent='Shell I paint that broken shell or have you done this? We were supposed to do that earlier.'
>>> sent=nltk.tokenize.regexp_tokenize(sent,pattern=r'\w+')
>>> sent
['Shell', 'I', 'paint', 'that', 'broken', 'shell', 'or', 'have', 'you', 'done', 'this', 'We', 'were', 'supposed', 'to', 'do', 'that', 'earlier']
>>> stem=nltk.PorterStemmer()
>>> for word in sent:
wordstem=stem.stem(word)
print(word,wordstem)
('Shell', 'Shell')
('I', 'I')
('paint', 'paint')
('that', 'that')
('broken', 'broken')
('shell', 'shell')
('or', 'or')
('have', 'have')
('you', 'you')
('done', 'done')
('this', 'thi')
('We', 'We')
('were', 'were')
('supposed', 'suppos')
('to', 'to')
('do', 'do')
('that', 'that')
('earlier', 'earlier')
Висновок: На даній лабораторній роботі я вивчила основи програмування на мові Python та ознайомилась з токенізацією та нормалізацією.