import sys from numpy import mat, mean, power ''' 首先是从文件中读取内容,然后遍历每一行,返回line.rstrip() 的值到生成器中,生成器的大小是文件的行数。 其中rstrip() 是返回该行删除 string 字符串末尾后的指定字符(默认为空格) ''' def read_input(file): for line in file:#按行读取文件 yield line.rstrip()#yield首先是个关键词,类似于return,返回的是个生成器 ''' 生成器是一个特殊的程序,可以被用作控制循环的迭代行为,python中生成器是迭代器的一种,使用yield返回值函数, 每次调用yield会暂停,而可以使用next()函数和send()函数恢复生成器。 生成器类似于返回值为数组的一个函数,这个函数可以接受参数,可以被调用,但是,不同于一般的函数会一次性返回包括了所有数值的数组, 生成器一次只能产生一个值,这样消耗的内存数量将大大减小, 而且允许调用函数可以很快的处理前几个返回值,因此生成器看起来像是一个函数,但是表现得却像是迭代器 ''' input =read_input(sys.stdin) # creates a list of input lines,读取文件,创建一个输入行列表 input = [float(line) for line in input] # overwrite with floats按行读取输入,创建一组对应的浮点数 numInputs = len(input)#得到数组的长度 input = mat(input)#把输入变为矩阵 sqInput =power(input, 2)#所有值变为平方 print("%d\t%f\t%f" % (numInputs,mean(input), mean(sqInput))) # calc mean of columns #print >> sys.stderr, "report: still alive" X: print("fatal error", file=sys.stderr)
对于Windows, 1.win+R
2.然后输入cmd
3.使用cd \ 把目标返回到最上面,使用cd 转到你保存mrMeanMapper.py的地方,
4.输入
5.得到结果
import sys from numpy import mat, mean, power def read_input(file): for line in file: yield line.rstrip() input = read_input(sys.stdin)#creates a list of input lines #split input lines into separate items and store in list of lists mapperOut = [line.split('\t') for line in input] #accumulate total number of samples, overall sum and overall sum sq cumVal=0.0 cumSumSq=0.0 cumN=0.0 for instance in mapperOut: nj = float(instance[0])#第一个字段是数据个数 cumN += nj#总数 cumVal += nj*float(instance[1])#第二个字段是一个map输出的均值,均值乘以数据个数就是数据总和 cumSumSq += nj*float(instance[2])#第三个字段是一个map输出的平方和的均值,乘以元素个数就是所有元素的平方和 #calculate means mean = cumVal/cumN#得到所有元素的均值 varSum=(cumSumSq-2*mean*cumVal+cumN*mean*mean)/cumN #output size, mean, mean(square values) print ("%d\t%f\t%f" % (cumN, mean, varSum)) #print >> sys.stderr, "report: still alive" X: print("fatal error", file=sys.stderr)
import mrjob from mrjob.job import MRJob class MRmean(MRJob): def __init__(self, *args, **kwargs): super(MRmean, self).__init__(*args, **kwargs) self.inCount = 0 self.inSum = 0 self.inSqSum = 0 def map(self, key, val): #needs exactly 2 arguments#类似于for循环,在每行输入上执行同样的步骤 if False: yield inVal = float(val) self.inCount += 1 self.inSum += inVal self.inSqSum += inVal*inVal #mapper() 中对输入值进行积累,所有值收集完毕后计算出均值和平方均值,最后把这些值作为中间值通过yield传出去 def map_final(self): mn = self.inSum/self.inCount mnSq = self.inSqSum/self.inCount yield (1, [self.inCount, mn, mnSq])#所有的mapper都使用1作为key,因为希望所有的中间值在同一个reducer里加起来 def reduce(self, key, packedValues): cumVal=0.0; cumSumSq=0.0; cumN=0.0 for valArr in packedValues: #get values from streamed inputs nj = float(valArr[0]) cumN += nj cumVal += nj*float(valArr[1]) cumSumSq += nj*float(valArr[2]) mean = cumVal/cumN var = (cumSumSq - 2*mean*cumVal + cumN*mean*mean)/cumN yield (mean, var) #emit mean and var #为mrjob指定mapper和reducer的名称 def steps(self): return ([self.mr(mapper=self.map, mapper_final=self.map_final,\ reducer=self.reduce,)]) if __name__ == '__main__': MRmean.run()
from numpy import * def loadDataSet(fileName):#加载数据 dataMat = []; labelMat = [] fr = open(fileName) for line in fr.readlines(): lineArr = line.strip().split('\t') #dataMat.append([float(lineArr[0]), float(lineArr[1]), float(lineArr[2])]) dataMat.append([float(lineArr[0]), float(lineArr[1])]) labelMat.append(float(lineArr[2])) return dataMat,labelMat def seqPegasos(dataSet, labels, lam, T):#T代表迭代次数,k代表待处理数据的大小 m,n = shape(dataSet); w = zeros(n)#初始化 for t in range(1, T+1):#迭代循环 i = random.randint(m)#random.randint(a,b)用于生成一个指定范围内的整数 eta = 1.0/(lam*t)#更新eta p = predict(w, dataSet[i,:])#权重乘以数据 if labels[i]*p < 1:#被错分了 w = (1.0 - 1/t)*w + eta*labels[i]*dataSet[i,:] else: w = (1.0 - 1/t)*w print (w) return w def predict(w, x): return w*x.T def batchPegasos(dataSet, labels, lam, T, k): m,n = shape(dataSet); w = zeros(n) dataIndex = list(range(m)) for t in range(1, T+1): wDelta = mat(zeros(n)) #reset wDelta eta = 1.0/(lam*t) random.shuffle(dataIndex) for j in range(k):#go over training set i = dataIndex[j] p = predict(w, dataSet[i,:]) #mapper code if labels[i]*p < 1: #mapper code wDelta += labels[i]*dataSet[i,:].A #accumulate changes w = (1.0 - 1/t)*w + (eta/k)*wDelta #apply changes at each T return w datArr,labelList = loadDataSet('testSet.txt') datMat = mat(datArr) #finalWs = seqPegasos(datMat, labelList, 2, 5000) finalWs = batchPegasos(datMat, labelList, 2, 50, 100) print (finalWs) import matplotlib import matplotlib.pyplot as plt fig = plt.figure() ax = fig.add_subplot(111) x1=[]; y1=[]; xm1=[]; ym1=[] for i in range(len(labelList)): if labelList[i] == 1.0: x1.append(datMat[i,0]); y1.append(datMat[i,1]) else: xm1.append(datMat[i,0]); ym1.append(datMat[i,1]) ax.scatter(x1, y1, marker='s', s=90,c='blue') ax.scatter(xm1, ym1, marker='o', s=50, c='red') x = arange(-6.0, 8.0, 0.1) y = (-finalWs[0,0]*x - 0)/finalWs[0,1] #y2 = (0.43799*x)/0.12316 y2 = (0.498442*x)/0.092387 #2 iterations ax.plot(x,y) ax.plot(x,y2,'g-.') ax.axis([-6,8,-4,5]) ax.legend(('50 Iterations', '2 Iterations') ) plt.show()
import mrjob from mrjob.job import MRJob import pickle from numpy import * class MRsvm(MRJob): DEFAULT_INPUT_PROTOCOL = 'json_value' def __init__(self, *args, **kwargs): super(MRsvm, self).__init__(*args, **kwargs) self.data = pickle.load(open('G:\python\python code\MLinactive\svmDat27'))#添加数据 self.w = 0 self.eta = 0.69 self.dataList = [] self.k = self.options.batchsize self.numMappers = 1 self.t = 1 #iteration number def configure_options(self): super(MRsvm, self).configure_options() self.add_passthrough_option( '--iterations', dest='iterations', default=2, type='int', help='T: number of iterations to run') self.add_passthrough_option( '--batchsize', dest='batchsize', default=100, type='int', help='k: number of data points in a batch') ''' 程序清单15-6里的第一个方法是map ( ), 这也是分布式的部分,它得到输人值并存储,以便 在map_fin()中处理。该方法支持三种类型的输人: w向量、七或者xo七是迭代次数,在本方法 中不参与运算。 状态不能保存,因此如果需要在每次迭代时保存任何变量并留给下一次迭代,可 以使用key/value对传递该值, 抑或是将其保存在磁盘上。显然前者更容易实现,速度也更快。 map_fin()方法在所有输人到达后开始执行。 这时已经获得了权重向量w和本次批处理中的 而是索引。数据存储在磁盘上,当脚本执行 一组x值。每个x值是一个整数,它并不是数据本身,而是索引。数据仔储在1}}上,}n}} 的时候读人到内存中。当map_fin()启动时,它首先将数据分成标签和数据,然后在本次批 的数据(存储在self.dataList里)上进行迭代,如果有任何值被错分就将其输出给redui w向量和t值都应被发送给reducero ''' # 得到输入值并进行存储 支持三种类型的输入:w向量 t或者x t是迭代次数,在该方法中不参与计算 # 状态不能保存,因此如果需要在每次迭代时保存任何变量并留给下一次迭代,可以使用key/value对传递该值,抑或是保存在磁盘上。前者较易实现,速度也更快 def map(self, mapperId, inVals): #needs exactly 2 arguments分布式部分,它得到输人值并存储,以便 #在map_fin()中处理。该方法支持三种类型的输人:w向量、t或者x, t是迭代次数,在本方法中不参与运算。 #input: nodeId, ('w', w-vector) OR nodeId, ('x', int) if False: yield if inVals[0]=='w': #accumulate W-vector self.w = inVals[1] elif inVals[0]=='x': self.dataList.append(inVals[1])#accumulate data points to calc elif inVals[0]=='t': self.t = inVals[1] else: self.eta=inVals #this is for debug, eta not used in map ''' map_fin() 方法在所有输人到达后开始执行。 这时已经获得了权重向量w和本次批处理中的 而是索引。数据存储在磁盘上,当脚本执行 一组x值。每个x值是一个整数,它并不是数据本身,而是索引。数据仔储在1}}上,}n}} 的时候读人到内存中。当map_fin() 启动时,它首先将数据分成标签和数据,然后在本次批 的数据(存储在self.dataList里) 上进行迭代,如果有任何值被错分就将其输出给redui w向量和t值都应被发送给reducero ''' def map_fin(self): labels = self.data[:,-1]; X=self.data[:,0:-1]#reshape data into X and Y if self.w == 0: self.w = [0.001]*shape(X)[1] #init w on first iteration for index in self.dataList: p = mat(self.w)*X[index,:].T #calc p=w*dataSet[key].T if labels[index]*p < 1.0: yield (1, ['u', index])#make sure everything has the same key yield (1, ['w', self.w]) #so it ends up at the same reducer yield (1, ['t', self.t]) ''' 最后是reduce()函数,对应本例只有一个reducer执行。该函数首先迭代所有的key/value对 并将值解包到一个局部变量datalist里。之后dataList里的值都将用于更新权重向量w,更新 量在wDel七a中完成累加.。然后,wMa七按照wDelta和学习率eta进行更新。在what更新完毕后, 又可以重新开始整个过程:一个新的批处理过程开始,随机选择一组向量并输出。注意,这些向 量的key是mapper编号。 ''' def reduce(self, _, packedVals): for valArr in packedVals: #get values from streamed inputs if valArr[0]=='u': self.dataList.append(valArr[1]) elif valArr[0]=='w': self.w = valArr[1] elif valArr[0]=='t': self.t = valArr[1] labels = self.data[:,-1]; X=self.data[:,0:-1] wMat = mat(self.w); wDelta = mat(zeros(len(self.w))) for index in self.dataList: wDelta += float(labels[index])*X[index,:] #wDelta += label*dataSet eta = 1.0/(2.0*self.t) #calc new: eta #calc new: w = (1.0 - 1/t)*w + (eta/k)*wDelta wMat = (1.0 - 1.0/self.t)*wMat + (eta/self.k)*wDelta for mapperNum in range(1,self.numMappers+1): yield (mapperNum, ['w', wMat.tolist()[0] ]) #emit w if self.t < self.options.iterations: yield (mapperNum, ['t', self.t+1])#increment T for j in range(self.k/self.numMappers):#emit random ints for mappers iid yield (mapperNum, ['x', random.randint(shape(self.data)[0]) ]) def steps(self): return ([self.mr(mapper=self.map, reducer=self.reduce, mapper_final=self.map_fin)]*self.options.iterations) if __name__ == '__main__': MRsvm.run()