# Load network params
npz_file =  "/Users/csiu/repo/predictTissue/src/model-mlp_n100-e100.txt.npz"
with np.load(npz_file) as f:
    param_values = [f['arr_%d' % i] for i in range(len(f.files))]
    
# save to variable
w_l1 = pd.DataFrame(param_values[0])
w_l2 = pd.DataFrame(param_values[2])

"""
Explanation: Today, I want to implement the other metric to extract feature importance: connection weight mentioned in:

Ibrahim, OM. 2013. A comparison of methods  for  assessing the  relative  importance of input variables in  artificial neural networks. Journal of Applied Sciences Research, 9(11): 5692-5700.
End of explanation
"""


def connection_weights(A, B):
    """
    Computes Connection weights algorithm
    A = matrix of weights of input-hidden layer (rows=input & cols=hidden)
    B = matrix of weights of hidden-output layer (rows=hidden & cols=output)
    """    
    cw = np.dot(A, B)
    
    # normalize to 100% for relative importance
    ri = cw / cw.sum()
    return(ri)

"""
Explanation: Connection weights
$RI_x = \sum_{y=1}^m{w_{xy}w_{yz}}$
Essentially the sum of products from the input to the output
Connection weights algorithm (CW)
End of explanation
"""


df = connection_weights(w_l1, w_l2)
df = pd.DataFrame(df)
df.head()

n = 150

f, ax = plt.subplots(figsize=(25, 6))
sns.boxplot(w_l1[:n].transpose())
plt.xlabel("Input feature")
plt.ylabel("weight of input-hidden node")
plt.title("Input-hidden node weights of the first {} features".format(n))

"""
Explanation: Using CW
End of explanation
"""


f, ax = plt.subplots(figsize=(25, 6))
df.plot(kind="line", ax=ax)
plt.xlabel("Input feature")
plt.ylabel("Relative importance")

"""
Explanation: Again, weight of some regions are more variable than others
End of explanation
"""


# Partitioning features to classes by max weight
df.idxmax(axis=1).value_counts(sort=False).plot(kind="bar")
plt.xlabel("Index of output class")
plt.ylabel("Count")
plt.title("Input features assigned to output class by maximizing importance")

"""
Explanation: Unlike Garson's algorithm, get different feature importance depending on the class
End of explanation
"""


