Apple (Inc.) ile ilgili tweet'leri apple (meyve) ile ilgili tweet'lerden ayırmak için nasıl bir model oluşturabilirim?


85

"Apple" ile ilgili 50 tweet için aşağıya bakın. Apple Inc. ile ilgili olumlu eşleşmeleri elimle etiketledim. Bunlar aşağıda 1 olarak işaretlenmiştir.

İşte birkaç satır:

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

İşte toplam veri kümesi: http://pastebin.com/eJuEb4eB

"Apple" ı (Inc) sınıflandıran bir model oluşturmam gerekiyor. Geride kalanlardan.

Makine öğrenimine genel bir bakış aramıyorum, bunun yerine kodda gerçek bir model arıyorum ( Python tercih edilir).


18

1
Verilerinizi elle etiketlersiniz, ancak ölçeklenen kitaplıklar istersiniz. Bu denetimli mi yoksa denetimsiz mi?
dan

1
Eddi, yorum için teşekkürler. Posta filtreleme e-postasının beynimde bir şeyin tıklanmasına gerçekten yardımcı olduğunu görün. Yapmaya çalıştığım şeyin gerçek hayattan bir örneğini görebildim, sadece farklı şekilde uyguladım.
SAL

5
Adlandırılmış Varlık Tanıma: nlp.stanford.edu/software/CRF-NER.shtml .
Neil McGuigan

1
Büyüleyici @NeilMcGuigan. Demo metninin bir kısmına ( nlp.stanford.edu:8080/ner/process ) yapıştırdım ve farklı modellerin kelimeleri nasıl sınıflandırdığından etkilendim.
Ryan

Yanıtlar:


39

Bunu şu şekilde yapardım:

  1. Cümleyi kelimelere bölün, normalleştirin, bir sözlük oluşturun
  2. Her kelimeyle, şirket hakkında tweet'lerde kaç kez geldiklerini ve meyve hakkında tweet'lerde kaç kez göründüklerini saklayın - bu tweetler bir insan tarafından onaylanmalıdır.
  3. Yeni bir tweet geldiğinde, tweet'teki her kelimeyi sözlükte bulun, ağırlıklı bir puan hesaplayın - sık sık şirket ile ilgili olarak kullanılan kelimeler yüksek bir şirket puanı alır ve bunun tersi de geçerlidir; Nadiren kullanılan veya hem şirket hem de meyve ile kullanılan kelimelerin bir puanı olmazdı.

2
Bu konudaki cevabınız için teşekkür ederim. Cevabınız yukarıdaki bir yorumla birlikte gerçekten bir çözüme ulaşmama yardımcı oldu. Bu çözümü geliştirmeme yardım edebilir misin?
SAL

10
Bu Bayes sınıflandırmasının gayri resmi bir tanımıdır.
sanityinc

1
"Bayes sınıflandırmasının sözde kod uygulamasını" tercih ediyorum :)
AMADANON Inc.

73

Aradığınız şeyin adı Adlandırılmış Varlık Tanıma . Adlandırılmış varlıklar hakkında bir şeyler öğrenmek üzere eğitilmiş olmaları temelinde adlandırılmış varlıkları bulmak için (en yaygın olarak) Koşullu Rastgele Alanları kullanan istatistiksel bir tekniktir .

Esasen, kelimenin adlandırılmış bir varlık olma olasılığını tahmin etmek için kelimenin içeriğine ve bağlamına bakar (birkaç kelimeyi geriye ve ileriye doğru bakarak).

İyi yazılım, kelimelerin uzunlukları veya şekilleri gibi diğer özelliklerine bakabilir ("Vowel-ünsüz-sesli" ile başlıyorsa "Vcv" gibi)

Çok iyi bir kütüphane (GPL) Stanford'un NER'sidir

İşte demo: http://nlp.stanford.edu:8080/ner/

Deneyebileceğiniz bazı örnek metinler:

Apple genel merkezinde bir elma yiyordum ve Coldplay'in kızı Apple Martin'i düşündüm.

(3sınıf ve 4sınıf sınıflandırıcılar bunu doğru anlar)


5
Bu gerçekten ilginçti. Kodunu görüntülemek mümkün mü english.conll.4class.distsim.crf.ser.gz? Böyle bir şeyin nasıl inşa edildiğini görmek isterim.
Ryan

NER kodu açık kaynak kodludur, ancak CONLL konferanslarında kullandıkları veriler değildir. Ancak, Reuters Corpus'u çevrimiçi olarak NIST adresinde bulabilirsiniz.
Neil McGuigan

31

Bu sorunu çözen, scikit-learn kullanarak açık kaynaklı ve ne yaptığımı açıklayan bir dizi blog yazısı içeren yarı çalışan bir sistemim var. Uğraştığım sorun , Adlandırılmış Varlık Tanıma ile aynı olmayan kelime anlamındaki belirsizliği giderme (birden fazla kelime duyusu seçeneğinden birini seçme ). Temel yaklaşımım, mevcut çözümlerle biraz rekabet edebilir ve (en önemlisi) özelleştirilebilir.

Size yeterince iyi bir ticari sonuç verebilecek bazı mevcut ticari NER araçları (OpenCalais, DBPedia Spotlight ve AlchemyAPI) vardır - önce bunları deneyin!

Bunlardan bazılarını bir müşteri projesi için kullandım (Londra'da NLP / ML kullanarak danışmanlık yapıyorum), ancak geri çağırmalarından ( hassasiyet ve hatırlama ) memnun değildim . Temelde kesin olabilirler ("Bu Apple Inc" dedikleri zaman genellikle doğrudurlar), ancak düşük hatırlama ile (bir insan için tweet açıkça Apple Inc ile ilgili olsa bile nadiren "Bu Apple Inc" derler). Tweetlere uygun bir açık kaynak sürümü oluşturmanın entelektüel açıdan ilginç bir egzersiz olacağını düşündüm. İşte mevcut kod: https://github.com/ianozsvald/social_media_brand_disambiguator

Not edeceğim - genelleştirilmiş kelime anlamındaki belirsizliği giderme problemini bu yaklaşımla çözmeye çalışmıyorum, sadece markanın belirsizliğini giderme (şirketler, insanlar, vb.) İsimleri zaten sizdeyken. Bu yüzden bu basit yaklaşımın işe yarayacağına inanıyorum.

Buna altı hafta önce başladım ve scikit-learn kullanılarak Python 2.7'de yazılmıştır. Çok basit bir yaklaşım kullanır. Bir ikili sayım vektörleştiricisi kullanarak (bir kelimenin kaç kez göründüğünü değil, yalnızca bir kelimenin görünüp görünmediğini sayıyorum) 1-3 n-gram ile vektörleştiriyorum  . TF-IDF ile ölçeklendirmiyorum (Değişken bir belge uzunluğuna sahip olduğunuzda TF-IDF iyidir; benim için tweetler sadece bir veya iki cümledir ve test sonuçlarım TF-IDF ile iyileşme göstermedi).

Çok basit ama şaşırtıcı derecede faydalı olan temel belirteçleri kullanıyorum. @ # Değerini yok sayar (bu nedenle bazı bağlamları kaybedersiniz) ve elbette bir URL'yi genişletmez. Daha sonra lojistik regresyon kullanarak eğitim alıyorum ve görünüşe göre bu problem bir şekilde doğrusal olarak ayrılabilir (bir sınıfa ilişkin pek çok terim diğeri için mevcut değildir). Şu anda herhangi bir kökten / temizlemeden kaçınıyorum (Çalışabilecek En Basit Olası Şey'i deniyorum).

Kodda tam bir BENİOKU var ve tweetlerinizi nispeten kolay bir şekilde besleyebilmeli ve ardından test önerilerimi uygulayabilmelisiniz.

İnsanlar Apple bilgisayarlarını yemediğinden veya içmediğinden, yazı yazmadığımız veya meyve ile oynamadığımız için bu Apple için işe yarıyor, böylece kelimeler kolayca bir kategoriye veya diğerine ayrılıyor. TV programı için # tanıma gibi bir şey düşünüldüğünde bu koşul geçerli olmayabilir (insanların Arap Baharı, kriket maçları, sınav revizyonu ve bir müzik grubu ile ilgili olarak #definance da kullandığı). Burada daha akıllı yaklaşımlar gerekebilir.

Ben blog gönderisi dizisi I (DataScienceLondon 140 kişilik daha kısa sunum dönüştü) BrightonPython kullanıcı grubu verdiğim bir bir saatlik sunum dahil olmak üzere bu projeyi açıklayan.

LogisticRegression (her sınıflandırma için bir olasılık elde ettiğiniz) gibi bir şey kullanırsanız, yalnızca kendine güvenen sınıflandırmaları seçebilir ve bu şekilde, geri çağırmaya karşı ticaret yaparak yüksek hassasiyeti zorlayabilirsiniz (böylece doğru sonuçları alırsınız, ancak bunlardan daha azını alırsınız). Bunu sisteminize ayarlamanız gerekecek.

Scikit-learn'ü kullanan olası bir algoritmik yaklaşım:

  • Binary CountVectorizer kullanın (Çoğu kelime yalnızca bir kez geçtiği için kısa mesajlardaki terim sayılarının fazla bilgi kattığını düşünmüyorum)
  • Bir Karar Ağacı sınıflandırıcıyla başlayın. O (bkz açıklanabilir performansa sahip olacak bir Karar Ağacı ile overfitting bir örnek için).
  • Lojistik regresyona geçin
  • Sınıflandırıcılar tarafından üretilen hataları araştırın (DecisionTree'nin dışa aktarılan çıktısını okuyun veya LogisticRegression'daki katsayılara bakın, yanlış sınıflandırılmış tweet'leri Vectorizer aracılığıyla geriye doğru çalışarak temelde yatan Kelime Torbası temsilinin neye benzediğini görün - orada daha az simge olacaktır. işlenmemiş tweet ile başladınız - bir sınıflandırma için yeterli var mı?)
  • Bu yaklaşımın çalışılmış bir sürümü için https://github.com/ianozsvald/social_media_brand_disambiguator/blob/master/learn1.py'deki örnek koduma bakın

Düşünülmesi gereken şeyler:

  • Daha büyük bir veri kümesine ihtiyacınız var. 2000 etiketli tweet kullanıyorum (benim beş saatimi aldı) ve en azından sınıf başına> 100 olan dengeli bir set istiyorsunuz (aşağıdaki aşırı uyum notuna bakın)
  • # @ Simgelerini belirteçlerde tutmak için belirteçleyiciyi (scikit-learn ile çok kolay) geliştirin ve belki büyük harfle yazılmış bir marka algılayıcı ekleyin (user @ user2425429 notları gibi)
  • İşler zorlaştığında doğrusal olmayan bir sınıflandırıcı düşünün (@ oiez'in yukarıdaki önerisi gibi). Kişisel olarak, LinearSVC'nin lojistik regresyondan daha kötü olduğunu buldum (ancak bu, henüz azaltmadığım yüksek boyutlu özellik uzayından kaynaklanıyor olabilir).
  • Konuşma etiketleyicisinin tweet'e özgü bir parçası (benim düşünceme göre Standford'un @Neil'in önerdiği gibi değil - benim deneyimime göre zayıf Twitter dilbilgisinde kötü performans gösteriyor)
  • Çok sayıda tokeniniz olduğunda, muhtemelen boyutsallık azaltma yapmak isteyeceksiniz (Bunu henüz denemedim - LogisticRegression l1 l2 cezalandırması hakkındaki blog yazıma bakın)

Yeniden. aşırı uyum gösterme. 2000 öğeli veri setimde Twitter'dan 'elma' tweetlerinin 10 dakikalık anlık görüntüsüne sahibim. Tweetlerin yaklaşık 2 / 3'ü Apple Inc için, 1 / 3'ü diğer elma kullanımları için. Her sınıfın dengeli bir alt kümesini (sanırım yaklaşık 584 satır) çıkarıyorum ve eğitim için beş kat çapraz doğrulama yapıyorum.

Sadece 10 dakikalık bir zaman aralığım olduğu için, aynı konu hakkında birçok tweet'im var ve muhtemelen sınıflandırıcımın mevcut araçlara göre bu kadar iyi olmasının nedeni budur - iyi bir genelleme yapmadan eğitim özelliklerine fazlasıyla uyacaktır (oysa mevcut ticari araçlar bu snapshop'ta daha kötü performans gösterir, ancak daha geniş bir veri kümesinde daha güvenilirdir). Bunu bir sonraki çalışma parçası olarak test etmek için zaman penceremi genişleteceğim.


Kodunuza bakmanın ve kopyalamaya / taklit etmeye / eğitmeye çalışmaktan zevk almadım, ancak ödülün 50 puanını tam olarak veremediğiniz için size bir özür borçluyum. Hafta sonu SO'dan uzaktaydım ve bunu ödüllendirmek için son tarihi kaçırdım. Neyse ki SO topluluğu devreye girdi ve size 25 puan vermeyi uygun gördü.
Ryan

1
Sorun değil :-) Kod, BENİOKU ve blog yazıları size yaklaşımım hakkında bir fikir verecektir. Kasıtlı olarak basit ama iyi çalışıyor görünüyor.
Ian Ozsvald

12

Aşağıdakileri yapabilirsiniz:

  1. Meyveler ve şirket ile ilgili tweet'lerde görülme sayılarını içeren bir sözcük diktesi yapın. Bu, eğilimini bildiğimiz bazı örnek tweet'lerle beslenerek sağlanabilir.

  2. Yeterli miktarda önceki veriyi kullanarak, apple inc ile ilgili tweet'te geçen bir kelimenin olasılığını bulabiliriz.

  3. Tüm tweetin olasılığını elde etmek için kelimelerin tek tek olasılıklarını çarpın.

Basitleştirilmiş bir örnek:

p_f = Meyve tweetlerinin olasılığı.

p_w_f = Meyveli tweet'te bir kelimenin geçme olasılığı.

p_t_f = Tweet'teki tüm kelimelerin bir meyve tweet'i oluşma olasılığı = p_w1_f * p_w2_f * ...

p_f_t = Belirli bir tweet verilen meyve olasılığı.

p_c, p_w_c, p_t_c, p_c_t şirket için ilgili değerlerdir.

Veritabanımızda bulunmayan yeni kelimelerin sıfır sıklığı sorununu ortadan kaldırmak için değer 1'in daha yumuşak bir laplacian eklenmiştir.

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

Dışarıdan bir kitaplık kullanmakla ilgili bir sorununuz yoksa, scikit-learn'ü tavsiye ederim çünkü bunu muhtemelen kendi başınıza kodlayabileceğiniz her şeyden daha iyi ve daha hızlı yapabilir. Bunun gibi bir şey yapardım:

Külliyatınızı oluşturun. Açıklık için liste anlamalarını yaptım, ancak verilerinizin nasıl saklandığına bağlı olarak farklı şeyler yapmanız gerekebilir:

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)

Önemli olan, şuna benzeyen iki listeyle karşılaşmanızdır:

([['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] pozitif ve negatif etiketleri temsil eder.

Ardından bir Pipeline oluşturursunuz! Pipeline, metin işleme adımlarını birbirine zincirlemeyi kolaylaştıran bir scikit-learn sınıfıdır, böylece eğitim / tahmin sırasında yalnızca bir nesneyi çağırmanız gerekir:

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

Ardışık Düzen içinde üç işlem adımı vardır. CountVectorizer, kelimeleri belirteçlere ayırır, böler, sayar ve verileri seyrek bir matrise dönüştürür. TfidfTransformer isteğe bağlıdır ve doğruluk derecesine bağlı olarak onu kaldırmak isteyebilirsiniz (çapraz doğrulama testleri yapmak ve en iyi parametreler için bir ızgara araması yapmak biraz işin içindedir, bu yüzden buraya girmeyeceğim). LinearSVC, standart bir metin sınıflandırma algoritmasıdır.

Son olarak, tweet kategorisini tahmin edersiniz:

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

Yine, tweet'in bir listede olması gerekiyor, bu yüzden işleve bir dize olarak girdiğini varsaydım.

Hepsini bir sınıfa falan koyun ve bitirdiniz. En azından bu çok basit örnekle.

Bu kodu test etmedim, bu yüzden sadece kopyalayıp yapıştırırsanız çalışmayabilir, ancak scikit-learn'ü kullanmak istiyorsanız size nereden başlayacağınız konusunda bir fikir vermelidir.

DÜZENLEME: Adımları daha detaylı açıklamaya çalıştım.


6

Bir karar ağacı kullanmak bu problem için oldukça işe yarıyor gibi görünüyor. En azından seçtiğim özelliklerle saf bir bayes sınıflandırıcısından daha yüksek bir doğruluk sağlıyor.

Bazı olasılıklarla oynamak istiyorsanız, nltk'nin yüklenmesini gerektiren aşağıdaki kodu kullanabilirsiniz. Nltk kitabı çevrimiçi olarak da ücretsiz olarak mevcuttur, bu nedenle tüm bunların gerçekte nasıl çalıştığını biraz okumak isteyebilirsiniz: 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
bu nasıl çalışıyor? Kodunuzda "seçtiğiniz özellikleri" göremiyorum. Eğitim setine göre özellikleri otomatik olarak seçiyor mu? Yoksa dict()başka bir yerde mi saklanıyor ? Bence birinin eğitim seti yeterince büyükse, bir bilgisayarın özellikleri kendi başına çözmesi gerekmez mi? (denetimsiz?)
Ryan

2
Özellikler tweet_features işlevi kullanılarak çıkarılır. Temel olarak url'leri tweet'lerden kaldırır ve ardından girişleri 'hasBigram (foo, bar)' = True gibi bir şey okuyan bir özellik diktesi oluşturur.
Paul Dubs

1
Peki 'hasBigram(foo,bar)' = Truetweet dizesi nerede bulunur foo bar? Yani her tweet için bigramlar ve trigramlar oluşturuyor ve bunu olumlu özellikte işaretliyor dict()? Bu nedenle, tweet verildiğinde, ve ? "alpha beta gamma delta"İçin dict () bigram'lar alpha,beta; beta,gamma; and gamma,delta;ve trigramlar oluşturacaktır. Ve verilen pozitif ve negatif bi ve tri gramlardan, karar ağacı veya bayes sınıflandırıcılar sihirlerini yapabilir mi? alpha,beta,gammabeta,gamma,delta
Ryan

2
Kesinlikle. Bayes sınıflandırıcısını kullanırken, üzerinde "show_most_informative_features ()" çağırarak da en kullanışlı özellikleri elde edebilirsiniz.
Paul Dubs

Paul, bunun kaba bir php sürümünü oluşturdum ve kesinlikle haklısın. Bu, ağırlıklı bir sözlük oluşturmanın süper verimli bir yoludur. Bunun, tüm anahtar kelimeleri manuel olarak oluşturmak zorunda kalmadan kolayca ölçeklenebileceğini düşünüyorum. Standart bir makine öğrenimi kitaplığı içinde bunun nasıl yapılacağı hakkında daha fazla bilgi edinmek için sabırsızlanıyorum.
Ryan

5

Şimdiye kadarki yorumlar için teşekkür ederim. İşte PHP ile hazırladığım çalışan bir çözüm . Yine de başkalarından aynı çözüme yönelik daha algoritmik bir yaklaşım duymakla ilgilenirim.

<?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;
}
?>

Yukarıdaki çıktılar:

           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

Verdiğiniz tüm örneklerde, Apple (inc) ya A pple ya da apple inc olarak anılıyordu , bu nedenle aşağıdakileri aramak için olası bir yol olabilir:

  • Apple'da büyük "A"

  • elmadan sonra bir "inc"

  • "OS", "işletim sistemi", "Mac", "iPhone" gibi kelimeler / ifadeler ...

  • veya bunların bir kombinasyonu


1
İşlevde büyük harfleri filtrelemek için bir strtolower yaptım. Biraz kaba ama işe yaradı.
SAL

@SAL Çok faydalı olmasını beklemiyordum, ancak bir zaman sınırınız varsa, o zaman ...
user2425429

4

Yanıtları Koşullu Rastgele Alanlara göre basitleştirmek için biraz ... bağlam burada çok büyük. Apple'ı şirkete karşı elma meyvesini açıkça gösteren tweet'lerden ayırmak isteyeceksiniz. Başlamanız için yararlı olabilecek özelliklerin bir listesini burada özetlememe izin verin. Daha fazla bilgi için isim öbekleri ve BIO etiketleri denen şeye bakın. Bkz. ( Http://www.cis.upenn.edu/~pereira/papers/crf.pdf )

Çevreleyen kelimeler: Önceki kelime ve sonraki kelime için veya belki de önceki 2 ve sonraki 2 kelime için daha fazla özellik istiyorsanız bir özellik vektörü oluşturun. Modelde çok fazla kelime istemezsiniz veya verilerle çok iyi eşleşmez. Natural Language Processing'de, bunu mümkün olduğunca genel tutmak isteyeceksiniz.

Çevreleyen sözcüklerden elde edilecek diğer özellikler şunları içerir:

İlk karakterin başkent olup olmadığı

Sözcükteki son karakterin nokta olup olmadığı

Kelimenin konuşma kısmı (Konuşma etiketlemesinin bir kısmına bakın)

Kelimenin metninin kendisi

Bunu tavsiye etmiyorum, ancak özellikle Apple için daha fazla özellik örneği vermek gerekirse:

WordIs (Apple)

NextWordIs (Inc.)

Sen anladın. Adlandırılmış Varlık Tanıma'yı bir diziyi tanımlıyor olarak düşünün ve sonra bir bilgisayara bunu nasıl hesaplayacağını söylemek için biraz matematik kullanın.

Doğal dil işlemenin ardışık düzen tabanlı bir sistem olduğunu unutmayın. Tipik olarak, bir şeyleri cümlelere bölersiniz, belirteç oluşturmaya geçersiniz, ardından konuşma etiketlemesinin bir bölümünü veya hatta bağımlılık ayrıştırmasını yaparsınız.

Bunların hepsi, aradığınızı belirlemek için modelinizde kullanabileceğiniz özelliklerin bir listesini size sunmak içindir.


3

Doğal dil metni işlemek için gerçekten iyi bir kütüphane var Python denir nltk. Ona bir bakmalısın.

Deneyebileceğiniz bir strateji, içinde "elma" kelimesi bulunan n-gramlara (kelime grupları) bakmaktır. Meyveden bahsederken bazı kelimelerin "elma" nın yanında, bazıları şirketten bahsederken kullanılması daha olasıdır ve bunları tweetleri sınıflandırmak için kullanabilirsiniz.


1
Teşekkürler Manetheran. Orijinal poster ben değilim ama yanıtı da merak ediyorum. Ödül için nltk, bir "merhaba dünya" makine öğrenimi göreviyle doğru yönde başlamama yardımcı olabilecek bir kod arıyorum (hatta kullanıyor ). Elma (inc) ve elma (meyve) mükemmel bir görev gibi görünüyor.
Ryan

3

LibShortText kullanın . Bu Python yardımcı programı, kısa metin kategorizasyon görevleri için zaten ayarlanmış ve iyi çalışıyor. Yapmanız gereken maksimum şey, bayrakların en iyi kombinasyonunu seçmek için bir döngü yazmaktır. E-postalarda denetimli konuşma hareketi sınıflandırması yapmak için kullandım ve sonuçlar% 95-97'ye kadar doğruydu (5 kat çapraz doğrulama sırasında!).

Ve yapımcıları geliyor LIBSVM ve LIBLINEAR kimin destek vektör makinesi (SVM) uygulaması sklearn ve karter kullanılır, makul bunların uygulanması arabası değil emin olabilirsiniz böylece.


2

Apple Inc'i (şirket) elmadan (meyve) ayırmak için bir AI filtresi yapın . Bunlar tweetler olduğundan, eğitim setinizi 140 alandan oluşan bir vektörle tanımlayın, her alan tweet'te X konumunda (0 ila 139) yazılan karakterdir. Tweet daha kısaysa, boş bırakılması için bir değer vermeniz yeterlidir.

Ardından iyi bir doğruluk elde etmek için yeterince büyük bir eğitim seti oluşturun (zevkinize göre öznel). Her tweet için bir sonuç değeri atama, bir Apple Inc 1 (doğru) almak tweet ve bir elma tweet (meyve) 0. Bu bir durumda olacağını alır denetimli öğrenme bir de lojistik regresyon .

Yani makine öğrenimi, kodlaması genellikle daha kolaydır ve daha iyi performans gösterir. Verdiğiniz setten öğrenmesi gerekir ve kodlanmış değildir.

Python bilmiyorum , bu yüzden onun kodunu yazamam, ancak makine öğreniminin mantığı ve teorisi için daha fazla zaman ayırırsan takip ettiğim sınıfa bakmak isteyebilirsin.

Deneyin Coursera kursu Makine Öğrenimi tarafından Andrew Ng . MATLAB veya Octave'de makine öğrenimini öğreneceksiniz , ancak temel bilgileri edindikten sonra, basit matematiği anlarsanız (lojistik regresyonda basit) herhangi bir dilde makine öğrenimi yazabileceksiniz.

Yani, birinden kodu almak, makine öğrenimi kodunda neler olup bittiğini anlamanızı sağlamaz. Gerçekte neler olup bittiğini görmek için konuya birkaç saat ayırmak isteyebilirsiniz.


Teşekkürler Fawar. Makine öğreniminin nasıl çalıştığını öğrenmek için bu "merhaba dünya" da tam da bu amaçla bir kod umuyordum. Yine de sınıfa bakacağım. İyi görünüyor.
Ryan

0

Varlık tanımayı öneren yanıtlardan kaçınmanızı tavsiye ederim. Çünkü bu görev önce bir metin sınıflandırması ve ikinci olarak varlık tanımadır (bunu varlık tanıma olmadan da yapabilirsiniz).

Sonuçlara giden en hızlı yolun spacy + prodigy olacağını düşünüyorum . Spacy, İngilizce dili için iyi düşünülmüş bir modeldir, bu yüzden kendinizinkini oluşturmak zorunda değilsiniz. Dahi, hızlı bir şekilde eğitim veri kümeleri oluşturmaya ve ihtiyaçlarınız için alan modeline ince ayar yapmaya izin verir.

Yeterli numuneniz varsa 1 günde düzgün bir modele sahip olabilirsiniz.


Aynı zamanda, spaCysahip nerboru hattı bileşeni, bu sınıflandırma için yararlı olmaz mı? Onların modelinin Apple(dünyanın en büyük ve en tanınmış şirketlerinden biri olduğu için) bir günde bulabileceğiniz bir modelden çok daha iyi tanıdığını varsayıyorum .
Szymon Maszke

@Szymon: NER yardımcı olabilir veya olmayabilir. Anladığım kadarıyla, ana sınıflandırma görevi için bir özellik olarak adlandırılmış varlıkları (metinde mevcut oldukları gerçeğini) kullanmak istiyorsunuz. Görünüşe göre, yüksek düzeyde belirsizlik olduğu için NER% 100 doğruluğa sahip olmayacak. Bu nedenle, ana sınıflandırma modeli hangi koşullar altında bu özelliğe güveneceğine karar verecektir. Temel bir sınıflandırma modelinin NER modelinin sonuçlarına çok düşük bir ağırlık vereceği (çok muhtemel olduğunu düşünüyorum) ortaya çıkabilir. Bu da (neredeyse) kullanılmayan NER'de vakit geçireceğiniz anlamına geliyor.
Dim

Demek istediğim değil. Sadece oluşturmak spacy.Doc, her metinden ile NERS iterate üzerinde doc.entsve herhangi NER olup olmadığını kontrol .textetmek eşit özelliği Apple. Eğlenceli gerçek, ilk örnekleri Apple'dan oluşuyor.
Szymon Maszke

Ve eğer birisi bir model yapmak isterse, bu büyük olasılıkla RNN'leri / CNN'leri ve benzerlerini içerir, onları buna göre ayarlar, mimariyi, hücre tiplerini vb. Bulur, daha kolay modellerin netliği ve bağlamı iyi ele alacağını düşünmüyorum. Birisi sizin için zaten yapmışsa, neden hayatınızı kolaylaştıralım (yol boyunca bir şeyler öğrenmek istemiyorsanız)?
Szymon Maszke

@SzymonMaszke, modeliniz daha karmaşık ve eğitilmesi daha zor. Modelinizin belirtilen amaç için çalışması için sadece bir NE bulmanız değil, aynı zamanda onu doğru bir yerde (belirteç) bulmanız gerekir. Modeli temel hedefinize göre optimize etmenizi önerdiğim kategorizasyon modeliyle - bunun Apple şirketi veya Apple meyvesi olduğunu belirleyin. Eğitilmesi daha kolay ve bu nedenle büyük olasılıkla daha doğru olacaktır.
Dim
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.