2011011384 郑玉昆 计34
代码中使用了大量的hashmap用来存储每个属性分量与类别属性的关系对。例如:
//>50K
Map<Integer, Integer> Age_r = new HashMap<>();
//<=50K
Map<Integer, Integer> Age_p = new HashMap<>();
Age_r存储键值对{ age , >50k人数 },Age_p存储键值对{ age , <=50k人数 },同样其他每个属性都对应了两个hashmap。
//参数
int alpha = 1;
int AgeBiase = 3;
int fnlwgtBiase = 500;
int EducationNumBiase = 1;
int CapitalGainBiase = 5;
int CapitalLossBiase = 5;
int HoursPerWeekBiase = 3;
以上为算法中可调参数,alpha表示平滑处理的增量,其余分别表示连续属性的分组间隔。
public void continuousDeal(Map<Integer, Integer> RichMap, Map<Integer, Integer> PoorMap, Integer attr, boolean flag)
continuousDeal()用来处理训练时的连续属性
public void enumerationDeal(Map<String, Integer> RichMap, Map<String, Integer> PoorMap, String attr, boolean flag)
enumerationDeal()用来处理训练时的离散属性
public void train()
train()用来进行数据的训练
public double continuousStatistics(Map<Integer, Integer> conMap, Integer attr, int delta, boolean flag)
continuousStatistics()用来处理测试集中的连续属性
public double enumerationStatistics(Map<String, Integer> enumMap, String attr, boolean flag)
enumerationStatistics()用来处理测试集中的离散属性
public void predict()
predict()用来进行数据的测试
为了防止在测试时某一属性出现零概率,所以定义了变量alpha
和m
,分别表示平滑增量
和独立属性数
,例如计算离散变量概率的代码如下:
1.0 * (sum + alpha) / (tRichPopulation + m * alpha);
对于连续属性,以年龄为例,单独分析一个年龄可能出现零概率,或者出现取样不够充分的现象,考虑到相近年龄的人具有一定的相似性,所以在实现过程中设置了一个区间宽度d,对于年龄A,在年龄训练集中选取[ A-d , A+d ]作为其所在区间,求出此区间中年龄的平均概率用来代替单个年龄的概率,这样做后计算出的概率更加平滑,也更具有代表性。
在实际的训练集和测试集中都存在一些离散属性出现缺失,对于训练集中出现的属性缺失,我选择将“?”作为该属性的特殊一项进行单独统计,理由是训练集数量足够大的话出现缺失的分布也是足够随机的,这样的话也相当于对该缺失属性取了所在属性的平均概率,这样的话对于结果的影响不至于很明显。
在刚开始时,凭借个人经验设定参数如下:
int alpha = 1;
int m = 13;
int AgeBiase = 3;
int fnlwgtBiase = 500;
int EducationNumBiase = 1;
int CapitalGainBiase = 5;
int CapitalLossBiase = 5;
int HoursPerWeekBiase = 3;
使用100%规模训练集得到如下结果:
准确率 = 83.93%
测试集规模 = 16281
预测正确的人数 = 13664
在100%规模训练集基础上经过暴力搜索后得出使用如下参数时准确率最高:
int alpha = 1;
int m = 13;
int AgeBiase = 0;
int fnlwgtBiase = 3500;
int EducationNumBiase = 3;
int CapitalGainBiase = 10;
int CapitalLossBiase = 6;
int HoursPerWeekBiase = 3;
准确率 = 84.11%
测试集规模 = 16281
预测正确的人数 = 13694
| Precision | Recall | F-measurse
------|-----------|---------|-----------
50k | 0.72 | 0.652 | 0.69 <=50k | 0.881 | 0.919 | 0.90
以上评价指标共同反应出该分类器在>50k的分类准确性上比<=50k的准确率要低,这说明前者的特征属性不如后者明显。
在最佳参数下,连续运行十次得到的正确率如下:
0.8234752165100424
0.8255021190344574
0.8355752103679135 //Max!
0.8282046557336773
0.8205884159449666
0.8239051655303729
0.8243351145507033
0.8215711565628647 //Min!
0.8257478041889319
0.8264234383637369
准确率在随机情况下变化不大,平均准确率为0.82553283
。这说明数据集规模的缩小使得准确率有一定下降,但影响极小。
0.8380934832012775
0.8382777470671334
0.8375406916037098
0.8363122658313371 //Min!
0.8385848535102266
0.8386462747988452
0.839014802530557
0.8401818070143111 //Max!
0.8398132792825993
0.8373564277378539
平均准确率为0.838382163
,发现准确率相对5%规模时有了约1.3%
的提升,提升很有限。
在最佳参数基础上,100%规模训练集时准确率为0.8411031263435906
,相对5%和50%的准确率都稍高一点,这说明训练集的扩大在此时对准确率的提升有一定影响,但收效甚微。
在训练集为0.005%
时,准确率平均为69.73%,这说明在准确率相对较低时训练集规模的扩大会带来准确率的大幅提升。