Як я можу побудувати модель для розрізнення твітів про Apple (Inc.) від твітів про яблуко (фрукти)?


85

Дивіться нижче 50 твітів про "яблуко". Я вручну позначив позитивні збіги щодо Apple Inc. Вони позначені як 1 нижче.

Ось кілька рядків:

1|“@chrisgilmer: Apple targets big business with new iOS 7 features http://bit.ly/15F9JeF ”. Finally.. A corp iTunes account!
0|“@Zach_Paull: When did green skittles change from lime to green apple? #notafan” @Skittles
1|@dtfcdvEric: @MaroneyFan11 apple inc is searching for people to help and tryout all their upcoming tablet within our own net page No.
0|@STFUTimothy have you tried apple pie shine?
1|#SuryaRay #India Microsoft to bring Xbox and PC games to Apple, Android phones: Report: Microsoft Corp... http://dlvr.it/3YvbQx  @SuryaRay

Ось загальний набір даних: http://pastebin.com/eJuEb4eB

Мені потрібно створити модель, яка класифікує "Apple" (Inc). від решти.

Я не шукаю загального огляду машинного навчання, навпаки, я шукаю фактичну модель у коді ( переважно Python ).


18
Ви в основному цього хочете: en.wikipedia.org/wiki/Bayesian_spam_filtering
Едді

1
Ви вручну позначаєте свої дані, але хочете бібліотеки такого масштабу. Це під наглядом чи без нагляду?
дан

1
Едді, дякую, за коментар. Дивіться, що електронна пошта з фільтрацією пошти дійсно допомогла мені щось зачепити в моєму мозку. Я зміг побачити реальний приклад того, що намагався зробити, просто застосував інакше.
SAL

5
Розпізнавання іменованої сутності: nlp.stanford.edu/software/CRF-NER.shtml .
Neil McGuigan

1
Захоплюючий @NeilMcGuigan. Я вставив частину тексту в їх демо ( nlp.stanford.edu:8080/ner/process ) і був вражений тим, як різні моделі класифікували слова.
Райан

Відповіді:


39

Я б зробив це наступним чином:

  1. Розбийте речення на слова, унормуйте їх, побудуйте словник
  2. З кожним словом зберігайте, скільки разів вони траплялися в твітах про компанію та скільки разів з’являлися в твітах про фрукти - ці твіти повинні бути підтверджені людиною
  3. Коли з’являється новий твіт, знайдіть у словнику кожне слово в твітті, обчисліть зважений бал - слова, які часто використовуються стосовно компанії, отримають високий бал компанії, і навпаки; слова, вживані рідко, або вживані як з компанією, так і з фруктами, не мали б великої оцінки.

2
Дякую за вашу відповідь на це. Ваша відповідь у поєднанні з коментарем вище справді допомогла мені знайти рішення. Чи можете ви допомогти мені відточити це рішення?
SAL

10
Це неофіційний опис байєсівської класифікації.
sanityinc

1
Я віддаю перевагу "псевдокоду реалізації байєсівської класифікації" :)
AMADANON Inc.

73

Те, що ви шукаєте, називається розпізнаванням іменованих суб’єктів . Це статистична техніка, яка (найчастіше) використовує умовні випадкові поля для пошуку іменованих сутностей, заснованих на тому, що їх навчили вивчати речі про іменовані сутності.

По суті, він розглядає зміст і контекст слова (оглядаючи кілька слів назад і вперед), щоб оцінити ймовірність того, що це слово є іменованою сутністю.

Хороше програмне забезпечення може розглядати інші особливості слів, такі як їх довжина або форма (наприклад, "Vcv", якщо воно починається з "Голосна-приголосна-голосна")

Дуже хорошою бібліотекою (GPL) є NER Стенфорда

Ось демонстрація: http://nlp.stanford.edu:8080/ner/

Деякі зразки тексту, щоб спробувати:

Я їв яблуко в штаб-квартирі Apple і думав про Apple Martin, дочку хлопця з Coldplay

(класифікатори 3class та 4class це правильно розуміють)


5
Це було дійсно цікаво. Чи можна переглянути код english.conll.4class.distsim.crf.ser.gz? Я хотів би побачити, як хтось будує щось подібне.
Райан

Код для NER є відкритим, але дані, які вони використовували на конференціях CONLL, ні. Однак ви можете знайти Reuters Corpus в Інтернеті на сайті NIST.
Neil McGuigan

31

У мене є напівробоча система, яка вирішує цю проблему, відкрита за допомогою scikit-learn, із низкою публікацій у блозі, що описують те, що я роблю. Проблема, з якою я вирішую проблему, - це неоднозначність сенсу слова (вибір одного з декількох варіантів сенсу слова ), що не є таким самим, як розпізнавання іменованої сутності. Мій базовий підхід є дещо конкурентоспроможним з існуючими рішеннями і (що важливо) є настроюваним.

Існують деякі існуючі комерційні інструменти NER (OpenCalais, DBPedia Spotlight та AlchemyAPI), які можуть дати вам досить хороший комерційний результат - спробуйте спочатку!

Я використовував деякі з них для клієнтського проекту (я консультуюсь з використанням NLP / ML у Лондоні), але я не був задоволений їх відкликанням ( точністю та відкликанням ). В основному вони можуть бути точними (коли вони кажуть: "Це Apple Inc", вони, як правило, правильні), але з низьким запам'ятовуванням (вони рідко кажуть "Це Apple Inc", хоча для людей твіт, очевидно, стосується Apple Inc). Я вважав, що це буде інтелектуально цікавою вправою створити версію з відкритим кодом, розроблену для твітів. Ось поточний код: https://github.com/ianozsvald/social_media_brand_disambiguator

Зауважу - я не намагаюся вирішити узагальнену проблему неоднозначності змісту слів за допомогою цього підходу, а просто неоднозначність торгової марки (компанії, люди тощо), коли у вас вже є їх ім’я. Тому я вірю, що цей прямолінійний підхід спрацює.

Я почав це шість тижнів тому, і це написано на Python 2.7 за допомогою scikit-learn. Він використовує дуже базовий підхід. Я векторизую за допомогою бінарного векторизатора підрахунку (я підраховую лише те, чи з’являється слово, а не скільки разів) з 1-3  н-грамами . Я не шкалюю за допомогою TF-IDF (TF-IDF добре, коли у вас змінна довжина документа; для мене твіти - це лише одне-два речення, і мої результати тестування не показали покращення з TF-IDF).

Я використовую базовий токенізатор, який є дуже простим, але напрочуд корисним. Він ігнорує @ # (таким чином, ви втрачаєте деякий контекст) і, звичайно, не розширюєте URL-адресу. Потім я тренуюсь, використовуючи логістичну регресію , і здається, що ця проблема є дещо лінійно відокремлюваною (багато термінів для одного класу не існує для іншого). В даний час я уникаю будь-якого стримування / очищення (я намагаюся найпростішу річ, яка може спрацювати).

У коді є повний README, і ви зможете відносно легко проковтнути свої твіти, а потім слідувати моїм пропозиціям для тестування.

Це працює для Apple, оскільки люди не їдять і не п’ють комп’ютери Apple, а також ми не друкуємо і не граємося з фруктами, тому слова легко розділити на одну або іншу категорію. Ця умова може не виконуватися, коли розглядається щось на зразок #definance для телевізійного шоу (де люди також використовують #definance стосовно Арабської весни, матчів у крикет, перегляду іспитів та музичного гурту). Тут цілком можуть знадобитися розумніші підходи.

У мене є низка публікацій у блозі, що описують цей проект, включаючи одногодинну презентацію, яку я провів у групі користувачів BrightonPython (яка перетворилася на більш коротку презентацію для 140 людей у ​​DataScienceLondon).

Якщо ви використовуєте щось на зразок LogisticRegression (де ви отримуєте ймовірність для кожної класифікації), ви можете вибрати лише впевнені класифікації, і таким чином ви можете домогтися високої точності, торгуючи проти відкликання (таким чином ви отримуєте правильні результати, але їх менше). Вам доведеться налаштувати це на свою систему.

Ось можливий алгоритмічний підхід із використанням scikit-learn:

  • Використовуйте двійковий CountVectorizer (я не думаю, що підрахунок термінів у коротких повідомленнях додає багато інформації, оскільки більшість слів трапляються лише один раз)
  • Почніть з класифікатора дерева рішень. Він матиме пояснювану ефективність (див. Приклад переобладнання дерева рішень ).
  • Перейти до логістичної регресії
  • Дослідіть помилки, породжені класифікаторами (прочитайте експортовану продукцію DecisionTree або подивіться на коефіцієнти в LogisticRegression, проведіть неправильно класифіковані твіти назад через Vectorizer, щоб побачити, як виглядає основне представлення Bag of Words - там буде менше токенів, ніж ви почали з сирого твіту - чи достатньо для класифікації?)
  • Подивіться на мій приклад коду на https://github.com/ianozsvald/social_media_brand_disambiguator/blob/master/learn1.py, щоб отримати працюючу версію цього підходу

Що слід врахувати:

  • Вам потрібен більший набір даних. Я використовую 2000 твітів із міткою (це зайняло у мене п’ять годин), і як мінімум ви хочете збалансований набір із> 100 на клас (див. Примітку про переобладнання нижче)
  • Удосконаліть маркер (дуже легко за допомогою scikit-learn), щоб зберегти # @ у маркерах, і, можливо, додати детектор з великими літерами (як зазначає користувач @ user2425429)
  • Розгляньте нелінійний класифікатор (як, наприклад, пропозиція @ oiez вище), коли справа стає складнішою. Особисто я виявив, що LinearSVC робить гірше, ніж логістична регресія (але це може бути пов'язано з просторим простором функцій, який я ще не скоротив).
  • Тег-специфікатор частини мовлення (на мою скромну думку, не Стенфорда, як пропонує @Neil - він погано працює з поганою граматикою Twitter, на мій досвід)
  • Після того, як у вас буде багато токенів, ви, мабуть, захочете трохи зменшити розмірність (я ще не пробував цього - див. Мій пост у блозі про покарання LogisticRegression l1 l2)

Re. переобладнання. У моєму наборі даних із 2000 елементів я маю 10-хвилинний знімок твітів про "яблуко". Приблизно 2/3 твітів стосуються Apple Inc, 1/3 - для інших видів використання. Я виймаю збалансовану підмножину (приблизно 584 рядки) кожного класу і виконую п'ятикратну перехресну перевірку для навчання.

Оскільки я маю лише 10-хвилинний інтервал часу, у мене є багато твітів на одну і ту ж тему, і, мабуть, саме тому мій класифікатор працює так добре щодо існуючих інструментів - він буде переобладнаний для навчальних функцій, не добре узагальнюючи (тоді як існуючий комерційний інструменти працюють гірше на цьому знімку, але надійніше в ширшому наборі даних). Я буду розширювати своє часове вікно, щоб перевірити це як наступну роботу.


Я не мав задоволення переглядати ваш код і намагатися дублювати / емулювати / навчати, але я винен вам вибачення за те, що не присудив 50 балів нагороди. У вихідні дні я був далеко від SO та пропустив кінцевий термін його нагородження. На щастя, спільнота SO вступила і визнала за потрібне присудити вам 25 балів.
Райан

1
Немає проблем :-) Код, README та публікації в блозі повинні дати вам уявлення про мій підхід. Це свідомо просто, але, здається, працює нормально.
Ian Ozsvald

12

Ви можете зробити наступне:

  1. Складіть слова, що містять їх кількість у фруктах та твітах, пов’язаних із компаніями. Цього можна досягти, подавши йому кілька зразків твітів, нахил яких ми знаємо.

  2. Використовуючи достатньо попередніх даних, ми можемо з’ясувати ймовірність появи слова у твіті про Apple Inc.

  3. Помножте окремі ймовірності слів, щоб отримати ймовірність всього твіту.

Спрощений приклад:

p_f = Імовірність фруктових твітів.

p_w_f = Ймовірність слова, що зустрічається у фруктовому твіті.

p_t_f = Сукупна ймовірність усіх слів у твіті, що трапляються фруктовим твітом = p_w1_f * p_w2_f * ...

p_f_t = Ймовірність фруктів за певного твіту.

p_c, p_w_c, p_t_c, p_c_t - це відповідні значення для компанії.

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

old_tweets = {'apple pie sweet potatoe cake baby https://vine.co/v/hzBaWVA3IE3': '0', ...}
known_words = {}
total_company_tweets = total_fruit_tweets =total_company_words = total_fruit_words = 0

for tweet in old_tweets:
    company = old_tweets[tweet]
    for word in tweet.lower().split(" "):
        if not word in known_words:
            known_words[word] = {"company":0, "fruit":0 }
        if company == "1":
            known_words[word]["company"] += 1
            total_company_words += 1
        else:
            known_words[word]["fruit"] += 1
            total_fruit_words += 1

    if company == "1":
        total_company_tweets += 1
    else:
        total_fruit_tweets += 1
total_tweets = len(old_tweets)

def predict_tweet(new_tweet,K=1):
    p_f = (total_fruit_tweets+K)/(total_tweets+K*2)
    p_c = (total_company_tweets+K)/(total_tweets+K*2)
    new_words = new_tweet.lower().split(" ")

    p_t_f = p_t_c = 1
    for word in new_words:
        try:
            wordFound = known_words[word]
        except KeyError:
            wordFound = {'fruit':0,'company':0}
        p_w_f = (wordFound['fruit']+K)/(total_fruit_words+K*(len(known_words)))
        p_w_c = (wordFound['company']+K)/(total_company_words+K*(len(known_words)))
    p_t_f *= p_w_f
    p_t_c *= p_w_c

    #Applying bayes rule
    p_f_t = p_f * p_t_f/(p_t_f*p_f + p_t_c*p_c)
    p_c_t = p_c * p_t_c/(p_t_f*p_f + p_t_c*p_c)
    if p_c_t > p_f_t:
        return "Company"
    return "Fruit"

9

Якщо у вас не виникає проблем із використанням зовнішньої бібліотеки, я рекомендую scikit-learn, оскільки він, мабуть, може зробити це краще та швидше, ніж будь-що, що ви можете кодувати самостійно. Я б просто зробив щось подібне:

Побудуйте свій корпус. Я зрозумів список для зрозумілості, але залежно від того, як зберігаються ваші дані, вам може знадобитися робити різні дії:

def corpus_builder(apple_inc_tweets, apple_fruit_tweets):
    corpus = [tweet for tweet in apple_inc_tweets] + [tweet for tweet in apple_fruit_tweets]
    labels = [1 for x in xrange(len(apple_inc_tweets))] + [0 for x in xrange(len(apple_fruit_tweets))]
    return (corpus, labels)

Найголовніше - ви отримаєте два списки, які виглядають так:

([['apple inc tweet i love ios and iphones'], ['apple iphones are great'], ['apple fruit tweet i love pie'], ['apple pie is great']], [1, 1, 0, 0])

[1, 1, 0, 0] представляють позитивні та негативні мітки.

Потім ви створюєте трубопровід! Pipeline - це клас scikit-learn, який полегшує поєднання етапів обробки тексту, тому вам потрібно викликати лише один об’єкт під час навчання / прогнозування:

def train(corpus, labels)
    pipe = Pipeline([('vect', CountVectorizer(ngram_range=(1, 3), stop_words='english')),
                        ('tfidf', TfidfTransformer(norm='l2')),
                        ('clf', LinearSVC()),])
    pipe.fit_transform(corpus, labels)
    return pipe

Усередині трубопроводу є три етапи обробки. CountVectorizer токенізує слова, розбиває їх, підраховує та перетворює дані в розріджену матрицю. TfidfTransformer є необов’язковим, і ви, можливо, захочете видалити його залежно від рейтингу точності (дещо задіяні перехресні перевірочні тести та пошук сітки для найкращих параметрів, тому я тут не буду про нього). LinearSVC - це стандартний алгоритм класифікації тексту.

Нарешті, ви передбачаєте категорію твітів:

def predict(pipe, tweet):
    prediction = pipe.predict([tweet])
    return prediction

Знову ж, твіт повинен бути у списку, тому я припустив, що він вводить функцію як рядок.

Покладіть усіх у клас або що завгодно, і все готово. Принаймні, на цьому дуже базовому прикладі.

Я не тестував цей код, тому він може не працювати, якщо просто скопіювати-вставити, але якщо ви хочете скористатися scikit-learn, він повинен дати вам уявлення з чого почати.

EDIT: спробував пояснити кроки більш детально.


6

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

Якщо ви хочете пограти з деякими можливостями, ви можете використовувати наступний код, який вимагає встановлення nltk. Книга nltk також є у вільному доступі в Інтернеті, тож ви можете прочитати трохи про те, як все це насправді працює: http://nltk.googlecode.com/svn/trunk/doc/book/ch06.html

#coding: utf-8
import nltk
import random
import re

def get_split_sets():
    structured_dataset = get_dataset()
    train_set = set(random.sample(structured_dataset, int(len(structured_dataset) * 0.7)))
    test_set = [x for x in structured_dataset if x not in train_set]

    train_set = [(tweet_features(x[1]), x[0]) for x in train_set]
    test_set = [(tweet_features(x[1]), x[0]) for x in test_set]
    return (train_set, test_set)

def check_accurracy(times=5):
    s = 0
    for _ in xrange(times):
        train_set, test_set = get_split_sets()
        c = nltk.classify.DecisionTreeClassifier.train(train_set)
        # Uncomment to use a naive bayes classifier instead
        #c = nltk.classify.NaiveBayesClassifier.train(train_set)
        s += nltk.classify.accuracy(c, test_set)

    return s / times


def remove_urls(tweet):
    tweet = re.sub(r'http:\/\/[^ ]+', "", tweet)
    tweet = re.sub(r'pic.twitter.com/[^ ]+', "", tweet)
    return tweet

def tweet_features(tweet):
    words = [x for x in nltk.tokenize.wordpunct_tokenize(remove_urls(tweet.lower())) if x.isalpha()]
    features = dict()
    for bigram in nltk.bigrams(words):
        features["hasBigram(%s)" % ",".join(bigram)] = True
    for trigram in nltk.trigrams(words):
        features["hasTrigram(%s)" % ",".join(trigram)] = True  
    return features

def get_dataset():
    dataset = """copy dataset in here
"""
    structured_dataset = [('fruit' if x[0] == '0' else 'company', x[2:]) for x in dataset.splitlines()]
    return structured_dataset

if __name__ == '__main__':
    print check_accurracy()

1
як це працює? Я не бачу ваших "вибраних функцій" у вашому коді. Чи автоматично він вибирає функції на основі навчального набору? Або він зберігається dict()десь ще? Думаю, якщо навчальний набір досить великий, чи не повинен комп’ютер сам розібратися в особливостях? (без нагляду?)
Райан

2
Функції витягуються за допомогою функції tweet_features. Він в основному видаляє URL-адреси з твітів, а потім створює функціональний дикт, записи якого читають щось на зразок 'hasBigram (foo, bar)' = True.
Paul Dubs,

1
То 'hasBigram(foo,bar)' = Trueде твіт-рядок включає foo bar? Отже, він будує біграми та триграми для кожного твіту та позначає це як позитив dict()? Тому, враховуючи твіт, "alpha beta gamma delta"він побудує dict () біграми для alpha,beta; beta,gamma; and gamma,delta;та триграми для alpha,beta,gammaта beta,gamma,delta? І з поданих позитивних та негативних бі і три грамів класифікатор дерева або байєса може зробити свою магію?
Райан

2
Точно так. Використовуючи класифікатор Байєса, ви також можете отримати найкорисніші функції, викликавши на ньому "show_most_informative_features ()".
Paul Dubs,

Поле, я створив грубу php-версію цього, і ви абсолютно праві. Це надзвичайно ефективний спосіб побудови зваженого словника. Я думаю, це можна легко масштабувати без необхідності вручну створювати всі ключові слова. Я з нетерпінням чекаю дізнатись більше про те, як це зробити в стандартних бібліотеках машинного навчання.
Райан

5

Дякую за коментарі. Ось робоче рішення, яке я підготував з PHP. Мені все одно цікаво почути від інших більш алгоритмічний підхід до цього самого рішення.

<?php

// Confusion Matrix Init
$tp = 0;
$fp = 0;
$fn = 0;
$tn = 0;
$arrFP = array();
$arrFN = array();

// Load All Tweets to string
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://pastebin.com/raw.php?i=m6pP8ctM');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$strCorpus = curl_exec($ch);
curl_close($ch);

// Load Tweets as Array
$arrCorpus = explode("\n", $strCorpus);
foreach ($arrCorpus as $k => $v) {
    // init
    $blnActualClass = substr($v,0,1);
    $strTweet = trim(substr($v,2));

    // Score Tweet
    $intScore = score($strTweet);

    // Build Confusion Matrix and Log False Positives & Negatives for Review
    if ($intScore > 0) {
        if ($blnActualClass == 1) {
            // True Positive
            $tp++;
        } else {
            // False Positive
            $fp++;
            $arrFP[] = $strTweet;
        }
    } else {
        if ($blnActualClass == 1) {
            // False Negative
            $fn++;
            $arrFN[] = $strTweet;
        } else {
            // True Negative
            $tn++;
        }
    }
}

// Confusion Matrix and Logging
echo "
           Predicted
            1     0
Actual 1   $tp     $fp
Actual 0    $fn    $tn

";

if (count($arrFP) > 0) {
    echo "\n\nFalse Positives\n";
    foreach ($arrFP as $strTweet) {
        echo "$strTweet\n";
    }
}

if (count($arrFN) > 0) {
    echo "\n\nFalse Negatives\n";
    foreach ($arrFN as $strTweet) {
        echo "$strTweet\n";
    }
}

function LoadDictionaryArray() {
    $strDictionary = <<<EOD
10|iTunes
10|ios 7
10|ios7
10|iPhone
10|apple inc
10|apple corp
10|apple.com
10|MacBook
10|desk top
10|desktop
1|config
1|facebook
1|snapchat
1|intel
1|investor
1|news
1|labs
1|gadget
1|apple store
1|microsoft
1|android
1|bonds
1|Corp.tax
1|macs
-1|pie
-1|clientes
-1|green apple
-1|banana
-10|apple pie
EOD;

    $arrDictionary = explode("\n", $strDictionary);
    foreach ($arrDictionary as $k => $v) {
        $arr = explode('|', $v);
        $arrDictionary[$k] = array('value' => $arr[0], 'term' => strtolower(trim($arr[1])));
    }
    return $arrDictionary;
}

function score($str) {
    $str = strtolower($str);
    $intScore = 0;
    foreach (LoadDictionaryArray() as $arrDictionaryItem) {
        if (strpos($str,$arrDictionaryItem['term']) !== false) {
            $intScore += $arrDictionaryItem['value'];
        }
    }
    return $intScore;
}
?>

Вищезазначені результати:

           Predicted
            1     0
Actual 1   31     1
Actual 0    1    17


False Positives
1|Royals apple #ASGame @mlb @ News Corp Building http://instagram.com/p/bBzzgMrrIV/


False Negatives
-1|RT @MaxFreixenet: Apple no tiene clientes. Tiene FANS// error.... PAGAS por productos y apps, ergo: ERES CLIENTE.

4

У всіх прикладах, які ви навели, Apple (inc) називали або A pple, або apple inc , тому можливим способом може бути пошук:

  • велике "А" в Apple

  • "inc" після яблука

  • слова / фрази, такі як "ОС", "операційна система", "Mac", "iPhone", ...

  • або їх поєднання


1
У функції я зробив strtolower, щоб відфільтрувати великі літери. Трохи грубо, але це спрацювало.
SAL

@SAL Я не сподівався, що це буде дуже корисно, але якщо у вас є обмеження за часом, тоді ...
user2425429

4

Щоб трохи спростити відповіді на основі умовних випадкових полів ... контекст тут величезний. Ви захочете виділити в тих твітах, які чітко показують компанію Apple проти яблук. Дозвольте мені окреслити тут перелік функцій, які можуть бути для вас корисними для початку. Для отримання додаткової інформації перегляньте іменники, що називаються, та щось, що називається BIO label. Див. ( Http://www.cis.upenn.edu/~pereira/papers/crf.pdf )

Навколишні слова: Створіть вектор об’єкта для попереднього та наступного слова, або якщо ви хочете отримати більше можливостей, можливо, для попередніх 2 та наступних 2 слів. Ви не хочете занадто багато слів у моделі, інакше вона не буде дуже відповідати даним. У процесі обробки природної мови ви хочете зберегти це якнайзагальніше.

Інші функції, які можна отримати від навколишніх слів, включають наступне:

Чи перший символ є великим

Чи останній символ у слові - крапка

Частина мови слова (Позначте частину мови позначення)

Сам текст слова

Я не раджу цього, але навести більше прикладів функцій спеціально для Apple:

WordI (Apple)

NextWordIs (Inc.)

Ви зрозуміли суть. Подумайте про розпізнавання іменованих сутностей як про опис послідовності, а потім за допомогою певної математики підкажіть комп’ютеру, як це обчислити.

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

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


3

Там дійсно хороша бібліотека для обробки текстів на природній мові в Python під назвою nltk. Вам слід поглянути на це.

Однією із стратегій, яку ви можете спробувати, є розгляд n-грамів (груп слів) із словом «яблуко» в них. Деякі слова частіше вживаються поруч із "яблуко", коли говорять про фрукти, інші - про компанію, і ви можете використовувати їх для класифікації твітів.


1
Спасибі Манетеран. Я не оригінальний плакат, але мене також цікавить відповідь. Для винагороди я шукаю якийсь код (навіть з використанням nltk), який може допомогти мені розпочати в правильному напрямку із завданням машинного навчання "привіт світ". Яблуко (вкл.) Проти яблука (фрукти) здається ідеальним завданням.
Райан

3

Використовуйте LibShortText . Цей Python утиліта вже налаштована на роботу з завданнями категоризації короткого тексту, і вона працює добре. Максимум, що вам потрібно буде зробити, це написати цикл, щоб вибрати найкращу комбінацію прапорів. Я використовував його для класифікації мовленнєвих актів під контролем в електронних листах, і результати були точними до 95-97% (під час 5-кратної перехресної перевірки!).

І це походить від виробників LIBSVM та LIBLINEAR , реалізація яких підтримує векторні машини підтримки (SVM) у sklearn та cran, тому ви можете бути впевнені, що їх реалізація не є помилкою.


2

Створіть фільтр ШІ, щоб відрізнити Apple Inc (компанія) від Apple (фрукти). Оскільки це твіти, визначте свій навчальний набір вектором із 140 полів, кожне поле є символом, записаним у твіті в позиції X (від 0 до 139). Якщо твіт коротший, просто вкажіть значення порожнього.

Потім побудуйте навчальний набір, достатньо великий, щоб отримати гарну точність (суб’єктивну на ваш смак). Присвоїти значення результату кожному твіту, a Apple Inc отримує 1 (істина), а твіт яблука (фрукт) отримує 0. Це був би випадок контрольованого навчання під час логістичної регресії .

Тобто машинне навчання, як правило, легше кодувати і ефективніше. Він повинен вчитися на наборі, який ви йому даєте, і це не кодовано.

Я не знаю Python , тому я не можу написати код для нього, але якби ви витратили більше часу на логіку та теорію машинного навчання, можливо, ви захочете виглядати в класі, який я слідую.

Спробуйте курс Coursera Machine Learning від Andrew Ng . Ви навчитесь машинному навчанню на MATLAB або Octave , але як тільки ви отримаєте основи, ви зможете писати машинне навчання будь-якою мовою, якщо зрозумієте просту математику (проста в логістичній регресії).

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


Дякую Fawar. Я сподівався на якийсь код з цього "привіт світу" саме з цією метою - дізнатися, як працює ML. Хоча я подивлюся на клас. Виглядає добре.
Ryan

0

Я б рекомендував уникати відповідей, що пропонують визнання сутності. Оскільки це завдання - це класифікація тексту першою, а розпізнавання сутності другою (ви можете зробити це взагалі без розпізнавання сутності).

Я думаю, що найшвидшим шляхом до результатів буде простора + вундеркінд . Spacy добре продумав модель англійської мови, тому вам не потрібно будувати власну. Хоча вундеркінд дозволяє швидко створювати навчальні набори даних та точно налаштовувати простору модель для ваших потреб.

Якщо у вас достатньо зразків, ви можете отримати гідну модель за 1 день.


У той же час, якщо spaCyє nerкомпонент трубопроводу, чи не було б це вигідно для цієї класифікації? Я припускаю, що їх модель може впізнати Apple(оскільки це одна з найбільших і найвідоміших компаній у світі) набагато краще, ніж модель, яку ви можете придумати за один день.
Szymon Maszke

@Szymon: NER може допомогти, а може і не допомогти. Як я розумію, ви хочете використовувати іменовані сутності (той факт, що вони присутні в тексті) як особливість для основного завдання класифікації. Очевидно, NER не матиме 100% точності, оскільки існує високий рівень неоднозначності. Тож основна модель класифікації вирішить, за яких обставин вона буде довіряти цій ознаці. Може виявитись (я думаю, що це дуже ймовірно), що базова модель класифікації надаватиме дуже низьку вагу результатам моделі NER. А це означає, що ви будете витрачати час на NER, який (майже) не використовується.
Дим

Не те, що я мав на увазі. Просто створіть spacy.Docз кожного тексту, doc.entsперегляньте їх NER і перевірте, чи має будь-який NER .textатрибут, рівний Apple. Цікаво, що їх перший приклад - Apple.
Szymon Maszke

І якби хтось хотів зробити модель, це, швидше за все, залучало б RNN / CNN та подібні, налаштовувало їх відповідно, знаходило архітектуру, типи комірок тощо, я не думаю, що простіші моделі добре справлялись би з неоднозначністю та контекстом. Навіщо полегшувати своє життя (якщо ви не хочете чогось навчитися по дорозі), якщо хтось це вже зробив за вас?
Szymon Maszke

@SzymonMaszke ваша модель є більш складною і важчою для навчання. Щоб ваша модель працювала на згадану мету, вам потрібно не тільки знайти NE, але і знайти її у правильному місці (маркер). За допомогою моделі класифікації я пропоную вам оптимізувати модель для своєї основної мети - визначити, що це компанія Apple, або фрукти Apple. Це легше тренуватись, а отже, швидше за все, воно буде більш точним.
Дім
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.