Выделение независимых признаков

В этой статье мы узнаем, как выделять признаки из набора данных, в котором результаты заранее не проставлены. Как и в случае кластеризации, задача состоит не столько в том, чтобы делать прогнозы, сколько в попытке охарактеризовать данные и сообщить о них интересную информацию.

Напомним, что методы кластеризации относили каждую строку набора данных к некоторой группе или точке в иерархии, – каждый образец попадал ровно в одну группу, которая была представлена средним своих членов. Выделение признаков – обобщение этой идеи; мы пытаемся найти новые строки, сочетание которых позволило бы реконструировать строки исходного набора. Мы не относим строки к кластеру, а создаем каждую строку из комбинации признаков.

Классическая задача, иллюстрирующая необходимость нахождения независимых признаков, – это задача о вечеринке, суть которой в том, чтобы понять смысл разговора, когда беседуют сразу много людей. У человеческого слуха есть замечательная особенность – способность выделять один голос среди многих, не обращая внимания на остальные. Наш мозг прекрасно умеет вычленять независимые звуки из шума. С помощью алгоритмов, подобных описанному в этой статье, и при наличии в комнате нескольких микрофонов компьютер может сделать то же самое – выделить отдельные звуки из какофонии, не зная заранее, на что они похожи.

Еще одно интересное применение методов выделения признаков – идентификация повторяющихся паттернов употребления слов в массиве документов. Это помогает выделять темы, которые могут независимо

присутствовать в различных сочетаниях. В настоящей статье мы построим систему, которая загружает новости из различных источников и идентифицирует упоминаемые в них основные темы. Может оказаться, что в некоторых новостях упоминается сразу несколько тем, и уж наверняка обнаружится, что одна и та же тема присутствует в нескольких новостях.

Второй пример касается фондового рынка. Предположительно, наблюдаемые на нем результаты обусловлены целым рядом причин. С помощью того же алгоритма мы сумеем отыскать эти причины и вызываемые ими независимые последствия.

Массив новостей

Прежде всего нам потребуется набор новостей, с которыми можно работать. Они должны быть взяты из различных источников, чтобы было проще различить темы, обсуждаемые в разных местах. К счастью, большинство крупных новостных агентств и сайтов поддерживают каналы в формате RSS или Atom либо для всех новостей, либо для отдельных категорий. В предыдущих статьях мы уже пользовались библиотекой Universal Feed Parser для разбора каналов блогов, она годится и для загрузки новостей. Если вы еще не установили эту библиотеку, скачайте ее с сайта http://feedparser.org.

Выбор источников

Существуют тысячи источников новостей – от крупных телеграфных агентств и газет до политических блогов. Вот несколько примеров:

•          Агентство «Рейтерс».

•          Агентство Associated Press.

•          Газета The New York Times.

•          Google News.

•          Salon.com.

•          Fox News.

•          Журнал «Форбс».

•          Агентство CNN International.

И это лишь малая толика. Выбор источников с различных концов политического спектра и придерживающихся разных литературных стилей позволит лучше проверить алгоритм, так как он сможет выделить существенные признаки и отбросить не относящиеся к делу. При наличии правильно подобранных данных алгоритм сможет также идентифицировать признак, присутствующий только в текстах определенной политической направленности, и приписать его новости в дополнение к тем признакам, которые описывают обсуждаемую тему.

Создайте файл newsfeatures.py, включите в него импорт необходимых библиотек и задайте список источников:

import feedparser import re

feedlist=[‘http://today.reuters.com/rss/topNews’,

‘http://today.reuters.com/rss/domesticNews’,

‘http://today.reuters.com/rss/worldNews’,

‘http://hosted.ap.org/lineups/T0PHEADS-rss_2.0.xml’,

‘http://hosted.ap.org/lineups/USHEADS-rss_2.0.xml’,

‘http://hosted.ap.org/lineups/W0RLDHEADS-rss_2.0.xml’,

‘http://hosted.ap.org/lineups/P0LITICSHEADS-rss_2.0.xml’,

‘http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml’,

‘http://www.nytimes.com/services/xml/rss/nyt/International.xml’,

‘http://news.google.com/?output=rss’,

‘http://feeds.salon.com/salon/news’,

‘http://www.foxnews.com/xmlfeed/rss/0,4313,0,00.rss’,

‘http://www.foxnews.com/xmlfeed/rss/0,4313,80,00.rss’,

‘http://www.foxnews.com/xmlfeed/rss/0,4313,81,00.rss’,

‘http://rss.cnn.com/rss/edition.rss’,

‘http://rss.cnn.com/rss/edition_world.rss’,

‘http://rss.cnn.com/rss/edition_us.rss’]

В список включены различные источники, в первую очередь – разделы «Главные новости» (topNews), «Мировые новости» (worldNews) и «Новости США» (domesticNews). Вы можете изменить этот список, как пожелаете, но необходимо, чтобы тематика перекрывалась. Если разные новости не будут иметь между собой ничего общего, алгоритму будет очень трудно извлечь существенные признаки и в результате получится набор ничего не значащих признаков.

Загрузка исходных данных


Для работы алгоритма выделения признаков, как и для алгоритма кластеризации, требуется большая числовая матрица, в которой каждая строка представляет один образец, а каждый столбец – некоторый признак. В нашем случае строками будут новости, а столбцами – слова. Число на пересечении строки и столбца показывает, сколько раз данное слово встречается в данной новости. Так, из показанной ниже матрицы видно, что в новости A слово hurricane (ураган) встречается три раза, в новости B слово democrats (демократы) встречается дважды и т. д.

articles = [‘A’,’B’,’C’,…

‘democrats’,’world’,…

words = [‘hurricane’ matrix = [[3,0,1, [1,2,0, [0,0,2,

Чтобы перейти от новостного канала к такой матрице, нам понадобятся два метода, аналогичные тем, что уже встречались в предыдущих статьях. Первый метод исключает из новостей все изображения и разметку. Добавьте метод stripHTML в файл newsfeatures.py:

def stripHTML(h): p=”

s=0

for c in h:

if c=='<‘: s=1 elif c==’>’:

s=0 p+=’ ‘

elif s==0: p+=c return p

Кроме того, нужно уметь выделять из текста слова, как мы это уже делали ранее. Если вы придумали более изощренный способ выделения слов, чем с помощью простого регулярного выражения, распознающего буквы и цифры, можете повторно воспользоваться им здесь. В противном случае добавьте в файл newsfeatures.py такую функцию: def separatewords(text): splitter=re.compile(‘\\W*’)

return [s.lower( ) for s in splitter.split(text) if len(s)>3] Следующая функция перебирает в цикле все каналы, разбирает их с помощью класса feedparser, убирает HTML-теги и выделяет отдельные слова. Она отслеживает как общее число вхождений каждого слова, так и число вхождений в каждую новость. Добавьте в файл newsfeatures.py следующую функцию: def getarticlewords( ): allwords={} articlewords=[] articletitles=[] ec=0

# Цикл по каналам for feed in feedlist: f=feedparser.parse(feed)

# Цикл по новостям for e in f.entries:

# Повторяющиеся новости игнорируются if e.title in articletitles: continue

# Выделяем слова

txt=e.title.encode(‘utf8’)+stripHTML(e.description.encode(‘utf8’)) words=separatewords(txt) articlewords.append({}) articletitles.append(e.title)

# Увеличиваем счетчики вхождений слова в allwords и в articlewords for word in words:

allwords.setdefault(word,0) allwords[word]+=1

articlewords[ec].setdefault(word,0) articlewords[ec][word]+=1 ec+=1

return allwords,articlewords,articletitles В этой функции есть три переменных:

•          В словаре allwords хранятся счетчики вхождений слов во все новости. Он понадобится нам для того, чтобы определить, какие слова следует считать признаками.

•          В списке articlewords хранятся счетчики слов для каждой новости.

•          В списке articletitles хранятся заголовки новостей.

Построение матрицы

Теперь у нас есть словари счетчиков вхождений слов во все статьи, а также в каждую отдельную статью, и предстоит преобразовать их в матрицу, которая была описана выше. На первом шаге мы создаем список слов, которые станут столбцами матрицы. Чтобы уменьшить размер матрицы, можно исключить слова, встречающиеся лишь в од- ной-двух новостях (скорее всего, для выделения признаков они бесполезны), а также присутствующие практически во всех новостях. Для начала попробуйте оставить лишь слова, встречающиеся как минимум в четырех новостях, но не более чем в 60% всех новостей. Затем можно воспользоваться трансформацией вложенных списков для создания матрицы, которая будет представлена просто как список списков. Каждый вложенный список создается путем прохода по списку wordvec с поиском слова в словаре. Если слово отсутствует, прибавляется 0, иначе создается счетчик вхождений данного слова в текущую новость. Добавьте функцию makematrix в файл newsfeatures.py: def makematrix(allw,articlew): wordvec=[]

#    Берем только слова, которые встречаются часто, но не слишком часто for w,c in allw.items( ):

if c>3 and c<len(articlew)*0.6: wordvec.append(w)

#    Создаем матрицу слов

l1=[[(word in f and f[word] or 0) for word in wordvec] for f in articlew] return l1,wordvec

Запустите интерпретатор Python и импортируйте модуль newsfeatures. Можно приступать к разбору каналов и созданию матрицы: $ python

>>> import newsfeatures

>>> allw,artw,artt= newsfeatures.getarticlewords( ) >>> wordmatrix,wordvec= newsfeatures.makematrix(allw,artw) >>> wordvec[0:10]

[‘increase’, ‘under’, ‘regan’, ‘rise’, ‘announced’, ‘force’,

‘street’, ‘new’, ‘men’, ‘reported’] >>> artt[1]

u’Fatah, Hamas men abducted freed: sources’ >>> wordmatrix[1][0:10]

[0, 0, 0, 0, 0, 0, 0, 0, 1, 0]

Мы вывели первые 10 элементов вектора слов. Показан заголовок второй новости, а за ним – первые 10 значений из соответствующей ей строки матрицы слов. Как видите, в этой статье один раз встречается слово men (мужчины), а больше никаких слов из первых десяти не встретилось.

Прошлые подходы

В предыдущих статьях вы видели различные способы обработки счетчиков слов в текстовых документах. Для сравнения полезно сначала попробовать их и посмотреть, какие получатся результаты, а затем сравнить эти результаты с теми, что даст алгоритм выделения признаков. Если у вас сохранились модули, написанные в предыдущих статьях, можете импортировать их и применить к загруженным из каналов данным. Если нет, тоже не страшно – в этом разделе мы продемонстрируем результаты работы вышеупомянутых методов на тестовых данных.

Вы можете следить за любыми ответами на эту запись через RSS 2.0 ленту. Вы можете оставить ответ, или trackback с вашего собственного сайта.

Оставьте отзыв

XHTML: Вы можете использовать следующие теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

 
Rambler's Top100