package IKAnalyzer; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Reader; import java.io.Serializable; import java.io.StringReader; import java.util.ArrayList; import java.util.List; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; import org.wltea.analyzer.lucene.IKAnalyzer; import weka.classifiers.Classifier; import weka.classifiers.trees.J48; import weka.core.Attribute; import weka.core.DenseInstance; import weka.core.Instance; import weka.core.Instances; import weka.core.Utils; import weka.filters.Filter; import weka.filters.unsupervised.attribute.StringToWordVector; //将简单的文本信息分为两个类别的Java程序 //MessageClassifier -m data/textToTrain/Education003.txt -c miss -t data/messageclassifier.model //改变txt和相应的hit/miss,训练(education01/02/03 miss,history01/02/03 hit) //MessageClassifier -m data/textToTest/Education000.txt -t data/messageclassifier.model,再进行分类 public class MessageClassifier implements Serializable { private static final long serialVersionUID = -5931873418320757767L; // 迄今收集的训练数据 private Instances m_Data = null; // 用于生成单词计数的过滤器 private StringToWordVector m_Filter = new StringToWordVector(); // 实际的分类器 private Classifier m_Classifier = new J48(); // 模型是否为最新 private boolean m_UpToDate; /** * 构建空训练集 */ public MessageClassifier() throws Exception { String nameOfDataset = "MessageClassificationProblem"; // 创建的属性列表 List<Attribute> attributes = new ArrayList<Attribute>(); // 添加属性以保存文本信息 attributes.add(new Attribute("Message", (List<String>) null)); // 添加类别属性 List<String> classValues = new ArrayList<String>(); classValues.add("miss"); classValues.add("hit"); attributes.add(new Attribute("Class", classValues)); // 创建初始容量为100的数据集 m_Data = new Instances(nameOfDataset, (ArrayList<Attribute>) attributes, 100); // 设置类别索引 m_Data.setClassIndex(m_Data.numAttributes() - 1); } /** * 将文本信息转化为实例的方法 */ private Instance makeInstance(String text, Instances data) { // 创建一个属性数量为2,权重为1,全部值都为缺失的实例 Instance instance = new DenseInstance(2); // 设置文本信息属性的值 Attribute messageAtt = data.attribute("Message"); instance.setValue(messageAtt, messageAtt.addStringValue(text)); // 让实例能访问数据集中的属性信息 instance.setDataset(data); return instance; } /** * 使用给定的训练文本信息更新模型 */ public void updateData(String message, String classValue) throws Exception { // 把文本信息转换为实例 Instance instance = makeInstance(message, m_Data); // 把实例设置为类别值 instance.setClassValue(classValue); // 添加实例到训练数据 m_Data.add(instance); m_UpToDate = false; // 输出提示信息 System.err.println("更新模型成功!"); } /** * 分类给定的文本消息 */ public void classifyMessage(String message) throws Exception { // 检查是否已构建分类器 if (m_Data.numInstances() == 0) throw new Exception("没有分类器可用"); // 检查是否分类器和过滤器为最新 if (!m_UpToDate) { // 初始化过滤器,并告知输入格式 m_Filter.setInputFormat(m_Data); // 从训练数据生成单词计数 Instances filteredData = Filter.useFilter(m_Data, m_Filter); // 重建分类器 m_Classifier.buildClassifier(filteredData); m_UpToDate = true; } // 形成单独的小测试集,所以该文本不会添加到m_Data的字符串属性中 Instances testSet = m_Data.stringFreeStructure(); // 使文本信息成为测试实例 Instance instance = makeInstance(message, testSet); // 过滤实例 m_Filter.input(instance); Instance filteredInstance = m_Filter.output(); // 获取预测类别的索引 double predicted = m_Classifier.classifyInstance(filteredInstance); // 输出类别值 System.err.println("文本信息分类为为:" + m_Data.classAttribute().value((int) predicted)); } /** * 主方法 * 可以识别以下参数 * -E * 文本是否为英文,默认中文 * -m 文本文件信息 * 指向一个文件,其中包含待分类的文本信息,或用于更新模型的文本信息。 * -c 类别标签 * 如果要更新模型,文本信息的类别标签。省略表示需要对文本信息进行分类。 * -t 模型文件 * 包含模型文件。如果不存在该文件,就会自动创建 * @param args 命令行选项 */ public static void main(String[] options) { try { //读入文本信息文件,存储为字符串 String messageName=Utils.getOption("m", options); if(messageName.length()==0){ throw new Exception("必须提供文本信息文件的名称。"); } FileReader m=new FileReader(messageName); StringBuffer message=new StringBuffer(); int i; while((i=m.read())!=-1){ message.append((char)i); } m.close(); //检查文本是否为英文 boolean isEnglish=Utils.getFlag("E", options); if(!isEnglish){ //只有汉字需要进行中文分词 Analyzer ikAnalyzer=new IKAnalyzer(); Reader reader=new StringReader(message.toString()); TokenStream stream=(TokenStream)ikAnalyzer.tokenStream("", reader); CharTermAttribute termAtt=(CharTermAttribute)stream.addAttribute(CharTermAttribute.class); message=new StringBuffer(); while(stream.incrementToken()){ message.append(termAtt.toString()+""); } ikAnalyzer.close(); } //检查是否已给定类别值 String classValue=Utils.getOption('c', options); //如果模型文件存在,则读入,否则创建新的模型文件 String modelName=Utils.getOption("t", options); if(modelName.length()==0){ throw new Exception("必须提供模型文件的名称"); } MessageClassifier messageCl; try { ObjectInputStream modelInObjectFile=new ObjectInputStream(new FileInputStream(modelName)); messageCl=(MessageClassifier)modelInObjectFile.readObject(); modelInObjectFile.close(); } catch (FileNotFoundException e) { messageCl=new MessageClassifier(); } //处理文本信息 if(classValue.length()!=0){ messageCl.updateData(message.toString(), classValue); }else{ messageCl.classifyMessage(message.toString()); } //保存文本信息分类器对象 ObjectOutputStream modelOutObjectFile=new ObjectOutputStream(new FileOutputStream(modelName)); modelOutObjectFile.writeObject(messageCl); modelOutObjectFile.close(); } catch (Exception e) { e.printStackTrace(); } } }
最近下载更多
xierhui LV6
2023年8月29日
15562126884 LV4
2021年4月18日
loveprograming LV1
2020年7月23日
噗噗猫MMM LV6
2020年6月11日
dc1323 LV3
2020年3月13日
shishunshun LV1
2020年3月5日
wjx985 LV2
2019年12月24日
yejiebao LV1
2019年9月14日
s2w2y2 LV3
2019年7月18日
可是不知道么 LV23
2019年5月23日
最近浏览更多
ljt289917726 LV3
2023年12月18日
xierhui LV6
2023年8月29日
胡明杨
2023年5月4日
暂无贡献等级
suiyibawokeyi
2022年6月5日
暂无贡献等级
holixie LV2
2022年5月3日
等你归来 LV2
2022年3月6日
gentleman1576 LV2
2021年12月4日
yinyun1985 LV14
2021年8月12日
1798672867 LV21
2021年7月18日
lxw804 LV2
2021年7月13日