用户:四九圣尊查看:9 回复:19 评论:9 创建时间:2018-10-01T22:35:31
今天我们要写一个ai对鸢尾花进行分类。
已知鸢尾花的花瓣长和宽,判断它是普通鸢尾花还是变色鸢尾花。
首先,了我们要从sklearn读取鸢尾花的数据:(代码写上去没高亮太丑了,所以发图片)
并转化成列表。
红线上面的是鸢尾花的四个特征。分别是:花瓣长度,花瓣宽度,花萼长度,花萼宽度。
红线下面的是鸢尾花类别,有三种:0(普通鸢尾花),1(野生鸢尾花),-1(变色鸢尾花)
这次我们做二分类,所以删掉野生鸢尾花。并且删掉花萼长度,花萼宽度的数据,减少计算量,以便让萌新看起来更加直观。
然后我们看看这时数据的分布:
蓝色是变色鸢尾花,黄色是普通鸢尾花。分类器的任务就是给出数据集其中的一个点,分出他是变色鸢尾花还是普通鸢尾花。现在我们就要用到感知机算法:
定义三个变量:a=0,b=0,c=0
定义f(花瓣长度,花瓣宽度) = 花瓣长度*a + 花瓣宽度*b + c。然后根据返回值的正负性判断是普通鸢尾花还是变色鸢尾花。这里我们定义,如果返回值>=0,是变色鸢尾花,否则为普通鸢尾花。
当:a=4.469999999999985,b=-6.77999999999998,c=-3.3000000000000016时,分类器可以正好完美分辨出所有数据类别。那么如何才能让a,b,c的值变成上面这样呢?(一开始a,b,c都为0)
我们随机选取一个点,用现有的a,b,c预测一次(现在a,b,c都是0)。比如(7.7, 3)。那么f(7.7,3)=7.7 * 0 + 3 *0 + 0 = 0。这时f(7.7,7.3) = 0。
按照我们的定义,他是变色鸢尾花,但实际喵是普通鸢尾花。这时,我们就要调整a,b,c的值。
新a = a + learning_rate(这个值决定了训练的速度,你可以自己调整) * 数据的真实类别(因为是普通鸢尾花,所以是-1) * 花瓣长度
新b = b + learning_rate(这个值决定了训练的速度,你可以自己调整) * 数据的真实类别(因为是普通鸢尾花,所以是-1) * 花瓣宽度
新c = c + learning_rate(这个值决定了训练的速度,你可以自己调整) * 数据的真实类别(因为是普通鸢尾花,所以是-1)
lr就是学习率,这里我设置的是0.1。
训练完后测试模型:
结果:
附上全部代码:
from sklearn.datasets import load_iris
from matplotlib import pyplot as plt
#装载数据
data_f = load_iris()
data = data_f.data
target = data_f.target.tolist()
data = [x.tolist() for x in data]
print(data)
print(target)
#数据预处理
del target[90:150]#删掉标签为2的数据
del data[90:150]
for i in range(len(target)):#替换标签
if target[i] == 0:
target[i] = -1
print(target)
for i in range(len(data)):#删除后两个特征
del data[i][2:4]
#画图
data_x = []
data_y = []
for i in data:
data_x.append(i[0])
for i in data:
data_y.append(i[1])
plt.scatter(data_x[0:50],data_y[0:50])
plt.scatter(data_x[51:90],data_y[51:90])
plt.show()
#感知机算法
a1 = 1
a2 = 3
b = 1
lr = 0.1
def predict(x,y):
return a1*x + a2*y +b
for i in range(150):
for i in range(len(data)):
true = target[i]
prediction = predict(data[i][0],data[i][1])
if true == -1 and prediction >= 0:
a1 = a1 + lr*true*data[i][0]
a2 = a2 + lr*true*data[i][1]
b = b+lr*true
if true == 1 and prediction <0:
a1 = a1 + lr*true*data[i][0]
a2 = a2 + lr*true*data[i][1]
b = b+lr*true
right = 0
for i in range(len(data)):
true_test = target[i]
c_r = predict(data[i][0],data[i][1])
print("分类器返回:%s"%(c_r))
if c_r >= 0 and true_test == 1:
right += 1
if c_r < 0 and true_test == -1:
right += 1
print("正确率为;%s/%s"%(right,len(target)))
print("计算函数为:%s * x + %s * y + %s"%(a1,a2,b))
点赞0
评论
进阶教程:
如果要分的类别有三个,不止两个,怎么办呢?
现在我们添加上野生鸢尾花,要分类的花种就有了:野生,变色,普通三种鸢尾花。
那么按照以前的方法,通过判断返回结果的正负性就已经无法完成这个任务了。因为返回值只有>=0的数和<0的数。不存在第三种。这时我们就需要训练三个不同的分类器,他们分别判断:这是野生鸢尾花吗?这是普通鸢尾花吗?这是变色鸢尾花吗?(返回值>=0就是,否则就不是)
将三个结果综合在一起,得到答案。比如,三个返回的值为(1,-1,-1)。那么他就是野生鸢尾花。因为其他两个分类器返回的值都是负数。
但是不排除返回值可能为两正一负甚至三正零负的可能。这时我们该如何处理呢?
比如返回结果为:(-1,2,3)。这时他是什么花呢?
现在我们就要使用归一化指数函数:
(它能将一个含任意实数的K维向量z“压缩”到另一个K维实向量σ(z)中,使得每一个元素的范围都在(0,1)之间,并且所有元素的和为1。该函数多于多分类问题中。)
根据公式,分别计算e的-1,2和3次方。得出的结果分别为:0.368,7.389,20.086。
将他们全部加在一起得:27.843。再用每个数除以27.843.得0.368/27.843,7.89/27.843,20.086/27.843。
所得出的结果就是分类器返回的真实概率分别是:0.013,0.265,0.722。
所以选择最后一个,它是变色鸢尾花!
点赞0
评论