-
Notifications
You must be signed in to change notification settings - Fork 28
Expand file tree
/
Copy pathsample_program_6_8_4_regression.py
More file actions
129 lines (115 loc) · 8.27 KB
/
Copy pathsample_program_6_8_4_regression.py
File metadata and controls
129 lines (115 loc) · 8.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# -*- coding: utf-8 -*-
"""
@author: hkaneko
"""
import sys
import numpy as np
import pandas as pd
import sample_functions
from sklearn import metrics
from sklearn import svm
from sklearn.cross_decomposition import PLSRegression
from sklearn.model_selection import train_test_split, cross_val_predict, GridSearchCV
# 下の y_name を、'boiling_point', 'logS', 'melting_point', 'pIC50', 'pIGC50' のいずれかにしてください。
# descriptors_with_[y_name].csv というファイルを dataset として読み込み計算します。
# さらに、y_name を別の名前に変えて、ご自身で別途 sample_program_6_8_0_csv.py もしくは
# sample_program_6_8_0_sdf.py で descriptors_with_[y_name].csv というファイルを、
# 他のファイルと同様の形式で準備すれば、同じように計算することができます。
y_name = 'melting_point'
# 'boiling_point' : 沸点のデータセットの場合
# 'logS' : 水溶解度のデータセットの場合
# 'melting_point' : 融点のデータセットの場合
# 'pIC50' : 薬理活性のデータセットの場合
# 'pIGC50' : 環境毒性のデータセットの場合
rate_of_test_samples = 0.25 # テストデータのサンプル数の割合。0 より大きく 1 未満
method_name = 'svr' # 'pls' or 'svr'
add_nonlinear_terms_flag = False # True (二乗項・交差項を追加) or False (追加しない)
fold_number = 5 # N-fold CV の N
max_number_of_principal_components = 30 # 使用する主成分の最大数
svr_cs = 2 ** np.arange(-5, 11, dtype=float) # C の候補
svr_epsilons = 2 ** np.arange(-10, 1, dtype=float) # ε の候補
svr_gammas = 2 ** np.arange(-20, 11, dtype=float) # γ の候補
if method_name != 'pls' and method_name != 'svr':
sys.exit('\'{0}\' という回帰分析手法はありません。method_name を見直してください。'.format(method_name))
dataset = pd.read_csv('descriptors_with_{0}.csv'.format(y_name), index_col=0) # 物性・活性と記述子のデータセットの読み込み
y = dataset.iloc[:, 0].copy()
x = dataset.iloc[:, 1:]
x = x.replace(np.inf, np.nan).fillna(np.nan) # inf を NaN に置き換え
nan_variable_flags = x.isnull().any() # NaN を含む変数
x = x.drop(x.columns[nan_variable_flags], axis=1) # NaN を含む変数を削除
number_of_test_samples = round(dataset.shape[0] * rate_of_test_samples)
# ランダムにトレーニングデータとテストデータとに分割
# random_state に数字を与えることで、別のときに同じ数字を使えば、ランダムとはいえ同じ結果にすることができます
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=number_of_test_samples, shuffle=True,
random_state=0)
# 標準偏差が 0 の説明変数を削除
std_0_variable_flags = x_train.std() == 0
x_train = x_train.drop(x_train.columns[std_0_variable_flags], axis=1)
x_test = x_test.drop(x_test.columns[std_0_variable_flags], axis=1)
if add_nonlinear_terms_flag:
x_train = pd.read_csv('x_train_{0}.csv'.format(y_name), index_col=0) # 物性・活性と記述子のデータセットの読み込み
x_test = pd.read_csv('x_test_{0}.csv'.format(y_name), index_col=0) # 物性・活性と記述子のデータセットの読み込み
# x_train = sample_functions.add_nonlinear_terms(x_train) # 説明変数の二乗項や交差項を追加
# x_test = sample_functions.add_nonlinear_terms(x_test) # 説明変数の二乗項や交差項を追加
# 標準偏差が 0 の説明変数を削除
std_0_nonlinear_variable_flags = x_train.std() == 0
x_train = x_train.drop(x_train.columns[std_0_nonlinear_variable_flags], axis=1)
x_test = x_test.drop(x_test.columns[std_0_nonlinear_variable_flags], axis=1)
# オートスケーリング
autoscaled_x_train = (x_train - x_train.mean()) / x_train.std()
autoscaled_y_train = (y_train - y_train.mean()) / y_train.std()
autoscaled_x_test = (x_test - x_train.mean()) / x_train.std()
if method_name == 'pls':
# CV による成分数の最適化
components = [] # 空の list の変数を作成して、成分数をこの変数に追加していきます同じく成分数をこの変数に追加
r2_in_cv_all = [] # 空の list の変数を作成して、成分数ごとのクロスバリデーション後の r2 をこの変数に追加
for component in range(1, min(np.linalg.matrix_rank(autoscaled_x_train), max_number_of_principal_components) + 1):
# PLS
model = PLSRegression(n_components=component) # PLS モデルの宣言
estimated_y_in_cv = pd.DataFrame(cross_val_predict(model, autoscaled_x_train, autoscaled_y_train,
cv=fold_number)) # クロスバリデーション推定値の計算し、DataFrame型に変換
estimated_y_in_cv = estimated_y_in_cv * y_train.std() + y_train.mean() # スケールをもとに戻す
r2_in_cv = metrics.r2_score(y_train, estimated_y_in_cv) # r2 を計算
print(component, r2_in_cv) # 成分数と r2 を表示
r2_in_cv_all.append(r2_in_cv) # r2 を追加
components.append(component) # 成分数を追加
# 成分数ごとの CV 後の r2 をプロットし、CV 後のr2が最大のときを最適成分数に
optimal_component_number = sample_functions.plot_and_selection_of_hyperparameter(components, r2_in_cv_all,
'number of components',
'cross-validated r2')
print('\nCV で最適化された成分数 :', optimal_component_number)
# PLS
model = PLSRegression(n_components=optimal_component_number) # モデルの宣言
elif method_name == 'svr':
# グラム行列の分散を最大化することによる γ の最適化
print('グラム行列の分散を最大化することによる γ の最適化')
optimal_svr_gamma = sample_functions.gamma_optimization_with_variance(autoscaled_x_train, svr_gammas)
# CV による ε の最適化
model_in_cv = GridSearchCV(svm.SVR(kernel='rbf', C=3, gamma=optimal_svr_gamma), {'epsilon': svr_epsilons},
cv=fold_number, verbose=2)
model_in_cv.fit(autoscaled_x_train, autoscaled_y_train)
optimal_svr_epsilon = model_in_cv.best_params_['epsilon']
# CV による C の最適化
model_in_cv = GridSearchCV(svm.SVR(kernel='rbf', epsilon=optimal_svr_epsilon, gamma=optimal_svr_gamma),
{'C': svr_cs}, cv=fold_number, verbose=2)
model_in_cv.fit(autoscaled_x_train, autoscaled_y_train)
optimal_svr_c = model_in_cv.best_params_['C']
# CV による γ の最適化
model_in_cv = GridSearchCV(svm.SVR(kernel='rbf', epsilon=optimal_svr_epsilon, C=optimal_svr_c),
{'gamma': svr_gammas}, cv=fold_number, verbose=2)
model_in_cv.fit(autoscaled_x_train, autoscaled_y_train)
optimal_svr_gamma = model_in_cv.best_params_['gamma']
# 最適化された C, ε, γ
print('C : {0}\nε : {1}\nGamma : {2}'.format(optimal_svr_c, optimal_svr_epsilon, optimal_svr_gamma))
# SVR
model = svm.SVR(kernel='rbf', C=optimal_svr_c, epsilon=optimal_svr_epsilon, gamma=optimal_svr_gamma) # モデルの宣言
model.fit(autoscaled_x_train, autoscaled_y_train) # モデルの構築
if method_name == 'pls':
# 標準回帰係数
standard_regression_coefficients = pd.DataFrame(model.coef_, index=x_train.columns,
columns=['standard_regression_coefficients'])
standard_regression_coefficients.to_csv(
'pls_standard_regression_coefficients.csv') # csv ファイルに保存。同じ名前のファイルがあるときは上書きされますので注意してください
# トレーニングデータ・テストデータの推定、実測値 vs. 推定値のプロット、r2, RMSE, MAE の値の表示、推定値の保存
sample_functions.estimation_and_performance_check_in_regression_train_and_test(model, autoscaled_x_train, y_train,
autoscaled_x_test, y_test)