** Dieser Beitrag ist der 4. Tagesartikel von Real Escape Advent Calendar 2013. ** **.
Artikel zu Tag 2 verwendet HTML, das mit der Bing-API abgerufen wurde, also Tag 2 Es ist einfacher zu verstehen, wenn Sie zuerst / items / 62291ba328de9d12bd30) lesen.
-Ich habe eine Python-Bibliothek namens [scikit-learn] überprüft (http://scikit-learn.org/stable/index.html).
scikit-learn offizielles Dokument zur Extraktion der Textidentität
Tfidf-Berechnung von Wörtern in Tweet mit scikit-learn
https://github.com/katryo/tfidf_with_sklearn
Fork me!
--tf-idf ist der Wert von ** tf * idf **. Wird an ein Wort eines Dokuments in einer Reihe von Dokumenten angehängt. Wörter mit hohem tf-idf können als wichtig angesehen werden. Es kann verwendet werden, um Wörter beim Abrufen von Informationen zu gewichten. --tf (Termhäufigkeit) ist ** die Anzahl der Vorkommen des Wortes (Term) im Dokument / die Gesamtzahl aller Wörter, die im Dokument enthalten sind **. Es wächst, wenn das Wort im Dokument häufig verwendet wird. --idf (Inverse Document Frequency) ist die Umkehrung von df. In der Realität wird das Protokoll jedoch verwendet, um die Berechnung zu vereinfachen. So wird es ** log (1 / df) **. Der untere Rand des Protokolls ist normalerweise 2, kann aber e oder 10 sein. Sollte sein. --df (Dokumenthäufigkeit) ist ** die Anzahl der Dokumente, in denen das Wort vorkommt / die Gesamtzahl der Dokumente **. Es wächst, wenn das Wort in einer Vielzahl von Themen verwendet wird. "Ha" und "o" und auf Englisch "is" und "that" sind sehr groß. Der Wert, der einem Wort in einem Dokumentensatz zugeordnet ist.
Verstehen Sie Ihren eigenen Inhalt, während Sie den Inhalt von Dokument zum Extrahieren der Textidentität von scikit-learn offiziell teilweise übersetzen Zusätzlich wird es beschrieben.
Beim Extrahieren der Identität aus dem Text mit scikit-learn sind drei Prozesse erforderlich.
-Tokenisierung: Konvertieren Sie Text in eine Wortsammlung. Im Fall von Englisch ist es in Ordnung, durch Leerzeichen zu teilen und dann Rauschen wie Symbole zu entfernen. Verwenden Sie jedoch auf Japanisch einen morphologischen Analysator wie MeCab oder KyTea. Da scikit-learn keinen japanischen morphologischen Analysator enthält, ist dieser Prozess separat erforderlich. --counting: Zählt die Häufigkeit des Auftretens jedes Wortes für jedes Dokument.
Beim Scikit-Lernen werden die obigen drei Schritte zusammenfassend als ** Vektorisierung ** bezeichnet, dh als "Vektorisierung". Der spätere Tfidf Vectorizer kann alle drei Schritte ausführen. Wenn Sie den Vorgang bereits zur Hälfte abgeschlossen haben, können Sie aus der Mitte oder der Hälfte berechnen.
Übrigens kann scikit-learn nicht nur eine Menge Wörter, sondern auch eine tfidf-Berechnung mit n-Gramm durchführen, die sich auf die Fortsetzung von zwei oder mehr Wörtern konzentriert, aber ich werde es diesmal nicht tun.
CountVectorizer Der Count Vectorizer in sklearn.feature_extraction.text kann tokenisieren und zählen. Da das Ergebnis der Zählung durch einen Vektor dargestellt wird, Vectorizer.
Die offizielle Dokumentation erklärt es hier.
TfidfTransformer Der Tfidf-Transformator, ebenfalls in sklearn.feature_extraction.text, ist für die Normalisierung verantwortlich. Die Methode fit_transform berechnet tfidf nur anhand der "Häufigkeit des Auftretens von Wörtern für jedes Dokument" und normalisiert es sogar. Hier in der offiziellen Dokumentation.
TfidfVectorizer Existenz, die die Funktionen von Count Vectorizer und Tfidf Transformer hat. Dreifaltigkeitsform, genau die Dreifaltigkeit. Dies ist praktisch, wenn Sie die Identität aus dem Rohtext extrahieren.
Das Hauptthema ist von hier. 36934 Arten von Wörtern auf 400 Webseiten, die von 8 Abfragen abgerufen wurden. Drucken Sie aus diesen "Wörter mit tfidf größer als 0,1 im angezeigten Dokument".
Zunächst einmal ist die Berechnung von tfidf ziemlich teuer. Berechnen wir also tfidf und wählen Sie dann das Ergebnis aus.
set_tfidf_with_sklearn_to_fetched_pages.py
import utils
import constants
import pickle
import os
from sklearn.feature_extraction.text import TfidfVectorizer
def is_bigger_than_min_tfidf(term, terms, tfidfs):
'''
[term for term in terms if is_bigger_than_min_tfidf(term, terms, tfidfs)]Verwenden Sie in
Eine Funktion, die aus der Liste der tfidf-Werte von Wörtern in der richtigen Reihenfolge errät.
Der Wert von tfidf ist MIN_Gibt True zurück, wenn es größer als TFIDF ist
'''
if tfidfs[terms.index(term)] > constants.MIN_TFIDF:
return True
return False
def tfidf(pages):
#analyzer ist eine Funktion, die eine Liste von Zeichenfolgen zurückgibt, wenn eine Zeichenfolge eingegeben wird.
vectorizer = TfidfVectorizer(analyzer=utils.stems, min_df=1, max_df=50)
corpus = [page.text for page in pages]
x = vectorizer.fit_transform(corpus)
#Von hier an hat down nichts mehr mit dem zurückgegebenen Wert zu tun. Ich wollte nur sehen, wie die hohen Worte von tfidf aussehen
terms = vectorizer.get_feature_names()
tfidfs = x.toarray()[constants.DOC_NUM]
print([term for term in terms if is_bigger_than_min_tfidf(term, terms, tfidfs)])
print('gesamt%Ich Arten von Wörtern%Gefunden von i Seite.' % (len(terms), len(pages)))
return x, vectorizer #x ist tfidf_Erhalten Sie hauptsächlich als Ergebnis
if __name__ == '__main__':
utils.go_to_fetched_pages_dir()
pages = utils.load_all_html_files() #Seiten rufen HTML ab und setzen es auf Text
tfidf_result, vectorizer = tfidf(pages) # tfidf_Ergebnis ist das x der tfidf-Funktion
pkl_tfidf_result_path = os.path.join('..', constants.TFIDF_RESULT_PKL_FILENAME)
pkl_tfidf_vectorizer_path = os.path.join('..', constants.TFIDF_VECTORIZER_PKL_FILENAME)
with open(pkl_tfidf_result_path, 'wb') as f:
pickle.dump(tfidf_result, f)
with open(pkl_tfidf_vectorizer_path, 'wb') as f:
pickle.dump(vectorizer, f)
In der tfidf-Funktion
vectorizer = TfidfVectorizer(analyzer=utils.stems, min_df=1, max_df=50)
Es wird gesagt. Der Analysator fügt eine Funktion ein, die eine Liste von Zeichenfolgen zurückgibt, wenn Sie eine Zeichenfolge einfügen. Standardmäßig wird es durch Leerzeichen geteilt und nur ein Zeichensymbol wird entfernt. Wenn Sie dies jedoch auf Japanisch tun, müssen Sie eine Funktion mithilfe eines morphologischen Analysators selbst erstellen und festlegen. Die Funktion utils.stems ist eine Funktion, die mit MeCab eine morphologische Analyse durchführt, sie in einen Stamm konvertiert und als Liste zurückgibt. Sie wurde in utils.py geschrieben, was später beschrieben wird.
Was in der tfidf-Funktion gedruckt wird, ist ein Wort, dessen tfidf-Wert 0,1 oder mehr unter den Wörtern beträgt, die auf einer der Ergebnisseiten gefunden werden, die nach "Magenneigung" durchsucht werden. Das Ergebnis davon wird später beschrieben.
Die im Code angezeigten Dienstprogramme lauten wie folgt und sind eine Sammlung nützlicher Funktionen, die in verschiedenen Situationen verwendet werden können.
utils.py
import MeCab
import constants
import os
import pdb
from web_page import WebPage
def _split_to_words(text, to_stem=False):
"""
Eingang: 'Alles für mich'
Ausgabe: tuple(['alles', 'mich selber', 'von', 'Wie', 'Was'])
"""
tagger = MeCab.Tagger('mecabrc') #Sie können einen anderen Tagger verwenden
mecab_result = tagger.parse(text)
info_of_words = mecab_result.split('\n')
words = []
for info in info_of_words:
#Wenn Sie durch Macab teilen, steht "" am Ende des Satzes davor'EOS'Kommt
if info == 'EOS' or info == '':
break
# info => 'Nana\t Assistent,Letzte Hilfe,*,*,*,*,Nana,N / a,N / a'
info_elems = info.split(',')
#Sechstens gibt es Wörter, die nicht verwendet werden. Wenn der sechste ist'*'Wenn ja, geben Sie die 0 ein
if info_elems[6] == '*':
# info_elems[0] => 'Van Rossam\t Substantiv'
words.append(info_elems[0][:-3])
continue
if to_stem:
#In Wortstamm konvertieren
words.append(info_elems[6])
continue
#Wort wie es ist
words.append(info_elems[0][:-3])
return words
def words(text):
words = _split_to_words(text=text, to_stem=False)
return words
def stems(text):
stems = _split_to_words(text=text, to_stem=True)
return stems
def load_all_html_files():
pages = []
for query in constants.QUERIES:
pages.extend(load_html_files_with_query(query))
return pages
def load_html_files_with_query(query):
pages = []
for i in range(constants.NUM_OF_FETCHED_PAGES):
with open('%s_%s.html' % (query, str(i)), 'r') as f:
page = WebPage()
page.html_body = f.read()
page.remove_html_tags()
pages.append(page)
return pages
def load_html_files():
"""
Verwenden Sie diese Option unter der Annahme, dass sich die HTML-Datei im Verzeichnis befindet
"""
pages = load_html_files_with_query(constants.QUERY)
return pages
def go_to_fetched_pages_dir():
if not os.path.exists(constants.FETCHED_PAGES_DIR_NAME):
os.mkdir(constants.FETCHED_PAGES_DIR_NAME)
os.chdir(constants.FETCHED_PAGES_DIR_NAME)
Und die Konstanten sind wie folgt.
constants.py
FETCHED_PAGES_DIR_NAME = 'fetched_pages'
QUERIES = 'Magen Pollinose lehnt Wurm Zahn Pollinose misst Depression mechanische Fraktur steife Schulter Dokumente'.split(' ')
NUM_OF_FETCHED_PAGES = 50
NB_PKL_FILENAME = 'naive_bayes_classifier.pkl'
DOC_NUM = 0
MIN_TFIDF = 0.1
TFIDF_RESULT_PKL_FILENAME = 'tfidf_result.pkl'
TFIDF_VECTORIZER_PKL_FILENAME = 'tfidf_vectorizer.pkl'
Wenn Sie sich die Reihenfolge der FRAGEN ansehen, können Sie sehen, dass die Kategorie "Magenneigung" an erster Stelle steht. Die DOC_NUM-Konstante wurde für dieses Experiment erstellt und verwendet, um die 0. Datei in der Kategorie "Magenneigung" anzugeben, dh die Datei mit dem Namen "Magenneigung_0.html".
Jetzt. Lassen Sie uns diesen Code ausführen.
$ python set_tfidf_with_sklearn_to_fetched_pages.py
Selbst wenn Sie scikit-learn verwenden, dauert die Berechnung von tfidf einige Zeit. In meiner Umgebung dauerte es 25,81 Sekunden. Ergebnis.
['gaJsHost', 'https', 'Tropfen', 'Brennen', 'Luft schlucken', 'Hyperazidität', 'Brust', 'Kochen', 'Nahrungsmittel', 'Ösophagus-Fissuren-Hernie']
Auf 400 Seiten wurden insgesamt 36934 Wörter gefunden.
Es ist ein Wort, das sich wie Bauchschmerzen anfühlt. Es wurde festgestellt, dass unter den Wörtern in Magenruhe_0.html die obigen 10 Arten von Wörtern tfidf größer als 0,1 haben.
gaJsHost und https scheinen Teil des JavaScript-Codes zu sein. Hmmm. Ich möchte all diesen Lärm loswerden, aber ich kann mir keinen guten Weg vorstellen. Besser noch, es kann besser sein, Wörter zu entfernen, die nur alphabetisch sind.
Übrigens sind Wörter wie "Ösophagusfissurenhernie" nicht in MeCabs IPADIC enthalten (siehe diesen Artikel für den Ursprung von IPADIC), also Wikipedia Es ist notwendig, es zu stärken, indem die Wörter des Hatena-Schlüsselworts in das Wörterbuch aufgenommen werden. Bitte googeln Sie, wie es geht.
Ich habe die offizielle Seite gelesen, aber das Ergebnis der Berechnung von tfidf wird in der Art von csr_matrix von scipy ausgegeben. Dies ist eine spärliche (meistens 0) Matrix, die das Wort tf-idf in jedem Dokument als Bruch von 0 bis 1 darstellt.
(Pdb) type(x)
<class 'scipy.sparse.csr.csr_matrix'>
Ich wusste nicht, wie der tfidf-Wertesatz dem Wort zugeordnet wurde (ich habe es später herausgefunden), also habe ich ein einfaches Experiment mit pdb.set_trace () durchgeführt.
TfidfVectorizer verfügt über die zu verwendende Methode
Und scipy.sparse.csr_matrix hat
Ist.
Als ich die Webseite mit der Dokumentnummer 0 überprüfte, war es zunächst eine Seite namens Stomach leaning.com. Finden Sie heraus, wie die Wörter auf dieser Seite dargestellt werden.
Nach dem Beizen des Berechnungsergebnisses von tfidf wurde der folgende Code ausgeführt.
play_with_tfidf.py
# -*- coding: utf-8 -*-
import pickle
import constants
import pdb
def is_bigger_than_min_tfidf(term, terms, tfidfs):
'''
[term for term in terms if is_bigger_than_min_tfidf(term, terms, tfidfs)]Verwenden Sie in
Eine Funktion, die aus der Liste der tfidf-Werte von Wörtern in der richtigen Reihenfolge errät.
Der Wert von tfidf ist MIN_Gibt True zurück, wenn es größer als TFIDF ist
'''
if tfidfs[terms.index(term)] > constants.MIN_TFIDF:
return True
return False
if __name__ == '__main__':
with open(constants.TFIDF_VECTORIZER_PKL_FILENAME, 'rb') as f:
vectorizer = pickle.load(f)
with open(constants.TFIDF_RESULT_PKL_FILENAME, 'rb') as f:
x = pickle.load(f)
pdb.set_trace()
terms = vectorizer.get_feature_names()
for i in range(3):
tfidfs = x.toarray()[i]
print([term for term in terms if is_bigger_than_min_tfidf(term, terms, tfidfs)])
Sie können pdb.set_trace als Haltepunkt verwenden und von dort aus Werte in einer interaktiven Umgebung ausgeben, um verschiedene Bestätigungsaufgaben auszuführen.
(Pdb) vectorizer.inverse_transform(x)[0]
> array(['Ösophagus-Fissuren-Hernie', 'Nahrungsmittel', 'Diät-Heilmittel', 'Operation', 'Reflux-Ösophagitis', 'Kochen', 'Brust', 'Hyperazidität', 'Magenschmerzen',
'Magengeschwür', 'Magen-Ptosis', 'Magenkrebs', 'Luft schlucken', 'Chinesische Kräutermedizin', 'Konstruktion', 'Chronische Gastritis', 'Zwölffingerdarmgeschwür', 'Krankenversicherung',
'Haftungsausschluss', 'Unternehmensinformationen', 'Polyp', 'Topf', 'Pflege', 'Amerikanische Familienlebensversicherungsgesellschaft', 'Aflac', 'gehen',
'Brennen', 'Bezüglich', 'Tropfen', 'unescape', 'try', 'ssl', 'protocol',
'javascript', 'inquiry', 'https', 'gaJsHost', 'ga', 'err',
'comCopyright', 'analytics', 'Inc', 'Cscript', 'CROSSFINITY',
'=\'"', "='", ':"', '.")', '."', ')\u3000', '(("', '("%', "'%",
'"))'],
dtype='<U26')
Der Begriff "Ösophagusfissurenhernie" ist selten und scheint auf anderen Seiten selten zu erscheinen. Deshalb habe ich mich entschieden, ihn als Marker zu verwenden.
(Pdb) vectorizer.get_feature_names().index('Ösophagus-Fissuren-Hernie')
36097
Es stellte sich heraus, dass es das 36097. Wort war. Was ist der Wert von tfidf für das 36097. Wort im 0. Dokument (dh Magenverstimmung.com)?
(Pdb) x.toarray()[0][36097]
0.10163697033184078
Ziemlich teuer. In Dokument Nummer 0 wurde festgestellt, dass das Wort mit der Wortnummer 36097 eine tfidf von 0,10163697033184078 hat. Ich glaube nicht, dass ein so hoher (in erster Linie ungleich Null) tfidf-Wert zufällig bei der Wortnummer 36097 erscheint. x.toarray () ist eine sehr spärliche Matrix, von der die meisten 0 sein sollten. Daher kann davon ausgegangen werden, dass die Reihenfolge der Wortliste, die von vectorizer.get_feature_names () verwendet werden kann, und die Reihenfolge der Wörter mit tfidf, die von x.toarray () verwendet werden können, identisch sind.
Auf diese Weise wurde bestätigt, dass die Wortliste in derselben Reihenfolge geführt wurde. Ich denke, irgendwo in der offiziellen Dokumentation steht, dass "die Reihenfolge der Wörter erhalten bleibt".
Danach habe ich pdb.set_trace () gelöscht und play_with_tfidf.py erneut ausgeführt.
['gaJsHost', 'https', 'Tropfen', 'Brennen', 'Luft schlucken', 'Hyperazidität', 'Brust', 'Kochen', 'Nahrungsmittel', 'Ösophagus-Fissuren-Hernie']
['Tropfen', 'Widerlich', 'Brennen', 'Magenschmerzen', 'Brust', 'Bestehen']
['TVCM', 'Gusuru', 'Tropfen', 'Nomu', 'もTropfen', 'Brennen', 'Brennenる', 'Ri', 'Aktion', 'Wissenschaft', 'Sacron', 'Cerbere', 'verdreifachen', 'Schleier', 'Kater', 'Schwach', 'Ordnen', 'Schleim', 'Magenschmerzen', 'Magenmedizin', 'Brust', 'Fülle']
Diese Wörter haben einen hohen tfidf (der sehr hoch zu sein scheint) und werden als nützlich angesehen, um die Ähnlichkeit zwischen Dokumenten und der Kategorie der Magenneigung zu berechnen.
scikit-learn Bequem.
Ich habe den Code auf Github gepostet.
https://github.com/katryo/tfidf_with_sklearn
Ich möchte die Berechnungsfunktion von tfidf implementieren und mit scicit-learn vergleichen.
Recommended Posts