Пример #1
0
    def addTaxo(self, taxonomy):

        self.taxonomy = taxonomy

        self.items.addTaxo(self.taxonomy)  # アイテムクラスにtaxonomyを追加する

        tFile = taxonomy.file
        itemFN = taxonomy.itemFN
        taxoFN = taxonomy.taxoFN

        tf = nu.Mtemp()
        xx1 = tf.file()
        cpara = "%s,%s:%s" % (self.idFN, taxoFN, self.itemFN)
        f = None
        f <<= nm.mnjoin(i=self.file,
                        k=self.itemFN,
                        K=itemFN,
                        f=taxoFN,
                        m=tFile)
        f <<= nm.mcut(f=cpara, o=xx1)
        f.run()

        ipara = "%s,%s" % (self.file, xx1)
        kpara = "%s,%s" % (self.idFN, self.itemFN)
        xx2 = tf.file()
        nm.mcat(i=ipara).muniq(k=kpara, o=xx2).run(msg="on")

        self.file = self.temp.file()
        shutil.move(xx2, self.file)
Пример #2
0
    def __convertToNumeric(self):
        wf1 = self.__tempW.file()
        wf2 = self.__tempW.file()
        wf3 = self.__tempW.file()
        self.mFile = self.__temp.file()
        nm.mcut(f="e1:node", i=self.__wfE, o=wf1).run()
        nm.mcut(f="e2:node", i=self.__wfE, o=wf2).run()
        mcmd = None
        if self.__wfN is not None:
            nm.mcut(f="n:node", i=self.__wfN, o=wf3).run()
            mcmd <<= nm.mcat(i=wf1 + "," + wf2 + "," + wf3, f="node")
        else:
            mcmd <<= nm.mcat(i=wf1 + "," + wf2, f="node")
        mcmd <<= nm.muniq(k="node")
        mcmd <<= nm.mnumber(q=True, a="id", o=self.mFile)
        mcmd.run()
        #エッジファイル変換・保存
        self.eFile = self.__temp.file()
        mcmd = nm.mjoin(i=self.__wfE,
                        m=self.mFile,
                        f="id:id1",
                        k="e1",
                        K="node")
        mcmd <<= nm.mjoin(m=self.mFile, f="id:id2", k="e2", K="node")
        mcmd <<= nm.muniq(k="id1,id2")
        mcmd <<= nm.msortf(f="id1%n,id2%n")
        mcmd <<= nm.mcut(f="id1:e1,id2:e2,no:row_index", o=self.eFile)
        mcmd.run()
        #take内部用エッジファイル保存
        self.eFileT = self.__temp.file()
        mcmd = nm.mcal(i=self.eFile, c="cat(\" \",$s{e1},$s{e2})", a="edge")
        mcmd <<= nm.mcut(nfno=True, f="edge", o=self.eFileT)
        mcmd.run()
        #ノードファイル変換・保存
        self.nFile = self.__temp.file()
        if self.__wfN is not None:
            mcmd = nm.mjoin(i=self.__wfN,
                            m=self.mFile,
                            f="id",
                            k="n",
                            K="node")
            mcmd <<= nm.muniq(k="id")
            mcmd <<= nm.msortf(f="id%n")
            mcmd <<= nm.mcut(f="id:n,no:row_index", o=self.nFile)
            mcmd.run()
        else:
            #エッジよりノード生成
            wf4 = self.__tempW.file()
            wf5 = self.__tempW.file()
            nm.mcut(i=self.eFile, f="e1:n", o=wf4).run()
            nm.mcut(i=self.eFile, f="e2:n", o=wf5).run()
            mcmd = nm.mcat(i="%s,%s" % (wf4, wf5))
            mcmd <<= nm.muniq(k="n")
            mcmd <<= nm.msortf(f="n%n")
            mcmd <<= nm.mnumber(q=True, a="row_index", o=self.nFile)
            mcmd.run()

        #ワークファイル削除
        self.__tempW.rm()
Пример #3
0
def _readCSV_sub(iFile):

    data = []
    for block in nm.mcat(i=iFile).keyblock(k="sid",
                                           s="sid,eid%n,item",
                                           dtype={
                                               "sid": "str",
                                               "eid": "int",
                                               "item": "str"
                                           },
                                           otype="dict"):

        sid = block["sid"][0]
        seq = []
        elements = []
        element = []
        eidPrev = block["eid"][0]

        for i in range(len(block["eid"])):
            eid = block["eid"][i]
            item = block["item"][i]
            if eid != eidPrev:
                elements.append([eidPrev, element])
                element = []

            element.append(item)
            eidPrev = eid

        elements.append([eidPrev, element])

        data.append([sid, elements])

    return data
Пример #4
0
def mkIndex(oFile, iFile):
    f = None
    f <<= nm.mcat(i=iFile)
    f <<= nm.mcut(f="date,c")
    f <<= nm.mavg(k="date", f="c")
    f <<= nm.mcal(c="round(${c},1)", a="i")
    f <<= nm.mcut(f="date,i", o="%s" % oFile)
    f.run()
Пример #5
0
	def enumerate(self,eArgs):
		tf=nu.Mtemp()

		# 最小サポートと最小サポート件数
		if "minCnt" in eArgs :
			self.minCnt = int(eArgs["minCnt"])
			self.minSup = float(self.minCnt)/ float(self.db.size)
		else:
			self.minSup = float(eArgs["minSup"])
			self.minCnt = int(self.minSup * float(self.db.size) + 0.99)


		# 最大サポートと最大サポート件数
		self.maxCnt=None
		if "maxCnt" in eArgs or "maxSup" in eArgs:
			if "maxCnt" in eArgs:
				self.maxCnt = int(eArgs["maxCnt"])
				self.maxSup = float(self.maxCnt)/float(self.db.size)
			else:
				self.maxSup = float(eArgs["maxSup"])
				self.maxCnt = int(self.maxSup * float(self.db.size) + 0.99)

		#未使用
		#@minProb = eArgs["minProb"].to_f # 事後確率
		#@minGR   = @minProb/(1-@minProb) # 増加率
		#@minGR   = eArgs["minGR"].to_f if eArgs["minGR"]

		# あるクラスをpos、他のクラスをnegにして、パターン列挙した結果ファイル名を格納する
		pFiles=[]
		tFiles=[]
		for cName,posSize in self.db.clsNameRecSize.items(): 
			negSize=self.db.size-posSize

			# minGRの計算
			if "minGR" in eArgs:
				self.minGR=eArgs["minGR"]
			else:
				minProb = eArgs["minProb"] if ( "minProb" in eArgs ) else 0.5
				if "uniform" in eArgs and eArgs["uniform"]:
					self.minGR = (minProb/(1-minProb)) * (self.db.clsSize-1) # マニュアルの式(4)
				else:
					self.minGR = (minProb/(1-minProb)) * (float(negSize)/float(posSize)) # マニュアルの式(4)


			# 最小サポートと最小サポート件数
			if "minCnt" in eArgs:
				self.minPos = eArgs["minCnt"]
			else:
				self.minPos = int(eArgs["minSup"] * float(posSize) + 0.99)

			# 最大サポートと最大サポート件数
			if "maxCnt" in eArgs or "maxSup" in eArgs:
				if "maxCnt" in eArgs:
					self.maxCnt = int(eArgs["maxCnt"])
				else:
 					self.maxCnt = int(eArgs["maxSup"] * float(posSize) + 0.99)


			self.sigma[cName] = self.calSigma(self.minPos,self.minGR,posSize,negSize)

			# lcm_seqのパラメータ設定と実行
			lcmout = tf.file() # lcm_seq出力ファイル
			# 頻出パターンがなかった場合、lcm出力ファイルが生成されないので
			# そのときのために空ファイルを生成しておいく。
			with open(lcmout, "w") as efile:
				pass

			params = {}
			if self.msgoff:
				params["type"] ="CIA_"
			else:
				params["type"] ="CIA"

			if self.maxCnt: # windowサイズ上限
				params["U"] = str(self.maxCnt)
			if "minLen" in eArgs:
				params["l"] = str(eArgs["minLen"])
			if 'maxLen' in eArgs:
				params["u"] = str(eArgs["maxLen"])
			if 'gap' in eArgs:
				params["g"] = str(eArgs["gap"])
			if 'win' in eArgs:
				params["G"] = str(eArgs["win"])

			params["w"] = self.weightFile[cName]
			params["i"] = self.file
			params["sup"] = str(self.sigma[cName])
			params["o"] = lcmout

			# lcm_seq実行
			#MCMD::msgLog("#{run}")
			if 'padding' in eArgs and eArgs["padding"]: # padding指定時は、0アイテムを出力しないlcm_seqを実行
				extTake.lcmseq_zero(params)
			else:
				extTake.lcmseq(params)

			# パターンのサポートを計算しCSV出力する
			#MCMD::msgLog("output patterns to CSV file ...")
			pFiles.append(self.temp.file())
			transle = self.temp.file()

			extTake.lcmtrans(lcmout,"e",transle) # pattern,countP,countN,size,pid

			f=None
			f <<= nm.mdelnull(f="pattern",i=transle)
			f <<= nm.mcal(c='round(${countN},1)',a="neg")
			f <<= nm.mcal(c='round(${countP}/%s,1)'%(self.posWeight[cName]),a="pos")
			f <<= nm.mdelnull(f="pattern")
			f <<= nm.msetstr(v=cName,a="class")
			f <<= nm.msetstr(v=posSize,a="posTotal")
			f <<= nm.msetstr(v=self.minGR,a="minGR")
			f <<= nm.mcut(f="class,pid,pattern,size,pos,neg,posTotal,minGR",o=pFiles[-1])
			f.run()

			#s = MCMD::mrecount("i=#{pFiles.last}") # 列挙されたパターンの数
			#MCMD::msgLog("the number of contrast patterns on class `#{cName}' enumerated is #{s}")

			if self.outtf :
				# トランザクション毎に出現するシーケンスを書き出す
				#MCMD::msgLog("output tid-patterns ...")
				tFiles.append(self.temp.file())

				xxw= tf.file()
				f=None
				f <<= nm.mcut(f=self.db.idFN,i=self.db.file)
				f <<= nm.muniq(k=self.db.idFN)
				f <<= nm.mnumber(S=0,a="__tid",q=True)
				f <<= nm.msortf(f="__tid",o=xxw)
				f.run()

				nm.mcut(f=self.db.idFN,i=self.db.file).muniq(k=self.db.idFN).mnumber(S=0,a="__tid",q=True,o=xxw).run()
				translt = self.temp.file()
				extTake.lcmtrans(lcmout,"t",translt)
				nm.mjoin(k="__tid",m=xxw,f=self.db.idFN,i=translt).msetstr(v=cName,a="class").mcut(f=self.db.idFN+",class,pid",o=tFiles[-1]).run()


		# クラス別のパターンとtid-pidファイルを統合して最終出力
		self.pFile = self.temp.file()
		self.tFile = self.temp.file()

		# パターンファイル併合
		xxpCat = tf.file()
		f =   nm.mcat(i=",".join(pFiles))
		f <<= nm.msortf(f="class,pid")
		f <<= nm.mnumber(s="class,pid",S=0,a="ppid",o=xxpCat)
		f.run()

		# パターンファイル計算
		items=self.db.items
		f=""
		f =   nm.mcut(f="class,ppid:pid,pattern,size,pos,neg,posTotal,minGR",i=xxpCat)
		f <<= nm.msetstr(v=self.db.size,a="total")
		f <<= nm.mcal(c='${total}-${posTotal}',a="negTotal") # negのトータル件数
		f <<= nm.mcal(c='${pos}/${posTotal}',a="support") # サポートの計算
		f <<= nm.mcal(c='if(${neg}==0,1.797693135e+308,(${pos}/${posTotal})/(${neg}/${negTotal}))',a="growthRate")
		if "uniform" in eArgs and eArgs["uniform"] == True:
			f <<= nm.mcal(c='(${pos}/${posTotal})/(${pos}/${posTotal}+(%s-1)*${neg}/${negTotal})'%(self.db.clsSize),a="postProb")
		else:
			f <<= nm.mcal(c='${pos}/(${pos}+${neg})',a="postProb")

		f <<= nm.msel(c='${pos}>=%s&&${growthRate}>=${minGR}'%(self.minPos)) # minSupとminGRによる選択
		f <<= nm.mvreplace(vf="pattern",m=items.file,K=items.idFN,f=items.itemFN)
		f <<= nm.mcut(f="class,pid,pattern,size,pos,neg,posTotal,negTotal,total,support,growthRate,postProb")
		f <<= nm.mvsort(vf="pattern")
		f <<= nm.msortf(f="class%nr,postProb%nr,pos%nr",o=self.pFile)
		f.run()

		if self.outtf :
			# 列挙されたパターンを含むtraのみ選択するためのマスタ
			xxp4=nm.mcut(f="class,pid",i=self.pFile)

			f =   nm.mcat(i=",".join(tFiles))
			f <<= nm.mjoin(k="class,pid",m=xxpCat,f="ppid") # 全クラス統一pid(ppid)結合
			f <<= nm.mcommon(k="class,ppid",K="class,pid",m=xxp4) # 列挙されたパターンの選択
			f <<= nm.mcut(f=self.db.idFN+",class,ppid:pid")
			f <<= nm.msortf(f=self.db.idFN+",class,pid",o=self.tFile)
			f.run()


		self.size = nu.mrecount(i=self.pFile)
Пример #6
0
    def enumerate(self, eArgs):

        pFiles = []
        tFiles = []
        tf = mtemp.Mtemp()
        for cName, posSize in self.db.clsNameRecSize.items():
            negSize = self.db.traSize - posSize
            if "minGR" in eArgs:
                self.minGR = eArgs["minGR"]
            else:
                minProb = eArgs["minProb"] if ("minProb" in eArgs) else 0.5
                if "uniform" in eArgs and eArgs["uniform"] == True:
                    self.minGR = (minProb / (1 - minProb)) * (
                        self.db.clsSize - 1)  # マニュアルの式(4)
                else:
                    self.minGR = (minProb / (1 - minProb)) * (
                        float(negSize) / float(posSize))  # マニュアルの式(4)

            # 最小サポートと最小サポート件数
            # s=0.05
            # s=c1:0.05,c2:0.06
            # S=10
            # S=c1:10,c2:15
            if "minCnt" in eArgs:
                if isinstance(eArgs["minCnt"], dict):
                    self.minPos = eArgs["minCnt"][cName]
                else:
                    self.minPos = eArgs["minCnt"]
            else:
                if isinstance(eArgs["minSup"], dict):
                    self.minPos = int(eArgs["minSup"][cName] * float(posSize) +
                                      0.99)
                else:
                    self.minPos = int(eArgs["minSup"] * flost(posSize) + 0.99)

            # 最大サポートと最大サポート件数
            if "maxCnt" in eArgs:
                if isinstance(eArgs["maxCnt"], dict):
                    self.maxPos = eArgs["maxCnt"][cName]
                else:
                    self.maxPos = eArgs["maxCnt"]

            elif "maxSup" in eArgs:
                if isinstance(eArgs["maxSup"], dict):
                    self.maxPos = int(eArgs["maxSup"][cName] * float(posSize) +
                                      0.99)
                else:
                    self.maxPos = int(eArgs["maxSup"] * float(posSize) + 0.99)
            else:
                self.maxPos = None

            self.sigma[cName] = self.calSigma(self.minPos, self.minGR, posSize,
                                              negSize)

            # lcmのパラメータ設定と実行
            # 頻出パターンがなかった場合、lcm出力ファイルが生成されないので
            # そのときのために空ファイルを生成しておいく。
            lcmout = tf.file()  # lcm出力ファイル
            with open(lcmout, "w") as efile:
                pass

            runPara = {}

            if self.msgoff:
                runPara["type"] = eArgs["type"] + "IA_"
            else:
                runPara["type"] = eArgs["type"] + "IA"

            #if self.maxPos: #rubyだとif @maxCntなってる(どこにも設定されてないので)動いてないはず
            if self.maxPos:
                runPara["U"] = self.maxPos

            if "minLen" in eArgs:
                runPara["l"] = str(eArgs["minLen"])

            if "maxLen" in eArgs:
                runPara["u"] = str(eArgs["maxLen"])

            runPara["w"] = self.weightFile[cName]

            runPara["i"] = self.file

            runPara["sup"] = str(self.sigma[cName])

            runPara["o"] = lcmout

            # lcm実行
            #MCMD::msgLog("#{run}")
            #TAKE::run_lcm(run)
            #print(self.sigma)
            #print(runPara)
            #MCMD::msgLog("output patterns to CSV file ...")

            extTake.lcm(runPara)

            pFiles.append(self.temp.file())

            transle = tf.file()
            extTake.lcmtrans(lcmout, "e", transle)

            f = nm.mdelnull(f="pattern", i=transle)
            f <<= nm.mcal(c='round(${countN},1)', a="neg")
            f <<= nm.mcal(c='round(${countP}/%s,1)' % (self.posWeight[cName]),
                          a="pos")
            f <<= nm.mdelnull(f="pattern")  #いる?
            f <<= nm.msetstr(v=cName, a="class")
            f <<= nm.msetstr(v=posSize, a="posTotal")
            f <<= nm.msetstr(v=self.minGR, a="minGR")
            f <<= nm.mcut(f="class,pid,pattern,size,pos,neg,posTotal,minGR",
                          o=pFiles[-1])
            f.run()

            #s = nutil.mrecount(i=self.file)
            #MCMD::msgLog("the number of contrast patterns on class `#{cName}' enumerated is #{s}")

            if self.outtf:
                # トランザクション毎に出現するパターンを書き出す
                #MCMD::msgLog("output tid-patterns ...")
                tFiles.append(self.temp.file())
                xxw = tf.file()

                xxw = nm.mcut(f=self.db.idFN, i=self.db.file)
                xxw <<= nm.muniq(k=self.db.idFN)
                xxw <<= nm.mnumber(S=0, a="__tid", q=True)

                translt = self.temp.file()
                extTake.lcmtrans(lcmout, "t", translt)

                f = nm.mjoin(k="__tid", m=xxw, f=self.db.idFN, i=translt)
                f <<= nm.msetstr(v=cName, a="class")
                f <<= nm.mcut(f=self.db.idFN + ",class,pid", o=tFiles[-1])
                f.run()

        # クラス別のパターンとtid-pidファイルを統合して最終出力
        self.pFile = self.temp.file()
        self.tFile = self.temp.file()

        # パターンファイル併合
        xxpCat = tf.file()
        f = nm.mcat(i=",".join(pFiles))
        f <<= nm.msortf(f="class,pid")
        f <<= nm.mnumber(s="class,pid", S=0, a="ppid", o=xxpCat)
        f.run()

        # パターンファイル計算
        items = self.db.items
        f = nm.mcut(f="class,ppid:pid,pattern,size,pos,neg,posTotal,minGR",
                    i=xxpCat)
        f <<= nm.msetstr(v=self.db.traSize, a="total")
        f <<= nm.mcal(c='${total}-${posTotal}', a="negTotal")  # negのトータル件数
        f <<= nm.mcal(c='${pos}/${posTotal}', a="support")  # サポートの計算
        f <<= nm.mcal(
            c=
            'if(${neg}==0,1.797693135e+308,(${pos}/${posTotal})/(${neg}/${negTotal}))',
            a="growthRate")

        if "uniform" in eArgs and eArgs["uniform"] == True:
            f <<= nm.mcal(
                c='(${pos}/${posTotal})/(${pos}/${posTotal}+(%s-1)*${neg}/${negTotal})'
                % (self.db.clsSize),
                a="postProb")
        else:
            f <<= nm.mcal(c='${pos}/(${pos}+${neg})', a="postProb")

        f <<= nm.msel(c='${pos}>=%s&&${growthRate}>=${minGR}' %
                      (self.minPos))  # minSupとminGRによる選択
        f <<= nm.mvreplace(vf="pattern",
                           m=items.file,
                           K=items.idFN,
                           f=items.itemFN)
        f <<= nm.mcut(
            f="class,pid,pattern,size,pos,neg,posTotal,negTotal,total,support,growthRate,postProb"
        )
        f <<= nm.mvsort(vf="pattern")
        f <<= nm.msortf(f="class%nr,postProb%nr,pos%nr", o=self.pFile)
        f.run()

        # アイテムを包含している冗長なタクソノミを削除
        if items.taxonomy:
            #MCMD::msgLog("reducing redundant rules in terms of taxonomy ...")
            ##ここは後で
            zdd = VSOP.constant(0)
            dt = nm.mcut(i=self.pFile, f="pattern")

            for fldVal in dt:
                zdd = zdd + VSOP.itemset(fldVal[0])

            zdd = self.reduceTaxo(zdd, self.db.items)

            xxp1 = tf.file()
            xxp2 = tf.file()
            xxp3 = tf.file()
            zdd.csvout(xxp1)

            nm.mcut(nfni=True, f="1:pattern",
                    i=xxp1).mvsort(vf="pattern").msortf(f="pattern",
                                                        o=xxp2).run()
            nm.msortf(f="pattern", i=self.pFile).mcommon(
                k="pattern", m=xxp2).msortf(f="class%nr,postProb%nr,pos%nr",
                                            o=xxp3).run()
            shutil.move(xxp3, self.pFile)

        if self.outtf:
            # 列挙されたパターンを含むtraのみ選択するためのマスタ
            xxp4 = nm.mcut(f="class,pid", i=self.pFile)
            f = nm.mcat(i=",".join(tFiles))
            f <<= nm.mjoin(k="class,pid", m=xxpCat,
                           f="ppid")  # 全クラス統一pid(ppid)結合
            f <<= nm.mcommon(k="class,ppid", K="class,pid",
                             m=xxp4)  # 列挙されたパターンの選択
            f <<= nm.mcut(f=self.db.idFN + ",class,ppid:pid")
            f <<= nm.msortf(f=self.db.idFN + ",class,pid", o=self.tFile)
            f.run()
Пример #7
0
20160928,0.004529897822
20160929,-0.006691477247
20160930,0.001175128078
20161003,-0.006315794379
20161004,-0.009465877672
20161005,-0.01304673778
20161006,-0.00959163141
20161007,0.01723557587
20161010,-0.001371284213
20161011,-0.002416670838
20161012,-0.004140242517
20161013,-0.003854546465
20161014,-0.01164231144
20161017,-0.001684303294
20161018,-0.002248115897
20161019,-0.003859145998
20161020,-0.006883326367
20161021,-0.01175535999
20161024,-0.01474462455
"""

temo = mtemp.Mtemp()
vv = temo.file()
with open(vv, "w") as wfp:
    wfp.write(sampDAT1)

xxx7_0 = n.mcat(i=vv).mcal(c="left($s{date},6)", a="month").mcut("f=month,val")

v = xxx7_0.cmd("tail -n 10").mcut(f="1:vvvvvvvv", nfn=True).run(msg="on")
print(v)
Пример #8
0
    def run(self):
        temp = mtemp.Mtemp()

        ### mtra2gc
        xxsimgN = temp.file()
        xxsimgE = temp.file()
        xxsimgE0 = temp.file()

        param = {}
        param["i"] = self.iFile
        if self.idFN:
            param["tid"] = self.idFN
        if self.itemFN:
            param["item"] = self.itemFN
        if self.sp1:
            param["s"] = self.sp1
        if self.sp2:
            param["S"] = self.sp2

        #####################
        # 異なる向きのconfidenceを列挙するためにsim=C th=0として双方向列挙しておく
        # 出力データは倍になるが、mfriendsで-directedとすることで元が取れている
        param["sim"] = "C"
        param["th"] = "0"

        param["node_support"] = True
        if self.numtp:
            param["num"] = True
        param["no"] = xxsimgN
        param["eo"] = xxsimgE0

        nt.mtra2gc(**param).run()

        f = nm.readcsv(xxsimgE0)
        for i in range(self.filterSize):
            f <<= nm.mselnum(f=self.filter[i],
                             c="[%s,%s]" % (self.lb[i], self.ub[i]))
        f <<= nm.writecsv(xxsimgE)
        f.run()

        ### mfrirends
        xxfriends = temp.file()
        xxfriendE = temp.file()
        xxw = temp.file()
        xxf = temp.file()
        xxff = temp.file()
        xxor = temp.file()

        if not os.path.isdir(xxfriends):
            os.makedirs(xxfriends)
        col = [["FF000080", "FF888880"], ["0000FF80", "8888FF80"],
               ["00FF0080", "88FF8880"]]

        for i in range(len(self.sim)):
            paramf = {}
            paramf["ei"] = xxsimgE
            paramf["ni"] = xxsimgN
            paramf["ef"] = "node1,node2"
            paramf["nf"] = "node"
            paramf["eo"] = xxfriendE
            paramf["no"] = xxfriends + "/n_" + str(i)
            paramf["sim"] = self.sim[i]
            paramf["dir"] = self.dir[i]
            paramf["rank"] = self.rank[i]
            paramf["directed"] = True

            nt.mfriends(**paramf).run()

            frec2 = nm.mfsort(f="node1,node2", i=xxfriendE)
            frec2 <<= nm.msummary(k="node1,node2",
                                  f=self.sim[i],
                                  c="count,mean")
            frec2 <<= nm.mselstr(f="count", v=2)
            # node1%0,node2%1,fld,count,mean
            # a,b,support,2,0.1818181818
            # a,d,support,2,0.1818181818

            f = nm.mjoin(k="node1,node2",
                         K="node1,node2",
                         m=frec2,
                         f="mean:s1",
                         n=True,
                         i=xxfriendE)
            f <<= nm.mjoin(k="node2,node1",
                           K="node1,node2",
                           m=frec2,
                           f="mean:s2",
                           n=True)
            # 1) xxrecs2でsimをjoinできない(s1,s2共にnull)ということは、それは片方向枝なので"F"をつける
            # 2) 双方向枝a->b,b->aのうちa->bのみ(s1がnullでない)に"W"の印をつける。
            # 3) それ以外の枝は"D"として削除
            f <<= nm.mcal(
                c='if(isnull($s{s1}),if(isnull($s{s2}),\"F\",\"D\"),\"W\")',
                a="dir")
            f <<= nm.mselstr(f="dir", v="D", r=True)
            f <<= nm.mcal(c='if($s{dir}==\"W\",$s{s1},$s{%s})' % (self.sim[i]),
                          a="sim")
            f <<= nm.mchgstr(f="dir:color",
                             c='W:%s,F:%s' % (col[i][0], col[i][1]),
                             A=True)
            f <<= nm.msetstr(v=[self.sim[i], str(i)], a="simType,simPriority")
            f <<= nm.mcut(f="simType,simPriority,node1,node2,sim,dir,color",
                          o=xxfriends + "/e_" + str(i))
            f.run()
            # node1%1,node2%0,simType,sim,dir,color
            # b,a,jaccard,0.3333333333,F,8888FF
            # j,c,jaccard,0.3333333333,F,8888FF
            # b,d,jaccard,0.3333333333,F,8888FF
            # a,e,jaccard,0.5,W,0000FF
            # d,e,jaccard,0.5,W,0000FF

        # rule fileの出力
        if self.orFile:
            mmm = nm.mcat(i=xxfriends + "/e_*").muniq(k="node1,node2")
            nm.mcommon(k="node1,node2", i=xxsimgE, m=mmm, o=self.orFile).run()

        # マルチ枝の単一化(W優先,パラメータ位置優先)
        if self.prune:
            """
			# 双方向と片方向に分割
			nm.mcat(i=xxfriends+"/e_*").mselstr(f="dir",v="W",o=xxw,u=xxf).run()
			# 片方向のみの枝を選択
			f =   nm.mcommon(k="node1,node2",K="node1,node2",r=True,m=xxw,i=xxf)
			f <<= nm.mcommon(k="node1,node2",K="node2,node1",r=True,m=xxw,o=xxff)
			f.run()
			f = nm.mcat(i=xxw+","+xxff).mbest(k="node1,node2",s="dir%r,simPriority%n",o=self.oeFile).run()
			"""
            #これだめ
            fo = nm.mcat(i=xxfriends + "/e_*").mselstr(f="dir", v="W")
            fu = fo.direction("u")  # これは再考
            fu <<= nm.mcommon(k="node1,node2", K="node1,node2", r=True, m=fo)
            fu <<= nm.mcommon(k="node1,node2", K="node2,node1", r=True, m=fo)
            #f  =   nm.m2cat()
            f = nm.mbest(i=[fo, fu],
                         k="node1,node2",
                         s="dir%r,simPriority%n",
                         o=self.oeFile)

            f.run()

        else:
            nm.mcat(i=xxfriends + "/e_*", o=self.oeFile).run()

        nm.mcat(i=xxfriends + "/n_0", o=self.onFile).run()