[PYTHON] Japanische Textvorverarbeitung ohne Aussage in Pandas

Eine Erinnerung daran, dass bei der Verarbeitung von Text mit Pandas nicht "Ich weiß nicht, verwenden Sie also einen for-Satz" angezeigt wird.

Sammeln Sie Informationen, um japanischen Text vorzuverarbeiten.

Ich würde mich freuen, wenn Sie mir sagen könnten, ob es eine bessere Verarbeitungsmethode gibt.

Ausführungsumgebung

pandas 0.25.3

TL;DR

Beispieldaten

Speichern Sie Informationen zu Damenmodemarken, die von HP stammen. Der Firmenname, der Markenname, der Filialname und die Adresse werden in csv gespeichert.

Da es von mehreren HPs abgekratzt wird, ist es nicht einheitlich, z. B. halbe Breite, volle Breite und leer. Die Postleitzahl kann enthalten sein oder nicht.

Die folgende Tabelle ist ein Beispiel für Daten. Das Ausführungsergebnis wird ebenfalls anhand dieser Daten als Beispiel beschrieben.

company brand location address
pal BONbazaar Bombazare Tokyo Dome Stadt La Coeur 1-1 Kasuga, Bunkyo-ku, Tokio-1 La Coeur Gebäude 2F
world index Emio-Stil 1 Takada Baba, Shinjuku-ku, Tokio-35-3 Emio Style 1F
pal Whim Gazette Marunouchi-Laden 〒100-6390 2 Marunouchi, Chiyoda-ku, Tokio-4-1 Marunouchi-Gebäude B1F
stripe SEVENDAYS=SUNDAY Aeon Mall Urawa Misono 2F 5-50-1, Misono, Midori-ku, Saitama-shi, Saitama Aeon Mall Urawa Misono
pal mystic Funabashi-Laden 〒273-0012 2 Hamacho, Stadt Funabashi, Präfektur Chiba-1-1 LaLaport TOKYO-BAY LaLaport 3
pal pual ce cin Ofuna Lumine Wing Geschäft 〒247-0056 1 Ofuna, Stadt Kamakura, Präfektur Kanagawa-4-1 Lumine Wing 4F
stripe Green Parks Sara Chapo Koiwa Laden 7 Minamikoiwa, Edogawa-ku, Tokio-24-15 Chapo Koiwa 1F
pal Discoat Discoat Petit Ikebukuro Einkaufspark 〒171-8532 1 Minami Ikebukuro, Toyoshima-ku, Tokio-29-1 Ikebukuro SP B1F
adastoria niko and... Atre Kawagoe 105 Wakita-cho, Kawagoe-shi, Saitama Atre Kawagoe 4F
pal CIAOPANIC TYPY Kameari-Laden 〒125-0061 3 Kameari, Katsushika-ku, Tokio-49-3 Ario Kameari 2F

Da nur eine Spalte ("Adress" -Spalte) zur Erläuterung verwendet wird, ist die Verarbeitung von Serien fast eingeführt, aber die Verarbeitung von DataFrame wird auch so weit wie möglich beschrieben.

wird bearbeitet

Grundsätzlich in Series.str, Python-String-Methode und [Operation mit regulären Ausdrücken] Sie können anrufen (https://docs.python.org/ja/3/library/re.html), um diese zu verwenden.

――Auszüge häufig verwendeter Gegenstände

Zeichenketten-Methodensystem

strip

Series.str.strip

Löschen Sie die leeren Zeichen am Anfang und Ende der Zeichenfolge.

df['strip']=df['address'].str.strip()

Natürlich sind auch "Series.str.rstrip" implementiert, das nur den Anfang löscht, und "lstrip", das nur das Ende löscht.

split, rsplit

Series.str.split

df['address'].str.split(expand=True)
0 1 2
1-1 Kasuga, Bunkyo-ku, Tokio-1 La Coeur Gebäude 2F
1 Takada Baba, Shinjuku-ku, Tokio-35-3 Emio-Stil 1F
〒100-6390 2 Marunouchi, Chiyoda-ku, Tokio-4-1 Marunouchi Gebäude B1F
5-50-1, Misono, Midori-ku, Saitama-shi, Saitama Aeon Mall Urawa Misono None
〒273-0012 2 Hamacho, Stadt Funabashi, Präfektur Chiba-1-1 LaLaport TOKYO-BAY LaLaport 3 None
〒247-0056 1 Ofuna, Stadt Kamakura, Präfektur Kanagawa-4-1 Lumine Wing 4F
7 Minamikoiwa, Edogawa-ku, Tokio-24-15 Chapo Koiwa 1F None
〒171-8532 1 Minami Ikebukuro, Toyoshima-ku, Tokio-29-1 Ikebukuro SP B1F None
Wakita Town, Kawagoe City, Präfektur Saitama 105 Atre Kawagoe 4F
〒125-0061 3 Kameari, Katsushika-ku, Tokio-49-3 Ario Kameari 2F None None
df['address'].str.rsplit(expand=True, n=1)
0 1
1-1 Kasuga, Bunkyo-ku, Tokio-1 La Coeur Gebäude 2F
1 Takada Baba, Shinjuku-ku, Tokio-35-3 Emio-Stil 1F
〒100-6390 2 Marunouchi, Chiyoda-ku, Tokio-4-1 Marunouchi Gebäude B1F
5-50-1, Misono, Midori-ku, Saitama-shi, Saitama Aeon Mall Urawa Misono
〒273-0012 2 Hamacho, Stadt Funabashi, Präfektur Chiba-1-1 LaLaport TOKYO-BAY LaLaport 3
〒247-0056 1 Ofuna, Stadt Kamakura, Präfektur Kanagawa-4-1 Lumine Wing 4F
7 Minamikoiwa, Edogawa-ku, Tokio-24-15 Chapo Koiwa 1F
〒171-8532 1 Minami Ikebukuro, Toyoshima-ku, Tokio-29-1 Ikebukuro SP B1F
105 Wakita-cho, Kawagoe-shi, Saitama Atre Kawagoe 4F
〒125-0061 3 Kameari, Katsushika-ku, Tokio-49-3 Ario Kameari 2F None

find

Series.str.find

df['address'].str.find('Tokio')
>> 0    0
1    0
2    10
3    -1
4    -1
5    -1
6    0
7    9
8    -1
9    9
#Vorerst"Tokio"Es ist auch möglich, eine Spalte anzugeben, die nicht enthält
df.query('address.str.find("Tokio")!=-1')

normalize Series.str.normalize

Hauptsächlich werden Zahlen und Symbole voller Breite in halbe Breite und Katakana halber Breite in volle Breite umgewandelt. Geben Sie als Formular 'NFKC' (Normalform KC) an.

# string
import unicodedata
unicodedata.normalize('NFKC', '123! ?? @ # Hankaku Katakana')
>> '123!?@#Hankaku Katakana'

# pandas
df['normalize'] = df['address'].str.normalize(form='NFKC')

Referenz: Liste der durch unicodedata.normalize ('NFKC', x) in Python normalisierten Zeichen

System des regulären Ausdrucks

findall

Series.str.findall

df['address'].str.findall('(.{2}Station)')
>> 0    [Bunkyo Ward]
1    [Shinjuku Station]
2    [Shirota Ward]
3    [Stadt Midori Ward]
4       []
5       []
6    [Togawa Ward]
7    [Toshima Station]
8       []
9    [Katsushika]

contains

Series.str.contains

df['address'].str.contains('.{2}Station')
>> 0     True
1     True
2     True
3     True
4    False
5    False
6     True
7     True
8    False
9     True

#  "○○ Station"Nur Daten anzeigen, die enthalten
df.query('address.str.contains(".{2}Station")')['address']
>>0 1-1 Kasuga, Bunkyo-ku, Tokio-1 La Coeur Gebäude 2F
1 Takada Baba, Shinjuku-ku, Tokio 1-35-3 Emio Style 1F
2    〒100-6390 2 Marunouchi, Chiyoda-ku, Tokio-4-1 Marunouchi-Gebäude B1F
3 5-50-1 Misono, Midori-ku, Saitama-shi, Saitama Aeon Mall Urawa Misono
6 Minamikoiwa, Edogawa-ku, Tokio 7-24-15 Chapo Koiwa 1F
7             〒171-8532 1 Minami Ikebukuro, Toyoshima-ku, Tokio-29-1 Ikebukuro SP B1F
9               〒125-0061 3 Kameari, Katsushika-ku, Tokio-49-3 Ario Kameari 2F
Flag-Spalten, die Zeichenfolgen enthalten

Durch Konvertieren des Bool-Werts in einen Int-Wert können Sie eine Spalte mit "1" in den Daten erstellen, die eine bestimmte Zeichenfolge enthalten. Praktisch für das Feature-Quantity-Engineering zum Erstellen von Feature-Mengen.

#Datenflag tokyo einschließlich Tokio_Erstellen Sie flg
df['tokyo_flg'] = df['address'].str.contains("Tokio").astype(int)
df['tokyo_flg']
>> 0    1
1    1
2    1
3    0
4    0
5    0
6    1
7    1
8    0
9    1

extract Series.str.extract

df['address'].str.extract('(Tokio|Präfektur Kanagawa)([^Ward Stadt]+[Ward Stadt])').dropna()

df['address'].str.extract('(?P<pref>Tokio|Präfektur Kanagawa)(?P<city>[^Ward Stadt]+[Ward Stadt])').dropna()
pref city
0 Tokio Bunkyo Ward
1 Tokio Shinjuku Station
2 Tokio Chiyoda Ward
5 Präfektur Kanagawa Stadt Kamakura
6 Tokio Edogawa Ward
7 Tokio Toshima Station
9 Tokio Katsushika

Sie können Tabellen für XX Ward in Tokio und XX City in der Präfektur Kanagawa erstellen.

replace

Series.str.replace

#Postleitzahl löschen
df['address'] = df['address'].str.replace("〒[0-9]{3}\-[0-9]{4}", "")

Übrigens unterscheidet sich Series.replace im Wörterbuchformat von "Series.str.replace". Kann übergeben werden

Mach etwas, was Pandas nicht haben

Wenn Sie Ihre eigenen Funktionen oder Paketfunktionen (neologdn, mecab usw.) verwenden möchten

Verwenden Sie Series.apply. Durch Übergeben einer Funktion wie "Series.apply (func)" können Sie die Verarbeitung dieser Funktion für die Daten von Series ausführen. Sie können auch eine Lambda-Funktion übergeben.

#Am Anfang des Textes'Adresse'Einfügen
df['address'].apply(lambda x:  'Adresse' + x)

Die eigentliche Textvorverarbeitung wird unten zusammengefasst.

neologdn (Textvorverarbeitung)

neologdn 0.4

Ein japanisches Textnormalisierungspaket, das lange Noten und Chiller normalisieren kann, die von der Standardbibliothek nicht allein verarbeitet werden können.

Natürlich vor der Analyse mit Mecab Wenn Sie es verwenden, bevor Sie die Zeichenfolge mit einem regulären Ausdruck erhalten, wird der zu schreibende reguläre Ausdruck vereinfacht. Daher ist es besser, ihn zuerst für japanischen Text auszuführen.

import neologdn
df['neologdn'] = df['address'].apply(neologdn.normalize)

#DataFrame mit Lambda-Funktion.Sie können sich auch bewerben
df['neologdn'] = df.apply(lambda x: neologdn.normalize(x['address']), axis=1)

Teilen

mecab-python3

mecab-python3 0.996.3

Wenn Sie nur das Teilungsergebnis wünschen, geben Sie -Owakati an.

import MeCab

# `-d`Geben Sie den Wörterbuchpfad mit an
tagger = MeCab.Tagger('-Owakati -d /usr/local/lib/mecab/dic/ipadic/')
df['neologdn'].apply(tagger.parse)

In diesem Fall wird auch der letzte Zeilenumbruch \ n angehängt. Wenn Sie ihn entfernen möchten, können Sie Ihre eigene Funktion definieren oder die Lambda-Anweisung verwenden.

tagger = MeCab.Tagger('-Owakati -d /usr/local/lib/mecab/dic/ipadic/')

#Funktion definieren
def my_parser(text):
    res = tagger.parse(text)
    return res.strip()

df['neologdn'].apply(my_parser)


#Es ist nicht erforderlich, eine Funktion mit der Lambda-Funktion zu deklarieren
df['neologdn'].apply(lambda x : tagger.parse(x).strip())
>>0 Kasuga 1-1, Bunkyo-ku, Tokio-1 La Coeur Gebäude 2 F.
1 Takada Baba, Shinjuku-ku, Tokio 1- 35 -3 Emio Style 1 F.
2 Marunouchi, Chiyoda-ku, Tokio 2- 4 -1 Marunouchi-Gebäude B 1 F.
3 5-50 Misono, Midori-ku, Stadt Saitama, Präfektur Saitama 1 Aeon Mall Urawa Misono
4 Hamacho, Stadt Funabashi, Präfektur Chiba 2- 1 -1 LaLaport TOKYO-BAY LaLaport 3
5 Ofuna, Stadt Kamakura, Präfektur Kanagawa 1- 4 -1 Lumine Wing 4 F.
6 Minamikoiwa, Edogawa-ku, Tokio 7- 24 -15 Chapo Koiwa 1 F.
7 Minami Ikebukuro, Toyoshima-ku, Tokio 1- 29 -1 Ikebukuro SP B 1 F.
8 Stadt Wakita, Stadt Kawagoe, Präfektur Saitama 105 Atre Kawagoe 4 F.
9 Kameari, Katsushika-ku, Tokio 3- 49 -3 Ario Kameari 2 F.

Sudachipy

SudachiDict-core 20190718
SudachiPy 0.4.2

Wenn Sie in SudachiPy das Teilungsergebnis wie im obigen Mecab erhalten möchten, müssen Sie eine Funktion erstellen, die nur die Oberflächenebene aus dem Analyseergebnisobjekt zurückgibt.

from sudachipy import tokenizer
from sudachipy import dictionary


tokenizer_obj = dictionary.Dictionary().create()
mode = tokenizer.Tokenizer.SplitMode.C

def sudachi_tokenize(text):
    res = tokenizer_obj.tokenize(text, mode)
    return ' '.join([m.surface() for m in res])

df['address'].apply(sudachi_tokenize)
>>0 1-chome, Kasuga, Bunkyo-ku, Tokio-1 La Coeur Gebäude 2 F.
1 Takada Baba, Shinjuku-ku, Tokio 1- 35 -3 Emio Style 1 F.
2 Marunouchi, Chiyoda-ku, Tokio 2- 4 -1 Marunouchi-Gebäude B 1 F.
3 5-50 Misono, Midori-ku, Stadt Saitama, Präfektur Saitama 1 Aeon Mall Urawa Misono
4 Hamacho, Stadt Funabashi, Präfektur Chiba 2- 1 -1 LaLaport TOKYO-BAY LaLaport 3
5 Ofuna, Stadt Kamakura, Präfektur Kanagawa 1- 4 -1 Lumine Wing 4 F.
6 Minamikoiwa, Edogawa-ku, Tokio 7- 24 -15 Chapo Koiwa 1 F.
7 Minami Ikebukuro, Toyoshima-ku, Tokio 1- 29 -1 Ikebukuro SP B 1 F.
8 105 Wakita-cho, Kawagoe-shi, Saitama Atre Kawagoe 4 F.
9 Kameari, Katsushika-ku, Tokio 3- 49 -3 Ario Kameari 2 F.

Im Gegensatz zu mecabs ipadic scheint Sudachis "SplitMode.C" die Adressen zusammenzustellen. (Behandeln Sie Präfektur + Stadt / Gemeinde / Stadt / Dorf als einen einzigartigen Ausdruck?)

Pass-Modus als Argument

Zusätzlich zu den obigen Ergebnissen Sudachi verfügt über 3 geteilte Einheiten (geteilter Modus), sodass Sie die Funktion sudachi_tokenize verwenden können, um den Modus anzugeben. Versuchen Sie anzupassen.

Da Series.apply Argumente mit variabler Länge übergeben kann, können Sie die Argumente auf der Funktionsseite hinzufügen und die Argumente auf der Anwendungsseite angeben.

def sudachi_tokenize_with_mode(text, mode):
    res = tokenizer_obj.tokenize(text, mode)
    return ' '.join([m.surface() for m in res])

df['address'].apply(sudachi_tokenize_with_mode, mode=tokenizer.Tokenizer.SplitMode.A)
>>0 Kasuga 1-1, Bunkyo-ku, Tokio-1 La Coeur Gebäude 2 F.
1 Takada Baba, Shinjuku-ku, Tokio 1- 35 -3 Emio Style 1 F.
2 Marunouchi, Chiyoda-ku, Tokio 2- 4 -1 Marunouchi-Gebäude B 1 F.
3 5-50 Misono, Midori-ku, Stadt Saitama, Präfektur Saitama 1 Aeon Mall Urawa Misono
4 Hamacho, Stadt Funabashi, Präfektur Chiba 2- 1 -1 LaLaport TOKYO-BAY LaLaport 3
5 Ofuna, Stadt Kamakura, Präfektur Kanagawa 1- 4 -1 Lumine Wing 4 F.
6 Minamikoiwa, Edogawa-ku, Tokio 7- 24 -15 Chapo Koiwa 1 F.
7 Minami Ikebukuro, Toyoshima-ku, Tokio 1- 29 -1 Ikebukuro SP B 1 F.
8 Atre Kawagoe 4F, 105 Wakita-cho, Kawagoe-shi, Saitama
9 Kameari, Katsushika-ku, Tokio 3- 49 -3 Ario Kameari 2 F.

Mit SplitMode.A war das Ergebnis fast das gleiche wie das Ergebnis von mecab.

Verwenden Sie expand

Sudachi verfügt über eine Normalisierungsfunktion, die * Simulation * in * Simulation * ändert.

Erwägen Sie, "normalized_form" gleichzeitig zurückzugeben und daraus einen DataFrame zu machen.

Da "Series.apply" keine Erweiterungsfunktion hat, versuchen Sie, sie auszuführen, indem Sie "result_type =" expand "in" DataFrame.apply "angeben.

def sudachi_tokenize_multi(text):
    res = tokenizer_obj.tokenize(text, mode)
    return ' '.join([m.surface() for m in res]), ' '.join([m.normalized_form() for m in res])

df.apply(lambda x: sudachi_tokenize_multi(x['neologdn']), axis=1, result_type='expand')
0 1
0 1-1 Kasuga, Bunkyo-ku, Tokio-1 La Coeur Gebäude 2 F. 1-1 Kasuga, Bunkyo-ku, Tokio-1 La Coeur 2 f
1 1 Takada Baba, Shinjuku-ku, Tokio- 35 -3 Emio Style 1 F. 1 Takada Baba, Shinjuku-ku, Tokio- 35 -3 Emio Style 1 f
2 2 Marunouchi, Chiyoda-ku, Tokio- 4 -1 Marunouchi-Gebäude B 1 F. 2 Marunouchi, Chiyoda-ku, Tokio- 4 -1 Marunouchi-Gebäude b 1 f
3 5-50, Midori-ku, Saitama-shi, Saitama Aeon Mall Urawa Misono 5-50, Midori-ku, Saitama-shi, Saitama Aeon Mall Urawa Misono
4 2 Hamacho, Stadt Funabashi, Präfektur Chiba- 1 -1 LaLaport TOKYO-BAY LaLaport 3 2 Hamacho, Stadt Funabashi, Präfektur Chiba- 1 -1 LaLaport Tokio-Bucht LaLaport 3
5 1 Ofuna, Stadt Kamakura, Präfektur Kanagawa- 4 -1 Lumine Wing 4 F. 1 Ofuna, Stadt Kamakura, Präfektur Kanagawa- 4 -1 Lumine Wing 4 f
6 7 Minamikoiwa, Edogawa-ku, Tokio- 24 -15 Chapo Koiwa 1 F. 7 Minamikoiwa, Edogawa-ku, Tokio- 24 -15 Shappo Koiwa 1 f
7 1 Minami Ikebukuro, Toyoshima-ku, Tokio- 29 -1 Ikebukuro SP B 1 F. 1 Minami Ikebukuro, Toyoshima-ku, Tokio- 29 -1 Ikebukuro SP b 1 f
8 105 Wakita-cho, Kawagoe-shi, Saitama Atre Kawagoe 4F 105 Wakita-cho, Kawagoe-shi, Saitama Atre Kawagoe 4 f
9 Kameari 3 Katsushika-ku, Tokio- 49 -3 Ario Kameari 2 F. Kameari 3 Katsushika-ku, Tokio- 49 -3 Ario Kameari 2 f

Im Fall der Adresse dachte ich, dass dies keine besonderen Auswirkungen haben würde, aber * Chapo * wurde in * Shappo * konvertiert und * TOKYO --BAY * wurde in * Tokyo - Bay * konvertiert. Alphabetische Zeichen wie F werden aus irgendeinem Grund auch in Kleinbuchstaben geschrieben.

Andere

Wie für die Reihenfolge der persönlichen Vorverarbeitung

  1. neologdn
  2. Löschen Sie unnötige Zeichenfolgen mit regulären Ausdrücken und geben Sie fehlende Werte ein
  3. Trennung mit Mecab

Wenn Sie SudachiPy verwenden, verfügt es jedoch auch über eine Normalisierungsfunktion. Daher möchten Sie es möglicherweise zuerst tokenisieren und dann die Zeichen löschen oder vervollständigen.

Wie ich am Anfang schrieb, würde ich es begrüßen, wenn Sie mir sagen könnten, ob es eine bessere Verarbeitungsmethode gibt.

Recommended Posts

Japanische Textvorverarbeitung ohne Aussage in Pandas
Japanische Vorverarbeitung für maschinelles Lernen
Ändern Sie die Liste in der for-Anweisung
Vorsichtsmaßnahmen bei Verwendung der for-Anweisung in Pandas
Pandas DataFrame mit nur 15 Zeichen auf den Kopf stellen, ohne for-Anweisung zu verwenden
Verwenden Sie in Ihrem Python keine readlines () für Anweisungen!
[Python] Japanische CSV mit Pandas ohne verstümmelte Zeichen lesen (weitere auf Japanisch geschriebene Spalten extrahieren)
Für andere Aussage
Doppelschleife für Anweisung und dann Drucken des Anweisungsverhaltens
Zusammenfassung der Vorverarbeitungsmethoden für Python-Anfänger (Pandas-Datenrahmen)
Praktisch, um Matplotlib-Unterzeichnungen in for-Anweisungen zu verwenden
Wenn Sie in der for-Anweisung plt.save möchten
[Memo] Textabgleich im Pandas-Datenrahmen mit Flashtext