上一篇文章已经描述了朴素贝叶斯算法newgroup的分类实现,这篇文章采用KNN算法实现newgroup的分类。
文中代码参考:http://blog.csdn.net/yangliuy/article/details/7401142
1、KNN算法描述
对于KNN算法,前面有一篇文章介绍其思想,但是按个事例采用的模拟的数值数据。本文将采用KNN进行文本分类。算法步骤如下:
(1)文本预处理,向量化,根据特征词的TF*IDF值计算 (上一篇文章已经处理)
(2)当新文本到达后,根据特征词计算新文本的向量
(3)在训练文本中选出与新文本最相近的K个文本,相似度用向量夹角的余弦值度量。
注:K的值目前没有好的办法确定,只有根据实验来调整K的值
(4)在新文本的K个相似文本中,依此计算每个类的权重,每个类的权重等于K个文本中属于该类的训练样本与测试样本的相似度之和。
(5)比较类的权重,将文本分到权重最大那个类别中
2、KNN算法实现
KNN算法的实现要注意
(1)用TreeMap<String,TreeMap<String,Double>>保存测试集和训练集
(2)注意要以"类目_文件名"作为每个文件的key,才能避免同名不同内容的文件出现
package com.datamine.NaiveBayes;
import java.io.*;
import java.util.*;
/**
* KNN算法的实现类,本程序用向量夹角余弦计算相识度
* @author Administrator
*/
public class KNNClassifier {
/**
* 用knn算法对测试文档集分类,读取测试样例和训练样例集
* @param trainFiles 训练样例的所有向量构成的文件
* @param testFiles 测试样例的所有向量构成的文件
* @param knnResultFile KNN分类结果文件路径
* @throws Exception
*/
private void doProcess(String trainFiles, String testFiles,
String knnResultFile) throws Exception {
/*
* 首先读取训练样本和测试样本,用map<String,map<word,TF>>保存测试集和训练集,注意训练样本的类目信息也得保存
* 然后遍历测试样本,对于每一个测试样本去计算它与所有训练样本的相识度,相识度保存到map<String,double>有序map中
* 然后取钱K个样本,针对这k个样本来给它们所属的类目计算权重得分,对属于同一个类目的权重求和进而得到最大得分的类目
* 就可以判断测试样例属于该类目下,K值可以反复测试,找到分类准确率最高的那个值
* 注意:
* 1、要以"类目_文件名"作为每个文件的key,才能避免同名不同内容的文件出现
* 2、注意设置JM参数,否则会出现JAVA Heap溢出错误
* 3、本程序用向量夹角余弦计算相识度
*/
File trainSample = new File(trainFiles);
BufferedReader trainSampleBR = new BufferedReader(new FileReader(trainSample));
String line;
String[] lineSplitBlock;
//trainFileNameWordTFMap<类名_文件名,map<特征词,特征权重>>
Map<String,TreeMap<String,Double>> trainFileNameWordTFMap = new TreeMap<String, TreeMap<String,Double>>();
//trainWordTFMap<特征词,特征权重>
TreeMap<String,Double> trainWordTFMap = new