$ pip3 install numpy
$ pip3 install scikit-learn
$ pip3 install pandas
scikit-learnはpythonで使用できる機械学習ライブラリ
ニュースコーパスは livedoorニュースコーパス を使用します。
livedoor ニュースコーパス
$ ls
text
$ cd text
$ ls
CHANGES.txt dokujo-tsushin livedoor-homme smax
README.txt it-life-hack movie-enter sports-watch
app.py kaden-channel peachy topic-news
app.py
import os, os.path import csv f = open('corpus.csv', 'w') csv_writer = csv.writer(f, quotechar="'") files = os.listdir('./') datas = [] for filename in files: if os.path.isfile(filename): continue category = filename for file in os.listdir('./'+filename): path = './'+filename+'/'+file r = open(path, 'r') line_a = r.readlines() text = '' for line in line_a[2:]: text += line.strip() r.close() datas.append() print(text) csv_writer.writerows(datas) f.close()
$python3 app.py
以下のようなCSVファイルが生成されます。
### NNの仕組み
– 全てのテキストを形態素に分解し、全ての単語を把握した後、全ての単語に対してテキストに出現するかと言うベクトルを作成する。
– その後、ニューラルネットワークに対し、このベクトルを入力とし、出力をカテゴリとして学習を行う
nlp_tasks.py
# -*- coding: utf-8 -*- #! /usr/bin/python3 import MeCab from sklearn.feature_extraction.text import CountVectorizer def _split_to_words(text): tagger = MeCab.Tagger('-O wakati') try: res = tagger.parse(text.strip()) except: return[] return res def get_vector_by_text_list(_items): count_vect = CountVectorizer(analyzer=_split_to_words) box = count_vect.fit_transform(_items) X = box.todense() return [X,count_vect]
models というフォルダを作成する
main.py
# -*- coding: utf-8 -*- #! /usr/bin/python3 import pandas as pd import numpy as np from sklearn.preprocessing import LabelEncoder from sklearn.externals import joblib import os.path import nlp_tasks from sklearn.neural_network import MLPClassifier # アルゴリズムのmlp def train(): classifier = MyMLPClassifier() classifier.train('corpus.csv') def predict(): classifier = MyMLPClassifier() classifier.load_model() result = classifier.predict(u"競馬の3歳馬日本一を決めるG1レース、「第88回日本ダービー」が行われ、4番人気のシャフリヤールが優勝しました。") print(result) class MyMLPClassifier(): model = None model_name = "mlp" def load_model(self): if os.path.exists(self.get_model_path())==False: raise Exception('no model file found!') self.model = joblib.load(self.get_model_path()) self.classes = joblib.load(self.get_model_path('class')).tolist() self.vectorizer = joblib.load(self.get_model_path('vect')) self.le = joblib.load(self.get_model_path('le')) def get_model_path(self, type='model'): return 'models/'+self.model_name+"_"+type+".pkl" def get_vector(self,text) return self.vectorizer.transform() def train(self, csvfile): df = pd.read_csv(cavfile,names=('text','category')) X, vectorizer = nlp_tasks.get_vector_by_text_list(df["text"]) le = LabelEncoder() le.fit(df['category']) Y = le.transform(df['category']) model = MLPClassifier(max_iter=300, hidden_layer_sizes=(100,),verbose=10,) model.fit(X, Y) # save models joblib.dump(model, self.get_model_path()) joblib.dump(le.classes_, self.get_model_path("class")) joblib.dump(vectorizer, self.get_model_path("vect")) joblib.dump(le, self.get_model_path("le")) self.model = model self.classes = le.classes_.tolist() self.vectorizer = vectorizer def predict(self, query): X = self.vectorizer.transform([query]) key = self.model.predict(X) return self.classes[key[0]] if __name__ == '__main__': train() #predict()
$ ls
corpus.csv main.py models nlp_tasks.py text
$ python3 main.py
Iteration 1, loss = 4.24610757
Iteration 2, loss = 2.08110509
Iteration 3, loss = 1.70032200
Iteration 4, loss = 1.49572560
// 省略
Iteration 136, loss = 0.00257828
Training loss did not improve more than tol=0.000100 for 10 consecutive epochs. Stopping.
if __name__ == '__main__': # train() predict()
$ python3 main.py
sports-watch
まじかーーーーーーーーーーーーーーーーーー
Sugeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee