File size: 14,444 Bytes
9a997e4
1ba3f22
 
 
 
 
 
 
9a997e4
 
 
 
 
 
 
 
 
 
b47829b
 
 
9a997e4
 
bc345ce
8e0d56d
bc345ce
8e0d56d
9a997e4
1ad0c1c
b47829b
1ba3f22
 
 
 
 
 
 
 
 
 
 
 
fd8f14e
 
 
 
e302458
fd8f14e
 
 
03475de
 
e302458
03475de
 
 
e302458
235e54a
 
e302458
 
 
 
 
 
235e54a
 
 
e302458
235e54a
 
e302458
 
 
235e54a
 
 
 
e302458
235e54a
 
 
 
e302458
 
 
 
 
 
235e54a
 
 
59a3f3b
 
 
a9a747c
59a3f3b
 
 
235e54a
da0bc3e
0a14c46
e302458
747c295
 
e302458
 
747c295
 
e302458
bf71bfa
e302458
bf71bfa
bc345ce
 
74c0c8e
 
 
 
 
 
da0bc3e
0a14c46
e302458
747c295
 
e302458
 
 
 
61cd73f
e302458
747c295
 
 
1ba3f22
 
da0bc3e
b47829b
e302458
 
b47829b
 
 
 
da0bc3e
 
b47829b
 
 
 
da0bc3e
 
b47829b
 
 
 
da0bc3e
 
b47829b
 
 
 
 
da0bc3e
 
b47829b
8a003cf
 
b47829b
 
 
da0bc3e
 
b47829b
 
 
 
da0bc3e
 
b47829b
 
 
 
da0bc3e
 
b47829b
 
 
 
da0bc3e
 
b47829b
 
 
 
da0bc3e
 
b47829b
1ba3f22
0a14c46
 
da0bc3e
9a997e4
8e0d56d
da0bc3e
1ba3f22
0287aa5
0a14c46
 
da0bc3e
0a14c46
 
 
da0bc3e
 
0a14c46
 
8a003cf
 
da0bc3e
9a997e4
c119738
da0bc3e
1ba3f22
0287aa5
0a14c46
 
da0bc3e
 
0a14c46
 
 
da0bc3e
 
0a14c46
 
8a003cf
 
da0bc3e
1ba3f22
8e0d56d
da0bc3e
9a997e4
1ba3f22
8e0d56d
74c0c8e
8e0d56d
 
74c0c8e
 
03475de
74c0c8e
 
 
 
 
 
 
03475de
74c0c8e
 
8e0d56d
74c0c8e
8e0d56d
 
b47829b
03475de
74c0c8e
 
da0bc3e
0a14c46
da0bc3e
1ba3f22
747c295
da0bc3e
747c295
da0bc3e
747c295
1ba3f22
 
da0bc3e
1ba3f22
da0bc3e
1ba3f22
 
74c0c8e
03475de
74c0c8e
da0bc3e
0a14c46
da0bc3e
1ba3f22
747c295
da0bc3e
316f8e9
da0bc3e
747c295
1ba3f22
 
747c295
da0bc3e
 
747c295
1ba3f22
 
da0bc3e
7ba6721
da0bc3e
7ba6721
1ba3f22
da0bc3e
1ba3f22
 
1ad0c1c
 
 
 
03475de
9a997e4
1ba3f22
da0bc3e
0a14c46
74c0c8e
 
da0bc3e
 
 
 
 
74c0c8e
9a997e4
b47829b
da0bc3e
9a997e4
b47829b
da0bc3e
9a997e4
1ba3f22
74c0c8e
b47829b
 
 
03475de
9a997e4
1ba3f22
 
da0bc3e
1ba3f22
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
"""A gradio app for credit card approval prediction using FHE."""

import subprocess
import time
import gradio as gr

from settings import (
    REPO_DIR,
    ACCOUNT_MIN_MAX,
    CHILDREN_MIN_MAX,
    INCOME_MIN_MAX,
    AGE_MIN_MAX,
    FAMILY_MIN_MAX,
    INCOME_TYPES,
    OCCUPATION_TYPES,
    HOUSING_TYPES,
    EDUCATION_TYPES,
    FAMILY_STATUS,
    YEARS_EMPLOYED_BINS,
    INCOME_VALUE,
    AGE_VALUE,
)
from backend import (
    keygen_send,
    pre_process_encrypt_send_applicant,
    pre_process_encrypt_send_bank,
    pre_process_encrypt_send_credit_bureau,
    run_fhe,
    get_output_and_decrypt,
    explain_encrypt_run_decrypt,
)


subprocess.Popen(["uvicorn", "server:app"], cwd=REPO_DIR)
time.sleep(3)


demo = gr.Blocks()


print("Starting the demo...")
with demo:

    gr.Markdown(
        """
            <p align="center">
                <img width=200 src="https://www.yamu.com/uploads/image/20220602/1d3eb99b96d3a84ef37eda59989e5e2f.png">
            </p>
        """
    )
    gr.Markdown(
        """
        <h1 align="center">使用全同态加密的信用卡审批预测</h1>        
        """
    )

    with gr.Accordion("什么是信用卡的审批评估分?", open=False):
        gr.Markdown(
            """
            这是一个复杂的过程,涉及多个实体:申请人、银行、信用中心和信用评分机构。
            当您申请信用卡时,您会向银行提供个人和财务信息。这可能包括您的收入、就业状况和现有债务。银行使用这些信息来评估您的信用度。
            为此,他们经常求助于信用中心和信用评分机构。
            - 信用中心收集并保存有关消费者信用历史的数据。这些数据包括您过去和当前的债务以及您的信用历史长度。
            - 信用评分机构使用算法来分析来自信用中心的数据并生成信用评分。 该分数是您信用度的数字表示。 
            - 银行使用您的信用评分以及您提供的信息来对您的信用卡申请做出决定。更高的信用评分通常会增加您获得批准的机会,并可能带来更好的条款(例如更低的利率)。            
            """
        )

    with gr.Accordion("为什么在此过程中添加新的隐私计算处理层至关重要?", open=False):
        gr.Markdown(
            """
            因为所涉及的数据高度敏感。它包括个人信息,如您的身份证号码号码、收入和信用记录。
            不同实体之间有大量数据共享。您的信息不仅掌握在银行手中,还掌握在信用中心和评分机构手中。有权访问您数据的实体越多,数据泄露的风险就越大。这可能导致身份盗窃和金融欺诈。还有数据准确性的问题。
            信用报告中的错误可能导致不公平的低信用评分,影响您获得信贷的能力。            
            """
        )

    with gr.Accordion(
        "为什么全同态加密(FHE)是提升信用评分能力的解决方案?", 
        open=False,
    ):
        gr.Markdown(
            """
            全同态加密 (FHE) 被视为增强涉及申请人、银行、信用中心和信用评分机构等多方的信用评分流程的隐私和准确性的理想解决方案。
            它允许对数据进行加密和处理,而无需解密。这意味着可以共享和分析敏感数据,而无需将实际信息暴露给任何一方或处理它的服务器。
            在信用评分的背景下,这将使对个人信誉的评估更加彻底和准确。可以组合和分析来自各种来源的数据以做出更明智的决策,但每一方的数据仍保持机密。
            因此,数据泄露或泄露的风险被大大降低,解决了主要的隐私问题。            

            总而言之,FHE 提供了一种做出更准确的信贷资格决策的方法,同时保持严格的数据隐私,为数据实用性和机密性之间的微妙平衡提供了一个复杂的解决方案。            
            """
        )

    gr.Markdown(
        """
        <p align="center">
            <img src="https://fheprc.oss-cn-hangzhou.aliyuncs.com/credit.png"
        </p>
        """
    )

    gr.Markdown("## 步骤1:创建密钥。")
    gr.Markdown("<hr />")
    gr.Markdown("<span style='color:grey'>申请人、银行和信贷机构设置</span>")
    gr.Markdown(
        """
        - 私钥由合作计算信用评分的实体共同生成。它用于加密和解密数据,绝不会与任何其他方共享。
        - 计算密钥(evaluation key)是服务器处理加密数据所需的公钥。因此,它也被传输到服务器进行进一步处理。
        """
    )
    keygen_button = gr.Button("生成密钥并将计算密钥发送到服务器。")
    evaluation_key = gr.Textbox(
        label="计算密钥:", max_lines=2, interactive=False
    )
    client_id = gr.Textbox(label="", max_lines=2, interactive=False, visible=False)
    
    # Button generate the keys
    keygen_button.click(
        keygen_send,
        outputs=[client_id, evaluation_key, keygen_button],
    )

    gr.Markdown("## 步骤2:填写申请信息。")
    gr.Markdown("<hr />")
    gr.Markdown("<span style='color:grey'>申请人、银行和信贷机构设置</span>")
    gr.Markdown(
        """
        选择与您要评估的个人资料相对应的信息。此模型使用了三种信息来源:
        - 申请人的个人信息,以评估其信用卡资格;
        - 申请人的银行账户历史记录,其中提供了与该决定相关的任何类型的申请人银行信息(此处,我们考虑开户时间);
        - 以及信用中心信息,这些信息代表了任何其他信息(这里指就业历史),这些信息可以提供与决策相关的额外见解。
        
        在运行FHE推理之前,请务必在更新后加密并发送值(通过右侧的按钮)。
        """
    )

    with gr.Row():
        with gr.Column():
            gr.Markdown("### 步骤2.1 - 申请人信息 🧑‍💼")
            bool_inputs = gr.CheckboxGroup(
                ["汽车", "房产", "手机"], 
                label="您目前持有或拥有以下哪些资产?"
            )
            num_children = gr.Slider(
                **CHILDREN_MIN_MAX, 
                step=1, 
                label="孩子数量", 
                info="您有几个小孩子?"
            )
            household_size = gr.Slider(
                **FAMILY_MIN_MAX, 
                step=1, 
                label="家庭规模", 
                info="您家里有几口人?"
            )
            total_income = gr.Slider(
                **INCOME_MIN_MAX,
                value=INCOME_VALUE,
                label="收入", 
                info="您的年总收入是多少?"
            )
            age = gr.Slider(
                **AGE_MIN_MAX,
                value=AGE_VALUE, 
                step=1, 
                label="年龄", 
                info="今年多大了?"
            )

        with gr.Column():
            income_type = gr.Dropdown(
                choices=INCOME_TYPES, 
                value=INCOME_TYPES[0], 
                label="收入类型", 
                info="您的主要收入来源是什么?"
            )
            education_type = gr.Dropdown(
                choices=EDUCATION_TYPES, 
                value=EDUCATION_TYPES[0], 
                label="教育程度", 
                info="您的教育背景是什么?"
            )
            family_status = gr.Dropdown(
                choices=FAMILY_STATUS, 
                value=FAMILY_STATUS[0], 
                label="家庭", 
                info="你的家庭状况如何?"
            )
            occupation_type = gr.Dropdown(
                choices=OCCUPATION_TYPES, 
                value=OCCUPATION_TYPES[0], 
                label="职业", 
                info="你的主要职业是什么?"
            )
            housing_type = gr.Dropdown(
                choices=HOUSING_TYPES, 
                value=HOUSING_TYPES[0], 
                label="住房", 
                info="你住在什么类型的房子?"
            )

    with gr.Row():
        with gr.Column(scale=2):
            encrypt_button_applicant = gr.Button("加密输入并发送到服务器。")
            
            encrypted_input_applicant = gr.Textbox(
                label="加密后的输入:", max_lines=2, interactive=False
            )

    gr.Markdown("<hr />")
    with gr.Column():
        gr.Markdown("### 步骤2.2-银行信息 🏦")
        account_age = gr.Slider(
            **ACCOUNT_MIN_MAX, 
            step=1, 
            label="账户年龄(月)", 
            info="此人拥有该银行账户多长时间了(以月为单位)?"
        )

    with gr.Row():
        with gr.Column(scale=2):
            encrypt_button_bank = gr.Button("加密输入并发送到服务器。")

            encrypted_input_bank = gr.Textbox(
                label="加密后的输入:", max_lines=2, interactive=False
            )

    gr.Markdown("<hr />")
    with gr.Column():
        gr.Markdown("### 步骤2.3 - 信用中心信息 🏢")
        employed = gr.Radio(["是", "否"], label="是否在职?", value="是")
        years_employed = gr.Dropdown(
            choices=YEARS_EMPLOYED_BINS, 
            value=YEARS_EMPLOYED_BINS[0], 
            label="工作年限", 
            info="该员工已工作多长时间(年数)?"
        )

    with gr.Row():
        with gr.Column(scale=2):
            encrypt_button_credit_bureau = gr.Button("加密输入并发送到服务器。")

            encrypted_input_credit_bureau = gr.Textbox(
                label="加密后的输入:", max_lines=2, interactive=False
            )

    # Button to pre-process, generate the key, encrypt and send the applicant inputs from the client 
    # side to the server
    encrypt_button_applicant.click(
        pre_process_encrypt_send_applicant,
        inputs=[client_id, bool_inputs, num_children, household_size, total_income, age, \
                income_type, education_type, family_status, occupation_type, housing_type],
        outputs=[encrypted_input_applicant, encrypt_button_applicant],
    )

    # Button to pre-process, generate the key, encrypt and send the bank inputs from the client 
    # side to the server
    encrypt_button_bank.click(
        pre_process_encrypt_send_bank,
        inputs=[client_id, account_age],
        outputs=[encrypted_input_bank, encrypt_button_bank],
    )

    # Button to pre-process, generate the key, encrypt and send the credit bureau inputs from the 
    # client side to the server    
    encrypt_button_credit_bureau.click(
        pre_process_encrypt_send_credit_bureau,
        inputs=[client_id, years_employed, employed],
        outputs=[encrypted_input_credit_bureau, encrypt_button_credit_bureau],
    )

    gr.Markdown("## 步骤 3:运行FHE计算。")
    gr.Markdown("<hr />")
    gr.Markdown("<span style='color:grey'>服务端</span>")
    gr.Markdown(
        """
        一旦服务器收到加密的输入,它就可以计算预测,而无需解密任何值。

        此服务器采用已在合成数据集上训练过的[决策树](https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html)分类器模型。
        """
    )

    execute_fhe_button = gr.Button("运行FHE计算。")
    fhe_execution_time = gr.Textbox(
        label="FHE总执行时间(秒):", max_lines=1, interactive=False
    )

    # Button to send the encodings to the server using post method
    execute_fhe_button.click(run_fhe, inputs=[client_id], outputs=[fhe_execution_time, execute_fhe_button])

    gr.Markdown("## 步骤4:接收来自服务器的加密输出并解密。")
    gr.Markdown("<hr />")
    gr.Markdown("<span style='color:grey'>申请人、银行和信贷机构解密</span>")
    gr.Markdown(
        """
        一旦服务器完成推理,加密输出将返回给申请人。

        提供信息来计算信用评分的三个实体是唯一可以解密结果的实体。他们参与解密协议,该协议允许只有当所有三方都解密其份额的结果时才能解密完整结果。
        """
    )
    gr.Markdown(
        """
        下面显示的第一个值是实际加密输出的缩短字节表示。
        然后,申请人可以使用其私钥解密该值。        
        """
    )

    get_output_button = gr.Button("接收来自服务器的加密输出。")
    encrypted_output_representation = gr.Textbox(
        label="加密输出表示: ", max_lines=2, interactive=False
    )
    prediction_output = gr.Textbox(
        label="预测", max_lines=1, interactive=False
    )

    # Button to send the encodings to the server using post method
    get_output_button.click(
        get_output_and_decrypt, 
        inputs=[client_id], 
        outputs=[prediction_output, encrypted_output_representation, get_output_button],
    )

    gr.Markdown("## 第5步:解释预测(仅当您的信用卡可能被拒绝时)。")
    gr.Markdown("<hr />")
    gr.Markdown(
        """
        如果信用卡申请可能被拒绝,申请人可以询问最有可能需要多少年的工作经验才能增加获得信用卡批准的机会。

        为简单起见,上述所有步骤都合并为一个按钮。因此,以下按钮会加密来自所有三方的相同输入(工作年限除外,工作年限会有所不同),在 FHE 中运行新的预测并解密输出。

        如果以下状态表明要尝试新的“工作年限”输入,则只需更新步骤2中的值并直接再次运行步骤6。        
        """
    )
    explain_button = gr.Button(
        "加密输入,在FHE中计算并解密输出。"
    )
    explain_prediction = gr.Textbox(
        label="需要额外的工作年限。", interactive=False
    )

    # Button to explain the prediction
    explain_button.click(
        explain_encrypt_run_decrypt,
        inputs=[client_id, prediction_output, years_employed, employed],
        outputs=[explain_prediction, explain_button],
    )

    gr.Markdown(
        "本应用是一个隐私保护机器学习的示例,仅供参考。"
    )

demo.launch(share=False)