此算法的实现基于下面理论那里的西瓜书伪代码,读数据部分直接用了大神的一段代码,源地址https://blog.csdn.net/qdbszsj/article/details/79110888
同时给出一些理论:https://blog.csdn.net/aaalswaaa1/article/details/83046813
import pandas as pd
import numpy as np
import random
import math
# 激活函数
def sigmoid(X, d):
if d == 1:
for i in range(len(X)):
X[i] = 1 / (1 + math.exp(-X[i]))
else:
for i in range(len(X)):
X[i] = sigmoid(X[i], d-1)
return X
# 数据读入
dataset = pd.read_csv('watermelon3.0.csv', delimiter=",",
header=None) # 不把第一行当属性名,直接读入,不改header会默认不读第一行
# 文本数字化
attributeMap = {}
attributeMap['浅白'] = 0
attributeMap['青绿'] = 0.5
attributeMap['乌黑'] = 1
attributeMap['蜷缩'] = 0
attributeMap['稍蜷'] = 0.5
attributeMap['硬挺'] = 1
attributeMap['沉闷'] = 0
attributeMap['浊响'] = 0.5
attributeMap['清脆'] = 1
attributeMap['模糊'] = 0
attributeMap['稍糊'] = 0.5
attributeMap['清晰'] = 1
attributeMap['凹陷'] = 0
attributeMap['稍凹'] = 0.5
attributeMap['平坦'] = 1
attributeMap['硬滑'] = 0
attributeMap['软粘'] = 1
attributeMap['否'] = 0
attributeMap['是'] = 1
dataset = np.array(dataset)
m, n = np.shape(dataset)
for i in range(m):
for j in range(n):
if dataset[i][j] in attributeMap:
dataset[i][j] = attributeMap[dataset[i][j]]
dataset[i][j] = round(dataset[i][j], 3)
# 初始化数据
X = dataset[:, :n-1] # 样本属性输入
Y = dataset[:, -1] # 样本输出
m, n = np.shape(X)
eta = 0.2 # 学习参数
q = 10 # 隐层神经元数
l = 1 # 输出神经元
w = [[random.random() for i in range(l)] for j in range(q)] # 隐层与输出层之间的连接权
v = [[random.random() for i in range(q)] for j in range(n)] # 输入层与隐层之间的连接权
theta = [random.random() for i in range(l)] # 输出层阈值
gamma = [random.random() for i in range(q)] # 隐层阈值
Ek = 4 # 累积误差
time = 0 # 最大循环次数
# 迭代学习
while(time < 5000 and Ek > 0.1):
Ek = 0
time += 1
for k in range(m):
alpha = np.dot(X[k], v) # 隐层输入
b = sigmoid(alpha-gamma, 1) # 隐层输出
beta = np.dot(b, w) # 输出层输入
y = sigmoid(beta-theta, 1) # 输出层输出
g = y*(1-y)*(Y[k]-y)
e = b*(1-b)*((np.dot(w, g)).T)
w += eta*np.dot(b.reshape((q, 1)), g.reshape((1, l)))
theta -= eta*g
v += eta*np.dot(X[k].reshape((n, 1)), e.reshape((1, q)))
gamma -= eta*e
E = sum((y-Y[k])*(y-Y[k]))/2
Ek += E
alpha = np.dot(X, v)
b = sigmoid(alpha-gamma, 2)
beta = np.dot(b, w)
y = sigmoid(beta - theta, 2)
print(y)
print(Ek)
print(time)