採用Weka中的KNN算法進行文本分類

      Weka是新西蘭Waikato大學開發的一款開源的基於Java的數據挖掘工具,其官方網址爲http://www.cs.waikato.ac.nz/ml/weka/。Weka作爲一個公共的數據挖掘的平臺,集成了大量的機器學習的算法,包括對數據進行預處理、分類、聚類、迴歸關聯規則等。Weka支持可視化界面操作以及API方式的調用,本文采用API調用方式,基於Weka中集成的KNN算法進行文本分類。

1.語料預處理

        文本分類作爲監督學習的一種需要提供訓練語料,對每一個輸入語料文本進行分詞處理。

2.特徵屬性的選取

        對於所有的輸入語料中的詞語,計算其TF*IDF數值,並對每一個詞語根據其TF*IDF的數值由高到低排序,選取TOP N(此處N=200)的詞語作爲特徵詞語。

3.每一篇語料文檔的處理

       根據上面統計處理的特徵詞語,計算每一篇文章中特徵詞語的TF*IDF數值。

4.CSV文件的生產

        CSV文件中每一個語料文本作爲一行,形如下圖所示:

        其中第一行的數據爲特徵屬性,第一列爲語料的類別屬性。

5.CSV文件轉爲ARFF文件

        在此Weka最終接收的格式爲ARFF文件,因此我先把CSV文件轉爲ARFF文件。ARFF文件格式如下:

        其中@relation traindata表示關心的名稱 ,@attribute class {food,military,sports,computer,economy}表示類別屬性可以的取值,@attribute 農夫山 numeric表示類別屬性,@data以下的內容表示對應特徵屬性的取值。
        首先生成ARFF文件的屬性信息
			InputStreamReader isr = new InputStreamReader(new FileInputStream(csvFile), "UTF-8");
			BufferedReader in = new BufferedReader(isr);
			String lineStr = in.readLine();
			FastVector atts = new FastVector();
			List attsList = new ArrayList<Attribute>();
			int attrLen = 0;
			FastVector attVals = new FastVector();
			File clsTypeFile = new File(GlobalUtil.CORPUS_CLS_TYPE);
			List<String> clsTypeList = readCorpusFileList(clsTypeFile);
			List<String> attrList = new ArrayList<String>();//存放數據所有的屬性
			if(lineStr!= null){
				String[] attr = lineStr.split(",");
				attrList = Arrays.asList(attr);
				for(String clsType : clsTypeList){
					attVals.addElement(clsType);
				}
				String clsAttr = attr[0];
				Attribute classAtts = new Attribute(clsAttr, attVals);
				atts.addElement(classAtts);
				attsList.add(classAtts);
				for(int i = 1;i < attr.length; i++){
					Attribute headAtts = new Attribute(attr[i]);
					atts.addElement(headAtts);
					attsList.add(headAtts);
				}
				
			}
        讀取CSV文件中第一行的內容(特徵屬性所在行),依次生成每一個特徵屬性。
       下面的代碼生成Instance實例,設置關係名稱以及類別屬性所在列。
			Instances instances = new Instances("traindata", atts, 0);
			instances.setClassIndex(0);
         然後依次讀取每一篇語料文本的特徵值,爲對應的特徵屬性賦值。
			while (lineStr != null) {
				if (!lineStr.trim().equals("")) {
					logger.info("當前處理的數據是: "+lineStr);
					Instance inst = new Instance(attrLen);
					String[] dataValue = lineStr.split(",");
					Attribute firstAtt = attsList.get(0);
					String firstVal = dataValue[0];
					inst.setValue(firstAtt, firstVal);
					for(int k = 1; k < attrLen; k++ ){
						Attribute numAttr = attsList.get(k);
						double numVal = Double.parseDouble(dataValue[k]);
						inst.setValue(numAttr, numVal);
					}
					instances.add(inst);
				}
				lineStr = in.readLine();
			}

6.採用Weka中的KNN算法處理ARFF文件

       KNN算法在Weka中對應的類名稱爲IBK,首先讀取ARFF文件
			
			File inputFile = new File(GlobalUtil.ARFF_FILE_NAME);// 訓練語料文件
			ArffLoader arffLoader = new ArffLoader();
			arffLoader.setFile(inputFile);
      加載KNN,設置需要考察的最近鄰的數目,進行分類處理。
			IBk classifier = (IBk)Class.forName("weka.classifiers.lazy.IBk").newInstance();//KNN算法分類器
			classifier.setKNN(GlobalUtil.NEIGHBOR_NUMS);
			classifier.buildClassifier(instancesTrain);
      此處我將生成的分類信息保存爲模型文件儲存起來,方便下次直接進行分類處理,而不必再次進行分類器的訓練。
SerializationHelper.write(GlobalUtil.MODEL_FILE_NAME , classifier);//將訓練結果保存爲模型文件
       也可以直接進行分類處理,以當前文件爲訓練文件,另外選取測試文件進行分類結果測試。
			for (int i = 0; i < sum; i++){// 測試分類結果
				int preIndex = i + 1;
				logger.info("第"+ preIndex +"個樣本的判斷結果是:" + classifier.classifyInstance(instancesTest.instance(i)));
				logger.info("第"+ preIndex +"個樣本的類別屬性是:" + instancesTest.instance(i).classValue());
				boolean flag = false;
				
				if (classifier.classifyInstance(instancesTest.instance(i)) == instancesTest.instance(i).classValue()){// 如果預測值和答案值相等(測試語料中的分類列提供的須爲正確答案,結果纔有意義)
					right++;// 正確值加1
					flag = true;
				}
				logger.info("第"+ preIndex +"個樣本的判斷結果是否正確:" + flag);
			}
			System.out.println("KNN classification precision:" + (right / sum));
至此分類處理完成。
發佈了46 篇原創文章 · 獲贊 14 · 訪問量 34萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章