[PYTHON] Beginn der Niko Niko Encyclopedia Analysis ~ JSON und berühren Sie die bereitgestellten Daten ~

Verwenden Sie den Nico Nico Encyclopedia Dataset

Der Nico Nico Encyclopedia Dataset ist eine Sammlung von Artikeln der Nico Nico Encyclopedia, die auf IDR veröffentlicht wurden, und Kommentare zu diesen Artikeln.

Es eignet sich für die Erforschung natürlicher Sprachen wie die Wissensextraktion, ist jedoch kein leiser Datensatz wie Wikipedia, sondern ein eher eigenartiger Datensatz.

Zum Beispiel fehlt fast der Hälfte der Sätze in der Nico Nico Encyclopedia das Thema, der Stil ist nicht immer einheitlich und AA ist ebenfalls enthalten.

Dieses Mal werde ich den Inhalt der Daten zusammen mit einem einfachen Vorverarbeitungswerkzeug auf der Suche nach ** interessanten Personen ** vorstellen, die diesen Datensatz analysieren möchten.

Behandeln Sie die mitgelieferte Nico Nico-Enzyklopädie vor

Bei den bereitgestellten Daten handelt es sich um eine ** etwas spezielle CSV **, die bei ordnungsgemäßer Vorverarbeitung in eine Standard-CSV umgewandelt werden kann. Außerdem ist HTML für die Analyse etwas problematisch, da einige Tags problematisch sind. Deshalb

  1. CSV vorverarbeiten
  2. Transformieren Sie den Nico Nico Encyclopedia-Artikel (HTML) in JSON
  3. Werfen Sie einen Blick

Ich werde dies in diesem Artikel versuchen.

Vorverarbeitung

Die wichtige Umgebung für die Vorverarbeitung ist nicht der Speicher, sondern die Festplattenkapazität. Wenn Sie versehentlich nur 50 GB zusätzlichen Speicherplatz haben, schlägt die Vorverarbeitung mit einem Fehler fehl.

Wenn Sie Python verwenden, ist es außerdem besser, mehr CPU und Speicher zu haben. ~~ Oder besser gesagt, die Leistung von Pandas ist nicht so gut ... ~~

Antrag auf Datennutzung

https://www.nii.ac.jp/dsc/idr/nico/nicopedia-apply.html

Bewerben Sie sich von hier aus. Wenn Sie sich bewerben, erhalten Sie innerhalb weniger Tage eine URL zum Herunterladen. Behalten Sie diese also bei.

Laden Sie die komprimierte Datei herunter und entpacken Sie sie

Bitte laden Sie es von der URL herunter und erweitern Sie es, um es so anzuwenden.

.
└── nico-dict
    └── zips
        ├── download.txt
        ├── head
        │   ├── head2008.csv
        │   ├── ...
        │   └── head2014.csv
        ├── head.zip
        ├── res
        │   ├── res2008.csv
        │   ├── ...
        │   └── res2014.csv
        ├── res.zip
        ├── rev2008.zip
        ├── rev2009
        │   ├── rev200901.csv
        │   ├── rev200902.csv
        │   ├── rev200903.csv
        │   ├── ...
        │   └── rev200912.csv
        ├── rev2009.zip
        ├──...
        ├── rev2013.zip
        ├── rev2014
        │   ├── rev201401.csv
        │   └── rev201402.csv
        └── rev2014.zip

Repository-Klon

Ursprünglich habe ich Clojure (Lisp) wegen der Verzögerungsbewertung und der einfachen Vorverarbeitung für die Analyse verwendet, aber ich habe ein Tool entwickelt, um HTML-> JSON mit so wenig Verarbeitung wie möglich zu erstellen, damit es mit Python analysiert werden kann.

https://github.com/MokkeMeguru/niconico-parser

Bitte klonen von.

git clone https://github.com/MokkeMeguru/niconico-parser

CSV formatieren.

https://github.com/MokkeMeguru/niconico-parser/blob/master/resources/preprocess.sh

Zu zips / preprocess.sh

sh preprocess.sh

Bitte tu es. Diese Datei ist die Verarbeitung, die erforderlich ist, um das CSV-Escape an moderne Spezifikationen anzupassen. (Hintergrundgeschichte: Ich habe diesen Prozess ziemlich oft getestet, aber vielleicht gibt es einen Fehler. Wenn Sie einen Fehler haben, kommentieren Sie ihn bitte.)

Speichern Sie die Artikelkopfinformationen in der Datenbank

Der Datensatz der Nico Nico Encyclopedia ist grob unterteilt.

  1. Kopfzeile (Artikel-ID, Titel, Titellesung, Kategorie usw.)
  2. Artikelkörper
  3. Kommentare zum Artikel

Es ist geworden. Von diesen ist 1. ein Betrag, der leicht in einer Datenbank erstellt werden kann, sodass wir eine Datenbank erstellen.

Erforderliche Dateien sind https://github.com/MokkeMeguru/niconico-parser/blob/master/resources/create-table.sql und https://github.com/MokkeMeguru/niconico-parser/blob/master/resources/ import-dir.sh. Ordnen Sie diese so an, dass sie "zips / head / " sind

sh import-dir.sh

Bitte. Dann erhalten Sie eine Datenbank von sqlite3 mit dem Namen header.db.

Lassen Sie uns für eine Testversion darauf zugreifen.

sqlite3 headers.db
sqlite3 > select * from article_header limit 10
 ...> ;
 1|Nico Nico Enzyklopädie|Nico Nico Daihakka|a|20080512173939
 4|Curry|Curry|a|20080512182423
 5|Ich bat Hatsune Miku, das ursprüngliche Lied "Du hast Blumen und ich singe" zu singen.|\N|v|20080719234213
 9|Go Go Curry|Go Go Curry|a|20080512183606
 13|Authentisches Gachimuchi Pants Wrestling|\N|v|20080513225239
 27|Der Kopf ist Pfanne(P)┗(^o^ )┓3|\N|v|20080529215132
 33|[Hatsune Miku] "Ein kleiner lustiger Zeitbericht" [Arrangiertes Lied]|\N|v|20080810020937
 37|【 SYNC.ART'S × U.N.Ist Owen sie? ] -Sweets Time-|\N|v|20080616003242
 46|Nico Nico Video Meteor Gruppe|\N|v|20080513210124
 47|Ich habe einen hohen Trank gemacht.|\N|v|20090102150209

Es hat eine Smiley-Enzyklopädie und es riecht, als könnte man Wissen bekommen, das Wikipedia nicht hat.

HTML->JSON! Eines der großen Probleme bei Artikeln der Nico Nico Encyclopedia ist, dass es viele seltsame Tags gibt. Im Gegensatz zu Wikipedia gibt es viele "
" - Tags und "" - Tags zum Formatieren, und es war eine persönliche Antwort, dass ich große Probleme hatte, den Satz abzurufen. (~~ Außerdem ist AA fast außer Betrieb. Erstelle ein Tag für AA ... ~~)

Der einfachste Weg, HTML zu analysieren, ist mit DSL (domänenspezifische Sprache). Ein bekanntes ist Kotlins HTML-Analyse-Tool.

Diesmal habe ich versucht, es einfach mit Lisp zu verarbeiten. Der detaillierte Code lautet ... na ja () ...

lein preprocess-corpus -r /path/to/nico-dict/zips

Nun, bitte führen Sie es so aus. (Klicken Sie hier für die Jar-Ausführung (Fehlerbericht)) Es dauert ungefähr 10 bis 15 Minuten, um ungefähr 20 bis 30 GB Disc zu verbrauchen.

Werfen wir einen kurzen Blick auf den Inhalt.

head -n 1 rev2008-jsoned.csv 
1,"{""type"":""element"",""attrs"":null,""tag"":""body"",""content"":[{""type"":""element"",""attrs"":null,""tag"":""h2"",""content"":[""Überblick""]},{""type"":""element"",""attrs"":null,""tag"":""p"",""content"":[""Was ist Nico Nico Encyclopedia?(Kürzung)Ist.""]}]}",200xxxxxxxx939,[],Nico Nico Enzyklopädie,Nico Nico Daihakka,a

Um jeweils einen Punkt zu erklären

  1. Artikel-ID
  2. JSON-Konvertierung + vorverarbeiteter Artikel
  3. Datum der Artikelaktualisierung
  4. Liste der auf der Seite enthaltenen Links (<a> Tags)
  5. Titel
  6. Lesen Sie den Titel
  7. Kategorie ("a" = Wort "v" = Video "i" = Produkt "l" = Live-Übertragung "c" = möglicherweise Community-Artikel (Kategorie nicht in den Spezifikationen enthalten))

Ich kann den Effekt der JSON-Konvertierung + Vorverarbeitung dieses Mal nicht wirklich vorstellen, aber zum Beispiel ist es einfacher, Dinge wie "

hoge hoge
bar </ p>" und das Diagramm zu handhaben Es kann erwähnt werden, dass es einfacher ist, Tools wie [Schnorchel] anzuwenden (http://kento1109.hatenablog.com/entry/2018/01/09/121048).

Lassen Sie uns einige Statistiken machen

Ich habe ein Vorverarbeitungswerkzeug gemacht! Es ist nicht sehr langweilig, also machen wir so etwas wie Statistiken. Apropos Datenverarbeitung, es scheint Python + Pandas zu sein, also werde ich die Verwendung von Python + Pandas untersuchen. (Pandas ist jedoch sehr schwer oder langsam. Verwenden Sie daher ein anderes Tool für eine umfassende Analyse.)

Wir werden wie im Jupyter-Notizbuch unten vorgehen.

Abhängigkeitsimport

import pandas as pd
import json
from pathlib import Path
from pprint import pprint

Deklaration globaler Variablen

Bitte ändern Sie für jede Umgebung.

############################
#Globale Variablen(Gegebenenfalls ändern) #
############################
#CSV-Header
header_name = ('article_id', 'article', 'update-date',
               'links', 'title', 'title_yomi', 'category''')
dtypes = {'article_id': 'uint16',
          'article': 'object',
          'update-date': 'object',
          'links': 'object',
          'title': 'object',
          'title_yomi': 'object',
          'category': 'object'
}

#Beispiel CSV
sample_filepath = "/home/meguru/Documents/nico-dict/zips/rev2014/rev201402-jsoned.csv"
sample_filepath = Path(sample_filepath)

#Beispiel-CSVs
fileparent = Path("/home/meguru/Documents/nico-dict/zips")
filepaths = [
    "rev2014/rev201401-jsoned.csv",
    "rev2014/rev201402-jsoned.csv",
    "rev2013/rev201301-jsoned.csv",
    "rev2013/rev201302-jsoned.csv",
    "rev2013/rev201303-jsoned.csv",
    "rev2013/rev201304-jsoned.csv",
    "rev2013/rev201305-jsoned.csv",
    "rev2013/rev201306-jsoned.csv",
    "rev2013/rev201307-jsoned.csv",
    "rev2013/rev201308-jsoned.csv",
    "rev2013/rev201309-jsoned.csv",
    "rev2013/rev201310-jsoned.csv",
    "rev2013/rev201311-jsoned.csv",
    "rev2013/rev201312-jsoned.csv",
]
filepaths = filter(lambda path: path.exists(),  map(
    lambda fpath: fileparent / Path(fpath), filepaths))
##################

Definition der Funktion zum Lesen von vorverarbeitetem CSV

def read_df(csvfile: Path, with_info: bool = False):
    """read jsoned.csv file
    args:
    - csvfile: Path
    a file path you want to read
    - with_info: bool
    with showing csv's information
    returns:
    - df
    readed data frame
    notes:
    if you call this function, you will got some log message
    """
    df = pd.read_csv(csvfile, names=header_name, dtype=dtypes)
    print('[Info] readed a file {}'.format(csvfile))
    if with_info:
        df.info()
    return df


def read_dfs(fileparent: Path, csvfiles: List[Path]):
    """read jsoned.csv files
    args:
    - fileparent: Path
    parent file path you want to read
    - csvfiles: List[Path]
    file paths you want to read
    returns:
    - dfl
    concated dataframe
    note:
    given.
        fileparent = \"/path/to\"
        csvfiles[0] = \"file\"
    then.
        search file <= \"/path/to/file\"
    """
    dfl = []
    for fpath in filepaths:
        dfi = pd.read_csv(fileparent / fpath,
                          index_col=None, names=header_name, dtype=dtypes)
        dfl.append(dfi)
    dfl = pd.concat(dfl, axis=0, ignore_index=True)
    return dfl

Laden Sie 1 Datei in das Beispiel und die Ansicht

Schauen wir uns diesmal an, wie die Links ( Tags) im HTML-Code zeigen, wie sie für jeden Artikeltyp verteilt sind.

df = read_df(sample_filepath, True)
# [Info] readed a file /home/meguru/Documents/nico-dict/zips/rev2014/rev201402-jsoned.csv
# <class 'pandas.core.frame.DataFrame'>
# RangeIndex: 6499 entries, 0 to 6498
# Data columns (total 7 columns):
# article_id     6499 non-null int64
# article        6499 non-null object
# update-date    6499 non-null int64
# links          6499 non-null object
# title          6491 non-null object
# title_yomi     6491 non-null object
# category       6491 non-null object
# dtypes: int64(2), object(5)
# memory usage: 355.5+ KB

Vorerst konnte ich bestätigen, dass diese Datei selbst einen 6.5k-Artikel enthält.

Analysieren Sie dann die JSON-verknüpften Linkinformationen, um die Anzahl der Links zu berechnen.

#Bestätigung der Rohdaten
df['links'][0]
# => '[{"type":"element","attrs":{"href":"http://wwwxxxxhtml"},"tag":"a","content":["Kochi xxxx Seite"]}]'
dfs= pd.DataFrame()
dfs['links']= df['links'].map(lambda x: len(json.loads(x)))
dfs['links'][0]
# => 1

Nehmen wir eine kurze Statistik.

dfs['category']=df['category']
dfsg=dfs.groupby('category')
dfsg.describe()
#            links                                                      
#            count       mean         std  min  25%   50%    75%     max
# category                                                              
# a         5558.0  41.687298  209.005652  0.0  0.0   2.0  11.00  2064.0
# c           36.0  54.305556  109.339529  0.0  2.0   2.0  38.25   376.0
# i            4.0   7.500000    5.507571  2.0  3.5   7.0  11.00    14.0
# l          786.0  22.760814  106.608535  0.0  0.0   2.0   9.00  1309.0
# v          107.0  32.887850   46.052744  0.0  3.0  11.0  37.00   153.0

"a" = Wort "v" = Video "i" = Produkt "l" = Live-Übertragung "c" = Community-Artikel, daher gibt es im Durchschnitt viele ** Community-Artikel-Links **. Wenn Sie sich jedoch den Median und den Maximalwert ansehen, können Sie feststellen, dass es notwendig erscheint, die Wortartikel genauer zu betrachten (zu klassifizieren).

Versuchen Sie, die Probendaten zu erhöhen und zu überprüfen

6k Artikel reichen nicht aus, also erhöhen wir die Daten.

dfl = read_dfs(fileparent, filepaths)
# >>>         article_id                                            article  ...             title_yomi category
# 0             8576  {"type":"element","attrs":null,"tag":"body","c...  ...Kabekick a
# [223849 rows x 7 columns]
dfls = pd.DataFrame()
dfls['links'] = dfl['links'].map(lambda x: len(json.loads(x)))
dfls['category'] = dfl['category']
dflsg = dfls.groupby('category')
dflsg.describe()
#              links
#              count       mean         std  min  25%  50%   75%     max
# category
# a         193264.0  32.400566  153.923988  0.0  0.0  2.0  10.0  4986.0
# c           1019.0  34.667321   77.390967  0.0  1.0  2.0  34.0   449.0
# i            247.0   6.137652    6.675194  0.0  1.0  3.0  10.0    28.0
# l          24929.0  20.266477  100.640253  0.0  0.0  1.0   5.0  1309.0
# v           3414.0  14.620387   22.969974  0.0  1.0  6.0  16.0   176.0

Insgesamt können Sie sehen, dass der Durchschnittswert von Live- und Videolinks umgekehrt wird, wenn die Anzahl der Videolinks abnimmt. Außerdem kann der Punkt bestätigt werden, dass der Schwankungsbereich der Anzahl der Links im Wortartikel zu groß ist, wie im Fall einer Stichprobe. Ebenfalls nicht intuitiv ist, dass ** Wortartikel unter dem Durchschnitt im dritten Quadranten ** liegen.

Aus den obigen Ergebnissen ist ersichtlich, dass zumindest die Anzahl der Links je nach Art des Artikels erheblich variiert, und ich denke, dass es besser erscheint, zu studieren, nachdem die Eigenschaften jedes Artikels einzeln betrachtet wurden. (Werfen Sie dem Betrachter zu, wie er die Ergebnisse von hier aus studieren und produzieren kann.)

Gibt es eine Korrelation zwischen der Anzahl der Artikellinks und der Artikelgröße?

Aus dem vorherigen Experiment können Sie erkennen, dass die Streuung für Wortartikel besonders groß ist. Der Grund dafür ist ** aus meiner Erfahrung und Intuition, wenn ich normalerweise die Enzyklopädie von Nico Nico ** betrachte, dass ich die Korrelation zwischen der Artikelgröße und der Anzahl der Links gefunden habe. Betrachten wir also die Anzahl der Zeichen in den JSON-konvertierten Daten als Artikelgröße und überprüfen Sie die Korrelation.

dfts.corr()
#                  links  article_size
# links         1.000000      0.713465
# article_size  0.713465      1.000000

Nun, zumindest scheint es eine starke positive Korrelation zu geben.

Wenn Sie etwas weiter gehen, sieht es so aus.

#Über Wortartikel
dfts[dfts['category'] == "a"].loc[:, ["links", "article_size"]].corr()
#                  links  article_size
# links         1.000000      0.724774
# article_size  0.724774      1.000000



#Über Community-Artikel
dfts[dfts['category'] == "c"].loc[:, ["links", "article_size"]].corr()
#                links  article_size
# links        1.00000       0.63424
# article_size 0.63424       1.00000

#Über Produktartikel
dfts[dfts['category'] == "i"].loc[:, ["links", "article_size"]].corr()
#                  links  article_size
# links         1.000000      0.254031
# article_size  0.254031      1.000000

#Über Live-Artikel
dfts[dfts['category'] == "l"].loc[:, ["links", "article_size"]].corr()
#                 links  article_size
# links         1.00000       0.58073
# article_size  0.58073       1.00000

#Über Videoartikel
dfts[dfts['category'] == "v"].loc[:, ["links", "article_size"]].corr()
#                  links  article_size
# links         1.000000      0.428443
# article_size  0.428443      1.000000

News Wir haben eine CLI zur Analyse von im Web veröffentlichten Artikeln entwickelt.

lein parse-from-web -u https://dic.nicovideo.jp/a/<contents-title>

Sie können die Artikeldaten wie folgt in JSON konvertieren lassen. Ein Beispiel für die Erfassung finden Sie unter Repository.

Dies ** belastet jedoch den Server des anderen Teilnehmers **. Verwenden Sie ihn daher bitte für Zwecke, z. B. zum Ausprobieren eines Tools für eine Weile. Selbst wenn Sie einen Fehler machen, ahmen Sie bitte nicht die Teppichbomben nach, die vom IP der Universität abgekratzt wurden.

Recommended Posts

Beginn der Niko Niko Encyclopedia Analysis ~ JSON und berühren Sie die bereitgestellten Daten ~
Die Bildanalyse war mit den von Microsoft COCO bereitgestellten Daten und der API einfach
Der Beginn von cif2cell
Analyse von Finanzdaten durch Pandas und deren Visualisierung (2)
Analyse von Finanzdaten durch Pandas und deren Visualisierung (1)
Mathematisches Verständnis der Hauptkomponentenanalyse von Anfang an
Geschichte der Bildanalyse von PDF-Dateien und Datenextraktion
Analyse der Messdaten (2) -Hydrobacter und Anpassung, lmfit Empfehlung-
DJango Hinweis: Von Anfang an (Vereinfachung und Aufteilung von URLConf)
Lassen Sie uns die Analyse der sinkenden Daten der Titanic so durchführen
Datenanalyse basierend auf den Wahlergebnissen der Gouverneurswahl von Tokio (2020)
Berühre den Schein und den Stummel
Ein Python-Anfänger hat in den letzten 10 Jahren zunächst versucht, die Wetterdaten schnell und einfach zu analysieren.
Empfohlene Bücher und Quellen für die Datenanalyseprogrammierung (Python oder R)
Eine einfache Datenanalyse von Bitcoin, die von CoinMetrics in Python bereitgestellt wird
Über Boxplot und Violinplot, die die Variation unabhängiger Daten visualisieren
Praxis der Datenanalyse durch Python und Pandas (Tokyo COVID-19 Data Edition)
Die Geschichte von Python und die Geschichte von NaN
Erster Python 3 ~ Der Beginn der Wiederholung ~
Berühren Sie das Objekt des neuronalen Netzes
Empfehlung zur Datenanalyse mit MessagePack
Zeitreihenanalyse 3 Vorverarbeitung von Zeitreihendaten
Datenverarbeitung 2 Analyse verschiedener Datenformate
Fassen Sie die wichtigsten Wachstumspunkte von Webdiensten und die Analysepunkte zusammen
Senden und Empfangen von Bilddaten als JSON in Python über das Netzwerk
Suchen Sie den Namen und die Daten einer freien Variablen in einem Funktionsobjekt
Extrahieren und zeichnen Sie die neuesten Bevölkerungsdaten aus den von der Stadt bereitgestellten PDF-Daten
Die Geschichte einer Soundkamera mit Touch Designer und ReSpeaker
Zusammenfassung der Wahrscheinlichkeitsverteilungen, die häufig in Statistiken und Datenanalysen vorkommen
Datenbereinigung offener Daten zur Ereignissituation des Ministeriums für Gesundheit, Arbeit und Soziales
Holen Sie sich den Schlüssel für die Migration von JSON-Daten auf der zweiten Ebene mit Python