申峰 博士生导师 副教授 西南财经大学金融学院

邮箱:shenfeng@swufe.edu.cn



在日常实践中,数据通常是不完整的,含噪声,这样的数据必须经过预处理,剔除噪声,恢复数据完整性和一致性后才能使用数据挖掘技术进行分析。



5.1 数据集加载



我们使用mice包中的nhanes2数据集进行研究,该数据集是一个含有缺失值的小规模数据集。



(1)加载mice包

rr library(lattice) library(mice)


鎼笺复鎼笺父鎸笺父鏀笺耿鎴笺赋碳鎰笺工鎴笺赴鏄笺梗鎰笺赋鎴笺埂鎰笺副鎰笺攻mice鎰笺副鎰笺功

The following object is masked _by_ 鎰笺副鎰笺攻.GlobalEnv鎰笺副鎰笺功:

    nhanes2


(2)加载mice包里的nhanes2数据集

rr attach(nhanes2)



(3)展示nhanes2数据集

rr nhanes2



(4)显示数据集行、列数(相当于dim)

rr nrow(nhanes2);ncol(nhanes2)

[1] 25
[1] 4


(5)获取数据集的概括信息:

NA代表缺失值;age年龄;bmi身体质量指数;hyp是否高血压;chl血清胆固醇总量。

rr summary(nhanes2)

    age          bmi          hyp          chl       
 20-39:12   Min.   :20.40   no  :13   Min.   :113.0  
 40-59: 7   1st Qu.:22.65   yes : 4   1st Qu.:185.0  
 60-99: 6   Median :26.75   NA's: 8   Median :187.0  
            Mean   :26.56             Mean   :191.4  
            3rd Qu.:28.93             3rd Qu.:212.0  
            Max.   :35.30             Max.   :284.0  
            NA's   :9                 NA's   :10     


(6)显示数据集前几行情况

rr head(nhanes2)



5.2 缺失状况了解



在数据预处理的过程中,首先我们要判断数据是否有缺失值。



(1)计算数据集nhanes中的缺失值的数量

rr is.na(nhanes2)

     age   bmi   hyp   chl
1  FALSE  TRUE  TRUE  TRUE
2  FALSE FALSE FALSE FALSE
3  FALSE  TRUE FALSE FALSE
4  FALSE  TRUE  TRUE  TRUE
5  FALSE FALSE FALSE FALSE
6  FALSE  TRUE  TRUE FALSE
7  FALSE FALSE FALSE FALSE
8  FALSE FALSE FALSE FALSE
9  FALSE FALSE FALSE FALSE
10 FALSE  TRUE  TRUE  TRUE
11 FALSE  TRUE  TRUE  TRUE
12 FALSE  TRUE  TRUE  TRUE
13 FALSE FALSE FALSE FALSE
14 FALSE FALSE FALSE FALSE
15 FALSE FALSE FALSE  TRUE
16 FALSE  TRUE  TRUE  TRUE
17 FALSE FALSE FALSE FALSE
18 FALSE FALSE FALSE FALSE
19 FALSE FALSE FALSE FALSE
20 FALSE FALSE FALSE  TRUE
21 FALSE  TRUE  TRUE  TRUE
22 FALSE FALSE FALSE FALSE
23 FALSE FALSE FALSE FALSE
24 FALSE FALSE FALSE  TRUE
25 FALSE FALSE FALSE FALSE

rr sum(is.na(nhanes2))

[1] 27

函数is.na()用来判断缺失值



(2)计算数据集nhanes中完整样本的数量

rr complete.cases(nhanes2)

 [1] FALSE  TRUE FALSE FALSE  TRUE FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE  TRUE  TRUE
[15] FALSE FALSE  TRUE  TRUE  TRUE FALSE FALSE  TRUE  TRUE FALSE  TRUE

rr sum(complete.cases(nhanes2))

[1] 13

函数complete.cases用来判断完整数据

数据共有27个缺失值,13行完整样本数量



(3)通过列表显示数据集缺失情况

rr md.pattern(nhanes2)

   age hyp bmi chl   
13   1   1   1   1  0
 1   1   1   0   1  1
 3   1   1   1   0  1
 1   1   0   0   1  2
 7   1   0   0   0  3
     0   8   9  10 27

1表示没有缺失数据,0表示存在缺失数据。 最左侧第1列表示样本数量,最右侧最后1列是缺失的属性数量。 最下方最后1行表示在该属性下的缺失的样本数量。



5.3 缺失值处理



1. 删除法


删除法是将缺失数据集转变成完整数据集最便捷、最粗暴的方法。删除法适用于缺失数据比例较小这种情况。

主要分2种删除方式:

(一) 删除样本。(删除行)

(二) 删除属性。(删除列)

大部分的统计软件包都默认采用行删除法来处理缺失值。因此,许多人在使用例如回归方法分析数据时,都没有意识到有“缺失值问题”需要处理。



使用na.omit()函数来对缺失数据的行进行删除

rr newnhanes = na.omit(nhanes2) newnhanes



思考:如果要删除数据集中的缺失属性该怎样操作呢?



2. 插补法


删除法虽然简单,但是会造成信息损失,改变数据结构等问题。 因此,在某些情况下,找到缺失值的合适替代值来进行插补,或许是更好的做法。

插补法主要包括:均值插补、回归插补、多重插补等变量插补方法。



(一)均值法



均值法是通过计算缺失值所在变量所有非缺失观测值的均值,使用均值来替代缺失值的插补方法。


我们以均值法为例来对nhanes2数据集的第4列进行实现。



(1)展示数据集nhanes2

rr nhanes2



(2)将第四列中为NA值的行号存入数据集sub中

rr is.na(nhanes2[,4])

 [1]  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE FALSE FALSE
[15]  TRUE  TRUE FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE  TRUE FALSE

rr sub=which(is.na(nhanes2[,4])) sub

 [1]  1  4 10 11 12 15 16 20 21 24


(3)将第四列不为NA的数存入数据集A中

rr A=nhanes2[-sub,] A



(4)将第四列为NA的数存入数据集B中

rr B=nhanes2[sub,] B



(5)计算数据集第四列没有缺失值数据的均值

rr A_4mean=mean(A[,4]) A_4mean

[1] 191.4


(6)利用均值代替缺失值

rr B[,4]=A_4mean B



思考:用中位数或四分位数进行插补该怎样操作呢?



(二)回归插补



回归插补是需要将插补变量作为因变量,其他相关变量作为自变量,通过建立回归模型预测出因变量的值 对缺失变量进行插补。


我们以回归插补为例来对nhanes2数据集的第4列进行实现。



(1)将第四列不为NA的数存入数据集C中

rr sub=which(is.na(nhanes2[,4])) C=nhanes2[-sub,]
C



(2)将第四列为NA的数存入数据集D中

rr D=nhanes2[sub,] D



(3)以C数据集中的age为自变量,chl为因变量构建线性回归模型lm

rr lm=lm(chl~age,data=C) lm


Call:
lm(formula = chl ~ age, data = C)

Coefficients:
(Intercept)     age40-59     age60-99  
     169.00        33.80        55.67  


(4)利用构建的lm模型对数据集D中的chl的缺失数据进行预测

rr E=predict(lm,D) E

       1        4       10       11       12       15       16       20       21 
169.0000 224.6667 202.8000 169.0000 202.8000 169.0000 169.0000 224.6667 169.0000 
      24 
224.6667 


(5)将预测出的数据E替代nhanes2中chl为NA的数据

rr F <- nhanes2 F[sub,4]=round(E) F

函数round()表示四舍五入。



(三)多重插补



多重插补是通过变量间的关系对缺失数据进行预测,利用蒙特卡洛方法生成多个 完整的数据集,再对这些数据集分别进行分析,最后对分析结果进行汇总处理。



(1)我们用mice()函数来进行多重插补

rr imp=mice(nhanes2,m=4)


 iter imp variable
  1   1  bmi  hyp
  1   2  bmi  hyp
  1   3  bmi  hyp
  1   4  bmi  hyp
  2   1  bmi  hyp
  2   2  bmi  hyp
  2   3  bmi  hyp
  2   4  bmi  hyp
  3   1  bmi  hyp
  3   2  bmi  hyp
  3   3  bmi  hyp
  3   4  bmi  hyp
  4   1  bmi  hyp
  4   2  bmi  hyp
  4   3  bmi  hyp
  4   4  bmi  hyp
  5   1  bmi  hyp
  5   2  bmi  hyp
  5   3  bmi  hyp
  5   4  bmi  hyp

rr #fit=with(imp,lm(chl~age+hyp+bmi)) #pooled=pool(fit)
#summary(pooled)

mice()函数中m默认为5,即插补5组新数据。因采用蒙特卡洛模拟方法生成插补数据,因此,如果不设种子时,每次插补数据并不相同。with()函数可依次对每个完整数据集应用统计模型;pool()函数将这些单独的分析结果整合为一组结果。最终模型的标准误和p值都将准确地反映出由于缺失值和多重插补而产生的不确定性。



(2)通过complete()函数来查看不同组的插补数据

rr complete(imp,action = 3)

LS0tDQp0aXRsZTogJ+esrOWFreeroCDmlbDmja7pooTlpITnkIYnDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCg0KLS0tDQoNCi0tLQ0KDQotLS0NCg0KIyMjI+eUs+WzsCDljZrlo6vnlJ/lr7zluIgg5Ymv5pWZ5o6IIOilv+WNl+i0oue7j+Wkp+WtpumHkeiejeWtpumZoiANCg0KIyMjI+mCrueuse+8mnNoZW5mZW5nQHN3dWZlLmVkdS5jbiMjIyMNCg0KLS0tDQoNCi0tLQ0KDQoNCiMjIyPlnKjml6XluLjlrp7ot7XkuK3vvIzmlbDmja7pgJrluLjmmK/kuI3lrozmlbTnmoTvvIzlkKvlmarlo7DvvIzov5nmoLfnmoTmlbDmja7lv4Xpobvnu4/ov4fpooTlpITnkIbvvIzliZTpmaTlmarlo7DvvIzmgaLlpI3mlbDmja7lrozmlbTmgKflkozkuIDoh7TmgKflkI7miY3og73kvb/nlKjmlbDmja7mjJbmjpjmioDmnK/ov5vooYzliIbmnpDjgIIjIyMjDQoNCg0KLS0tDQoNCi0tLQ0KDQojIzUuMSDmlbDmja7pm4bliqDovb0jIw0KDQotLS0NCg0KLS0tDQoNCuaIkeS7rOS9v+eUqG1pY2XljIXkuK3nmoRuaGFuZXMy5pWw5o2u6ZuG6L+b6KGM56CU56m277yM6K+l5pWw5o2u6ZuG5piv5LiA5Liq5ZCr5pyJ57y65aSx5YC855qE5bCP6KeE5qih5pWw5o2u6ZuG44CCDQoNCg0KLS0tDQoNCi0tLQ0KDQrvvIgx77yJ5Yqg6L29bWljZeWMhQ0KYGBge3J9DQpsaWJyYXJ5KGxhdHRpY2UpDQpsaWJyYXJ5KG1pY2UpDQpgYGANCg0KLS0tDQoNCi0tLQ0KDQrvvIgy77yJ5Yqg6L29bWljZeWMhemHjOeahG5oYW5lczLmlbDmja7pm4YNCmBgYHtyfQ0KYXR0YWNoKG5oYW5lczIpDQpgYGANCg0KDQotLS0NCg0KLS0tDQoNCu+8iDPvvInlsZXnpLpuaGFuZXMy5pWw5o2u6ZuGDQpgYGB7cn0NCm5oYW5lczINCmBgYA0KDQotLS0NCg0KLS0tDQoNCu+8iDTvvInmmL7npLrmlbDmja7pm4booYzjgIHliJfmlbDvvIjnm7jlvZPkuo5kaW3vvIkNCmBgYHtyfQ0KbnJvdyhuaGFuZXMyKTtuY29sKG5oYW5lczIpIA0KYGBgDQoNCi0tLQ0KDQotLS0NCg0KDQrvvIg177yJ6I635Y+W5pWw5o2u6ZuG55qE5qaC5ous5L+h5oGv77yaDQoNCk5B5Luj6KGo57y65aSx5YC877ybYWdl5bm06b6E77ybYm1p6Lqr5L2T6LSo6YeP5oyH5pWw77ybaHlw5piv5ZCm6auY6KGA5Y6L77ybY2hs6KGA5riF6IOG5Zu66YaH5oC76YeP44CCDQoNCmBgYHtyfQ0Kc3VtbWFyeShuaGFuZXMyKQ0KYGBgDQoNCg0KLS0tDQoNCi0tLQ0KDQrvvIg277yJ5pi+56S65pWw5o2u6ZuG5YmN5Yeg6KGM5oOF5Ya1DQoNCmBgYHtyfQ0KaGVhZChuaGFuZXMyKQ0KYGBgDQoNCg0KDQotLS0NCg0KDQoNCi0tLQ0KDQojIyMgNS4yIOe8uuWkseeKtuWGteS6huinoyMjIw0KDQotLS0NCg0KLS0tDQoNCuWcqOaVsOaNrumihOWkhOeQhueahOi/h+eoi+S4re+8jOmmluWFiOaIkeS7rOimgeWIpOaWreaVsOaNruaYr+WQpuaciee8uuWkseWAvOOAgg0KDQotLS0NCg0KLS0tDQoNCu+8iDHvvInorqHnrpfmlbDmja7pm4ZuaGFuZXPkuK3nmoTnvLrlpLHlgLznmoTmlbDph48NCg0KYGBge3J9DQppcy5uYShuaGFuZXMyKQ0KYGBgDQoNCmBgYHtyfQ0Kc3VtKGlzLm5hKG5oYW5lczIpKQ0KYGBgDQrlh73mlbBpcy5uYSgp55So5p2l5Yik5pat57y65aSx5YC8DQoNCi0tLQ0KDQotLS0NCg0K77yIMu+8ieiuoeeul+aVsOaNrumbhm5oYW5lc+S4reWujOaVtOagt+acrOeahOaVsOmHjw0KDQpgYGB7cn0NCmNvbXBsZXRlLmNhc2VzKG5oYW5lczIpDQpgYGANCg0KDQpgYGB7cn0NCnN1bShjb21wbGV0ZS5jYXNlcyhuaGFuZXMyKSkNCmBgYA0KDQrlh73mlbBjb21wbGV0ZS5jYXNlc+eUqOadpeWIpOaWreWujOaVtOaVsOaNrg0KDQrmlbDmja7lhbHmnIkyN+S4que8uuWkseWAvO+8jDEz6KGM5a6M5pW05qC35pys5pWw6YePDQoNCg0KLS0tDQoNCi0tLQ0KDQrvvIgz77yJ6YCa6L+H5YiX6KGo5pi+56S65pWw5o2u6ZuG57y65aSx5oOF5Ya1DQoNCmBgYHtyfQ0KbWQucGF0dGVybihuaGFuZXMyKSANCmBgYA0KDQox6KGo56S65rKh5pyJ57y65aSx5pWw5o2u77yMMOihqOekuuWtmOWcqOe8uuWkseaVsOaNruOAgg0K5pyA5bem5L6n56ysMeWIl+ihqOekuuagt+acrOaVsOmHj++8jOacgOWPs+S+p+acgOWQjjHliJfmmK/nvLrlpLHnmoTlsZ7mgKfmlbDph4/jgIINCuacgOS4i+aWueacgOWQjjHooYzooajnpLrlnKjor6XlsZ7mgKfkuIvnmoTnvLrlpLHnmoTmoLfmnKzmlbDph4/jgIINCg0KDQotLS0NCg0KDQoNCi0tLQ0KDQojIyMgNS4zIOe8uuWkseWAvOWkhOeQhiMjIw0KDQotLS0NCg0KLS0tDQoNCg0KDQoNCiMjIyMgMS4g5Yig6Zmk5rOVDQoNCi0tLS0NCg0K5Yig6Zmk5rOV5piv5bCG57y65aSx5pWw5o2u6ZuG6L2s5Y+Y5oiQ5a6M5pW05pWw5o2u6ZuG5pyA5L6/5o2344CB5pyA57KX5pq055qE5pa55rOV44CC5Yig6Zmk5rOV6YCC55So5LqO57y65aSx5pWw5o2u5q+U5L6L6L6D5bCP6L+Z56eN5oOF5Ya144CCDQoNCuS4u+imgeWIhjLnp43liKDpmaTmlrnlvI/vvJoNCg0K77yI5LiA77yJIOWIoOmZpOagt+acrOOAgu+8iOWIoOmZpOihjO+8iQ0KDQrvvIjkuozvvIkg5Yig6Zmk5bGe5oCn44CC77yI5Yig6Zmk5YiX77yJDQoNCuWkp+mDqOWIhueahOe7n+iuoei9r+S7tuWMhemDvem7mOiupOmHh+eUqOihjOWIoOmZpOazleadpeWkhOeQhue8uuWkseWAvOOAguWboOatpO+8jOiuuOWkmuS6uuWcqOS9v+eUqOS+i+WmguWbnuW9kuaWueazleWIhuaekOaVsOaNruaXtu+8jOmDveayoeacieaEj+ivhuWIsOacieKAnOe8uuWkseWAvOmXrumimOKAnemcgOimgeWkhOeQhuOAgg0KDQoNCi0tLQ0KDQotLS0NCg0K5L2/55SobmEub21pdCgp5Ye95pWw5p2l5a+557y65aSx5pWw5o2u55qE6KGM6L+b6KGM5Yig6ZmkDQoNCmBgYHtyfQ0KbmV3bmhhbmVzID0gbmEub21pdChuaGFuZXMyKQ0KbmV3bmhhbmVzDQpgYGANCg0KDQotLS0NCg0KLS0tDQoNCuaAneiAg++8muWmguaenOimgeWIoOmZpOaVsOaNrumbhuS4reeahOe8uuWkseWxnuaAp+ivpeaAjuagt+aTjeS9nOWRou+8nw0KDQotLS0NCg0KLS0tDQoNCiMjIyMgMi4g5o+S6KGl5rOVDQoNCi0tLQ0KDQrliKDpmaTms5Xomb3nhLbnroDljZXvvIzkvYbmmK/kvJrpgKDmiJDkv6Hmga/mjZ/lpLHvvIzmlLnlj5jmlbDmja7nu5PmnoTnrYnpl67popjjgIINCuWboOatpO+8jOWcqOafkOS6m+aDheWGteS4i++8jOaJvuWIsOe8uuWkseWAvOeahOWQiOmAguabv+S7o+WAvOadpei/m+ihjOaPkuihpe+8jOaIluiuuOaYr+abtOWlveeahOWBmuazleOAgg0KDQoNCuaPkuihpeazleS4u+imgeWMheaLrO+8muWdh+WAvOaPkuihpeOAgeWbnuW9kuaPkuihpeOAgeWkmumHjeaPkuihpeetieWPmOmHj+aPkuihpeaWueazleOAgg0KDQotLS0NCg0KLS0tDQoNCu+8iOS4gO+8ieWdh+WAvOazlQ0KDQotLS0NCg0KLS0tDQoNCuWdh+WAvOazleaYr+mAmui/h+iuoeeul+e8uuWkseWAvOaJgOWcqOWPmOmHj+aJgOaciemdnue8uuWkseingua1i+WAvOeahOWdh+WAvO+8jOS9v+eUqOWdh+WAvOadpeabv+S7o+e8uuWkseWAvOeahOaPkuihpeaWueazleOAgg0KDQotLS0NCg0KDQrmiJHku6zku6XlnYflgLzms5XkuLrkvovmnaXlr7luaGFuZXMy5pWw5o2u6ZuG55qE56ysNOWIl+i/m+ihjOWunueOsOOAgg0KDQotLS0NCg0KLS0tDQoNCu+8iDHvvInlsZXnpLrmlbDmja7pm4ZuaGFuZXMyDQpgYGB7cn0NCm5oYW5lczINCmBgYA0KDQotLS0NCg0KLS0tDQoNCu+8iDLvvInlsIbnrKzlm5vliJfkuK3kuLpOQeWAvOeahOihjOWPt+WtmOWFpeaVsOaNrumbhnN1YuS4rQ0KDQpgYGB7cn0NCmlzLm5hKG5oYW5lczJbLDRdKQ0KYGBgDQoNCg0KDQpgYGB7cn0NCnN1Yj13aGljaChpcy5uYShuaGFuZXMyWyw0XSkpIA0Kc3ViDQpgYGANCg0KLS0tDQoNCi0tLQ0KDQrvvIgz77yJ5bCG56ys5Zub5YiX5LiN5Li6TkHnmoTmlbDlrZjlhaXmlbDmja7pm4ZB5LitDQoNCmBgYHtyfQ0KQT1uaGFuZXMyWy1zdWIsXQ0KQQ0KYGBgDQoNCi0tLQ0KDQotLS0NCg0K77yINO+8ieWwhuesrOWbm+WIl+S4uk5B55qE5pWw5a2Y5YWl5pWw5o2u6ZuGQuS4rQ0KDQpgYGB7cn0NCkI9bmhhbmVzMltzdWIsXQ0KQg0KYGBgDQoNCi0tLQ0KDQotLS0NCg0K77yINe+8ieiuoeeul+aVsOaNrumbhuesrOWbm+WIl+ayoeaciee8uuWkseWAvOaVsOaNrueahOWdh+WAvA0KDQpgYGB7cn0NCkFfNG1lYW49bWVhbihBWyw0XSkNCkFfNG1lYW4NCmBgYA0KDQoNCi0tLQ0KDQotLS0NCg0K77yINu+8ieWIqeeUqOWdh+WAvOS7o+abv+e8uuWkseWAvA0KDQpgYGB7cn0NCkJbLDRdPUFfNG1lYW4NCkINCmBgYA0KDQoNCi0tLQ0KDQotLS0NCg0KDQrmgJ3ogIPvvJrnlKjkuK3kvY3mlbDmiJblm5vliIbkvY3mlbDov5vooYzmj5LooaXor6XmgI7moLfmk43kvZzlkaLvvJ8NCg0KLS0tDQoNCi0tLQ0KDQrvvIjkuozvvInlm57lvZLmj5LooaUNCg0KLS0tDQoNCi0tLQ0KDQrlm57lvZLmj5LooaXmmK/pnIDopoHlsIbmj5LooaXlj5jph4/kvZzkuLrlm6Dlj5jph4/vvIzlhbbku5bnm7jlhbPlj5jph4/kvZzkuLroh6rlj5jph4/vvIzpgJrov4flu7rnq4vlm57lvZLmqKHlnovpooTmtYvlh7rlm6Dlj5jph4/nmoTlgLwNCuWvuee8uuWkseWPmOmHj+i/m+ihjOaPkuihpeOAgg0KDQotLS0NCg0KDQoNCuaIkeS7rOS7peWbnuW9kuaPkuihpeS4uuS+i+adpeWvuW5oYW5lczLmlbDmja7pm4bnmoTnrKw05YiX6L+b6KGM5a6e546w44CCDQoNCi0tLQ0KDQotLS0NCg0K77yIMe+8ieWwhuesrOWbm+WIl+S4jeS4uk5B55qE5pWw5a2Y5YWl5pWw5o2u6ZuGQ+S4rQ0KDQpgYGB7cn0NCnN1Yj13aGljaChpcy5uYShuaGFuZXMyWyw0XSkpIA0KQz1uaGFuZXMyWy1zdWIsXSAgICANCkMNCmBgYA0KDQotLS0NCg0KLS0tDQoNCu+8iDLvvInlsIbnrKzlm5vliJfkuLpOQeeahOaVsOWtmOWFpeaVsOaNrumbhkTkuK0NCg0KYGBge3J9DQpEPW5oYW5lczJbc3ViLF0gDQpEDQpgYGANCg0KLS0tDQoNCi0tLQ0KDQrvvIgz77yJ5LulQ+aVsOaNrumbhuS4reeahGFnZeS4uuiHquWPmOmHj++8jGNobOS4uuWboOWPmOmHj+aehOW7uue6v+aAp+WbnuW9kuaooeWei2xtDQoNCmBgYHtyfQ0KbG09bG0oY2hsfmFnZSxkYXRhPUMpDQpsbQ0KYGBgDQoNCi0tLQ0KDQotLS0NCg0K77yINO+8ieWIqeeUqOaehOW7uueahGxt5qih5Z6L5a+55pWw5o2u6ZuGROS4reeahGNobOeahOe8uuWkseaVsOaNrui/m+ihjOmihOa1iw0KDQpgYGB7cn0NCkU9cHJlZGljdChsbSxEKQ0KRQ0KYGBgDQoNCi0tLQ0KDQotLS0NCg0K77yINe+8ieWwhumihOa1i+WHuueahOaVsOaNrkXmm7/ku6NuaGFuZXMy5LitY2hs5Li6TkHnmoTmlbDmja4NCg0KYGBge3J9DQpGIDwtIG5oYW5lczINCkZbc3ViLDRdPXJvdW5kKEUpDQpGDQpgYGANCg0K5Ye95pWwcm91bmQoKeihqOekuuWbm+iIjeS6lOWFpeOAgg0KDQoNCi0tLQ0KDQotLS0NCg0KIyMjIO+8iOS4ie+8ieWkmumHjeaPkuihpQ0KDQotLS0NCg0KLS0tDQoNCuWkmumHjeaPkuihpeaYr+mAmui/h+WPmOmHj+mXtOeahOWFs+ezu+Wvuee8uuWkseaVsOaNrui/m+ihjOmihOa1i++8jOWIqeeUqOiSmeeJueWNoea0m+aWueazleeUn+aIkOWkmuS4qg0K5a6M5pW055qE5pWw5o2u6ZuG77yM5YaN5a+56L+Z5Lqb5pWw5o2u6ZuG5YiG5Yir6L+b6KGM5YiG5p6Q77yM5pyA5ZCO5a+55YiG5p6Q57uT5p6c6L+b6KGM5rGH5oC75aSE55CG44CCDQoNCi0tLQ0KDQotLS0NCg0K77yIMe+8ieaIkeS7rOeUqG1pY2UoKeWHveaVsOadpei/m+ihjOWkmumHjeaPkuihpQ0KDQpgYGB7cn0NCmltcD1taWNlKG5oYW5lczIsbT00KQ0KI2ZpdD13aXRoKGltcCxsbShjaGx+YWdlK2h5cCtibWkpKQ0KI3Bvb2xlZD1wb29sKGZpdCkgICAgICAgICAgICAgICAgICANCiNzdW1tYXJ5KHBvb2xlZCkgDQpgYGANCg0KbWljZSgp5Ye95pWw5Litbem7mOiupOS4ujXvvIzljbPmj5LooaU157uE5paw5pWw5o2u44CC5Zug6YeH55So6JKZ54m55Y2h5rSb5qih5ouf5pa55rOV55Sf5oiQ5o+S6KGl5pWw5o2u77yM5Zug5q2k77yM5aaC5p6c5LiN6K6+56eN5a2Q5pe277yM5q+P5qyh5o+S6KGl5pWw5o2u5bm25LiN55u45ZCM44CCd2l0aCgp5Ye95pWw5Y+v5L6d5qyh5a+55q+P5Liq5a6M5pW05pWw5o2u6ZuG5bqU55So57uf6K6h5qih5Z6L77ybcG9vbCgp5Ye95pWw5bCG6L+Z5Lqb5Y2V54us55qE5YiG5p6Q57uT5p6c5pW05ZCI5Li65LiA57uE57uT5p6c44CC5pyA57uI5qih5Z6L55qE5qCH5YeG6K+v5ZKMcOWAvOmDveWwhuWHhuehruWcsOWPjeaYoOWHuueUseS6jue8uuWkseWAvOWSjOWkmumHjeaPkuihpeiAjOS6p+eUn+eahOS4jeehruWumuaAp+OAgg0KDQotLS0NCg0KLS0tDQoNCg0KDQrvvIgy77yJ6YCa6L+HY29tcGxldGUoKeWHveaVsOadpeafpeeci+S4jeWQjOe7hOeahOaPkuihpeaVsOaNrg0KDQpgYGB7cn0NCmNvbXBsZXRlKGltcCxhY3Rpb24gPSAzKQ0KYGBgDQoNCg0KDQoNCg0KDQoNCg0KDQo=