[PYTHON] Ich habe versucht, ein Schätzmodell für Artikeltitel zu erstellen, die wahrscheinlich mit Qiita in Einklang stehen

Ich habe Python berührt, aber ich habe wenig Erfahrung mit der Implementierung von maschinellem Lernen. → Ich möchte vor allem etwas mit natürlicher Sprachverarbeitung machen Mit diesem Gefühl habe ich ein Buzz-Schätzmodell erstellt.

Überblick

Implementierung

Sammeln Sie Artikeltiteldaten

Artikel zum Trend

Beziehen Sie es über das Twitter-Konto (Qiita Popular Posts), das Trendartikel mithilfe der Twitter-API einführt. 3229 Daten werden gesammelt, die URL und die Piktogramme im Tweet werden entfernt und dann in die JSON-Datei kopiert.

def retrieveTweets(screenName, count):
    global totalIdx
    timeLine = t.statuses.user_timeline(screen_name=screenName, count=count)
    maxId = 0
    for tweetsIdx, tweet in enumerate(timeLine):
        maxId = tweet["id"]
        addArticleTitles(tweet)
        totalIdx += 1
    print("Starting additional retrieving...")
    retrieveContinuedTweets(screenName, count, maxId)

def retrieveContinuedTweets(screenName, count, maxId):
    global totalIdx, isFinished
    tmpMaxId = maxId
    while True:
        timeLine = t.statuses.user_timeline(screen_name=screenName, count=count, max_id=tmpMaxId)
        prevMaxId = 0
        for tweetsIdx, tweet in enumerate(timeLine):
            tmpMaxId = tweet["id"]
            addArticleTitles(tweet)
            print("totalIdx = {}, prevMaxId = {}, maxId = {}, title = {}\n".format(totalIdx, prevMaxId, tmpMaxId, trendArticleTitles[totalIdx]["articleTitle"]))
            if prevMaxId == 0 and totalIdx % 200 != 0:
                isFinished = True
                break
            prevMaxId = tmpMaxId
            totalIdx += 1
        if isFinished:
            print("Finished collecting {} qiita_trend_titles.".format(totalIdx))
            break

def addArticleTitles(tweet):
    global trendArticleTitles
    tmpTitle = re.sub(r"(https?|ftp)(:\/\/[-_\.!~*\'()a-zA-Z0-9;\/?:\@&=\+\$,%#]+)", "", tweet["text"]) #URL in Tweets entfernen
    tmpTitle = ''.join(s for s in tmpTitle if s not in emoji.UNICODE_EMOJI)
    articleTitle = tmpTitle[:len(tmpTitle)-1] #Entfernen Sie den halbbreiten Raum am Ende
    datum = {"articleTitle": articleTitle}
    trendArticleTitles.append(datum)

Regelmäßiger Artikel

Verwenden Sie die Qiita-API, um die Titel regulärer Artikel abzurufen, die nicht summend sind. Hier wurden 9450 Daten gesammelt und in eine JSON-Datei sowie Trendartikel-Titel verschoben.

articleTitles = []
idx = 0
print("Starting collecting article titles...")
for page in range(3, 101):
    #Schließen Sie frühe Seiten aus, um Artikel von Spam-Konten auszuschließen
    params = {"page": str(page), "per_page": str(per_page)}
    response = requests.get(url, headers=headers, params=params)
    resJson = response.json()
    for article in resJson:
        if article.get("likes_count") < notBuzzThreshold:
            title = article.get("title")
            articleTitles.append({"articleTitle": title})
            print("{}th article title = {}, url = {}".format(idx, title, article["url"]))
            idx += 1
print("Finished collecting {} qiita_article_titles.".format(idx))

Kombinieren Sie Artikeltiteldatensätze in einer Datei

Laden Sie zunächst die beiden oben gesammelten Arten von Artikeltiteldaten. Während wir ein Flag hinzufügen, um festzustellen, ob es sich um einen Trendartikel handelt, werden wir ihn als einzelnes Datenelement fertigstellen. Mischen Sie für alle Fälle den Inhalt der kombinierten Daten.

Wieder wird die JSON-Datei am Ende ausgegeben und die Datenerfassung ist abgeschlossen.

mergedData = []
for datum in trendData:
    mergedData.append({
        "articleTitle": datum["articleTitle"],
        "isTrend": 1
    })
for datum in normalData:
    mergedData.append({
        "articleTitle": datum["articleTitle"],
        "isTrend": 0
    })

#Mische die Reihenfolge der kombinierten Ergebnisse
random.shuffle(mergedData)
print("Finished shuffling 'Merged Article Titles'.")

Üben Sie mit der Spam-Erkennung

Ich habe versucht, ein Schätzmodell mit Naive Bayes zu erstellen, war mir aber nicht sicher, womit ich anfangen sollte. Daher habe ich Naive Bayes selbst überprüft und einen Artikel ausprobiert, der die Spam-Erkennung in Naive Bayes implementiert, damit ich vor dieser Implementierung ein Gefühl dafür bekommen kann.

Naive Buchten-Studie

Naive Bayes-Praxis mit Spam-Erkennung

Nachdem ich viel über Naive Bayes gelernt habe, habe ich die Implementierung geübt. Ich ging weiter entlang der ↓. Maschinelles Lernen ~ Junk-Mail-Klassifizierung (Naive Bayes-Klassifizierer) ~

Ersetzt durch Qiita-Artikeldatensatz

Jetzt, da Sie ein Gefühl für Naive Bayes haben, ist es Zeit, sich mit dem Hauptthema zu befassen. Ich werde über die Teile schreiben, die gegenüber der Implementierung des in der Praxis verwendeten Artikels geändert wurden.

Installieren Sie MeCab, ipadic-NEologd

Da der Spam-Erkennungsdatensatz auf Englisch ist, kann er direkt in scikit-learn geworfen werden, der Titel des Qiita-Artikels jedoch nicht. Fügen Sie zuerst MeCab und ipadic-NEologd hinzu, damit Sie Wörter auf Japanisch gut teilen können. (Das Ergebnis der Teilung wurde vorerst mit CountVectorizer erhalten, war aber unnatürlich.)

Ich habe mich hauptsächlich auf die folgende Seite bezogen.

Modellbau

Aus der Implementierung der Spam-Erkennungspraxis haben wir Folgendes hinzugefügt:

def getStopWords():
    stopWords = []
    with open("./datasets/Japanese.txt", mode="r", encoding="utf-8") as f:
        for word in f:
            if word != "\n":
                stopWords.append(word.rstrip("\n"))
    print("amount of stopWords = {}".format(len(stopWords)))
    return stopWords

def removeEmoji(text):
    return "".join(ch for ch in text if ch not in emoji.UNICODE_EMOJI)

stopWords = getStopWords()
tagger = MeCab.Tagger("mecabrc")
def extractWords(text):
    text = removeEmoji(text)
    text = neologdn.normalize(text)
    words = []
    analyzedResults = tagger.parse(text).split("\n")
    for result in analyzedResults:
        splittedWord = result.split(",")[0].split("\t")[0]
        if not splittedWord in stopWords:
            words.append(splittedWord)
    return words

Wenn Sie die Wortaufteilungsmethode an den Argumentanalysator von CountVectorizer übergeben, scheint sich auch Japanisch gut aufzuteilen. groß.

vecCount = CountVectorizer(analyzer=extractWords, min_df=3)

Ausführungsergebnis

Wir haben drei Texte für die Vorhersage vorbereitet: "" Ich habe die App veröffentlicht "", "Unity Tutorial", "Git Command Memo". "Ich habe versucht, die App freizugeben" soll "summen".

Count Vectorizer ohne angegebenen Analysator

Offensichtlich ist die Anzahl der Wörter gering. Ich habe das Gefühl, dass es nicht normal geteilt wurde.

word size:  1016
word content:  {'Von': 809, 'ms': 447, 'nginx': 464, 'django': 232, 'intellij': 363}
Train accuracy = 0.771
Test accuracy = 0.747
[0 0 0]

Bestimmen Sie den NEoglod von MeCab als morphologischen Analysator

Es scheint, dass die Wörter geteilt werden können, aber es gibt viele Wörter ... Die Klassifizierung ist wie erwartet.

word size:  3870
word content:  {'Von': 1696, 'MS': 623, 'Teams': 931, 'Zu': 1853, 'Benachrichtigung': 3711}
Train accuracy = 0.842
Test accuracy = 0.783
[1 0 0]

Stoppwörter und Piktogramme entfernen

Die Anzahl der Wörter wurde reduziert und die Genauigkeit der Testdaten wurde leicht erhöht. Ich fühlte die Wichtigkeit der Vorbehandlung.

word size:  3719
word content:  {'MS': 623, 'Teams': 931, 'Zu': 1824, 'Benachrichtigung': 3571, 'Machen': 1735}
Train accuracy = 0.842
Test accuracy = 0.784
[1 0 0]

Verschiedene Normalisierungsprozesse hinzugefügt

Die Genauigkeit der Trainingsdaten hat leicht abgenommen, aber die Genauigkeit der Testdaten hat sich entsprechend erhöht. Außerdem habe ich vergessen, die Klassifizierungswahrscheinlichkeit anzuzeigen, daher werde ich sie hier anzeigen. Der Text, von dem ich annahm, dass er summt, war ehrlich gesagt mit einer höheren Wahrscheinlichkeit überrascht als ich erwartet hatte. (Es ist unzuverlässig, wenn Sie es nicht mit mehr Texten versuchen ...)

word size:  3700
word content:  {'MS': 648, 'Teams': 955, 'Zu': 1838, 'Benachrichtigung': 3583, 'Machen': 1748}
[1 0 0]
[[0.23452364 0.76547636]
 [0.92761086 0.07238914]
 [0.99557625 0.00442375]]
Train accuracy = 0.841
Test accuracy = 0.785

Überlegungen / Probleme usw.

Diesmal schien die Änderung der Genauigkeit im Bereich des Fehlers zu liegen. Ich konnte nur die in NEologd enthaltenen Mindestbedingungen garantieren, daher dachte ich, dass die Genauigkeit durch die Vektorisierung technischer Begriffe verbessert werden könnte. Danach scheint sich die Genauigkeit zu verbessern, selbst wenn Sie wichtige Wörter mit TF-IDF usw. aus dem Artikeltitel und dem Artikelinhalt extrahieren und verwenden.

Recommended Posts

Ich habe versucht, ein Schätzmodell für Artikeltitel zu erstellen, die wahrscheinlich mit Qiita in Einklang stehen
Ich habe versucht, mit Raspberry Pi 4 eine Umgebung von Ubuntu 20.04 LTS + ROS2 zu erstellen
Ich habe versucht, die Operationen zusammenzufassen, die wahrscheinlich mit numpy-stl verwendet werden
Ich habe versucht, einen Artikel mit SQL Alchemy auf Wiki.js zu erstellen
Ich habe versucht, den Authentifizierungscode der Qiita-API mit Python abzurufen.
Ich habe versucht, das Verhalten des neuen Koronavirus mit dem SEIR-Modell vorherzusagen.
Ich habe versucht, ein Objekt mit M2Det zu erkennen!
Ich habe versucht, ein Modell mit dem Beispiel von Amazon SageMaker Autopilot zu erstellen
Ich habe versucht, eine Umgebung mit WSL + Ubuntu + VS-Code in einer Windows-Umgebung zu erstellen
Ich habe versucht, Funktionen mit SIFT von OpenCV zu extrahieren
Ich habe versucht, das Artikel-Update des Livedoor-Blogs mit Python und Selen zu automatisieren.
Ich habe versucht, künstliches Perzeptron mit Python zu implementieren
Ich habe versucht, eine ML-Pipeline mit Cloud Composer zu erstellen
Ich habe versucht, eine OCR-App mit PySimpleGUI zu erstellen
Ich habe versucht, die alternative Klasse mit Tensorflow zu finden
Ich habe versucht, mit Python (Mac OS X) eine Umgebung für maschinelles Lernen zu erstellen.
[Python] Ich habe versucht, mit tkinter eine Anwendung zu erstellen, die das Gehalt anhand der Arbeitszeit berechnet
Ich habe mit Lambda eine App erstellt, die LINE über die Qiita-API über "Likes" informiert.
Ich habe mit Docker eine API erstellt, die den vorhergesagten Wert des maschinellen Lernmodells zurückgibt
Ich habe versucht, mit Docker einen Dienst aufzubauen, der maschinell erlernte Daten mit explosiver Geschwindigkeit verkauft
Ich habe versucht, den Verkauf von Spielesoftware mit VARISTA anhand des Artikels von Codexa vorherzusagen
Ich habe versucht, die Entropie des Bildes mit Python zu finden
Ich habe versucht, mit TensorFlow den Durchschnitt mehrerer Spalten zu ermitteln
Ich habe versucht, ListNet of Rank Learning mit Chainer zu implementieren
Ich habe versucht, in einem tief erlernten Sprachmodell zu schreiben
Ich habe versucht, SSD jetzt mit PyTorch zu implementieren (Modellversion)
Ich habe versucht, die Anzahl der im Inland infizierten Menschen der neuen Korona mit einem mathematischen Modell vorherzusagen
[Python] Ich habe versucht, Wörter, die für Anfänger schwer zu verstehen sind, auf leicht verständliche Weise zu erklären.
Ich habe versucht, eine Originalsprache "PPAP Script" zu erstellen, die PPAP (Pen Pineapple Appo Pen) mit Python abbildet
Ich habe versucht, eine Aktivität zu erstellen, die gemeinsam die Positionsinformationen festlegt
Ich habe versucht, das Ranking des Qiita-Adventskalenders mit Python zu kratzen
Ich habe versucht, die Bewässerung des Pflanzgefäßes mit Raspberry Pi zu automatisieren
Ich habe versucht, das SD-Boot-Image von LicheePi Nano zu erstellen
[Python] Ein Memo, das ich versucht habe, mit Asyncio zu beginnen
Ich habe versucht, mit Python eine Liste von Primzahlen zu erstellen
Ich habe versucht zu beheben "Ich habe versucht, die Wahrscheinlichkeit eines Bingospiels mit Python zu simulieren"
Ich habe versucht zusammenzufassen, was mit Qiita mit Word Cloud ausgegeben wurde
Ich habe versucht, in 3 Jahren 5 Muster der Analysebasis zu erstellen
Ich habe versucht, die Größe des logischen Volumes mit LVM zu erweitern
Ich habe versucht, Boeing die Geigenleistung durch Posenschätzung vorzustellen
Ich habe versucht, die Effizienz der täglichen Arbeit mit Python zu verbessern
Ich habe versucht, automatisch Bilder von Kanna Hashimoto mit Python zu sammeln! !!
Ich habe versucht, mit Python + OpenCV eine Bildähnlichkeitsfunktion zu erstellen
Ich habe versucht, mit Go einen exklusiven Kontrollmechanismus zu erstellen
Ich habe versucht, eine Umgebung zu erstellen, in der Tweet-Daten in WSL (bash) erfasst, gespeichert und analysiert werden können.
(Python) Ich habe eine App von Trello erstellt, die regelmäßig über das Auslaufen von Aufgaben informiert, die bald ablaufen.
Ich habe versucht, die Liste der Drehzahlen des SSH-Anmeldeziels mit Python + openpyxl in einer Excel-Tabelle auszugeben.
Ich habe versucht, Deep Learning zu implementieren, das nicht nur mit NumPy tiefgreifend ist
Ich habe versucht, eine Blockchain zu implementieren, die tatsächlich mit ungefähr 170 Zeilen funktioniert
Ich habe mit TWE-Lite-2525A einen Öffnungs- / Schließsensor (Twitter-Link) erstellt
Ich habe versucht, die Bewegungen von Wiire-Playern automatisch mit Software zu extrahieren
Ich habe versucht, die Negativität von Nono Morikubo zu analysieren. [Vergleiche mit Posipa]
Ich habe versucht, die Standardrolle neuer Mitarbeiter mit Python zu optimieren
Ich habe versucht, den Text des Romans "Wetterkind" mit Word Cloud zu visualisieren
Ich habe versucht, das Modell mit der Low-Code-Bibliothek für maschinelles Lernen "PyCaret" zu visualisieren.
Ich habe versucht, das neueste Haltungsschätzungsmodell "Dark Pose" [CVPR2020] zu erklären.
Ich habe versucht, die Filminformationen der TMDb-API mit Python abzurufen
Ich habe versucht, alle Entscheidungsbäume des zufälligen Waldes mit SVG zu visualisieren
Ich habe versucht, eine Mac Python-Entwicklungsumgebung mit pythonz + direnv zu erstellen
[Lambda] Ich habe versucht, ein externes Python-Modul über S3 zu integrieren
Ich möchte eine API erstellen, die ein Modell mit einer rekursiven Beziehung im Django REST Framework zurückgibt