How can display differences of two matrices by sub

2020-05-06 10:01发布

问题:

I have two matrices [A](Expected_matrice) , [B](Predicted_matrice) I need to create the third one [C](Error_matrice) via subtraction of them [C]=[A]-[B] and pass it to Pandas dataframe and save in csv file.

Since abovementioned matrices' size are 24*20 and I try to:

First: Plot [C] via sns.heatmap(C, cbar=True, cmap="gray_gist")

Second: Evaluate [C] via applying sum(abs(abs([A])-abs([B])))/24*20 to check that how good it is. In fact I calculating amount of Error by that. I also know that it's possible to use another method like MSE from Sklearn import metrics by applying:

from Sklearn import metrics
print(metrics.mean_squared_error(A,B))

Since the elements of matrices are lists I've used : [i - j for (i, j) in zip(A,B)]

My codes are following:

import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from scipy.ndimage.filters import gaussian_filter

#A,B can be read from .csv files
A = pd.read_csv('D:\A.csv', header=None)
B = pd.read_csv('D:\B.csv', header=None)

#A,B can be assumed as lists
df_A = pd.DataFrame(A)
df_B = pd.DataFrame(B)

#calculate error matrix via subtraction 
C = [i - j for (i, j) in zip(A,B)]

#Pass error matrix to Pandas dataframe
df_C = pd.DataFrame(C)
df_C.to_csv('Error_Matrix.csv', header=None, index=None)

#Evaluation
Eval= sum(abs(abs([A])-abs([B])))/24*20
Eval_ =  '{:04}'.format(Eval)
print(Eval_)

#Plotting C
fig, ax = plt.subplots(nrows=1, ncols=2 , figsize=(20,15))

plt.subplot(1,2,1)
ax = sns.heatmap(C, cbar=True, cmap="gist_gray")
plt.title(f'Error Matrix  Error={Eval_}', fontsize=14 , fontweight='bold', color='black', loc='center', style='italic')
plt.axis('off')

plt.subplot(1,2,2)
C_smooth = gaussian_filter(dfr_b, sigma=1)
ax = sns.heatmap(C_smooth, vmin=np.min(C_smooth), vmax=np.max(C_smooth), cmap ="gray" , cbar=True , cbar_kws={"ticks":[0,33,67,100]})
plt.title(f'Error Matrix Smooth  Error={Eval_}', fontsize=14 , fontweight='bold', color='black', loc='center', style='italic')
plt.axis('off')
plt.savefig('Error_Matrix.png') 
plt.show()

Expected results:

Note white color shows Error=0 and solid black color shows Error=maximum. Mostly should be error but i don't want to have black result I expected Gray color mostly.

Data(matrix A,B): Matrix A , Matrix B

回答1:

I'd do something like this:

import matplotlib.pyplot as plt
import numpy as np


mx = 10 + 3 * np.random.random( 20 * 10 )
mx = mx.reshape( 20, 10 )
nx = 10 + 3 * np.random.random( 20 * 10 )
nx = nx.reshape( 20, 10 )
deltax = mx - nx
ox = 100 * ( 1 - np.abs( ( deltax) / mx ) )

scale = max( [ abs(min( np.concatenate( deltax ) ) ), abs( max( np.concatenate( deltax ) ) ) ] )

chi2 = np.sum( mx - nx )**2
chi2Red = chi2/( len( mx ) * len( mx[0] ) )
print chi2, chi2Red

fig = plt.figure()
ax = fig.add_subplot( 2, 2, 1 )
bx = fig.add_subplot( 2, 2, 2 )
cx = fig.add_subplot( 2, 2, 3 )
dx = fig.add_subplot( 2, 2, 4 )

MX1 = ax.matshow( mx, vmin=0, vmax=30 )
MX2 = bx.matshow( nx, vmin=0, vmax=30 )
diffMX = cx.matshow( deltax, cmap='seismic', vmin=-scale, vmax=scale )
errMX = dx.matshow( ox, vmin=0, vmax=100  )
plt.colorbar( MX1, ax=ax )
plt.colorbar( MX2, ax=bx )
plt.colorbar( diffMX, ax=cx )
plt.colorbar( errMX, ax=dx )
plt.show()

giving:

>> 219.40945851846487 1.0970472925923245

I have to say though, that I do not like loosing the information about the sign of deviation. The lower left graph, hence, would be my actual preference. It could be scaled and shifted like the last one such that zero becomes 100% and the data will range from 80% to 120% or somewhat like that.