Pythonに基づく簡単な自然言語処理の実践
Pythonに基づく簡単な自然言語処理実践筆者のプログラム猿に属するデータ科学と機械から実戦マニュアルを学ぶ.
Pythonベースの簡単な自然言語処理
本稿ではPythonベースの簡単な自然言語処理タスクについて説明し,本稿のすべてのコードをここに置く.Pythonの文法を前置きして読むことと機械学習開発環境の構築を提案し、より多くの機械学習資料は機械学習、深さ学習と自然言語処理分野で推薦された書籍のリストとプログラム猿向けのデータ科学と機械学習知識体系と資料の合集を参考にする.
Twenty News Group語彙セット処理
20 Newsgroupデータセットには、異なるニュースグループからのドキュメント約20000件が含まれており、最初にKen Langが収集して整理した.このセクションには、データセットのキャプチャ、フィーチャー抽出、単純分類器トレーニング、トピックモデルトレーニングなどが含まれます.このセクションのコードには、主な処理コードパッケージライブラリとNotebookベースのインタラクティブな例が含まれています.まず、データのキャプチャが必要です.
次に、Notebookでデータフォーマットをインタラクティブに表示します.
次に、語彙セットの特徴を抽出します.
ドキュメントを分類タスクに使用するには、TF-IDFなどの一般的な方法を使用してフィーチャーベクトルに変換する必要があります.
フィーチャー抽出、分類器トレーニング、予測を個別の関数にカプセル化できます.
次に、トレーニングを実行し、予測と評価を行います.
また、ドキュメントセットのトピックを抽出することもできます.
一般的な自然言語処理ツールパッケージ
上記の20 NewsGroupコーパスセット処理について説明したように、データ取得、データ前処理、データ特徴抽出、分類モデルトレーニング、トピックモデルまたは語ベクトルなどの高度な特徴抽出など、一般的な自然言語処理タスクが含まれていることがわかります.筆者はpython-fireでクラスをコマンドラインで呼び出せるツールに素早くカプセル化することに慣れており、外部モジュール呼び出しの使用もサポートしています.このセクションでは、gensimのウィキペディア処理クラスを使用することができます.例えば、中国語のウィキペディアデータを分析する必要があります.
キャプチャが完了したら、OpenCCで簡体字に変換する必要があります.キャプチャが完了したら、生成されたテキストファイルを結巴分詞で分詞することができます.コードはここを参照して、
また、分詞後のドキュメントに対してトピックモデルまたは語ベクトル抽出を行うこともできます.ここでは、分詞後のファイルを使用して、中国語と英語の違いを無視することができます.
この関数は、コマンドラインを使用して直接呼び出し、分詞後のファイルに転送することもできます.また、その語彙セットに対して語ベクトルを確立することもできます.コードはここを参照してください.ワードベクトルの基本的な使用に慣れていない学生は、GensimベースのWord 2 Vecの実践を参照してください.
Pythonベースの簡単な自然言語処理
本稿ではPythonベースの簡単な自然言語処理タスクについて説明し,本稿のすべてのコードをここに置く.Pythonの文法を前置きして読むことと機械学習開発環境の構築を提案し、より多くの機械学習資料は機械学習、深さ学習と自然言語処理分野で推薦された書籍のリストとプログラム猿向けのデータ科学と機械学習知識体系と資料の合集を参考にする.
Twenty News Group語彙セット処理
20 Newsgroupデータセットには、異なるニュースグループからのドキュメント約20000件が含まれており、最初にKen Langが収集して整理した.このセクションには、データセットのキャプチャ、フィーチャー抽出、単純分類器トレーニング、トピックモデルトレーニングなどが含まれます.このセクションのコードには、主な処理コードパッケージライブラリとNotebookベースのインタラクティブな例が含まれています.まず、データのキャプチャが必要です.
def fetch_data(self, subset='train', categories=None):
"""return data
Arguments:
subset -> string -- train / test / all
"""
rand = np.random.mtrand.RandomState(8675309)
data = fetch_20newsgroups(subset=subset,
categories=categories,
shuffle=True,
random_state=rand)
self.data[subset] = data
次に、Notebookでデータフォーマットをインタラクティブに表示します.
#
twp = TwentyNewsGroup()
#
twp.fetch_data()
twenty_train = twp.data['train']
print(" ", "->", twenty_train.keys())
print(" ", "->", len(twenty_train.data))
print(" ", "->",[ twenty_train.target_names[t] for t in twenty_train.target[:10]])
-> dict_keys(['data', 'filenames', 'target_names', 'target', 'DESCR', 'description'])
-> 11314
-> ['sci.space', 'comp.sys.mac.hardware', 'sci.electronics', 'comp.sys.mac.hardware', 'sci.space', 'rec.sport.hockey', 'talk.religion.misc', 'sci.med', 'talk.religion.misc', 'talk.politics.guns']
次に、語彙セットの特徴を抽出します.
#
# - (Document-Term Matrix)
from sklearn.feature_extraction.text import CountVectorizer
count_vect = CountVectorizer()
X_train_counts = count_vect.fit_transform(twenty_train.data)
print("DTM ","->",X_train_counts.shape)
#
print(" ","->", count_vect.vocabulary_.get(u'algorithm'))
DTM -> (11314, 130107)
-> 27366
ドキュメントを分類タスクに使用するには、TF-IDFなどの一般的な方法を使用してフィーチャーベクトルに変換する必要があります.
# TF
from sklearn.feature_extraction.text import TfidfTransformer
tf_transformer = TfidfTransformer(use_idf=False).fit(X_train_counts)
X_train_tf = tf_transformer.transform(X_train_counts)
print(" TF ","->",X_train_tf)
# TF-IDF
from sklearn.feature_extraction.text import TfidfTransformer
tf_transformer = TfidfTransformer().fit(X_train_counts)
X_train_tfidf = tf_transformer.transform(X_train_counts)
print(" TF-IDF ","->",X_train_tfidf)
TF -> (0, 6447) 0.0380693493813
(0, 37842) 0.0380693493813
フィーチャー抽出、分類器トレーニング、予測を個別の関数にカプセル化できます.
def extract_feature(self):
"""
"""
# -
self.train_dtm = self.count_vect.fit_transform(self.data['train'].data)
# TF
tf_transformer = TfidfTransformer(use_idf=False)
self.train_tf = tf_transformer.transform(self.train_dtm)
# TF-IDF
tfidf_transformer = TfidfTransformer().fit(self.train_dtm)
self.train_tfidf = tf_transformer.transform(self.train_dtm)
def train_classifier(self):
"""
"""
self.extract_feature();
self.clf = MultinomialNB().fit(
self.train_tfidf, self.data['train'].target)
def predict(self, docs):
"""
"""
X_new_counts = self.count_vect.transform(docs)
tfidf_transformer = TfidfTransformer().fit(X_new_counts)
X_new_tfidf = tfidf_transformer.transform(X_new_counts)
return self.clf.predict(X_new_tfidf)
次に、トレーニングを実行し、予測と評価を行います.
#
twp.train_classifier()
#
docs_new = ['God is love', 'OpenGL on the GPU is fast']
predicted = twp.predict(docs_new)
for doc, category in zip(docs_new, predicted):
print('%r => %s' % (doc, twenty_train.target_names[category]))
#
twp.fetch_data(subset='test')
predicted = twp.predict(twp.data['test'].data)
import numpy as np
#
#
np.mean(predicted == twp.data['test'].target)
# Metrics
from sklearn import metrics
print(metrics.classification_report(
twp.data['test'].target, predicted,
target_names=twp.data['test'].target_names))
# Confusion Matrix
metrics.confusion_matrix(twp.data['test'].target, predicted)
'God is love' => soc.religion.christian
'OpenGL on the GPU is fast' => rec.autos
precision recall f1-score support
alt.atheism 0.79 0.50 0.61 319
...
talk.religion.misc 1.00 0.08 0.15 251
avg / total 0.82 0.79 0.77 7532
Out[16]:
array([[158, 0, 1, 1, 0, 1, 0, 3, 7, 1, 2, 6, 1,
8, 3, 114, 6, 7, 0, 0],
...
[ 35, 3, 1, 0, 0, 0, 1, 4, 1, 1, 6, 3, 0,
6, 5, 127, 30, 5, 2, 21]])
また、ドキュメントセットのトピックを抽出することもできます.
#
twp.topics_by_lda()
Topic 0 : stream s1 astronaut zoo laurentian maynard s2 gtoal pem fpu
Topic 1 : 145 cx 0d bh sl 75u 6um m6 sy gld
Topic 2 : apartment wpi mars nazis monash palestine ottoman sas winner gerard
Topic 3 : livesey contest satellite tamu mathew orbital wpd marriage solntze pope
Topic 4 : x11 contest lib font string contrib visual xterm ahl brake
Topic 5 : ax g9v b8f a86 1d9 pl 0t wm 34u giz
Topic 6 : printf null char manes behanna senate handgun civilians homicides magpie
Topic 7 : buf jpeg chi tor bos det que uwo pit blah
Topic 8 : oracle di t4 risc nist instruction msg postscript dma convex
Topic 9 : candida cray yeast viking dog venus bloom symptoms observatory roby
Topic 10 : cx ck hz lk mv cramer adl optilink k8 uw
Topic 11 : ripem rsa sandvik w0 bosnia psuvm hudson utk defensive veal
Topic 12 : db espn sabbath br widgets liar davidian urartu sdpa cooling
Topic 13 : ripem dyer ucsu carleton adaptec tires chem alchemy lockheed rsa
Topic 14 : ingr sv alomar jupiter borland het intergraph factory paradox captain
Topic 15 : militia palestinian cpr pts handheld sharks igc apc jake lehigh
Topic 16 : alaska duke col russia uoknor aurora princeton nsmca gene stereo
Topic 17 : uuencode msg helmet eos satan dseg homosexual ics gear pyron
Topic 18 : entries myers x11r4 radar remark cipher maine hamburg senior bontchev
Topic 19 : cubs ufl vitamin temple gsfc mccall astro bellcore uranium wesleyan
一般的な自然言語処理ツールパッケージ
上記の20 NewsGroupコーパスセット処理について説明したように、データ取得、データ前処理、データ特徴抽出、分類モデルトレーニング、トピックモデルまたは語ベクトルなどの高度な特徴抽出など、一般的な自然言語処理タスクが含まれていることがわかります.筆者はpython-fireでクラスをコマンドラインで呼び出せるツールに素早くカプセル化することに慣れており、外部モジュール呼び出しの使用もサポートしています.このセクションでは、gensimのウィキペディア処理クラスを使用することができます.例えば、中国語のウィキペディアデータを分析する必要があります.
class Wiki(object):
"""
"""
def wiki2texts(self, wiki_data_path, wiki_texts_path='./wiki_texts.txt'):
"""
Arguments:
wiki_data_path --
"""
if not wiki_data_path:
print(" Wiki https://dumps.wikimedia.org/zhwiki/ ")
exit()
#
wiki_corpus = WikiCorpus(wiki_data_path, dictionary={})
texts_num = 0
with open(wiki_text_path, 'w', encoding='utf-8') as output:
for text in wiki_corpus.get_texts():
output.write(b' '.join(text).decode('utf-8') + '
')
texts_num += 1
if texts_num % 10000 == 0:
logging.info(" %d " % texts_num)
print(" , OpenCC ")
キャプチャが完了したら、OpenCCで簡体字に変換する必要があります.キャプチャが完了したら、生成されたテキストファイルを結巴分詞で分詞することができます.コードはここを参照して、
python chinese_text_processor.py tokenize_file /output.txt
を使用して直接このタスクを実行し、出力ファイルを生成します.分詞後のファイルを取得すると、簡単な語袋表示またはドキュメント-語ベクトルに変換できます.詳細コードは、ここを参照してください.class CorpusProcessor:
"""
"""
def corpus2bow(self, tokenized_corpus=default_documents):
"""returns (vocab,corpus_in_bow)
BOW
Arguments:
tokenized_corpus --
Return:
vocab -- {'human': 0, ... 'minors': 11}
corpus_in_bow -- [[(0, 1), (1, 1), (2, 1)]...]
"""
dictionary = corpora.Dictionary(tokenized_corpus)
#
vocab = dictionary.token2id
#
corpus_in_bow = [dictionary.doc2bow(text) for text in tokenized_corpus]
return (vocab, corpus_in_bow)
def corpus2dtm(self, tokenized_corpus=default_documents, min_df=10, max_df=100):
"""returns (vocab, DTM)
-
- dtm -> matrix: -
I like hate databases
D1 1 1 0 1
D2 1 0 1 1
"""
if type(tokenized_corpus[0]) is list:
documents = [" ".join(document) for document in tokenized_corpus]
else:
documents = tokenized_corpus
if max_df == -1:
max_df = round(len(documents) / 2)
#
vec = CountVectorizer(min_df=min_df,
max_df=max_df,
analyzer="word",
token_pattern="[\S]+",
tokenizer=None,
preprocessor=None,
stop_words=None
)
#
DTM = vec.fit_transform(documents)
#
vocab = vec.get_feature_names()
return (vocab, DTM)
また、分詞後のドキュメントに対してトピックモデルまたは語ベクトル抽出を行うこともできます.ここでは、分詞後のファイルを使用して、中国語と英語の違いを無視することができます.
def topics_by_lda(self, tokenized_corpus_path, num_topics=20, num_words=10, max_lines=10000, split="\s+", max_df=100):
"""
LDA
Arguments:
tokenized_corpus_path -> string --
num_topics -> integer --
num_words -> integer --
max_lines -> integer --
split -> string --
max_df -> integer -- ,
"""
#
corpus = []
with open(tokenized_corpus_path, 'r', encoding='utf-8') as tokenized_corpus:
flag = 0
for document in tokenized_corpus:
#
if(flag > max_lines):
break
#
corpus.append(re.split(split, document))
flag = flag + 1
# BOW
(vocab, DTM) = self.corpus2dtm(corpus, max_df=max_df)
# LDA
lda = LdaMulticore(
matutils.Sparse2Corpus(DTM, documents_columns=False),
num_topics=num_topics,
id2word=dict([(i, s) for i, s in enumerate(vocab)]),
workers=4
)
#
topics = lda.show_topics(
num_topics=num_topics,
num_words=num_words,
formatted=False,
log=False)
for ti, topic in enumerate(topics):
print("Topic", ti, ":", " ".join(word[0] for word in topic[1]))
この関数は、コマンドラインを使用して直接呼び出し、分詞後のファイルに転送することもできます.また、その語彙セットに対して語ベクトルを確立することもできます.コードはここを参照してください.ワードベクトルの基本的な使用に慣れていない学生は、GensimベースのWord 2 Vecの実践を参照してください.
def wv_train(self, tokenized_text_path, output_model_path='./wv_model.bin'):
"""
,
"""
sentences = word2vec.Text8Corpus(tokenized_text_path)
#
model = word2vec.Word2Vec(sentences, size=250)
#
model.save(output_model_path)
def wv_visualize(self, model_path, word=[" ", " "]):
"""
:
model_path: Word2Vec
"""
#
model = word2vec.Word2Vec.load(model_path)
#
words = [wp[0] for wp in model.most_similar(word, topn=20)]
#
wordsInVector = [model[word] for word in words]
# PCA
pca = PCA(n_components=2)
pca.fit(wordsInVector)
X = pca.transform(wordsInVector)
#
xs = X[:, 0]
ys = X[:, 1]
plt.figure(figsize=(12, 8))
plt.scatter(xs, ys, marker='o')
#
for i, w in enumerate(words):
plt.annotate(
w,
xy=(xs[i], ys[i]), xytext=(6, 6),
textcoords='offset points', ha='left', va='top',
**dict(fontsize=10)
)
plt.show()