Yet another classifier

    Вместо вступления


    Лень — двигатель прогресса. Не хочешь сам молоть зерно — сделай мельницу, не хочешь сам кидать во врагов камни — сооруди катапульту, надоело гореть на кострах инквизиции и гнуть спину под феодалом — замути с ребятами ренессанс… впрочем, о чем это я.
    Автоматизация, господа. Берешь какой-нибудь полезный процесс, в котором участвует человек, заменяешь человека на сложный механизм, получаешь профит. Относительно недавно также стало модно заменять человека куском кода. О, сколько благородных профессий может пасть под натиском информатизации. Особенно если учесть, что кусок кода в наше время способен не только на заранее определенное поведение, но и на «обучение» какому-то поведению.

    Немного обобщим


    Вообще говоря, такие сверхспособности для алгоритма, который олицетворяет наш кусок кода, называются не просто обучением, а машинным обучением (machine learning). Обычно мы подразумеваем, что только нечто, наделенное интеллектом, способно обучаться. И, как неудивительно, дисциплина машинного обучения входит в куда более общую дисциплину искусственного интеллекта (artificial intelligence a.k.a. AI)
    image
    Как явствует из картинки, многие задачи AI основываются на алгоритмах машинного обучения. Остается только выбрать что-нибудь веселое и не менее весело решить.

    И пофантазируем


    Допустим тебя, %username%, наняли специалистом по машинному обучению в компанию, которая владеет сайтом IMDb . И говорят мол, вот хотим, чтобы аки у русских иванов на их Кинопоиске, рецензии пользователей помечались цветом зеленым али красным в зависимости от того позитивная или негативная рецензия. И тут вы как бы понимаете, что необходимо взять неприличных размеров базу с рецензиями и выдать на-гора алгоритм, который хорошенько обучится и все их множество разобьет на два непересекающихся подмножества (класса), да так, чтобы вероятность ошибки была минимальна.
    Как и человек, наш алгоритм может учиться либо на своих ошибках (обучение без учителя, unsupervised learning), либо на чужом примере (обучение с учителем, supervised learning). Но, в данном случае, сам он различить позитив и негатив не может, т.к. его никогда не звали на вечеринки и он мало общался с другими людьми. Стало быть, нужно раздобыть выборку уже размеченных на классы рецензий (обучающую выборку), дабы осуществить обучение на готовых примерах (прецедентах).
    Итого, мы хотим решить задачу анализа мнений (sentiment analysis), относящуюся к задачам обработки естественного языка (natural language processing), обучив некий классификатор, который для каждой новой рецензии будет говорить нам позитивная она или негативная. Теперь нужно выбрать классификатор и закодить все это дело.

    Боже, как наивно


    Вообще, в дикой природе водится огромное количество разных классификаторов. Самое простое, что мы могли бы здесь придумать — это отнести все статьи, например, к позитивным. Результат: обучаться не нужно, точность классификатора 50%, интересность 0%.
    А вот если подумать… Как мы выбираем класс, к которому отнесем очередной объект? Мы выбираем его так, чтобы вероятность принадлежности объекта к этому классу была максимальна (капитан!), т.е.
    image
    , где С это какой-то класс, а d — объект, в нашем случае это рецензия. Таким образом, мы пытаемся максимизировать апостериорную вероятность принадлежности рецензии к позитивному или негативному классу.
    Увидев условную вероятность, сразу напрашивается применить к ней теорему Байеса, а так как мы все равно ищем максимум, то еще напрашивается отбросить, за ненадобностью, знаменатель, получив в итоге:
    image
    Все это классно, скажете вы, но откуда получать эти чудо-вероятности в реальной жизни? Ну с P все просто: если у вас есть обучающая выборка, которая адекватно отображает распределение классов, можете оценить:
    image
    , где n — количество объектов, относящихся к классу С, N — размер выборки.
    С P(d|C) все чуть сложнее. Тут мы должны сделать «наивное» предположении о независимости отдельных слов в документе друг от друга:
    image
    и понять, что восстановление n одномерных плотностей задача куда более простая, чем одной n-мерной.
    При этом по обучающей выборке можно оценить:
    image
    , где m — количество слов w в классе С, М — количество слов(а точнее говоря, токенов) в классе С. Так мы получили:
    image
    а вот уже такой классификатор называется наивным байесовским (naive Bayes classifier).
    Пару слов о валидности наивного предположения о независимости. Такое предположение редко бывает верным, в данном случае оно, например, явно неверно. Но, как показывает практика, наивные байесовские классификаторы показывают на удивление хорошие результаты во многих задачах, в том числе в тех, где предположение о независимости, строго говоря, не выполняется.
    Достоинствами наивного байесовского классификатора являются нечувствительность к размерам обучающей выборки, высокая скорость обучения и устойчивость к так называемому переобучению (overfitting — явление, при котором алгоритм очень хорошо работает на тренировочной выборке и плохо на тестовой). Поэтому их применяют либо когда исходных данных очень мало, либо когда таких данных очень много, и на первое место выходит скорость обучения. Недостатки: не самая лучшая точность, особенно если нарушается предположение о независимости.

    Developers, developers, developers


    А теперь для тех кто уже отчаялся увидеть код. В качестве обучающей выборки взята коллекция рецензий IMDb, подготовленная университетом Cornell (сотрудники которого и сами провели с этими данными занимательное исследование).
    Самые интересные методы add_example и classify. Первый, соответственно, занимается обучением, восстанавливая нужные плотности вероятностей, второй — применяет полученную модель.
    def add_example(self, klass, words):
        """
         * Builds a model on an example document with label klass ('pos' or 'neg') and
         * words, a list of words in document.
        """
        self.docs_counter_for_klass[klass] += 1
        for word in words:
          self.token_counter_for_klass[klass] += 1
          self.word_in_klass_counter_for[klass][word] += 1 
    

    Обучение весьма незамысловато — получаем слова из рецензии и ее помеченный класс. Считаем количество документов в классе n, количество слов в классе М и количество слов w в классе — m. Все, дальше классифицируем.
     def classify(self, words):
        """
          'words' is a list of words to classify. Return 'pos' or 'neg' classification.
        """
        score_for_klass = collections.defaultdict(lambda: 0)
        num_of_docs = sum(self.docs_counter_for_klass.values())
        
        for klass in self.klasses:
          klass_prior = float(self.docs_counter_for_klass[klass]) / num_of_docs        
          score_for_klass[klass] += math.log(klass_prior)
          klass_vocabulary_size = len(self.word_in_klass_counter_for[klass].keys())
          for word in words:            
            score_for_klass[klass] += math.log(self.word_in_klass_counter_for[klass][word] + 1)
            score_for_klass[klass] -= math.log(self.token_counter_for_klass[klass] + klass_vocabulary_size)
                   
        sentiment = max(self.klasses, key=lambda klass: score_for_klass[klass])     
        return sentiment
    

    Т.к. вероятности могут быть числами весьма маленькими, а мы все равно занимаемся максимизацией, то можно без зазрения совести все прологарифмировать:
    image
    — это объясняет происходящее. Результирующим классов, соответственно, становится тот, что получил максимальный score.

      def cross_validation_splits(self, train_dir):
        """Returns a lsit of TrainSplits corresponding to the cross validation splits."""
        
        print '[INFO]\tPerforming %d-fold cross-validation on data set:\t%s' % (self.num_folds, train_dir)
        splits = [] 
        for fold in range(0, self.num_folds):
          split = TrainSplit()
          for klass in self.klasses:
            train_file_names = os.listdir('%s/%s/' % (train_dir, klass))
            for file_name in train_file_names:
              example = Example()
              example.words = self.read_file('%s/%s/%s' % (train_dir, klass, file_name))
              example.klass = klass
              if file_name[2] == str(fold):
                split.test.append(example)
              else:
                split.train.append(example)
          splits.append(split)
        return splits
    

    Для наиболее полного использования имеющихся данных применена перекрестная проверка (k-fold cross-validation): имеющиеся в наличии данные разбиваются на k частей, затем на k−1 частях данных производится обучение модели, а оставшаяся часть данных используется для тестирования. Процедура повторяется k раз, в итоге каждая из k частей данных используется для тестирования. Результирующая эффективность классификатора вычисляется просто как среднее.

    Ну и дабы полностью достичь дзэна, прилагаю картинку, изображающую процесс обучения с учителем (в общем случае):
    image


    Что же из всего этого получилось?

    $python NaiveBayes.py ../data/imdb1
    [INFO] Performing 10-fold cross-validation on data set: ../data/imdb1
    [INFO] Fold 0 Accuracy: 0.765000
    [INFO] Fold 1 Accuracy: 0.825000
    [INFO] Fold 2 Accuracy: 0.810000
    [INFO] Fold 3 Accuracy: 0.800000
    [INFO] Fold 4 Accuracy: 0.815000
    [INFO] Fold 5 Accuracy: 0.810000
    [INFO] Fold 6 Accuracy: 0.825000
    [INFO] Fold 7 Accuracy: 0.825000
    [INFO] Fold 8 Accuracy: 0.765000
    [INFO] Fold 9 Accuracy: 0.820000
    [INFO] Accuracy: 0.806000

    С фильтрацией стоп-слов:
    $python NaiveBayes.py -f ../data/imdb1
    [INFO] Performing 10-fold cross-validation on data set: ../data/imdb1
    [INFO] Fold 0 Accuracy: 0.770000
    [INFO] Fold 1 Accuracy: 0.815000
    [INFO] Fold 2 Accuracy: 0.810000
    [INFO] Fold 3 Accuracy: 0.825000
    [INFO] Fold 4 Accuracy: 0.810000
    [INFO] Fold 5 Accuracy: 0.800000
    [INFO] Fold 6 Accuracy: 0.815000
    [INFO] Fold 7 Accuracy: 0.830000
    [INFO] Fold 8 Accuracy: 0.760000
    [INFO] Fold 9 Accuracy: 0.815000
    [INFO] Accuracy: 0.805000
    Оставляю читателю на подумать, почему фильтрация стоп-слов так повлияла на результат (ну т.е. почему почти вообще никак не повлияла).

    Примеры


    Если отойти от скупых цифр, что же мы получили на самом деле?
    Для затравки:
    "Yes, it IS awful! The books are good, but this movie is a travesty of epic proportions! 4 people in front of me stood up and walked out of the movie. It was that bad. Yes, 50 minutes of wedding...very schlocky accompanied by sappy music. I actually timed the movie with a stop watch I was so bored. There is about 20 minutes of action and the rest is Bella pregnant and dying. The end. No, seriously. One of the worst movies I have ever see"
    

    Такая рецензия однозначно распознается, как негативная, что неудивительно. Интересней посмотреть на ошибки.
    " `Strange Days' chronicles the last two days of 1999 in los angeles. as the locals gear up for the new millenium, lenny nero (ralph fiennes) goes about his business of peddling erotic memory clips. He pines for his ex-girlfriend, faith (juliette lewis ), not noticing that another friend, mace (angela bassett) really cares for him. This film features good performances, impressive film-making technique and breath-taking crowd scenes. Director kathryn bigelow knows her stuff and does not hesitate to use it. But as a whole, this is an unsatisfying movie. The problem is that the writers, james cameron and jay cocks ,were too ambitious, aiming for a film with social relevance, thrills, and drama. Not that ambitious film-making should be discouraged; just that when it fails to achieve its goals, it fails badly and obviously. The film just ends up preachy, unexciting and uninvolving."
    

    Эта рецензия помечена, как положительная, но была распознана, как отрицательная. Тут можно задаться вопрос о корректности исходной пометки, потому что даже человеку, на мой взгляд, трудновато определить позитивна или негативна эта рецензия. Неудивительно, по крайне мере, почему классификатор отнес ее к негативной: unsatisfying, fails, badly, unexciting, uninvolving,- достаточно сильные индикаторы негатива, перевешивающие остальное.
    Ну и, конечно, классификатор не понимает сарказма и с легкостью в таком случае принимает отрицательное за положительное:
    "This is what you call a GREAT movie? AWESOME acting you say?Oh yeah! Robert is just so great actor that my eyes bleeding when I'm see him. And the script is so good that my head is exploding. And the ending..ohhh, you gonna love it! Everything is so perfect and nice - I dont got words to describe it!"
    

    Заключение


    Классификаторы, в том числе наивный байесовский, применяются во многих областях помимо анализа мнений: фильтрация спама, распознавание речи, кредитный скоринг, биометрическая идентификация и т.д.
    Кроме наивного байесовского существует еще множество других классификаторов: перцептроны, деревья решений, классификаторы, основанные на методе опорных векторов(SVM), ядерные классификаторы (кernel сlassifiers) и т.д. А ведь кроме обучения с учителем есть еще обучение без учителя, обучение с подкреплением (reinforcement learning ), обучение ранжированию (learning to rank) и многое другое… но это уже совсем другая история



    Данная статья написана в рамках конкурса статей студентов проекта Технопарк@ Mail.Ru
    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 43

      0
      Первый абзац сразу напомнил антиутопию «Механическое пианино» Курта Воннегута. Правда, там замена людей механизмами приводит к не самым лучшим последствиям.
        0
        Стоило бы добавить статью о результатах исследования этих данных в Корнелле.
        www.cs.cornell.edu/home/llee/papers/sentiment.pdf
          0
          спасибо за подсказку, добавил.
          0
          Как-то пользовался кинопоиском и не задумывался, насколько он сложный. Теперь буду по-другому на него смотреть.
            +1
            нет, ну в Кинопоиске, я полагаю все же, в зависимости от оценки рецензия окрашивается, так что подобного нагромаждать не пришлось.
            Но с классификатором было бы куда веселей.
              0
              Забавно, но на кинопоиске я видел отрицательные рецензии с 7/10, нейтральные с 5/10 и положительные с теми же 5/10.
              Однозначно они окрашиваются по другому признаку.
                0
                Ну, возможно, сам пользователь определяет. У меня акка на Кинопоиске нет)
            0
            Кстати, название статьи намекает на YACC?
              +1
              изначально — нет, но идея хорошая)
              +3
              Не понравилось. Слишком много пафоса, слишком мало выхлопа, и новизна этого выхлопа равна нулю.
                0
                всегда найдётся тот, для кого в статье нет ничего нового. Как и тот, для кого она окажется полезной. По любой технологии оч много книжек, и все они повторяются на 90% — но все они приносят пользу.

                Так что я бы не был столь категоричен.
                  +4
                  И какова же польза от этого поста при условии того, что он просто пересказывает один из фрагментов стэнфордского NLP в пафосной «бульварной» обертке, характерной для креатива студентов младших курсов? :-)
                    +3
                    1. не все проходили стенфордские курсы.
                    2. статья вовсе не пересказывает курс.
                    3. знания по NLP, machine learning, sentiment analysis, opinion mining я получил задолго до появления вышеозначенных курсов и так совпало, что теор. принципы, лежащие в их основе не изменились с тех пор. Поэтому они одни для меня, для стенфорда и для всех остальных. Все что остается — выбрать обертку. Она Вам, увы, не понравилась.
                      0
                      Теоретические принципы вы тоже так себе получили. К примеру, «ядерных классификаторов» не существует, а kernels лежат в основе метода опорных векторов.
                        0
                        О, да. конечно же Вы правы
                          0
                          Ну, напишите тогда о «ядерных классификаторах», что ли :-) Будет интересно почитать. Подозреваю, что мнезапно выяснится, что это просто использование kernels в функциях гипотезы SVM и — таки да — нейросетях, и отдельным классификатором, стало быть, они являются где-то так же, как градиентный спуск и метод обратной пропагации.

                          Но, может быть, вы сможете рассказать мне что-то новое. Вот это уже и правда будет интересно.
                            0
                            Подозреваю, что внезапно выяснится, что я бульварно-пафосно пересказываю книгу или еще что-нибудь) Но спасибо за предложение, возможно я так и сделаю. Хотя Вас, конечно, сложно чем-то удивить.
                              0
                              Ну, название той книжки с английского корректно переводится как «самообучаемые классификаторы с использованием kernel метода», а вовсе не «ядерные классификаторы». Т.е. сами типы классификаторов остаются теми же, что и были — регрессии, SVM, нейросети. А вот уже внутри них используется этот самый кернел-метод.
                                +1
                                Все началось с того, что ядерных классификаторв не бывает вовсе, а ядра используются только в SVM — тут Вы не достигли особых успехов в обосновании своей позиции. Теперь начинается спор о том, кто «корректнее» умеет переводить и правильно выбирать названия. Может сразу расстегнем ширинки и решим все по-мужски?
                                  0
                                  Повторяю еще раз, для студентов: ядерных классификаторов не существует. В SVM ядра используются.

                                  Не спорьте со старшими.
                                    0
                                    Вау, вот это действительно аргумент взрослого человека, браво. Все, теперь ни за что не буду спорить с Вами)
                                    0
                                    В описании книги, на которую вы сослались, говорится про применение ядер в классических классификаторах, таких как SVM и нейронные сети. Гугль по запросу «kernel classifier» после этой книги сразу выдаёт статью по тому же SVM. Судя по статьям, которые я читал раньше, идея использования ядер появилась (или по крайней мере получила распространение) в SVM, а затем начала распространяться на другие классификаторы, в т.ч. на нейронки. Так что я не вижу смысла доказывать, что «ядерные классификаторы» не являются чем-то обособленным, лучше вы попробуйте доказать, что действительно существует отдельное направление ядерерных классификаторов. Иначе мы придём к обсуждению чайника Рассела.
                                      0
                                      1. Я нигде в статье не обсуждал kernel classifiers, я их просто упомянул. Вы же спорите со мной о том, что это такое.
                                      2. Изначально спор велся о том, что kernel classifiers не существует.
                                      3. Судя по научной литературе (1, 2, 3, 4,… далее гугл) kernel classifiers обсуждаются достаточно обособленно, хотя, безусловно, обсуждается именно применение ядер в существующих классификаторах.
                                      4.К несчастью, я не знаком с критерием «отдельности направления», но если Вы его поведаете мне, я может что-нибудь и докажу, а может и провалюсь. Как знать.
                                        0
                                        1. Изначально вам намекнули, что «ядерные классифиаторы» не имеет смысла выделять в отдельное направление, ибо без других методов, таких как метод опорных векторов или нейронные сети, использование ядер попросту невозможно. Использование ядра — это не классификация, это метод преобразования данных, деталь, такая же как процедура обратного распространения или градиентный спуск. Вы начали с этим спорить, из-за чего и разгорелась дискуссия.
                                        2. Выражение «kernel classifier», так же, как существуют выражения «fast classifier», «text classifier», «linear classifier» и т.д., но ни одно из этих выражений не обозначает отдельный тип классификаторов, а только показывает некоторое их свойство (по правилам английского языка kernel в данном случае перехрдит в разряд прилагательных). Пример с linear classifier особенно показателен: выражение просто указывает на способ комбинирования переменных, но при этом к линейным классификаторам относится целый ряд методов, в т.ч. SVM (безядерный), logistic regression, naive bayes, etc. Поэтому никак нельзя написать «существуют другие методы классификации, такие как метод опорных векторов, логичстическая регрессия, линейный классификатор, ...». Это просто некорректно с т.з. логики.
                                        3. См. выше.
                                        4. Отдельный метод классификации — это как минимум метод классификации, т.е. описание конкретных шагов, необходимых для выполнения классификации объектов. А непосредственно ядра, как уже было сказано выше, классификацию не выполняют.
                                          0
                                          1. Нет, Вы не правы, мне никто на это не намекал, мне сказали, а потом повторили, что их не существует. И опять же Вы не правы, я ни с кем не обсуждал обратное распространение и градиентный спуск. Но я ценю Вашу фантазию.
                                          2. Теперь мы спорим, что такое «отдельный тип классификатора»? Хорошо, тогда, следуя Вашей же логике naive bayes «не обозначает отдельный тип классификатора, а только показывает некоторое свойство». И здесь naive bayes по правилам английского языка тоже отнюдь не существительные(я, кстати, kernel classifiers первел как Вы и хотели — «ядерные классификаторы»)
                                          3. Ну под такое определение можно что угодно подобрать. Не особо сложно классификацию с использованием ядер описать конкретными шагами.
                                          И хотелось бы узнать от Вас, что именно «непосредственно выполняет» классификацию.
                                            0
                                            1. Ещё раз говорю: отдельного метода «ядерный классификатор» не существует. Судя по гуглю, ядерными называют подмножество методов классификации, использующих в своей работе функцию ядра. Так же, как линейными называют классификаторы, комбинирующие переменные линейно.

                                            2. Речь не о терминологии, речь о логике. Нарисуйте круги Эйлера: для байеса у вас будет один большой круг всех байесовских классификаторов, в нём полностью помещается круг наивных байесовских классификаторов, а в нём несколько подвидов наивных байесовских классификаторов, таких как полиномиальных байесовский классификатор, например. Вы не можете нарисовать круг «наивный классификатор», который бы охватывал или хотя бы пересекался с кругом «байесовский классификатор», поскольку понятие «наивности» определено только для байесовского классификатора. В то же время, если вы нарисуете круги Эйлера для нейронных сетей, SVM, и «ядерных классификаторов», то 1) ядерный классификатор окажется на пересечении нейронок и опорных векторов; 2) он не будет выходить дальше кругов этих 2-х классификаторов (ок, ядра могут быть использованы и в других классификаторах, но это только вопрос количества понятий — всё равно ядерный классификатор всегда будет польностью находиться внутри другов других классификаторов).

                                            3. Непосредственно выполняет классификацию — это берёт экземпляр и присваивает ему метку класса. Опишите. Напишите мне алгоритм, который с помощью исключительно ядер присвоит тому же текстовому отзыву метку «pos» или «neg». Мне очень интересно на это посмотреть.
                                              0
                                              1. Мы еще не определились с понятием того, что же такое «отдельный метод», а Вы уже несетесь куда-то вперед.
                                              2. Ну мы же в данный момент спорим именно о терминологии, каким образом мы перешли в область логики? И, вообще говоря, SVM и перцептрон включают в себя еще всякое. Или Вы думаете классификация на них заканчивается?
                                              3. Нет, мне было интересно кто или что это делает, потому что Вы уверенно сказали, что этим занимаются не ядра.
                                              Вы нарочно не читаете то, что я пишу или это случайность?) «классификацию с использованием ядер». Я нигде не писал про " с помощью исключительно ядер". Опять приступ буйства фантазии.

                                              Серьезно, все это конечно «безумно весело» и я так с Вами могу общаться очень долго, если хотите. Но.
                                              Во-первых, мы спорим о полнейшей ерунде. Да, возможно в статье стоило написать не «ядерные классификаторы», а что-то типа «классификаторы основанные на применении ядер» или «ядерные методы в классификации», чтобы уменьшить количество баттхерта у двух человек. Но Вы правда расцениваете это более, чем незначительную помарку, чтобы в течение нескольких часов расписывать простыни?
                                              Во-вторых, скажу еще раз, что я нигде не написал, что ядерные классификаторы — это отдельный и абсолютно обособленный вид классификации\классификаторов. Вы же решили, что я так сказал и пытаетесь доказать мне, что я не прав.
                                              В-третьих, ну если правда больше не к чему по существу придраться, то может и не стоило. А то похоже на «кажется кто-то в Интернете не прав». Наверняка Вам этот спор наскучал так же, как и мне. Давайте я вот прям заранее признаю, что Вы во всем правы, тогда Вам и отвечать не придется и трать, и мы сэкономим время друг друга.
                                                0
                                                1. Я уже давно определился и несколько раз объяснил вам, так что догоняйте.

                                                2. Нет, мы говорим о логике. Вы поставили в один ряд понятия, которые по логике ну никак не равнозначны. Я понимаю, что SVM и ANN включают в себя ещё много чего. Я говорил о том, что использование функции ядра не выходит за пределы этих методов:

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

                                                3. Значит описать классификацию с помощью только ядер вы не можете, а любые алгоритмы всё равно сведутся к использованию тех же SVM и ANN. Что лично для меня было изначально очевидно. В SVM классификация строится на основании положени относительно гиперплоскости: объект оказался с одной стороны — класс #1, с другой — класс #2. В Naive Bayes — на основании получившейся вероятности: для какого класса она больше, к тому и относим. В логистической регресси/перцептронах примерно так же. Всё, что сами по себе делают ядра, это переводят данные из пространства одной размерности в пространство другой, более высокой. К принятию решения о принадлежности к классу это не имеет никакого отношения. Поэтому название «kernel classifier» не даёт ни малейшего намёка на то, как собственно должна проводиться классификация.

                                                Во-первых, я ещё раз говорю: дело не в названии, а в том, что kernel classifier — это не какой-то метод вроде SVM, Naive Bayes или ANN, а выражение, обозначающее свойство некоторых из упомянутых классификаторов. Так что «классификаторы основанные на применении ядер», «ядерные методы в классификации» и т.д. просто не должны стоять в одном ряду с конкретными методами, ибо это понятия из разных категорий. И это не помарка, это грубая ошибка, вкупе с вашими попытками спорить показывающая глубокое непонимание темы. Так что я настоятельно рекоммендую вам перестать спорить и не усугублять ситуацию.
                                                Во-вторых, как я уже неоднократно отмечал, вы поставили kernel classifiers в один ряд с настоящими методами классификации. Это всё равно что начать перечислять ягоды и сказать: малина, черника, смородина, чёрная,…. Понятно, что ягоды могут быть чёрными, но это не значит, что есть отдельным биологический вид чёрных ягод.
                                                В-третьих, придраться ещё много к чему можно, но учитывая, что вы всё ещё учитесь и, скорее всего, не использовали sentiment analysis на практике, всё это можно простить. Другое дело, что вы начали огрызаться и спорить с гораздо более опытными людьми, кидаясь то в ложные определения, то в демагогию, лишь бы доказать, что вы правы. А вот это уже некрасиво.
                                                  0
                                                  Вопрос обеим: может плодотворнее написать статью про ядра в ИНС? Я бы почитал охотнее, чем спор о терминологии.
                                                    0
                                                    Я Вам предложил остановиться, но Вы сами не захотели
                                                    — О «гораздо более опытных» людях. Мне очень сложно судить о Вашем опыте, он на Вас не написан. Могу судить только по Вашим статьям. Из них я понял, что Вы может запихнуть датасет в R и посмотреть на графики, а так же, то, что по Вашему мнению getters и setters нарушают инкапсуляцию. Простите, что я не восхищен, пусть в своей статье и я тоже не сделал ничего сверхвыдающегося.
                                                    — О «грубых ошибках и глубоком непонимании». Вы поговорили о моих, я поговорю о Ваших.
                                                    1. Глубокое непонимание: Ваше определение «отдельного метода», с которым Вы «давно определились». Я под это определение могу щас придумать пару-тройку классификаторов, которые на самом то деле вовсе отдельными методами не будут.
                                                    2. Грубая ошибка: проблема с диаграммами Эйлера-Венна. Если следовать Вашей логике построения диаграмм, то классификация как раз покроет все три кргуа. А еще она пересечется с кластеризацией на ANN.
                                                    3. Глубокое непонимание: Использвание функции ядра выходит за пределы двух этих кругов. Ядра, например, можно и в байесовских классификаторах использовать.
                                                    4. Глубокое непонимание: классификация с помощью ядер. Задача: распознавать написанные от руки числа от 0 до 9. Все как обычно: цифры представляют собой картинки черно-белые, признаками будут значения интенсивности для пикселей. Алгоритм простой будет: чтобы классифицировать новую картинку, мы будет относить ее к тому классу, к которому принадлежит наболее схожая(близкая) с ней картинка из обучающей выборки. Для этого зададимся функциями f0,...,f9:
                                                    fi:x->R, где х — это вектор признаков (вектор изображения).
                                                    Зададимся также метрикой:
                                                    || x — x' || = sqrt[ sigma { фj(x) — фj(x') }^2 ], где j=1..n; ф = (ф1, .., фn) называется feature mapping. Например, это может быть произведением интенсивностей пикселей:
                                                    ф = (х1х1, ...,x1xn, x2x1, ...,xnxn). Т.е. можно сказать определяем корреляцию изображений.
                                                    Т.о. мы можем представить f следующим образом:
                                                    f(x) = sigma(ai) sigma[ фj(xj)фj(x) ] = sigma[ ai k(xi, x)], где i=1..m, j=1..n; m- количество отмапенных объектов из обучающей выборки ф(х1),.., ф(xm); a из R^m; к — ядро, а функция, включающая ядро называется ядерным классификатором (kernel classifier).
                                                    5. Глубокое непонимание: «В логистической регресси/перцептронах примерно так же». Соглашусь, что в перцептронах примерное так же. как в SVM. Но регрессия она по-вашему как наивный байес или как SVM?
                                                    Вы продолжаете приписывать мне то, что я не говорил. Я уже согласился признать, что допустил незначительную ошибку и неправильно сформулировал свою мысль, но Вам этого мало и Вы продолжаете со мной спорить. После этого именно я виду себя некрасиво. Давайте я еще раз признаю, то что я ошибся, а Вы признаетесь, что не «гораздо более опытный» суперпрофессионал в области машинного обучения?
                                                      0
                                                      О «гораздо более опытных» людях. Мне очень сложно судить о Вашем опыте, он на Вас не написан. Могу судить только по Вашим статьям. Из них я понял, что Вы может запихнуть датасет в R и посмотреть на графики, а так же, то, что по Вашему мнению getters и setters нарушают инкапсуляцию. Простите, что я не восхищен, пусть в своей статье и я тоже не сделал ничего сверхвыдающегося.

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

                                                      1. Глубокое непонимание: Ваше определение «отдельного метода», с которым Вы «давно определились». Я под это определение могу щас придумать пару-тройку классификаторов, которые на самом то деле вовсе отдельными методами не будут.

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

                                                      Грубая ошибка: проблема с диаграммами Эйлера-Венна. Если следовать Вашей логике построения диаграмм, то классификация как раз покроет все три кргуа. А еще она пересечется с кластеризацией на ANN.

                                                      То ли вы круги Эйлера не понимаете, то ли русский язык. Классификация не покроет полностью эти круги. Полное покрытие подразумевает, что одно понятие полностью является дочерним понятием другого. Тот же SVM не является дочерним понятием классификации, поскольку сам по себе метод может быть использован и для других, не связанных с классификацией задач, например, регрессии. Классификация с регрессией (равно как и с кластеризацией) никак не пересекаются, поскольку это разные понятия. Хотя многие методы используются и там, и там, а значит пересекаются с обоими кругами.

                                                      Глубокое непонимание: Использвание функции ядра выходит за пределы двух этих кругов. Ядра, например, можно и в байесовских классификаторах использовать.

                                                      Читайте внимательно:

                                                      (ок, ядра могут быть использованы и в других классификаторах, но это только вопрос количества понятий — всё равно ядерный классификатор всегда будет польностью находиться внутри другов других классификаторов)


                                                      4. Глубокое непонимание: классификация с помощью ядер. Задача: распознавать написанные от руки числа от 0 до 9. Все как обычно: цифры представляют собой картинки черно-белые, признаками будут значения интенсивности для пикселей. Алгоритм простой будет: чтобы классифицировать новую картинку, мы будет относить ее к тому классу, к которому принадлежит наболее схожая(близкая) с ней картинка из обучающей выборки. Для этого зададимся функциями f0,...,f9:
                                                      fi:x->R, где х — это вектор признаков (вектор изображения).
                                                      Зададимся также метрикой:
                                                      || x — x' || = sqrt[ sigma { фj(x) — фj(x') }^2 ], где j=1..n; ф = (ф1, .., фn) называется feature mapping. Например, это может быть произведением интенсивностей пикселей:
                                                      ф = (х1х1, ...,x1xn, x2x1, ...,xnxn). Т.е. можно сказать определяем корреляцию изображений.
                                                      Т.о. мы можем представить f следующим образом:
                                                      f(x) = sigma(ai) sigma[ фj(xj)фj(x) ] = sigma[ ai k(xi, x)], где i=1..m, j=1..n; m- количество отмапенных объектов из обучающей выборки ф(х1),.., ф(xm); a из R^m; к — ядро, а функция, включающая ядро называется ядерным классификатором (kernel classifier).

                                                      Нечитаемо, но будем считать, что идею я понял. А теперь, внимание, вопрос: входной образец вы будете сравнивать с каждым образцом обучающей выборки? Или всё-таки построите модель, представляющую всю выборку? Если модель, то как вы будете её строить? Средним значением пикселей? Неэффективно по множеству причин. Остаётся минимизация ошибки на обучающей выборке с помощью какого-нибудь градиентного спуска или обратного распространения ошибки. Ой, а это у нас тогда не нейронка с ядрами получилась? А ведь и правда, она.
                                                      Нет, если очень хочется, то можно и не строить модель, а сравнивать с каждым обучающим образцом напрямую. Фигня война, что это будет дико неэффективно (как с вычислительной точки зрения, так и с точки зрения классификации), забудем даже про то, что это уже выходит за рамки машинного обучения. Самый интересный момент тут состоит в том, что 1) вы описали distance-based classifier; 2) он вполне может существовать без ядер, следовательно, ядра не являются присущими этому методу. А называть ядерным классификатор, который может существовать без ядер, это уже как-то совсем.
                                                      Вы почему-то упорно не хотите понимать разницу между классификацией и преобразованием данных, за которое отвечают ядра. Kernel trick сам по себе не описывает процесс назначения меток образцам, он только отвечает за перевод признаков в пространство более высокой размерности, чтобы сделать образцы линейно разделимыми.

                                                      5. Глубокое непонимание: «В логистической регресси/перцептронах примерно так же». Соглашусь, что в перцептронах примерное так же. как в SVM. Но регрессия она по-вашему как наивный байес или как SVM?

                                                      Вы вообще осознаёте, что перцептрон и логистическая регрессия описывают одну и ту же модель?
                                                        0
                                                        Да, забавно то, что я потерял интерес к Вашим статьям) Удивлен ли я? Нет. Ожидал ли я этого? Да, определенно.
                                                        За мои знания в области не бойтесь, я ведь к счастью их получаю не от Вас. А то я бы тут тоже начал рассказывать, что регрессия примерно тоже, что и наивный байес, а потом бы доказывал это на диаграммах Эйлера-Венна, при этом постоянно меняя свои «показания».
                                                        Вы на секунду представьте, что то, что Вы написали тут — рассказываете на какой-нибудь научной конференции. Я вот себя уже представил. Да обратили бы внимание, потроллили бы еще — профессора это любят. Но то, что говорите Вы, как человек «гораздо более опытный»… Но это только мое мнение, у Вас свое ЧСВ, Вы наверняка считаете по-другому.
                                                        Я Вам больше не буду отвечать по ряду причин:
                                                        1. спор пустой
                                                        2. как я ни старался — он уже давно отошел от изначальной темы
                                                        3. Вы начали отвечать вопросом на вопрос и топтаться на месте в своей аргументации(с моей точки зрения, опять же)
                                                        4. по-моему Вы спорите ради спора, ибо я несколько раз предлагал Вам остановиться (ну и еще потому, что Вы строчите мне простыни-ответы в 2 часа ночи)
                                                        5. на мой взгляд Вы не ведете себя, как человек более опытный: спорите не аргументированно, при этом спорите со мной о том, что я не говорил, уходите о темы, делаете неадекватные сравнения, когда кончаются аргументы начинаете ссылаться на мою, якобы, неопытность и непонимание, в принципе не можете признать свои ошибки

                                                        ну и 6. Тот пример классификатора, который Вы только что раскритиковали я взял из книги, которая породила наш спор. Вы тогда автору все свои претензии изложите, пожалуйста, он наверняка послушает Вас. Только не забудьте перевести свои статьи и кинуть ему ссылку, чтобы он точно понял с каким профессионалом имеет дело.
                                                        А я, по вышеизложенным соображениям, не могу более доверять Вашему мнению
                                                          0
                                                          Ахаха, повеселили-повеселили :)

                                                          А то я бы тут тоже начал рассказывать, что регрессия примерно тоже, что и наивный байес

                                                          Цитату. Если не можете процитировать, не надо приписывать мне то, что я не говорил.

                                                          а потом бы доказывал это на диаграммах Эйлера-Венна, при этом постоянно меняя свои «показания».

                                                          Т.е. отсылка к ранее сказанному — это теперь называется «менять показания»?

                                                          Вы на секунду представьте, что то, что Вы написали тут — рассказываете на какой-нибудь научной конференции.

                                                          Рассказывал неоднократно. Вопросы?

                                                          Но то, что говорите Вы, как человек «гораздо более опытный»… Но это только мое мнение, у Вас свое ЧСВ, Вы наверняка считаете по-другому. Но то, что говорите Вы, как человек «гораздо более опытный»… Но это только мое мнение, у Вас свое ЧСВ, Вы наверняка считаете по-другому.

                                                          Я вам уже сказал: меня удивляет ваша позиция игнорирования опыта других людей, но это ваше право. Во всех своих аргументах я опираюсь на логику. Чёткую железную логику. И диаграммы Эйлера я вам привожу, чтобы вы начали думать логически. К моему ЧСВ это не имеет никакого отношения. Как и к ЧСВ автора, с которым вы изначально начали спорить.

                                                          2. как я ни старался — он уже давно отошел от изначальной темы

                                                          У вас — может быть, я же по-прежнему доказываю всё ту же мысль.

                                                          по-моему Вы спорите ради спора, ибо я несколько раз предлагал Вам остановиться (ну и еще потому, что Вы строчите мне простыни-ответы в 2 часа ночи)

                                                          Если человек неправ, его принято поправлять. Это профессиональный этикет. А если человек неправ, но при этом начинает спорить и огрызаться, то это уже вызывает негодование.
                                                          Вы ещё не знаете, во сколько я спать ложусь ;)

                                                          в принципе не можете признать свои ошибки

                                                          А в чём я ошибся?

                                                          Тот пример классификатора, который Вы только что раскритиковали я взял из книги, которая породила наш спор.

                                                          Цитату из книги, описывающую этот классификатор. И конкретно то место, где утверждается, что ядрёные классификаторы — это отдельный метод, а не модификация одного из ранее известных методов с использованием функции ядра.
                    +3
                    Код один в один содран из стэнфордского курса NLP. Хоть бы опечатки в комментариях оригинала поправили:
                    def crossValidationSplits(self, trainDir):
                        """Returns a lsit of TrainSplits corresponding to the cross validation splits."""
                    </code>
                      0
                      Кстати говоря, если немного потюнинговать алгоритм, то можно добиться лучшего результата:
                      без стоп–слов:
                      [INFO]	Accuracy: 0.829000

                      с стоп–словами:
                      [INFO]	Accuracy: 0.827000
                        0
                        пространство для тюнинга, безусловно, есть. Можно пользовать не только unigram'ами при обучении, например.
                        +2
                        видимо Вы весьма бегло проходили сенфордские курсы.
                        1. так был только скелет, от которого я оставил, по большей части, только названия функций
                        2. наполнение мое.
                        Так что не надо про содранность «один в один». Очепятку исправлю, спасибо.
                          0
                          Ок, погорячился в выборе слов. Извиняюсь.
                          Просто подпись «статья написана в рамках конкурса» и копипасченый код (пускай частично) — режут глаз.
                            0
                            да, возможно стоило переназвать все функции (логику обработки то особо не изменишь: распарсил, передал на обучение, потренировался), чтобы никого излишне не смущать. My bad
                        0
                        Стенфордские курсы — замечательная штука, и я, например, очень рад интересу, который явно услился в рунете в результате…

                        Я тоже наслушался этих курсов, начитался Джурафски. Писал почти такой же классификатор, правда делал не сентимент анализ, а классификатор определяющий жанры текста. Для тестирования брал корпуса, вот смех — то, из «библиотека в кармане» — наивный байесовский классификатор отработал на «ура» с англоязычными текстами.

                        В общем, в результате класс умеет определять является ли текст документалистикой, фантастикой, приключенияи или Драммой (удивительно, но фантастику и приключения отличает пристойно)

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

                        метод для обучения (у автора «add_example»)

                            def learn(self, genre, words):
                                if genre not in self.genres:
                                    self.genres[genre] = 0
                                self.genres[genre] += len(words)
                        
                                for word in words:
                                    if not word in self.vocabulary:
                                        self.vocabulary[word] = {}
                                    if not genre in self.vocabulary[word]:
                                        self.vocabulary[word][genre] = 1
                                    else:
                                        self.vocabulary[word][genre] += 1
                        
                        


                        И сам классификатор

                            def classify(self, words):
                                result = {}
                                for g in self.genres:
                                    result[g] = 0
                        
                                for word in words:
                                    if word in self.vocabulary:
                                        for genre in self.genres:
                                            if genre in self.vocabulary[word]:
                                                k = (self.vocabulary[word][genre] + 1.0) / (self.genres[genre] + len(self.vocabulary))
                                                result[genre] += math.log(k)
                                            else:
                                                result[genre] += math.log(1.0 / (self.genres[genre] + len(self.vocabulary)))
                                    else:
                                        for genre in self.genres:
                                            result[genre] += math.log(1.0 / (self.genres[genre] + len(self.vocabulary)))
                        
                                sigma = 0
                        
                                for g in self.genres:
                                    sigma += self.genres[g]
                        
                                for g in self.genres:
                                    result[g] += math.log(self.genres[g]/float(sigma))
                                return result
                        
                        


                        В любом случае, спасибо за статью!
                          0
                          Ой, я вам ниже ответил.
                          0
                          Вместо слова «learn» обычно используют «train». Ну это так, к слову.
                            0
                            Ой, конечно не вопрос. Конечно, train, нормально, даже лучше, звучит, но то такое )

                          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                          Самое читаемое