![2d55b282730d4f28832d42d0328ccce7.png](https://i-blog.csdnimg.cn/blog_migrate/55c9473c5c9a8f117311f85713d6543c.jpeg)
总觉着没整理好,还是先写吧。为什么要写感知机?实际上是为了熟悉theano的使用。真正做起来才发现一个最简单的感知机以前的理解都有问题。我想我还是先列一下为什么在文本分类中不用感知机吧。晚上随意搜到了一个”菜菜的sklearn课堂“,真敢说呀,为啥实际中不用逻辑回归原因是没人用,逻辑回归的预测结果不是概率。。。大姐,模型预测的就是个条件概率,所以才叫判别模型。逻辑回归的本质是sigmoid函数,大姐,损失函数才是本质吧?概率跟损失函数有关系。。。讲工程的,非数学专业的,最好还是照着经典讲,比如《统计学习方法》,别胡扯八道。工程也讲不明白,极度怀疑这些人看过sklearn源码吗。讲解就跟买东西直播似的。。。
为什么不用感知机:
- 线性分类器(这不是主要原因)
- 误分类点驱动的损失函数,训练时,w的初值不同或者误分类点选择顺序不同都会得到不同的分类超平面,这种解不确定的算法无论是文本分类还是其他分类应用都是不能接受的。不过sklearn求解的超平面是固定的,具体计算细节待查看源码。
- 只能解决二分类问题,对于多分类问题,只能用one-vs-rest方法。如果类目为千万级的,你的训练千万级的分类模型。
接下来,按照线性分类模型的必列项列举:
- 预测函数
![81904e7047a031331e0741266ec35e64.png](https://i-blog.csdnimg.cn/blog_migrate/eb9818dc3afd20014da30700bd75a4bd.png)
- 损失函数
![81144ac5885618d01e3fdfa521a431c7.png](https://i-blog.csdnimg.cn/blog_migrate/4612fa8b091849b3b88eb9202c512db0.png)
从损失函数表达式我们应该看到:
(1)感知机的训练只受误分类点驱动
(2)标准感知机中没有正则化罚项来避免过拟合问题
看到这个损失函数,我要对科大讯飞的那位说,这式子从哪个学的角度来说,都不是均方误差。
最后,上本篇小文的主要内容,用theano实现感知机
示例数据依然用《统计学习方法》例2.1
import numpy as np
import theano
import theano.tensor as T
# 绘图模块
import numpy as np
from matplotlib import pyplot as plt
from matplotlib.colors import ListedColormap
%matplotlib inline
def plot_predict(x, w, b):
return np.dot(w, x) + b
def plot_decsion_plane(X_data, y_data, w, b):
# 画决策面
colors = ['red', 'blue']
cmap = ListedColormap(colors[:len(np.unique(y_data))])
x1_min, x1_max = X_data[:, 0].min() - 1, X_data[:, 0].max() + 1
x2_min, x2_max = X_data[:, 1].min() - 1, X_data[:, 1].max() + 1
xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, 0.02),np.arange(x2_min, x2_max, 0.02))
Z = plot_predict(np.array([xx1.ravel(), xx2.ravel()]), w, b)
Z = Z.reshape(xx1.shape)
plt.contourf(xx1, xx2, Z, alpha=0.4, cmap=cmap)
plt.xlim(xx1.min(), xx1.max())
plt.ylim(xx2.min(), xx2.max())
# 画样本点
markers = ('x', 'o')
for idx, ci in enumerate(np.unique(y_data)):
plt.scatter(x=X_data[y_data == ci, 0], y=X_data[y_data == ci, 1], alpha=0.8, c=np.atleast_2d(cmap(idx)),
marker=markers[idx], label=ci)
# 画图例
plt.legend(loc='upper left')
plt.show()
# 定义训练数据
X_data = np.array([[3,3],
[4,3],
[1,1]])
y_data = np.array([1, 1, -1])
D = (X_data, y_data)
# 学习速率
eta0 = 1.0
# 最大训练迭代次数
training_steps = 20
# 随机变量生成器
rng = np.random
# 声明theano符号变量
x = T.dmatrix("x")
y = T.dvector("y")
# 随机初始化权重向量w
# w和偏置变量b都为共享变量,
# 在训练迭代过程中(updates)能构保存它们的上一次迭代时的值plot_decsion_plane
w = theano.shared(rng.randn(D[0].shape[1]), name="w")
# 初始化偏置项
b = theano.shared(0., name="b")
print("初始化模型")
print("w=", w.get_value(), end=" ")
print("b=", b.get_value())
# 创建theano表达式图
p_1 = T.dot(x, w) + b # 感知机预测概率公式
prediction = T.sgn(p_1) # 感知机预测阈值
cost = -T.sum(T.dot(T.cast(T.neq(y,prediction), 'float32'),y*p_1)) # 错误分类实例驱动
gw, gb = T.grad(cost, [w, b]) # 计算损失函数梯度
# 编译
train = theano.function(
inputs=[x,y],
outputs=[prediction, cost],
updates=((w, w - eta0 * gw), (b, b - eta0 * gb))) # 学习效率为1
predict = theano.function(inputs=[x], outputs=prediction)
# 训练
for i in range(training_steps):
pred, cost = train(D[0], D[1])
print("iter %d"%i)
print("w=", w.get_value(), end=" ")
print("b=", b.get_value(), end=" ")
print("cost=%f" % cost)
# 画决策面
plot_decsion_plane(X_data, y_data, w.get_value(), b.get_value())
分类超平面
![99579c62de012e30eea573a72d62d173.png](https://i-blog.csdnimg.cn/blog_migrate/637881000afd96be335d0ff696dbd651.png)
关于感知机,我想应该记住
- 它的本质是最小化误分类点数量,从而最小化误分类点到超片面的距离。
- 所有线性分类模型的预测表达式中都有wx+b这个线性表达式,在感知机和支持向量机中用wx+b=0的超平面做分类模型的几何解释。
- 文本分类中不用感知机的最主要原因应该是它求解出的超平面的不确定性。
真心希望,有大牛来拍砖,而不是胡扯八道。