'21/10/04更新:汎用性を高めるため、関数の引数を変更しました。3つの引数は順に、pandas DataFrame, X軸に指定する列名, Y軸に指定する列名です。
本記事では、下図3つのような近似式を作成する雛形コードを載せました。scipyのoptimize.curve_fitを利用します。
▼y = ax に近似したい場合(切片0)
▼ y = ax + b に近似したい場合
▼ y = ax^2 + bx + c に近似したい場合
■本プログラム
# -*- coding: utf-8 -*- import pandas as pd import numpy as np import scipy as sp from scipy import optimize import math import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt import datetime now = datetime.datetime.now() now = now.strftime("%y%m%d") # 近似式 y = ax 用の関数A:切片なしの1次式 def approximation_expression_A(x, a): return a * x # 近似式 y = ax + b 用の関数AB:切片ありの1次式 def approximation_expression_AB(x, a, b): return a * x + b # 近似式 y = ax^2 + bx + c 用の関数ABC:2次式 def approximation_expression_ABC(x, a, b, c): return a * pow(x, 2) + b * x + c # 関数A:y = ax def plot_reg_A(DF, X_name, Y_name): save_fname = X_name + Y_name + "_LinearRegression_A" # 近似式の作成 popt, pcov = optimize.curve_fit(approximation_expression_A, DF[X_name], DF[Y_name]) ax = plt.figure(num=0, dpi=120).gca() ax.set_title("pred vs real ", fontsize=14) ax.set_xlabel(X_name, fontsize=16) ax.set_ylabel(Y_name, fontsize=16) rp = ax.scatter(x = X_name, y = Y_name, data = DF, facecolors="none", edgecolors='black') # purple # Xデータの最小値と最大値 x_min = DF[X_name].min() x_max = DF[X_name].max() # Yデータの最小値と最大値 y_min = DF[Y_name].min() y_max = DF[Y_name].max() # プロットするためのxデータの範囲を決める x_min = min(x_min, y_min) x_max = min(x_max, y_max) print(x_min) print(x_max) # グラフのレンジを決める x_range = x_max - x_min # データの範囲が100以下か以上かで分ける print("x_range = x_max - x_min = " + str(x_range)) if x_max > 1: min_lim = 0 if x_range <= 10: max_lim = math.floor(x_max + 1) else: max_lim = math.floor(x_max + 10) rp.axes.set_xlim(min_lim, max_lim) rp.axes.set_ylim(min_lim, max_lim) else: max_lim = 0 if x_range <= 100: max_lim = math.floor(x_max - 1) else: max_lim = math.floor(x_max - 10) rp.axes.set_xlim(min_lim, max_lim) rp.axes.set_ylim(min_lim, max_lim) # 近似式プロットのためのデータを作成 x_approximation = np.linspace(min_lim, max_lim, 10) # numpyでxデータを作成 y_approximation = popt[0] * x_approximation # 近似式に代入してyデータを作成 line_approximation = ax.plot(x_approximation, y_approximation, linestyle = 'dashed', linewidth = 3, color='r') rp.axes.set_aspect('equal', adjustable='box') plt.grid(True) # 凡例を指定して記入する場合は、リストで指定する ax.legend([line_approximation[0]], ["y = {:.2f}x".format(popt[0])], loc='upper left', numpoints=1, fontsize=15) plt.tick_params(labelsize=15) plt.tight_layout() plt.savefig(save_fname + '.png') plt.close() # 関数AB:y = ax + b def plot_reg_AB(DF, X_name, Y_name): save_fname = X_name + Y_name + "_LinearRegression_AB" # 近似式の作成 popt, pcov = optimize.curve_fit(approximation_expression_AB, DF[X_name], DF[Y_name]) ax = plt.figure(num=0, dpi=120).gca() #plt.rcParams["axes.labelsize"] = 15 ax.set_title("pred vs real ", fontsize=14) ax.set_xlabel(X_name, fontsize=16) ax.set_ylabel(Y_name, fontsize=16) rp = ax.scatter(x = X_name, y = Y_name, data = DF, facecolors="none", edgecolors='black') # purple # Xデータの最小値と最大値 x_min = DF[X_name].min() x_max = DF[X_name].max() # Yデータの最小値と最大値 y_min = DF[Y_name].min() y_max = DF[Y_name].max() # プロットするためのxデータの範囲を決める x_min = min(x_min, y_min) x_max = min(x_max, y_max) print(x_min) print(x_max) # グラフのレンジを決める x_range = x_max - x_min # データの範囲が100以下か以上かで分ける print("x_range = x_max - x_min = " + str(x_range)) if x_max > 1: min_lim = 0 if x_range <= 10: max_lim = math.floor(x_max + 1) else: max_lim = math.floor(x_max + 10) rp.axes.set_xlim(min_lim, max_lim) rp.axes.set_ylim(min_lim, max_lim) else: max_lim = 0 if x_range <= 100: max_lim = math.floor(x_max - 1) else: max_lim = math.floor(x_max - 10) rp.axes.set_xlim(min_lim, max_lim) rp.axes.set_ylim(min_lim, max_lim) # 近似式プロットのためのデータを作成 x_approximation = np.linspace(min_lim, max_lim, 10) # numpyでxデータを作成 y_approximation = popt[0] * x_approximation + popt[1] # 近似式に代入してyデータを作成 line_approximation = ax.plot(x_approximation, y_approximation, linestyle = 'dashed', linewidth = 3, color='r') rp.axes.set_aspect('equal', adjustable='box') plt.grid(True) # 凡例を指定して記入する場合は、リストで指定する ax.legend([line_approximation[0]], ["y = {0:.2f}x + {1:.2f}".format(popt[0], popt[1])], loc='upper left', numpoints=1, fontsize=15) plt.tick_params(labelsize=15) plt.tight_layout() plt.savefig(save_fname + '.png') plt.close() # 関数ABC:y = ax^2 + bx + c def plot_reg_ABC(DF, X_name, Y_name): save_fname = X_name + Y_name + "_LinearRegression_ABC" # 近似式の作成 popt, pcov = optimize.curve_fit(approximation_expression_ABC, DF[X_name], DF[Y_name]) ax = plt.figure(num=0, dpi=120).gca() #plt.rcParams["axes.labelsize"] = 15 ax.set_title("pred vs real ", fontsize=14) ax.set_xlabel(X_name, fontsize=16) ax.set_ylabel(Y_name, fontsize=16) rp = ax.scatter(x = X_name, y = Y_name, data = DF, facecolors="none", edgecolors='black') # purple # Xデータの最小値と最大値 x_min = DF[X_name].min() x_max = DF[X_name].max() # Yデータの最小値と最大値 y_min = DF[Y_name].min() y_max = DF[Y_name].max() # プロットするためのxデータの範囲を決める x_min = min(x_min, y_min) x_max = min(x_max, y_max) print(x_min) print(x_max) # グラフのレンジを決める x_range = x_max - x_min # データの範囲が100以下か以上かで分ける print("x_range = x_max - x_min = " + str(x_range)) if x_max > 1: min_lim = 0 if x_range <= 10: max_lim = math.floor(x_max + 1) else: max_lim = math.floor(x_max + 10) rp.axes.set_xlim(min_lim, max_lim) rp.axes.set_ylim(min_lim, max_lim) else: max_lim = 0 if x_range <= 100: max_lim = math.floor(x_max - 1) else: max_lim = math.floor(x_max - 10) rp.axes.set_xlim(min_lim, max_lim) rp.axes.set_ylim(min_lim, max_lim) # 近似式プロットのためのデータを作成 x_approximation = np.linspace(min_lim, max_lim, 10) # numpyでxデータを作成 # 近似式に代入してyデータを作成 y_approximation = popt[0] * pow(x_approximation, 2) + popt[1] * x_approximation + popt[2] line_approximation = ax.plot(x_approximation, y_approximation, linestyle = 'dashed', linewidth = 3, color='r') rp.axes.set_aspect('equal', adjustable='box') plt.grid(True) # 凡例を指定して記入する場合は、リストで指定する ax.legend([line_approximation[0]], ["y = {0:.2f}x^2 + {1:.2f}x + {2:.2f}".format(popt[0], popt[1], popt[2])], loc='upper left', numpoints=1, fontsize=15) plt.tick_params(labelsize=15) plt.tight_layout() plt.savefig(save_fname + '.png') plt.close() if __name__ == '__main__': ##### 基本パラメータ ##### file_path = "test_data.csv" df = pd.read_csv(file_path) # 散布図(近似式付き)関数を呼び出して実行する # 引数3つは順に、pandasデータフレーム, X軸にプロットしたい列名, Y軸にプロットしたい列名 plot_reg_A(df, "PRICE", "PRICE_pred") plot_reg_AB(df, "PRICE", "PRICE_pred") plot_reg_ABC(df, "PRICE", "PRICE_pred") print("finished")
▼手法は同じで、その他活用例として下記リンクを貼り付けます。
以上
<広告>
リンク