csv ファイルを読み込んで機械学習と予測をするサンプルプログラム 【scikit-learn】

Python

CSV ファイルを読み込んで機械学習と予測を行うサンプルプログラムです。scikit-learn、Python を使っています。
CSV ファイルを差し替えてヘッダー部分を修正すれば、任意のデータについて機械学習や予測ができるようになると思います。

環境: Windows 10、Anaconda、Python 3.x

使い方

① PC に任意のフォルダを作成して、中に以下のファイル(合計4ファイル)を作成し、末尾のサンプルコードを貼りつけて保存してください。

learn1.py  機械学習を実行する python スクリプト
機械学習の学習段階で使う。
csv1.csv  学習のための csv ファイル
入力データ(col1 ~ col8)と正解データ(col9)の両方が入っている。
predict1.py  予測用の python スクリプト
機械学習の実際の使用段階で使う。
csv2.csv  予測のための csv ファイル
入力データ(col1 ~ col8)のみが入っている。正解データ(col9)は入っていない。

② コンソールから、学習用のスクリプト learn1.py を実行してください。正解データの入ったファイル csv1.csv を読み込んで、機械学習を実行します。
学習後、学習済みのパラメータが保存されます。また、正解率のテストが実行され、結果が表示されます。
③ 予測用のスクリプト predict1.py を実行してください。②の段階では使用していないデータ csv2.csv を用いて、予測を行います。予測結果はファイル名 csv3.csv で保存されます。

スクリプトの説明

学習用データ csv1.csv の説明

csv1.csv は、機械学習のスクリプト learn1.py で使うための学習用データです。
入力用のデータと正解データが入っています。この例では、csv ファイルのヘッダーcol1 ~ col8 を入力用データとし、col9 を正解データとして予測させるサンプルコードとしています。プログラムを書き換えれば、どの列を入力とするか、いくつ入力するか、どの列を正解データとするか、任意に設定できます。
添付したデータは、実際に私が取得しているログデータからの抜粋です。csv1.csv のようなログデータ(正解データを含む)を自動で取得していけば、正解データのない場合(csv2.csvのような場合)でも、予測ができるようになります。

学習用スクリプト predict1.py の説明

・ 最初に import … として、機械学習に必要なパッケージを読み込んでいます。
・ def としたところで、機械学習に必要なステップを関数で定義しています。
具体的には、csv ファイルの読み込みcsv ファイルの分割((入力用データ、出力用データ) × (学習用データ、テスト用データ)に分割)、機械学習の実行(fit)、テスト用の予測と正解の評価(predict_score1)の4つを定義しています。
・ path1 としたところで、フォルダのあるパスを設定しています。以降、すべてのファイルの読み書きは、このフォルダ内で行います。
・ read_csv1 関数を実行し、csv1.csv の読み込みを実行します。
・ header1 は、csv1.csv の中で、入力データにしたい列のタイトルを定義しています。header2 は、正解データとする列のタイトルです。header1 は複数の列を指定できますが、header2 は1列しか定義できません。
CSV ファイルの中で、col1 ~ col8 の8つの列の数値を入力とし、col9 の数値を予測するよう機械学習をさせるという意味です。
つぎに、上記の入力と出力を分割し、かつ、訓練用データとテスト用データに分割するように split1() 関数を実行し、csv1.csv のデータを4つに分けます。
x1_xxxx としたものが入力データ、y1_xxxx としたものが出力データ、xx_train としたものが訓練用データ、xx_test としたものがテスト用データです。
例えば、x1_train, y1_train は、機械学習の学習用に使うトレーニングデータで、x1_train を入力したら、y1_train が出力されるように(パラメータを振って)機械学習を行う、という意味です。
・ 機械学習は、fit1() とした関数で実行しています。学習後のデータ(モデル)は model1 として取得しています。fitting_model1.sav は、学習後のデータを保存するときのファイル名です。
このファイルを読み込むことで、予測ができるようになります。
・ また、n1 = 7 としたところで、機械学習を行う際に使うモデルを指定しています。具体的にはサポートベクターマシン (n1 = 2)、ランダムフォレスト(n1 = 6, 7)などです。詳細は、def fit() で定義している部分を参照してください。
・ その後、predict_score1() 関数で、テスト用データを使った予測と評価を行います。具体的には、学習後のモデル model1 にテスト用のデータ x2_test を与えて予測させ、正解データ y2_test と比較して、正解率 score を評価します。
・ 最後に評価結果を表示します。80% 等の正解率が出力されるようにしています。
スクリプトを実行すると、正解率がわかるので、実行後、n1 = 7 等とした数値を n1 = 2, 3, 4, 5, 6 等に変えて、学習モデルを変えてみてください。正解率が変わると思います。機械学習の最初の学習段階で、学習対象(学習に使う CSV ファイル)に応じて、最適な学習モデルが変わるため、最適なモデルと学習用データを探すことになります。
サンプルコードでは、学習に必要な入力データは col1 ~ col8 としました。しかし、情報が多すぎるとノイズが多いことになります。予測をするのに必要な情報のみとなるよう列を絞ったほうが的確な判断ができるようになります。また、正解を得るための情報が不足しているのであれば、入力すべき情報を増やす、または、より妥当なデータに入れ替える必要があります。

実用段階でのデータ csv2.csv の説明

csv2.csv は、実際の使用段階を想定したデータです。具体的には、上述の学習用データで正解データのない(正解がわからない)データとなっています。かつ、csv1.csv とはデータが被らないデータ(学習済みモデルからすると、学習では用いていない初めてのデータ)になっています。

使用段階用スクリプト predict1.py の説明

・ 最初に import … として、機械学習に必要なパッケージを読み込んでいます。
・ def としたところで、予測を行う関数を定義しています。具体的には、使用段階用の csv ファイル(csv2.csv)を読み込んで、入力に必要な列(col1 ~ col8)を取得します。入力用の列は、学習段階と同じ(header1が同じ)になるようそろえておく必要があります。
・ つぎに、学習段階で生成した学習済みモデル(fitting_model1.sav)を model1 として読み込みます。このモデルを使って予測 model1.predict() を行います。
予測したデータ y1 は、入力前のデータ x1 と結合して、値 xy1 を返します。
予測を行ったら、print() 関数で xy1 を表示し、予測した結果を csv ファイル csv3.csv として保存します。

まとめ

csv ファイルを読み込み、scikit-learn を用いて、機械学習と予測を行うサンプルプログラムをまとめました。
任意の csv ファイルに差し替えて、入力用の列、出力用(正解データ)の列を設定すれば、機械学習と予測ができることになります。機械学習の中身をブラックボックスとして扱えるようになります!
これで、基本的な機械学習についても自由に扱えるようになりました。

関連リンク
・ 【scikit-learn】 LinearRegression の予測結果を整数で出力する方法

スクリプト

learn1.py

import os 
import sklearn 
import numpy as np1
import pandas as pd1
import joblib 
from sklearn.linear_model import LinearRegression
from sklearn.svm import SVC
from sklearn.svm import LinearSVC 
from sklearn.linear_model import LogisticRegression 
from sklearn.neighbors import KNeighborsClassifier 
from sklearn.ensemble import RandomForestClassifier 
from sklearn.model_selection import train_test_split 

def read_csv1( file1 ): 
    return pd1.read_csv( file1 ) 

def split1( csv1, header1, header2 ): 
    # csv1 = csv1.reindex( np1.random.permutation( csv1.index ) ).reset_index( drop=True )    # randomize 
    # print( csv1 )
    x1 = csv1.loc[:, header1 ]
    y1 = csv1.loc[:, header2 ]
    x1_train, x2_test, y1_train, y2_test = train_test_split( x1, y1, random_state=0 )
    y1_train = y1_train.values.ravel() 
    y2_test  = y2_test.values.ravel() 
    return x1_train, x2_test, y1_train, y2_test

def fit1( x0_train, y0_train, file1, n1 ): 
    all_models1 = [ 
        joblib.load( file1 ),                                                         # 0: only read existing model 
        LinearRegression(),                                                           # 1: linear regression 
        SVC(),                                                                        # 2: support vector machine 
        LinearSVC( max_iter=1000 ),                                                   # 3: linear suppoort vector machine 
        LogisticRegression( max_iter=10000 ),                                         # 4: logistic regression 
        KNeighborsClassifier( n_neighbors = 1 ),                                      # 5: kneighbors classifier 
        RandomForestClassifier(),                                                     # 6: random forest 1 
        RandomForestClassifier( min_samples_leaf=2, random_state=0, max_depth=100 )   # 7: random forest (customized) 
    ] 
    model1 = all_models1[ n1 ]                   # fitting model 
    model1.fit( x0_train, y0_train )             # learning 
    joblib.dump( model1, file1 )                 # save the model 
    return model1 

def predict_score1( model1, x0_test, y0_test ): 
    y1_pred = model1.predict( x0_test ) 
    # print( "predict" )
    # print( y1_pred ) 
    # print( type( y1_pred ) ) 
    # print( "answer" )
    # print( y0_test.T )
    # print( y0_test.to_numpy().T[0])
    # print( type( y0_test ) )
    # score, % 
    return model1.score( x0_test, y0_test )

path1 = os.path.dirname(__file__) + "/" 

file1 = path1 + "csv1.csv" 
csv1 = read_csv1( file1 )                                                 # read csv file 

header1 = ["col1","col2","col3","col4","col5","col6","col7","col8"]       # csv header 1 
header2 = ["col9"]                                                        # csv header 2 
x1_train, x2_test, y1_train, y2_test = split1( csv1, header1, header2 )   # split 

file1 = path1 + 'fitting_model1.sav' 
n1 = 7                                                                    # fitting model 0-7 
model1 = fit1( x1_train, y1_train, file1, n1 )                            # training 
s1 = predict_score1( model1, x2_test, y2_test )                           # test 
print( "score: " + str( s1 ) + " %"  ) 

#for n1 in range( 1, 8 ): 
#   print( n1 ) 
#   model1 = fit1( x1_train, y1_train, file1, n1 )   # training 
#   s1 = test1( model1, x2_test, y2_test )                                # test 
#   print( "score: " + str( s1 ) + " %"  ) 

predict1.py



import os 
import sklearn 
import pandas as pd1
import joblib 

def predict1( file1, file2, header1 ): 
    x1 = pd1.read_csv( file1 ).loc[:, header1] 
    model1 = joblib.load( file2 )                                    # load model 
    y1 = model1.predict( x1 )                                        # predict 
    # y1 = ( y1+0.5 ).astype(int) 
    xy1 = x1.assign( col9 = y1 ) 
    return xy1 

path1 = os.path.dirname(__file__) + "/" 

header1 = ["col1","col2","col3","col4","col5","col6","col7","col8"]  # csv header 1 
file1 = path1 + "csv2.csv" 
file2 = path1 + 'fitting_model1.sav' 
xy1 = predict1( file1, file2, header1 )                              # predict 
print( xy1 ) 

file2 = path1 + "csv3.csv"                                           # save the predicted result 
xy1.to_csv( file2 ) 

csv1.csv

col1,col2,col3,col4,col5,col6,col7,col8,col9
19,09,30,07,47,04,0,0,12
19,09,30,07,52,05,0,0,12
19,09,30,07,57,05,0,0,12
19,09,30,08,02,04,0,0,11
19,09,30,08,07,04,0,0,11
19,10,01,07,47,04,1,0,12
19,10,01,07,52,04,1,0,12
19,10,01,07,57,04,1,0,12
19,10,01,08,02,04,1,0,11
19,10,01,08,07,04,1,0,11
19,10,02,07,47,04,2,0,11
19,10,02,07,52,04,2,0,12
19,10,02,07,57,04,2,0,12
19,10,02,08,02,05,2,0,11
19,10,02,08,07,05,2,0,11
19,10,03,07,47,04,3,0,12
19,10,03,07,52,04,3,0,12
19,10,03,07,57,04,3,0,12
19,10,03,08,02,04,3,0,11
19,10,03,08,07,04,3,0,11
19,10,04,07,47,04,4,0,12
19,10,04,07,52,04,4,0,12
19,10,04,07,57,04,4,0,12
19,10,04,08,02,04,4,0,11
19,10,04,08,07,05,4,0,11
19,10,05,07,47,04,5,0,11
19,10,05,07,52,04,5,0,11
19,10,05,07,57,04,5,0,11
19,10,05,08,02,04,5,0,10
19,10,05,08,07,05,5,0,10
19,10,06,07,47,04,6,0,11
19,10,06,07,52,05,6,0,11
19,10,06,07,57,04,6,0,11
19,10,06,08,02,05,6,0,10
19,10,06,08,07,04,6,0,10
19,10,07,07,42,04,0,0,12
19,10,07,07,47,04,0,0,12
19,10,07,07,52,04,0,0,12
19,10,07,07,57,05,0,0,12
19,10,07,08,02,05,0,0,11
19,10,07,08,07,04,0,0,11
19,10,08,07,42,05,1,0,12
19,10,08,07,47,05,1,0,12
19,10,08,07,52,04,1,0,12
19,10,08,07,57,05,1,0,12
19,10,08,08,02,04,1,0,11
19,10,08,08,07,04,1,0,11
19,10,09,07,42,04,2,0,12
19,10,09,07,47,04,2,0,12
19,10,09,07,52,04,2,0,12
19,10,09,07,57,04,2,0,12
19,10,09,08,02,04,2,0,11
19,10,09,08,07,04,2,0,11
19,10,10,07,42,04,3,0,12
19,10,10,07,47,05,3,0,12
19,10,10,07,52,05,3,0,12
19,10,10,07,57,05,3,0,12
19,10,10,08,02,04,3,0,11
19,10,10,08,07,05,3,0,11
19,10,11,07,42,04,4,0,12
19,10,11,07,47,05,4,0,12
19,10,11,07,52,04,4,0,12
19,10,11,07,57,05,4,0,12
19,10,11,08,02,05,4,0,11
19,10,11,08,07,04,4,0,11
19,10,12,07,42,04,5,0,11
19,10,12,07,47,05,5,0,11
19,10,12,07,52,05,5,0,11
19,10,12,07,57,04,5,0,11
19,10,12,08,02,05,5,0,10
19,10,12,08,07,05,5,0,10
19,10,13,07,42,10,6,0,11
19,10,13,07,47,10,6,0,11

csv2.csv

col1,col2,col3,col4,col5,col6,col7,col8
20,10,08,07,57,05,3,0
20,10,08,08,02,05,3,0
20,10,08,08,07,06,3,0
20,10,08,08,12,04,3,0
20,10,08,08,17,05,3,0
20,10,08,08,22,05,3,0
20,10,10,07,42,07,5,0
20,10,10,07,47,06,5,0
20,10,10,07,52,06,5,0
20,10,10,07,57,04,5,0
20,10,10,08,02,07,5,0
20,10,10,08,07,05,5,0
20,10,10,08,12,07,5,0
20,10,10,08,17,06,5,0
20,10,10,08,22,05,5,0
タイトルとURLをコピーしました