@@ -94,6 +94,107 @@ def transform_feature(x):
94
94
art_warning (e )
95
95
96
96
97
+ @pytest .mark .skip_framework ("dl_frameworks" )
98
+ @pytest .mark .parametrize ("scaler_type" , ["standard" , "robust" , "minmax" ])
99
+ def test_black_box_scalers (art_warning , scaler_type , decision_tree_estimator , get_iris_dataset ):
100
+ try :
101
+ attack_feature = 2 # petal length
102
+
103
+ # need to transform attacked feature into categorical
104
+ def transform_feature (x ):
105
+ x [x > 0.5 ] = 2.0
106
+ x [(x > 0.2 ) & (x <= 0.5 )] = 1.0
107
+ x [x <= 0.2 ] = 0.0
108
+
109
+ values = [0.0 , 1.0 , 2.0 ]
110
+
111
+ (x_train_iris , y_train_iris ), (x_test_iris , y_test_iris ) = get_iris_dataset
112
+ # training data without attacked feature
113
+ x_train_for_attack = np .delete (x_train_iris , attack_feature , 1 )
114
+ # only attacked feature
115
+ x_train_feature = x_train_iris [:, attack_feature ].copy ().reshape (- 1 , 1 )
116
+ transform_feature (x_train_feature )
117
+ # training data with attacked feature (after transformation)
118
+ x_train = np .concatenate ((x_train_for_attack [:, :attack_feature ], x_train_feature ), axis = 1 )
119
+ x_train = np .concatenate ((x_train , x_train_for_attack [:, attack_feature :]), axis = 1 )
120
+
121
+ # test data without attacked feature
122
+ x_test_for_attack = np .delete (x_test_iris , attack_feature , 1 )
123
+ # only attacked feature
124
+ x_test_feature = x_test_iris [:, attack_feature ].copy ().reshape (- 1 , 1 )
125
+ transform_feature (x_test_feature )
126
+
127
+ classifier = decision_tree_estimator ()
128
+
129
+ attack = AttributeInferenceBlackBox (classifier , attack_feature = attack_feature , scaler_type = scaler_type )
130
+ # get original model's predictions
131
+ x_train_predictions = np .array ([np .argmax (arr ) for arr in classifier .predict (x_train_iris )]).reshape (- 1 , 1 )
132
+ x_test_predictions = np .array ([np .argmax (arr ) for arr in classifier .predict (x_test_iris )]).reshape (- 1 , 1 )
133
+ # train attack model
134
+ attack .fit (x_train )
135
+ # infer attacked feature
136
+ inferred_train = attack .infer (x_train_for_attack , pred = x_train_predictions , values = values )
137
+ inferred_test = attack .infer (x_test_for_attack , pred = x_test_predictions , values = values )
138
+ # check accuracy
139
+ train_acc = np .sum (inferred_train == x_train_feature .reshape (1 , - 1 )) / len (inferred_train )
140
+ test_acc = np .sum (inferred_test == x_test_feature .reshape (1 , - 1 )) / len (inferred_test )
141
+ assert pytest .approx (0.8285 , abs = 0.3 ) == train_acc
142
+ assert pytest .approx (0.8888 , abs = 0.3 ) == test_acc
143
+
144
+ except ARTTestException as e :
145
+ art_warning (e )
146
+
147
+
148
+ @pytest .mark .skip_framework ("dl_frameworks" )
149
+ def test_black_box_tabular_no_scaler (art_warning , decision_tree_estimator , get_iris_dataset ):
150
+ try :
151
+ attack_feature = 2 # petal length
152
+
153
+ # need to transform attacked feature into categorical
154
+ def transform_feature (x ):
155
+ x [x > 0.5 ] = 2.0
156
+ x [(x > 0.2 ) & (x <= 0.5 )] = 1.0
157
+ x [x <= 0.2 ] = 0.0
158
+
159
+ values = [0.0 , 1.0 , 2.0 ]
160
+
161
+ (x_train_iris , y_train_iris ), (x_test_iris , y_test_iris ) = get_iris_dataset
162
+ # training data without attacked feature
163
+ x_train_for_attack = np .delete (x_train_iris , attack_feature , 1 )
164
+ # only attacked feature
165
+ x_train_feature = x_train_iris [:, attack_feature ].copy ().reshape (- 1 , 1 )
166
+ transform_feature (x_train_feature )
167
+ # training data with attacked feature (after transformation)
168
+ x_train = np .concatenate ((x_train_for_attack [:, :attack_feature ], x_train_feature ), axis = 1 )
169
+ x_train = np .concatenate ((x_train , x_train_for_attack [:, attack_feature :]), axis = 1 )
170
+
171
+ # test data without attacked feature
172
+ x_test_for_attack = np .delete (x_test_iris , attack_feature , 1 )
173
+ # only attacked feature
174
+ x_test_feature = x_test_iris [:, attack_feature ].copy ().reshape (- 1 , 1 )
175
+ transform_feature (x_test_feature )
176
+
177
+ classifier = decision_tree_estimator ()
178
+
179
+ attack = AttributeInferenceBlackBox (classifier , attack_feature = attack_feature , scaler_type = None )
180
+ # get original model's predictions
181
+ x_train_predictions = np .array ([np .argmax (arr ) for arr in classifier .predict (x_train_iris )]).reshape (- 1 , 1 )
182
+ x_test_predictions = np .array ([np .argmax (arr ) for arr in classifier .predict (x_test_iris )]).reshape (- 1 , 1 )
183
+ # train attack model
184
+ attack .fit (x_train )
185
+ # infer attacked feature
186
+ inferred_train = attack .infer (x_train_for_attack , pred = x_train_predictions , values = values )
187
+ inferred_test = attack .infer (x_test_for_attack , pred = x_test_predictions , values = values )
188
+ # check accuracy
189
+ train_acc = np .sum (inferred_train == x_train_feature .reshape (1 , - 1 )) / len (inferred_train )
190
+ test_acc = np .sum (inferred_test == x_test_feature .reshape (1 , - 1 )) / len (inferred_test )
191
+ assert pytest .approx (0.8285 , abs = 0.3 ) == train_acc
192
+ assert pytest .approx (0.8888 , abs = 0.3 ) == test_acc
193
+
194
+ except ARTTestException as e :
195
+ art_warning (e )
196
+
197
+
97
198
@pytest .mark .skip_framework ("dl_frameworks" )
98
199
@pytest .mark .parametrize ("model_type" , ["nn" , "rf" , "gb" , "lr" , "dt" , "knn" , "svm" ])
99
200
def test_black_box_continuous (art_warning , decision_tree_estimator , get_iris_dataset , model_type ):
0 commit comments