鱼C论坛

 找回密码
 立即注册
查看: 2715|回复: 4

[已解决]builtins.TypeError不知道怎么解决

[复制链接]
发表于 2018-1-9 10:10:18 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. # -*- coding: utf-8 -*-
  2. from numpy import *
  3. import time
  4. import matplotlib.pyplot as plt
  5. import operator

  6. #核函数(点积函数)
  7. def calcKernelValue(x1,x2):
  8.     value=0
  9.     for i in range(len(x1)):
  10.         value=value+x1[i]*x2[i]
  11.     return float(value)

  12. #计算核函数矩阵,存放K<x1,x2>的值
  13. def calcKernelMatrix(dataSetIn):
  14.     kernelMatrix=zeros((len(dataSetIn),len(dataSetIn)))
  15.     for i in range(len(dataSetIn)):
  16.         for j in range(len(dataSetIn)):
  17.             kernelMatrix[i][j]=calcKernelValue(dataSetIn[i],dataSetIn[j])
  18.     return kernelMatrix

  19. class SVM:
  20.     def __init__(self,dataSetIn,labelsIn,maxiter,C,error_admit):
  21.         self.X=dataSetIn
  22.         self.Y=labelsIn
  23.         self.m=len(labelsIn)#样本数
  24.         self.alphas = [0]*self.m#阿尔法参数数组
  25.         self.b=0
  26.         self.maxiter=maxiter#最大迭代次数
  27.         self.C=C#惩罚因子
  28.         self.error_admit=error_admit#容错值
  29.         self.kernelValue = calcKernelMatrix(dataSetIn)#核函数矩阵
  30.         self.fx = [0]*self.m
  31.         self.E = [0]*self.m

  32. #计算g(xi)=∑[k从1到N]αk*yk*K(xi,xk)+b   
  33. def calcfx(svm):
  34.     for i in range(svm.m):
  35.         svm.fx[i]=sum(map(operator.mul,map(operator.mul,svm.alphas,svm.Y),svm.kernelValue[i]))+svm.b

  36. #计算E(xi)
  37. def calcE(svm):
  38.     for k in range(svm.m):
  39.         svm.E[k]=svm.fx[k]-svm.Y[k]

  40. #通过比较|Ei-Ek|,获取第二个阿尔法参数下标j
  41. def findSecondAlphas(svm,i):
  42.     maxEdiff=-99999
  43.     j=-1
  44.     for k in range(svm.m):
  45.         if i!=k and abs(svm.E[i]-svm.E[k])>maxEdiff:
  46.             maxEdiff=abs(svm.E[i]-svm.E[k])
  47.             j=k
  48.     j=int(random.uniform(0, svm.m))
  49.       #这里如果用<span style="font-family: Arial, Helvetica, sans-serif;">比较|Ei-Ek|的方法获取第二个拉格朗日乘子的话,会迭代进入死循环,所以我改为用随机获取第二个乘子,则结果好很多.最终的支持向量也分布在分割面附近</span>
  50.     while i==j:
  51.         j=int(random.uniform(0, svm.m))
  52.     return j
  53. #构建SVM分类器
  54. def structure_svm(dataSet,labels,maxiter=1000,C=0.6,error_admit=0):
  55.     svm=SVM(dataSet,labels,maxiter,C,error_admit)
  56.     continue_iter=True
  57.     iter_num=1
  58.     while iter_num<svm.maxiter and continue_iter:
  59.         continue_iter=False
  60.         iter_num+=1
  61.         #更新fx(x)和E(x)
  62.         calcfx(svm)
  63.         calcE(svm)
  64.         #KKT条件:
  65.         #当 αi=0 <=>  yi*Ei>0
  66.         #0<αi<C  <=>  yi*Ei=0
  67.         #αi=C  <=>  yi*Ei<0
  68.         #所以  
  69.         #如果yi*Ei < 0并且αi < C 则违反了KKT条件
  70.         #因为原本yi*Ei < 0 应该对应的是αi = C
  71.         #同理,yi*Ei > 0并且αi > 0则违反了KKT条件
  72.         #因为原本yi*Ei  > 0对应的应该是αi =0

  73.         i=-1
  74.         for k in range(svm.m):
  75.             yi_Ei=svm.Y[k]*svm.E[k]
  76.             #先遍历间隔边界上的支持向量点,即0<αi<C的点,也叫做非边界数据样本
  77.             if svm.alphas[k]>0 and svm.alphas[k]<C and yi_Ei!=0 :
  78.                 i=k
  79.                 continue_iter=True
  80.                 break

  81.         #在遍历整个样本集,查找违反KKT条件的样本
  82.         if not continue_iter:
  83.             for k in range(svm.m):
  84.                 yi_Ei=svm.Y[k]*svm.E[k]
  85.                 if (yi_Ei<-error_admit and svm.alphas[k]<C) or (yi_Ei>error_admit and svm.alphas[k]>0) or (yi_Ei==0 and (svm.alphas[k]==0 or svm.alphas[k]==C)):
  86.                     i=k
  87.                     continue_iter=True
  88.                     break
  89.         
  90.         
  91.         if continue_iter and i>=0:
  92.             j=findSecondAlphas(svm,i)
  93.             #确定边界
  94.             #如果yi!=yj  则:L=max(0,αj-αi),H=min(C,C+αj-αi)
  95.             #如果yi=yj   则:L=max(0,αi+αj-C),H=min(C,αi+αj)
  96.             #αj=αj-yi(Ei-Ej)/η   η=2K<xi,xj>-K<xi,xi>-K<xj,xj>
  97.             #αj= H   if αj>H
  98.             #  = αj  if L<=αj<=H
  99.             #  = L   if αj<L
  100.             #αi=αi+yiyj(αj'old-αj)
  101.             L,H=0,0
  102.             if svm.Y[i]!=svm.Y[j]:
  103.                 L=max(0,svm.alphas[j]-svm.alphas[i])
  104.                 H=min(C,C+svm.alphas[j]-svm.alphas[i])
  105.             else:
  106.                 L=max(0,svm.alphas[j]+svm.alphas[i]-C)
  107.                 H=min(C,svm.alphas[j]+svm.alphas[i])
  108.                
  109.             eta=2*svm.kernelValue[i,j]-svm.kernelValue[i,i]-svm.kernelValue[j,j]

  110.             #更新alpha_j
  111.             #print(svm.E[i],svm.E[j],svm.E[i]-svm.E[j],eta)
  112.             alphas_j_new=svm.alphas[j]-svm.Y[j]*(svm.E[i]-svm.E[j])/eta
  113.             if alphas_j_new>H:
  114.                 alphas_j_new=H
  115.             elif alphas_j_new<L:
  116.                 alphas_j_new=L
  117.             else:
  118.                 alphas_j_new=alphas_j_new
  119.             #更新alpha_i
  120.             #print(svm.alphas[j],alphas_j_new,svm.alphas[j]-alphas_j_new)
  121.             alphas_i_new=svm.alphas[i]+svm.Y[i]*svm.Y[j]*(svm.alphas[j]-alphas_j_new)

  122.             #更新b值
  123.             #b1=b-Ei-yi*(αi-αi'old)K<xi,xi>-yj*(αj-αj'old)K<xi,xj>
  124.             #b2=b=Ej-yi*(αi-αi'old)K<xi,xj>-yj*(αj-αj'old)K<xj,xj>
  125.             #如果0<αi<C和0<αi<C,那么b1=b2
  126.             #如果αi=0或者αi=C,同时αj=0或者αj=C,则取中间值b=(b1+b2)/2
  127.             #总之:
  128.             #b= b1          if 0<αi<C
  129.             # = b2          if 0<αj<C
  130.             # = (b1+b2)/2   otherwise
  131.             b1=svm.b-svm.E[i]-svm.Y[i]*(alphas_i_new-svm.alphas[i])*svm.kernelValue[i,i]-svm.Y[j]*(alphas_j_new-svm.alphas[j])*svm.kernelValue[i,j]
  132.             b2=svm.b-svm.E[j]-svm.Y[i]*(alphas_i_new-svm.alphas[i])*svm.kernelValue[i,j]-svm.Y[j]*(alphas_j_new-svm.alphas[j])*svm.kernelValue[j,j]
  133.             if alphas_i_new>0 and alphas_i_new<C:
  134.                 b=b1
  135.             elif alphas_j_new>0 and alphas_j_new<C:
  136.                 b=b2
  137.             else:
  138.                 b=(b1+b2)/2
  139.             alphas_i_old=svm.alphas[i]
  140.             alphas_j_old=svm.alphas[j]
  141.             b_old=svm.b
  142.             svm.alphas[i]=alphas_i_new
  143.             svm.alphas[j]=alphas_j_new
  144.             svm.b=b
  145.     print(svm.alphas)
  146.     return svm

  147. #画图
  148. def showSVM(svm):

  149.     #画出所有样本点
  150.     for i in xrange(svm.m):
  151.         if svm.Y[i] == -1:
  152.             plt.plot(svm.X[i][0], svm.X[i][1], 'or' ,c='red')
  153.         elif svm.Y[i] == 1:
  154.             plt.plot(svm.X[i][0], svm.X[i][1], 'or' ,c='green')

  155.     for i in xrange(svm.m):
  156.         if svm.alphas[i] != 0:
  157.             plt.plot(svm.X[i][0], svm.X[i][1], 'or' ,c='blue')

  158.     w1,w2=0,0
  159.     min_x,max_x=99999,-99999
  160.     #计算w,和最小,最大的x1
  161.     for i in xrange(svm.m):
  162.         w1 += svm.alphas[i]*svm.Y[i]*svm.X[i][0]
  163.         w2 += svm.alphas[i]*svm.Y[i]*svm.X[i][1]
  164.         if min_x>svm.X[i][0]:
  165.             min_x=svm.X[i][0]
  166.         if max_x<svm.X[i][0]:
  167.             max_x=svm.X[i][0]
  168.     #计算x2        
  169.     y_min_x = float(-svm.b - w1 * min_x) / w2
  170.     y_max_x = float(-svm.b - w1 * max_x) / w2
  171.     #画出分界线
  172.     plt.plot([min_x, max_x], [y_min_x, y_max_x], '-g')
  173.     plt.show()
  174.    

  175. dataSet = []
  176. labels = []
  177. fileIn = open('E:\\testSet.txt')
  178. for line in fileIn.readlines():
  179.     lineArr = line.strip().split('        ')
  180.     dataSet.append([float(lineArr[0]), float(lineArr[1])])
  181.     labels.append(float(lineArr[2]))

  182. svm=structure_svm(dataSet,labels)
  183. showSVM(svm)
复制代码
最佳答案
2018-1-9 10:43:50
看提示应该是
operator.mul 函数不支持一个 list (map函数返回的list) 和一个 int (svm.kernelValue)作为实参进行计算吧
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2018-1-9 10:13:17 | 显示全部楼层
具体错误信息贴出来
一行一行的去读你代码太耗时间了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-1-9 10:25:55 | 显示全部楼层
BngThea 发表于 2018-1-9 10:13
具体错误信息贴出来
一行一行的去读你代码太耗时间了

File "f:\BaiduYunDownload\homework\easyguitest.py", line 198, in <module>
  svm=structure_svm(dataSet,labels)
File "f:\BaiduYunDownload\homework\easyguitest.py", line 68, in structure_svm
  calcfx(svm)
File "f:\BaiduYunDownload\homework\easyguitest.py", line 39, in calcfx
  svm.fx[i]=sum(map(operator.mul,map(operator.mul,svm.alphas,svm.Y),svm.kernelValue[i]))+svm.b

builtins.TypeError: unsupported operand type(s) for +: 'map' and 'int'
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-1-9 10:43:50 | 显示全部楼层    本楼为最佳答案   
看提示应该是
operator.mul 函数不支持一个 list (map函数返回的list) 和一个 int (svm.kernelValue)作为实参进行计算吧
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-1-9 10:51:16 | 显示全部楼层
'map' and 'int' 类型不能直接进行运算
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-7-13 16:09

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表