'19/12/22更新
・汎用性を持たせるためにcsvファイルを指定して読み込むようにした
・NN(Neural Network)の隠れ層をリストとして、複数パターンを指定できるようにした
・得られた回帰モデル(回帰式)をシリアライズにより「.joblib」ファイルで保存する
本記事では、scikit-learn(sklearn, サイキットラーン)で回帰分析できる次の7つの方法と結果例を載せました。
1. LinearRegression:線形重回帰
2. GradientBoostingRegressor:勾配ブースティング回帰
3. RandomForestRegressor:ランダムフォレスト回帰
4. Support Vector Regression(SVR):サポートベクトルマシン(SVM)の回帰版
▼Neural Network「Multilayer perceptron」:ニューラルネットワーク
5. Logistic Neurons:活性化関数にSigmoid(シグモイド)関数
6. TanH Neurons:活性化関数にtanh(ハイパボリックタンジェント)関数
7. Relu:活性化関数にRelu(Rectified Linear Unit)関数
Anacondaをインストールした環境であれば本コードをコピペで実行可能です。使用したデータはsklearnに含まれているボストンデータセットです。一旦、csvファイル化する方法はこちら→
Python scikit-learn付属のボストン市の住宅価格データ(Boston house prices dataset)をcsvファイル化する - HK29’s blog
■本プログラム
回帰分析の結果例は本コードの下に記載しています。
import os, sys, glob, datetime
import numpy as np
import pandas as pd
import scipy as sp
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.linear_model import LinearRegression
from sklearn.svm import SVR
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.ensemble import RandomForestRegressor
from sklearn import neural_network
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
import joblib
def my_load_csv(path, check_column, check_duplicate_columns,
start_row, input_columns, out_start_column,
target_Yname, target_value2ln):
df = pd.read_csv(path, skiprows=start_row-1, encoding="shift-jis")
print("df -> " + str(df))
print(df.dtypes)
df.replace('none', '0', inplace=True)
df.replace('FALSE', '0', inplace=True)
df_buf1 = df.iloc[:, :out_start_column]
df_buf2 = df.iloc[:, out_start_column:]
df_buf2.replace('0', np.nan, inplace=True)
df_buf2.replace(0, np.nan, inplace=True)
columns_list = df_buf2.columns
df = pd.concat([df_buf1, df_buf2], axis=1)
df.to_csv("data_nan.csv", sep=",", header=True, index=False)
print('check NaN -> ' + str(df.isnull().any()))
print(df.dtypes)
if check_duplicate_columns:
df2 = df.drop_duplicates(check_duplicate_columns, keep='first')
else:
df2 = df
print("df2 -> " + str(df2))
if check_column[0]:
df3 = df2.dropna(subset=[check_column[1]])
else:
df3 = df2[df2[check_column[1]].str.contains(check_column[2], na=False)]
print("df3 -> " + str(df3))
if target_value2ln:
df4 = df3.assign(tmp = np.log(df3[target_Yname]))
target_Yname = target_Yname + '_ln'
tmp_columns = df4.columns.values
print("tmp_columns -> " + str(tmp_columns))
tmp_columns[-1] = target_Yname
df4.columns = tmp_columns
print("df4 -> " + str(df4))
df4.to_csv("data_df4.csv", sep=",", header=True, index=False)
DF = df4
else:
DF = df3
x_DF = DF.iloc[:, input_columns[0]:input_columns[1]]
print("x_DF -> " + str(x_DF))
y = DF.loc[:,target_Yname]
DF_columns = x_DF.columns
print("DF_columns -> " + str(DF_columns))
DF.to_csv("data_DF.csv", sep=",", header=True, index=False)
print('check2 NaN -> ' + str(DF.isnull().any()))
return x_DF, y, DF_columns, target_Yname
def my_scaler(X_df, my_feature_names):
scaler = StandardScaler()
x_sc = scaler.fit_transform(X_df)
x_sc = pd.DataFrame(x_sc)
x_sc.columns = my_feature_names
x_sc.to_csv('data_scalerX.csv', sep=',', index=False, encoding='utf-8', header=True)
x_sc.describe().to_csv('data_describe.csv', index=True, encoding='utf-8',
mode='a', header=True)
return x_sc
def my_mscaler(X_df, my_feature_names):
mscaler = MinMaxScaler()
x_msc = mscaler.fit_transform(X_df)
x_msc = pd.DataFrame(x_msc)
x_msc.columns = my_feature_names
x_msc.to_csv('data_scalerX.csv', sep=',', index=False, encoding='utf-8', header=True)
x_msc.describe().to_csv('data_describe.csv', index=True, encoding='utf-8',
mode='a', header=True)
return x_msc
def plot_scatter(X_df, Y, target_Yname, Xname_for_graph, pred_Y, cnt, name, R2):
fig = plt.figure(dpi=120)
ax = fig.add_subplot(1,1,1)
ax.set_title('Scatter Num' + str(cnt), fontsize=14)
ax.set_xlabel(Xname_for_graph, fontsize=16)
ax.set_ylabel(target_Yname + '(target)', fontsize=16)
ax.scatter(X_df.loc[:,Xname_for_graph], Y, facecolors='none', edgecolors='b', label='Raw data')
ax.scatter(X_df.loc[:,Xname_for_graph], pred_Y, facecolors='none', edgecolors='r', label=name)
ax.legend(loc='lower right', fontsize=14)
ax.tick_params(labelsize=16)
plt.text(4, 40, 'R2={:.1%}'.format(R2), size = 16, color = "red")
plt.tight_layout()
plt.grid()
plt.savefig("scatter_" + target_Yname + '_' + name + '.png')
plt.cla()
plt.clf()
plt.close()
def plot_reg(Y, target_Yname, Xname_for_graph, pred_Y, cnt, name):
DF = pd.concat([Y, pred_Y], axis=1)
DF.columns = [target_Yname, target_Yname + "_pred"]
slope, intercept, r_value, p_value, std_err = sp.stats.linregress(Y, pred_Y)
r_pearsonr, p_pearsonr = sp.stats.pearsonr(Y, pred_Y)
ax = plt.figure(num=0, dpi=120).gca()
plt.rcParams["axes.labelsize"] = 15
ax.set_title(name, fontsize=14)
sns.regplot(x = target_Yname, y = target_Yname + "_pred", data = DF, color="purple",
line_kws={'label':"y={0:.2f}x+{1:.1f}".format(slope,intercept)})
ax.set_xlim(0, 60)
ax.set_ylim(0, 60)
ax.set_aspect('equal', adjustable='box')
plt.grid(True)
plt.legend(loc='upper left', fontsize=15)
plt.tick_params(labelsize=15)
plt.savefig(target_Yname + '_' + name + "_real_vs_pred.png")
plt.close()
buf1_str = ("slope, intercept, r_value, p_value, std_err, r_pearsonr, p_pearsonr")
buf2_list = [slope, intercept, r_value, p_value, std_err, r_pearsonr, p_pearsonr]
buf2_list_str = [str(n) for n in buf2_list]
buf2_list_str_with_csv = ','.join(buf2_list_str)
with open("data_" + target_Yname + '_' + name + "_r_p.csv", 'a') as f:
f.write(buf1_str + '\n')
f.writelines(buf2_list_str_with_csv)
def run_regressor(reg_list, X_df, Y, Xname_for_graph, target_Yname):
x_train, x_test, y_train, y_test= train_test_split(X_df, Y, test_size=0.2, random_state=42)
'''
print("train data")
print(x_train, y_train)
print("test data")
print(x_test, y_test)
'''
now = datetime.datetime.now()
now = now.strftime("%y%m%d")
i = 1
for name, regr in reg_list:
regr.fit(x_train, y_train)
joblib.dump(regr, now + '_' + target_Yname + '_' + name + '.joblib')
R2 = regr.score(x_test, y_test)
print('{0:}. {1:} -> R2:{2:.1%}'.format(i, name, R2))
pred_Y_np = regr.predict(X_df)
pred_Y = pd.Series(pred_Y_np)
plot_scatter(X_df, Y, target_Yname, Xname_for_graph, pred_Y, i, name, R2)
plot_reg(Y, target_Yname, Xname_for_graph, pred_Y, i, name)
i += 1
def my_del_files():
for f1 in glob.glob('*.png'):
os.remove(f1)
for f2 in glob.glob('data_*'):
os.remove(f2)
if __name__ == '__main__':
path = "zzz_boston_XYdata.csv"
input_factors = 13
target_Yname = 'PRICE'
Xname_for_graph = 'RM'
start_row = 1
target_value2ln = False
check_flag = True
check_column = (check_flag, target_Yname, 'ok')
check_duplicates_columns=[]
input_columns = (0, input_factors)
out_start_column = 14
scalerjudge = 0
my_del_files()
data = my_load_csv(path, check_column, check_duplicates_columns,
start_row, input_columns, out_start_column,
target_Yname, target_value2ln)
X = data[0]
Y = data[1]
feature_names = data[2]
target_Yname = data[3]
print(X)
print(Y)
print(feature_names)
print(target_Yname)
if scalerjudge == 1:
X = my_scaler(X, feature_names)
elif scalerjudge == 2:
X = my_mscaler(X, feature_names)
else:
pass
print('### scalerX data')
print(X)
regr_algorithm_list = [
('LinearRegression', LinearRegression()),
('GradientBoostingRegressor', GradientBoostingRegressor(random_state=1, n_estimators=100, max_depth=5)),
('RandomForestRegressor', RandomForestRegressor(n_estimators=9, max_depth=9, random_state=1)),
('Support Vector Regression', SVR(gamma='scale', C=18.0, epsilon=1.4)),
]
run_regressor(regr_algorithm_list, X, Y, Xname_for_graph, target_Yname)
hidden_layers_list = [(200,100,50,),
(200,100,50,25,),
(200,100,50,25,5,)]
for hidden_layers in hidden_layers_list:
s = len(hidden_layers)
nn_layer_name = '_{}layer'.format(s)
regr_algorithm_list = [
('NN_TanH Neurons'+ nn_layer_name, neural_network.MLPRegressor(activation='tanh', hidden_layer_sizes=hidden_layers ,solver='lbfgs')),
('NN_Relu' + nn_layer_name, neural_network.MLPRegressor(activation='relu', hidden_layer_sizes=hidden_layers, solver='lbfgs'))
]
run_regressor(regr_algorithm_list, X, Y, Xname_for_graph, target_Yname)
■解析結果
ニューラルネットワークの結果は活性化関数別に4,5,6であり、各々について隠れ層が3層、4層、5層の場合の結果を載せた。しかし、それらの設定(ハイパーパラメータ)は最適化されたものではないため、適合度がよろしくない様子がわかる。つまり、ニューラルネットワークは適当に設定して実行すれば良い結果が得られるわけではなく、解析しようとしている各々のデータ群に対して、適切な活性化関数の選択と隠れ層やノード数などの設定値を考慮や探索して設定する必要がある。
一方、ランダムフォレストの設定は比較的楽であり、決定木の枝葉の数を増やせばモデルの適合度は増す。注意点は全ての回帰分析に言えることで過剰適合である。
1. LinearRegression
2. GradientBoostingRegressor
3. RandomForestRegressor
4. Logistic Neurons(neural network「Multilayer perceptron」)
5. TanH Neurons(neural network「Multilayer perceptron」)
6. Relu(neural network「Multilayer perceptron」)
7. Support Vector Regression(SVR)
■参考資料
1. LinearRegression
sklearn.linear_model.LinearRegression — scikit-learn 0.21.3 documentation
2. Gradient Boosting regression
3.2.4.3.6. sklearn.ensemble.GradientBoostingRegressor — scikit-learn 0.21.3 documentation
3. RandomForestRegressor
3.2.4.3.2. sklearn.ensemble.RandomForestRegressor — scikit-learn 0.21.3 documentation
4,5,6. neural_network.MLPRegressor
sklearn.neural_network.MLPRegressor — scikit-learn 0.21.3 documentation
http://scikit-learn.org/stable/modules/neural_networks_supervised.html#regression
7. Support Vector Regression(SVR)
sklearn.svm.SVR — scikit-learn 0.21.3 documentation
以上
<広告>
リンク