def test_misc(self): secint = mpc.SecInt() secfxp = mpc.SecFxp() secfld = mpc.SecFld() for secnum in (secint, secfxp, secfld): self.assertEqual(type(mpc.run(mpc.output(secnum(0), raw=True))), secnum.field) self.assertEqual(mpc.run(mpc.output(mpc._reshare([secnum(0)]))), [0]) self.assertEqual(mpc.run(mpc.output(mpc.all(secnum(1) for _ in range(5)))), True) self.assertEqual(mpc.run(mpc.output(mpc.all([secnum(1), secnum(1), secnum(0)]))), False) self.assertEqual(mpc.run(mpc.output(mpc.any(secnum(0) for _ in range(5)))), False) self.assertEqual(mpc.run(mpc.output(mpc.any([secnum(0), secnum(1), secnum(1)]))), True) self.assertEqual(mpc.run(mpc.output(mpc.sum([secnum(1)], start=1))), 2) self.assertEqual(mpc.run(mpc.output(mpc.prod([secnum(1)], start=1))), 1) self.assertEqual(mpc.run(mpc.output(mpc.sum([secnum(1)], start=secnum(1)))), 2) self.assertEqual(mpc.run(mpc.output(mpc.min(secint(i) for i in range(-1, 2, 1)))), -1) self.assertEqual(mpc.run(mpc.output(mpc.argmin(secint(i) for i in range(-1, 2, 1))[0])), 0) self.assertEqual(mpc.run(mpc.output(mpc.max(secfxp(i) for i in range(-1, 2, 1)))), 1) self.assertEqual(mpc.run(mpc.output(mpc.argmax(secfxp(i) for i in range(-1, 2, 1))[0])), 2) self.assertEqual(mpc.run(mpc.output(list(mpc.min_max(map(secfxp, range(5)))))), [0, 4]) x = (secint(i) for i in range(-3, 3)) s = [0, -1, 1, -2, 2, -3] self.assertEqual(mpc.run(mpc.output(mpc.sorted(x, key=lambda a: a*(2*a+1)))), s) x = (secfxp(i) for i in range(5)) self.assertEqual(mpc.run(mpc.output(mpc.sorted(x, reverse=True))), [4, 3, 2, 1, 0]) self.assertEqual(mpc.run(mpc.output(mpc.sum(map(secint, range(5))))), 10) self.assertEqual(mpc.run(mpc.output(mpc.sum([secfxp(2.75)], start=3.125))), 5.875) self.assertEqual(int(mpc.run(mpc.output(mpc.prod(map(secfxp, range(1, 5)))))), 24) self.assertEqual(int(mpc.run(mpc.output(mpc.prod([secfxp(1.414214)]*4)))), 4)
async def main(): if sys.argv[1:]: n = int(sys.argv[1]) else: n = 5 print('Setting input to default =', n) s = [(-1)**i * (i + n//2)**2 for i in range(n)] secnum = mpc.SecInt() print('Using secure integers:', secnum) x = list(map(secnum, s)) async with mpc: mpc.random.shuffle(secnum, x) # secret in-place random shuffle print('Randomly shuffled input:', await mpc.output(x)) x = mpc.sorted(x, key=lambda a: a**2) # sort on absolute value print('Sorted by absolute value:', await mpc.output(x)) secnum = mpc.SecFxp() print('Using secure fixed-point numbers:', secnum) x = list(map(secnum, s)) async with mpc: mpc.random.shuffle(secnum, x) # secret in-place random shuffle print('Randomly shuffled input:', await mpc.output(x)) x = mpc.seclist(x) x.sort(reverse=True) # in-place sort in descending order print('Sorted by descending value:', await mpc.output(list(x)))
def test_secfxp(self): secfxp = mpc.SecFxp() s = seclist([5, -3, 2, 5, 5], secfxp) self.assertFalse(mpc.run(mpc.output(s < s))) t = s[:] t[-1] += 1 self.assertTrue(mpc.run(mpc.output(s < t))) s = [[1, 0], [0, 1], [0, 0], [1, 1]] ss = mpc.sorted([[secfxp(a) for a in _] for _ in s], key=seclist) self.assertEqual([mpc.run(mpc.output(_)) for _ in ss], sorted(s))
def test_empty_input(self): secint = mpc.SecInt() self.assertEqual(mpc.run(mpc.gather([])), []) self.assertEqual(mpc.run(mpc.output([])), []) self.assertEqual(mpc._reshare([]), []) self.assertEqual(mpc.convert([], None), []) self.assertEqual(mpc.sum([]), 0) self.assertEqual(mpc.sum([], start=1), 1) self.assertEqual(mpc.run(mpc.output(mpc.sum([], start=secint(1)))), 1) self.assertEqual(mpc.prod([]), 1) self.assertEqual(mpc.all([]), 1) self.assertEqual(mpc.any([]), 0) self.assertEqual(mpc.sorted([]), []) self.assertEqual(mpc.in_prod([], []), 0) self.assertEqual(mpc.vector_add([], []), []) self.assertEqual(mpc.vector_sub([], []), []) self.assertEqual(mpc.scalar_mul(secint(0), []), []) self.assertEqual(mpc.schur_prod([], []), []) self.assertEqual(mpc.from_bits([]), 0)
def test_misc(self): secint = mpc.SecInt() secfxp = mpc.SecFxp() secfld = mpc.SecFld() for secnum in (secint, secfxp, secfld): self.assertEqual(type(mpc.run(mpc.output(secnum(0), raw=True))), secnum.field) self.assertEqual(mpc.run(mpc.output(mpc._reshare([secnum(0)]))), [0]) self.assertEqual( mpc.run(mpc.output(mpc.all(secnum(1) for _ in range(5)))), True) self.assertEqual( mpc.run(mpc.output(mpc.all([secnum(1), secnum(1), secnum(0)]))), False) self.assertEqual( mpc.run(mpc.output(mpc.any(secnum(0) for _ in range(5)))), False) self.assertEqual( mpc.run(mpc.output(mpc.any([secnum(0), secnum(1), secnum(1)]))), True) self.assertEqual( mpc.run(mpc.output(mpc.sum([secnum(1)], start=1))), 2) self.assertEqual( mpc.run(mpc.output(mpc.prod([secnum(1)], start=1))), 1) self.assertEqual( mpc.run(mpc.output(mpc.sum([secnum(1)], start=secnum(1)))), 2) self.assertEqual( mpc.run(mpc.output(mpc.find([secnum(1)], 0, e=-1))), -1) self.assertEqual(mpc.run(mpc.output(mpc.find([secnum(1)], 1))), 0) self.assertEqual( mpc.run(mpc.output(mpc.find([secnum(1)], 1, f=lambda i: i))), 0) self.assertEqual( mpc.run(mpc.output(mpc.min(secint(i) for i in range(-1, 2, 1)))), -1) self.assertEqual( mpc.run( mpc.output(mpc.argmin(secint(i) for i in range(-1, 2, 1))[0])), 0) self.assertEqual( mpc.run(mpc.output(mpc.max(secfxp(i) for i in range(-1, 2, 1)))), 1) self.assertEqual( mpc.run( mpc.output(mpc.argmax(secfxp(i) for i in range(-1, 2, 1))[0])), 2) self.assertEqual( mpc.run(mpc.output(list(mpc.min_max(map(secfxp, range(5)))))), [0, 4]) x = (secint(i) for i in range(-3, 3)) s = [0, -1, 1, -2, 2, -3] self.assertEqual( mpc.run(mpc.output(mpc.sorted(x, key=lambda a: a * (2 * a + 1)))), s) x = (secfxp(i) for i in range(5)) self.assertEqual(mpc.run(mpc.output(mpc.sorted(x, reverse=True))), [4, 3, 2, 1, 0]) self.assertEqual(mpc.run(mpc.output(mpc.sum(map(secint, range(5))))), 10) self.assertEqual( mpc.run(mpc.output(mpc.sum([secfxp(2.75)], start=3.125))), 5.875) self.assertEqual( int(mpc.run(mpc.output(mpc.prod(map(secfxp, range(1, 5)))))), 24) self.assertEqual( int(mpc.run(mpc.output(mpc.prod([secfxp(1.414214)] * 4)))), 4) self.assertEqual(mpc.find([], 0), 0) self.assertEqual(mpc.find([], 0, e=None), (1, 0)) self.assertEqual( mpc.run(mpc.output(list(mpc.find([secfld(1)], 1, e=None)))), [0, 0]) self.assertEqual( mpc.run(mpc.output(mpc.find([secfld(2)], 2, bits=False))), 0) x = [secint(i) for i in range(5)] f = lambda i: [i**2, 3**i] self.assertEqual(mpc.run(mpc.output(mpc.find(x, 2, bits=False, f=f))), [4, 9]) cs_f = lambda b, i: [b * (2 * i + 1) + i**2, (b * 2 + 1) * 3**i] self.assertEqual( mpc.run(mpc.output(mpc.find(x, 2, bits=False, cs_f=cs_f))), [4, 9])
def build_tree(self, data, remain_index, depth=0): """ 此处有三个树继续生长的条件: 1: 深度没有到达最大, 树的深度假如是3, 意思是需要生长成3层, 那么这里的depth只能是0, 1 所以判断条件是 depth < self.max_depth - 1 2: 点样本数 >= min_samples_split 3: 此节点上的样本的 target_name 值不一样(如果值 一样说明已经划分得很好了,不需要再分) """ now_data = data[remain_index] # print("now_data:", now_data, remain_index) now_data_list = now_data.values.tolist() # print("now lsit = ", now_data_list) sort_list = mpc.sorted(now_data_list[0]) # await mpc.barrier() unique_flag = mpc.eq(sort_list[0], sort_list[len(sort_list) - 1]) result = mpc.run(mpc.output(unique_flag)) #await mpc.barrier() #print("11111:", result, type(result)) flag1 = (depth < self.max_depth - 1) flag2 = (len(now_data) >= self.min_samples_split) flag3 = (result == 0) # print('flg:', flag1, flag2, flag3) if flag1 and flag2 and flag3: #print("enter new branch") se = None split_feature = None split_value = None left_index_of_now_data = None right_index_of_now_data = None self.logger.info(('--树的深度:%d' % depth)) for feature in self.features: self.logger.info(('----划分特征:', feature)) # print("feather:", self.features) feature_list = now_data[feature].values.tolist() tmp_list = mpc.sorted(feature_list) # feature_new_list = [] for i in range(len(tmp_list) - 1): if (mpc.run( mpc.output(mpc.eq(tmp_list[i], tmp_list[i + 1]))) == 0): feature_new_list.append(tmp_list[i]) feature_new_list.append(tmp_list[len(tmp_list) - 1]) # add last element; #feature_values = now_data[feature].unique() #print(",11", feature_values) #print('len of f newlist;', len(feature_new_list)) for fea_val in feature_new_list: #print("new frahte varleu:") # 尝试划分 #left_index = list(now_data[feature] < fea_val) #right_index = list(now_data[feature] >= fea_val) left_index = [] right_index = [] for ele in feature_list: if (mpc.run(mpc.output(mpc.lt(ele, fea_val))) == 1): left_index.append(True) right_index.append(False) else: left_index.append(False) right_index.append(True) #print("\n\n*****************left index", left_index) #print("*****************rith index", right_index) tmp = now_data[left_index][self.target_name] #print("ttttmp: ", tmp) left_se = calculate_se(tmp) right_se = calculate_se( now_data[right_index][self.target_name]) sum_se = left_se + right_se #self.logger.info(('------划分值:%.3f,左节点损失:%.3f,右节点损失:%.3f,总损失:%.3f' % # (fea_val, left_se, right_se, sum_se))) if se is None or sum_se < se: split_feature = feature split_value = fea_val se = sum_se left_index_of_now_data = left_index right_index_of_now_data = right_index self.logger.info(('--最佳划分特征:', split_feature)) self.logger.info(('--最佳划分值:', split_value)) node = Node(remain_index, self.logger, split_feature, split_value, deep=depth) """ trick for DataFrame, index revert 下面这部分代码是为了记录划分后样本在原始数据中的的索引 DataFrame的数据索引可以使用True和False 所以下面得到的是一个bool类型元素组成的数组 利用这个数组进行索引获得划分后的数据 """ left_index_of_all_data = [] #print("remian_dindex:", remain_index) for i in remain_index: if i: if left_index_of_now_data[0]: left_index_of_all_data.append(True) del left_index_of_now_data[0] else: left_index_of_all_data.append(False) del left_index_of_now_data[0] else: left_index_of_all_data.append(False) right_index_of_all_data = [] for i in remain_index: if i: if right_index_of_now_data[0]: right_index_of_all_data.append(True) del right_index_of_now_data[0] else: right_index_of_all_data.append(False) del right_index_of_now_data[0] else: right_index_of_all_data.append(False) #print("left_idnex_fllda:", left_index_of_all_data) #print("left_idnex_fllda:", right_index_of_all_data) print("\n\n") node.left_child = self.build_tree(data, left_index_of_all_data, depth + 1) node.right_child = self.build_tree(data, right_index_of_all_data, depth + 1) return node else: node = Node(remain_index, self.logger, is_leaf=True, loss=self.loss, deep=depth) if len(self.target_name.split('_')) == 3: label_name = 'label_' + self.target_name.split('_')[1] else: label_name = 'label' node.update_predict_value(now_data[self.target_name], now_data[label_name]) self.leaf_nodes.append(node) return node