基于weka的数据库挖掘➖分类方法的实现
关于作者
- 作者介绍
🍓 博客主页:作者主页
🍓 简介:JAVA领域优质创作者🥇、一名初入职场小白🎓、曾在校期间参加各种省赛、国赛,斩获一系列荣誉 🏆
🍓 关注我:关注我学习资料、文档下载统统都有,每日定时更新文章,励志做一名JAVA资深程序猿👨💻
目的
1.掌握KNN算法对测试数据进行分类的具体过程
2.掌握ID3算法生成决策树的过程
3.掌握朴素贝叶斯算法对文本的分类的过程
内容
1.根据给出的A、B、C三类点的样本坐标值,采用KNN方法对 点(3,0)(3,1)(3,5)(0,0)(5,1)进行分类
2.利用ID3算法,生成给定样本数据集的决策树(需要根据运行结果画出对应的决策树)
3.现有文本分类数据10个类别(汽车、财经、IT、健康、体育、旅游、教育、招聘、文化、军事),共100篇文章, 使用朴素贝叶斯方法,对测试文本进行分类,输出该测试文本的类别
步骤及结果
1.根据给出的A、B、C三类点的样本坐标值,采用KNN方法对 点(3,0)(3,1)(3,5)(0,0)(5,1)进行分类。
2.利用ID3算法,生成给定样本数据集的决策树(需要根据运行结果画出对应的决策树)
3.现有文本分类数据10个类别(汽车、财经、IT、健康、体育、旅游、教育、招聘、文化、军事),共100篇文章, 使用朴素贝叶斯方法,对测试文本进行分类,输出该测试文本的类别。
BayesClassifier.Java
朴素贝叶斯分类器, 利用样本数据集计算先验概率和各个文本向量属性在分类中的条件概率,从而计算出各个概率值,最后对各个概率值进行排序,选出最大的概率值,即为所属的分类。
java
public class BayesClassifier
{
private TrainingDataManager tdm;//训练集管理器
private String trainnigDataPath;//训练集路径
private static double zoomFactor = 10.0f;复制代码
默认的构造器,初始化训练集
public BayesClassifier()
{
tdm =new TrainingDataManager();
}
// 计算给定的文本属性向量X在给定的分类Cj中的类条件概率
// ClassConditionalProbability连乘值
//@param X 给定的文本属性向量
//@param Cj 给定的类别
//@return 分类条件概率连乘值,即
float calcProd(String[] X, String Cj)
{
float ret = 1.0F;
// 类条件概率连乘
for (int i = 0; i <X.length; i++)
{
String Xi = X[i];
//因为结果过小,因此在连乘之前放大10倍,这对最终结果并无影响,因为我们只是比较概率大小而已
ret *=ClassConditionalProbability.calculatePxc(Xi, Cj)*zoomFactor;
}
// 再乘以先验概率
ret *= PriorProbability.calculatePc(Cj);
return ret;
}
//去掉停用词
//@param text 给定的文本
//@return 去停用词后结果
public String[] DropStopWords(String[] oldWords)
{
Vector<String> v1 = new Vector<String>();
for(int i=0;i<oldWords.length;++i)
{
if(StopWordsHandler.IsStopWord(oldWords[i])==false)
{//不是停用词
v1.add(oldWords[i]);
}
}
String[] newWords = new String[v1.size()];
v1.toArray(newWords);
return newWords;
}
//对给定的文本进行分类
//@param text 给定的文本
//@return 分类结果
//@SuppressWarnings("unchecked")
public String classify(String text)
{
String[] terms = null;
terms= ChineseSpliter.split(text, " ").split(" ");//中文分词处理(分词后结果可能还包含有停用词)
terms = DropStopWords(terms);//去掉停用词,以免影响分词
String[] Classes = tdm.getTraningClassifications();//分类
float probility = 0.0F;
List<ClassifyResult> crs = new ArrayList<ClassifyResult>();//分类结果
for (int i = 0; i <Classes.length; i++)
{
String Ci = Classes[i];//第i个分类
probility = calcProd(terms, Ci);//计算给定的文本属性向量terms在给定的分类Ci中的分类条件概率
//保存分类结果
ClassifyResult cr = new ClassifyResult();
cr.classification = Ci;//分类
cr.probility = probility;//关键字在分类的条件概率
System.out.println("In process.");
System.out.println(Ci + ":" + probility);
crs.add(cr);
}
//对最后概率结果进行排序
java.util.Collections.sort(crs,new Comparator()
{
public int compare(final Object o1,final Object o2)
{
final ClassifyResult m1 = (ClassifyResult) o1;
final ClassifyResult m2 = (ClassifyResult) o2;
final double ret = m1.probility - m2.probility;
if (ret < 0)
{
return 1;
}
else
{
return -1;
}
}
});
//返回概率最大的分类
return crs.get(0).classification;
}
public static void main(String[] args)
{
String text = "微软公司提出以446亿美元的价格收购雅虎中国网2月1日报道 美联社消息,微软公司提出以446亿美元现金加股票的价格收购搜索网站雅虎公司。微软提出以每股31美元的价格收购雅虎。微软的收购报价较雅虎1月31日的收盘价19.18美元溢价62%。微软公司称雅虎公司的股东可以选择以现金或股票进行交易。微软和雅虎公司在2006年底和2007年初已在寻求双方合作。而近两年,雅虎一直处于困境:市场份额下滑、运营业绩不佳、股价大幅下跌。对于力图在互联网市场有所作为的微软来说,收购雅虎无疑是一条捷径,因为双方具有非常强的互补性。(小桥)";
BayesClassifier classifier = new BayesClassifier();//构造Bayes分类器
String result = classifier.classify(text);//进行分类
System.out.println("此项属于["+result+"]");
}
}
ChineseSpliter.java
中文分词器,因为对文本进行分类时,需要计算文本中每个词在各类别中出现的概率,所以需要对文本进行分词,用到了分词器
java
public class ChineseSpliter {
/**
* 对给定的文本进行中文分词
* @param text 给定的文本
* @param splitToken 用于分割的标记,如"|"
* @return 分词完毕的文本
*/
public static String split(String text,String splitToken)
{
String result = null;
MMAnalyzer analyzer = new MMAnalyzer(); //中文分词工具
try
{
result = analyzer.segment(text, splitToken);
}
catch (IOException e)
{
e.printStackTrace();
}
return result;
}
}
public class ClassifyResult {
public double probility;//分类的概率
public String classification;//分类
public ClassifyResult()
{
this.probility = 0;
this.classification = null;
}
}
PriorProbability.java
先验概率计算: P(c~j~)=N(C=c~j~)/N
其中,N(C=c~j~)表示类别c~j~中的训练文本数量;
N表示训练文本集总数量。
java
public class PriorProbability {
private static TrainingDataManager tdm =new TrainingDataManager();
/**
* 先验概率
* @param c 给定的分类
* @return 给定条件下的先验概率
*/
public static float calculatePc(String c)
{
float ret = 0F;
float Nc = tdm.getTrainingFileCountOfClassification(c);//返回训练文本集中在给定分类下的训练文本数目
float N = tdm.getTrainingFileCount();//返回训练文本集中所有的文本数目
ret = Nc / N;
return ret;
}
}
StopWordsHandler.java
停用词处理器,去掉文档中无意思的词语也是必须的一项工作,这里简单的定义了一些常见的停用词,并根据这些常用停用词在分词时进行判断。
相当于预处理,去噪
java
public class StopWordsHandler {
private static String stopWordsList[] ={"的", "我们","要","自己","之","将",""",""",",","(",")","后","应","到","某","后","个","是","位","新","一","两","在","中","或","有","更","好",""};//常用停用词
public static boolean IsStopWord(String word)
{
for(int i=0;i<stopWordsList.length;++i)
{
if(word.equalsIgnoreCase(stopWordsList[i]))
return true;
}
return false;
}
}
TrainingDataManager.java
训练集管理器,首先需要从训练样本集中得到假设的先验概率和给定假设下观察到不同数据的概率。
java
public class TrainingDataManager {
private String[] traningFileClassifications;//训练语料分类集合
private File traningTextDir;//训练语料存放目录
private static String defaultPath = "F:\\studyfiles\\数据挖掘\\3\\Bayes\\BayesData\\Sample";
public TrainingDataManager()
{
traningTextDir = new File(defaultPath);
if (!traningTextDir.isDirectory())
{
throw new IllegalArgumentException("训练语料库搜索失败! [" +defaultPath + "]");
}
this.traningFileClassifications = traningTextDir.list();
}
返回训练文本类别,这个类别就是目录名
@return 训练文本类别
public String[] getTraningClassifications()
{
return this.traningFileClassifications;
}
根据训练文本类别返回这个类别下的所有训练文本路径(full path)
@param classification 给定的分类
@return 给定分类下所有文件的路径(full path)
public String[] getFilesPath(String classification)
{
File classDir = new File(traningTextDir.getPath() +File.separator +classification);
String[] ret = classDir.list();
for (int i = 0; i < ret.length; i++)
{
ret[i] = traningTextDir.getPath() +File.separator +classification +File.separator +ret[i];
}
return ret;
}
返回给定路径的文本文件内容
@param filePath 给定的文本文件路径
@return 文本内容
@throws java.io.FileNotFoundException
@throws java.io.IOException
public static String getText(String filePath) throws FileNotFoundException,IOException
{
InputStreamReader isReader =new InputStreamReader(new FileInputStream(filePath),"GBK");
BufferedReader reader = new BufferedReader(isReader);
String aline;
StringBuilder sb = new StringBuilder();
while ((aline = reader.readLine()) != null)
{
sb.append(aline + " ");
}
isReader.close();
reader.close();
return sb.toString();
}
返回训练文本集中所有的文本数目
@return 训练文本集中所有的文本数目
public int getTrainingFileCount()
{
int ret = 0;
for (int i = 0; i < traningFileClassifications.length; i++)
{
ret +=getTrainingFileCountOfClassification(traningFileClassifications[i]);
}
return ret;
}
返回训练文本集中在给定分类下的训练文本数目
@param classification 给定的分类
@return 训练文本集中在给定分类下的训练文本数目
public int getTrainingFileCountOfClassification(String classification)
{
File classDir = new File(traningTextDir.getPath() +File.separator +classification);
return classDir.list().length;
}
返回给定分类中包含关键字/词的训练文本的数目
@param classification 给定的分类
@param key 给定的关键字/词
@return 给定分类中包含关键字/词的训练文本的数目
public int getCountContainKeyOfClassification(String classification,String key)
{
int ret = 0;
try
{
String[] filePath = getFilesPath(classification);
for (int j = 0; j < filePath.length; j++)
{
String text = getText(filePath[j]);
if (text.contains(key))
{
ret++;
}
}
}
catch (FileNotFoundException ex)
{
Logger.getLogger(TrainingDataManager.class.getName()).log(Level.SEVERE, null,ex);
}
catch (IOException ex)
{
Logger.getLogger(TrainingDataManager.class.getName()).log(Level.SEVERE, null,ex);
}
return ret;
}
}