第三章主要利用weka 做了几个简单的demo,我会按照书上的介绍,尽可能实践一遍。
首先贴一下我用的weka的maven坐标:
<dependency>
<groupId>nz.ac.waikato.cms.weka</groupId>
<artifactId>weka-dev</artifactId>
<version>3.9.3</version>
</dependency>
3.3 回归
3.2 章节是介绍分类算法的, 但是我没找到分类算法的数据在哪下载,就不多做介绍了。我们先从回归开始:
- 线性回归
- 加载数据
xlsx数据下载地址
下载的数据是xlsx格式的,我们要另存为csv格式,并检查下转换之后的文件,把最后多余的空行删除掉。 - 分析属性:
|属性|属性名称 |
| – | – |
| X1 | 相对密实性 |
| X2 | 表面积 |
| X3 | 墙体面积 |
…
| Y1 | 加热负载 |
| Y2 | 冷却负载 |
我们要做的就是根据x1,x2…的属性,得到计算Y1的线性函数。
- 明确目的之后,我们就开始撸码
import weka.classifiers.Evaluation;
import weka.classifiers.functions.LinearRegression;
import weka.core.Instances;
import weka.core.converters.CSVLoader;
import weka.filters.Filter;
import weka.filters.unsupervised.attribute.Remove;
import java.io.File;
import java.util.Random;
/**
* @author ding
* @date 2019/3/31
*/
public class WekaLinear {
public static void main(String[] args) throws Exception {
// 1. 载入csv文件
CSVLoader csvLoader = new CSVLoader();
csvLoader.setSource(new File("E://ENB2012_data.csv"));
// 2. 获取data实例
Instances data = csvLoader.getDataSet();
// 对倒数第二列Y1(加热负加载)数据进行计算
data.setClassIndex(data.numAttributes() - 2);
// 移除Y2列(冷却负加载),因为和我们要求的Y1(加热负加载无关)
Remove remove = new Remove();
remove.setOptions(new String[]{"-R",data.numAttributes()+""});
remove.setInputFormat(data);
data = Filter.useFilter(data, remove);
//3. 创建线性函数
LinearRegression model = new LinearRegression();
model.buildClassifier(data);
System.out.println(model);
/**
* 以上输出内容为:weka直接根据训练数据集帮我们计算出了一个线性函数,看上去是不是很神奇
*Linear Regression Model
*
* Y1 =
*
* -64.774 * X1 +
* -0.0428 * X2 +
* 0.0163 * X3 +
* -0.089 * X4 +
* 4.1699 * X5 +
* 19.9327 * X7 +
* 0.2038 * X8 +
* 83.9329
*/
//4. 做10折交叉验证
Evaluation evl = new Evaluation(data);
evl.crossValidateModel(model,data,10,new Random(1),new String[]{});
//5. 输出评价,包括相关系数,平均绝对误差,相对绝对误差等
System.out.println(evl.toSummaryString());
/**
* 评价输出结果
* Correlation coefficient 0.956
* Mean absolute error 2.0923
* Root mean squared error 2.9569
* Relative absolute error 22.8555 %
* Root relative squared error 29.282 %
* Total Number of Instances 768
*/
}
}
- 回归树
上图比较了线性回归和回归树的区别,不知道为何图转不过来,各位麻烦转转脑袋就行。
在weka中,M5类用于实现回归树。
代码如下。
// 还是用线性回归的数据 data
M5P m5P = new M5P();
m5P.setOptions(new String[]{});
m5P.buildClassifier(data);
System.out.println(m5P);
/**
* 输出为:
* X1 <= 0.75 :
* | X7 <= 0.175 :
* | | X1 <= 0.65 : LM1 (48/1.264%)
* | | X1 > 0.65 : LM2 (96/3.201%)
* | X7 > 0.175 :
* | | X1 <= 0.65 : LM3 (80/3.652%)
* | | X1 > 0.65 :
* | | | X7 <= 0.325 : LM4 (80/3.724%)
* | | | X7 > 0.325 :
* | | | | X1 <= 0.675 : LM5 (20/1.687%)
* | | | | X1 > 0.675 :
* | | | | | X8 <= 2.5 : LM6 (24/1.314%)
* | | | | | X8 > 2.5 :
* | | | | | | X8 <= 4.5 : LM7 (24/2.737%)
* | | | | | | X8 > 4.5 :
* | | | | | | | X1 <= 0.7 : LM8 (4/0.91%)
* | | | | | | | X1 > 0.7 : LM9 (8/1.265%)
* X1 > 0.75 :
* | X1 <= 0.805 :
* | | X7 <= 0.175 : LM10 (48/5.775%)
* | | X7 > 0.175 :
* | | | X7 <= 0.325 : LM11 (40/5.26%)
* | | | X7 > 0.325 : LM12 (40/5.756%)
* | X1 > 0.805 :
* | | X7 <= 0.175 :
* | | | X8 <= 1.5 :
* | | | | X7 <= 0.05 :
* | | | | | X2 <= 539 : LM13 (4/0%)
* | | | | | X2 > 539 : LM14 (12/4.501%)
* | | | | X7 > 0.05 :
* | | | | | X1 <= 0.94 : LM15 (12/4.329%)
* | | | | | X1 > 0.94 : LM16 (4/0.226%)
* | | | X8 > 1.5 :
* | | | | X1 <= 0.94 : LM17 (48/5.693%)
* | | | | X1 > 0.94 : LM18 (16/1.119%)
* | | X7 > 0.175 :
* | | | X1 <= 0.84 :
* | | | | X7 <= 0.325 :
* | | | | | X8 <= 2.5 : LM19 (8/3.901%)
* | | | | | X8 > 2.5 : LM20 (12/3.913%)
* | | | | X7 > 0.325 : LM21 (20/5.632%)
* | | | X1 > 0.84 :
* | | | | X7 <= 0.325 : LM22 (60/4.548%)
* | | | | X7 > 0.325 :
* | | | | | X3 <= 306.25 : LM23 (40/4.504%)
* | | | | | X3 > 306.25 : LM24 (20/6.934%)
*/
可以看到,根据x的范围不同, 所得到的计算函数也是不同的,这样子,得到的函数拟合度更好。
3.4 聚类
很不幸的是,书上的例子又没贴出数据源。。。
书上的例子是这样的: 有一个银行客户的数据集,有600个客户实例,每个实例有11个属性:年龄,性别,地区,收入,是否有子女等,利用EM(期望最大化)聚类算法来识别常见的客户组。
EM工作过程如下:
- 给定一组簇,EM首先为每个实例指派一个属于某个特定簇的概率分布:比如起始有A,B,C三个簇,有个实例属于A,B,C三个簇的肯能性分别为:0.7,0.1,0.2
- EM重新评估每个类的概率分布的参数向量
算法不断对这两步做迭代,知道参数收敛或者达到最大值。
public class WekaClustering {
public static void main(String[] args) throws Exception {
Instances data = new Instances(new BufferedReader(new FileReader(args[0])));
EM model = new EM();
model.buildClusterer(data);
// 这样就会输出对数据的聚类分组结果
System.out.println(model);
}
}
总结: 简单实现了聚类和回归算法的入门demo, 还有很多参数性的东西没有配置,以后还要多多学习。简单看了下后面的章节,基本以实践和代码为主,可能不会更新了。因为我觉得重复贴代码片段可能意义不大。