import csv
import matplotlib.pyplot as plt
class ANN:
def __init__(self, path):
with open(path) as Data_file:
Datas = csv.reader(Data_file)
AData = [data for data in Datas]
self._RawData = self._InputData(path)
self._Input_array, self._Target_list = self._DivInOut()
self._DivTar()
self.fold = 0
def _InputData(self, path):
with open(path) as Data_file:
Datas = csv.reader(Data_file)
AData = [data for data in Datas]
newMatrix = Matrix(len(AData), len(AData[0]))
count = 0
for i in range(newMatrix.numRows()):
for j in range(newMatrix.numCols()):
newMatrix[i, j] = AData[count][j]
count += 1
return newMatrix
def _DivInOut(self):
AInput = self._RawData.tolist() # Convert Matrix to a list
AOutput = [row[-1] for row in AInput] # Extract the last column as output
self.NumData = len(AInput)
self.NumInput = len(AInput[0]) - 1 # Number of columns except the output column
return AInput, AOutput
def _DivTar(self):
Class = set(self._Target_list)
self.NumOutput = len(Class)
self._Target_array = [
[1 if self._Target_list[i] == val else 0 for val in Class] for i in range(self.NumData)
]
def CleanData(self, data_range):
low, high = data_range
newList= Alist() #ใช้ลิสที่เขียนขึ้นมาเองในการเก็บค่า
case1,case2 = (0,0)
for i in range(self._Input_array.num_rows()):
for j in range(self._Input_array.num_cols()):
try:
self._Input_array[i,j]=float(self._Input_array[i,j])
except ValueError:
case1+=1
newList.Append(i)
continue
if not ((low <= self._Input_array[i,j] <= high)):
case2+=1
newList.Append(i)
newList.ClearRepeatVal() #เอาค่า row ที่ซ้ำกันออกไป
print(f"Inputs contain {case1} non-float values")
print(f"inputs contain {case2} out-of-range values")
print(f"Removing {len(newList)} rows......")
for i in range(len(newList)-1,-1,-1):
self._Input_array = self._Input_array.delete(newList[i],0)
self._Target_list.Pop(newList[i])
self.NumData,self.NumInput = self._Input_array.shape
print("Removing process done")
self._DivTar()
def _SeparateFold(self,fold,reset = False): #แบ่งชุดข้อมูลการ Test
if reset:
self.fold = 0
assert self.fold != fold , "Out of range"
print(f"Divided into {fold} folds. This is round {self.fold + 1}")
Num=self.NumData//fold
self.Input_Train = Matrix.zeros((self.NumData-Num , self.NumInput) , 'f')
self.Input_Test = Matrix.zeros((Num , self.NumInput) , 'f')
self.Target_Train = Matrix.zeros((self.NumData-Num , self.NumOutput) , 'i')
self.Target_Test = Matrix.zeros((Num , self.NumOutput) , 'i')
testing_indices = data_indices[:fold_size]
training_indices = data_indices[fold_size:]
self.training_data = (
Matrix([self.inputs.data[i] for i in training_indices]),
Matrix([self.targets.data[i] for i in training_indices])
)
self.testing_data = (
Matrix([self.inputs.data[i] for i in testing_indices]),
Matrix([self.targets.data[i] for i in testing_indices])
)
self.fold += 1
def _Training(self): # การ Train ข้อมูล
for i in range(self.Input_Train.numRows()):
for j in range(self.Input_Train.numCols()):
self.Input_Train[i, j] = float(self.Input_Train[i, j])
for i in range(self.Target_Train.numRows()):
for j in range(self.Target_Train.numCols()):
self.Target_Train[i, j] = float(self.Target_Train[i, j])
self.Input_Train_T = self.Input_Train.transpose()
self.Target_Train_T = self.Target_Train.transpose()
self.weights_input_hidden = Matrix.uniform(-0.1, 0.1, (self.NumInput, self._hid_node))
self.weights_hidden_output = Matrix.uniform(-0.1, 0.1, (self._hid_node, self.NumOutput))
def _Plot(self): #Plot กราฟค่า losses เทียบกับ epochs
temp_epochs = Array(self._epochs)
temp_losses = Array(len(self.losses))
for i in range(1, self._epochs+1):
temp_epochs[i-1] = i
for i in range(len(self.losses)):
temp_losses[i] = self.losses[i]
plt.plot(temp_epochs, temp_losses)
plt.show()
def _Testing(self, curTrain_seq): #การ Test ข้อมูล
for i in range(self.Input_Test.numRows()):
for j in range(self.Input_Test.numCols()):
self.Input_Test[i,j] = float(self.Input_Test[i,j])
for i in range(self.Target_Test.numRows()):
for j in range(self.Target_Test.numCols()):
self.Target_Test[i,j] = float(self.Target_Test[i,j])
self.Input_Test_T = self.Input_Test.transpose()
self.Target_Test_T = self.Target_Test.transpose()
def Train_Model(self, fold): #4 #Train ข้อมูลไปตามจำนวน fold ที่ใส่ไว้ โดยเปลี่ยนชุดข้อมูลสำหรับการ Test ทุก ๆ รอบ
accuracy = Alist()
for i in range(fold):
if i == 0:
reset = True
else:
reset = False
self._SeparateFold(fold, reset)
acc = self._Training()
accuracy.Append(acc)
mean_acc = sum(accuracy)/len(accuracy)
print("-"*50)
print('Mean Accuracy = {0:.2f}%'.format(mean_acc*100))