Libsvm java工程實踐

在上篇文章中對libsvm的流程和簡單的java代碼測試作了說明,本篇簡單對libsvm如何在工程中實踐進行簡短說明,不當的地方歡迎你們指正。java

第一步是對libsvm的預測函數進行調整,我是從svm_predict類中抽取部分代碼組成預測防範,代碼以下:node

/**
     * 對傳入的文本特徵根據訓練好的分類模型進行分類
     * @param model 已經訓練好的模型
     * @param contentFeature    傳入的計算好的文本分詞後的特徵
     * @return
     */
    public static int libSvmPredict(svm_model model, String contentFeature){
        //默認分類類別爲-1
        int label = -1;
        //判斷傳入的文本特徵是否爲空
        if (contentFeature == null) return label;
        //對傳入的特徵進行切分
        StringTokenizer st = new StringTokenizer(contentFeature," \t\n\r\f:");
        //這裏target用不到,測試中會用到,即咱們測試語料的類別標籤
//        double target = atof(st.nextToken());
        int m = st.countTokens()/2;
        svm_node[] x = new svm_node[m];
        for(int j=0;j<m;j++)
        {
            x[j] = new svm_node();
            x[j].index = atoi(st.nextToken());
            x[j].value = atof(st.nextToken());
        }

        double v = svm.svm_predict(model,x);
        label = (int) v;
        return label;
    }
View Code

第二步對待分類的文本按照上篇文章中講到的方法根據terms詞表生成libsvm須要的格式,注意我這裏爲了方便僅作了詞的tf,idf默認都爲1,代碼以下:ide

/**
     * 獲取模型分詞用的term詞表
     * @param termsPath
     * @return
     */
    public static Map<String, Integer> getModelTerms(String termsPath){
        Map<String, Integer> termsMap = new HashMap<String, Integer>(  );
        try {
            String termsStr = FileOptionUtil.readFile( termsPath, "UTF-8" );
            if (termsStr != null){
                String[] terms = termsStr.split( "\r\n" );
                if (terms!=null && terms.length>0){
                    for (int i=0; i<terms.length; i++){
                        String term = terms[i];
                        String[] termM = term.split( "\t" );
                        if (termM!=null && termM.length==2){
                            termsMap.put( termM[0], Integer.parseInt(termM[1]) );
                        }
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return termsMap;
    }

    public static String getContentFeature(String content, Map<String, Integer> terms){
        String contentFature = "";
        //對傳入的文本進行分詞
        Map<String, Integer> contentTermsMap = HanLPAnalyser.segString( content );
        Map<Integer, Double> contentTfIdf = new TreeMap<Integer, Double>( new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1.compareTo( o2 );
            }
        } );
        //計算tf-idf,這裏咱們就用單存的tf代替tf-idf,idf值均爲1
        for (String word : contentTermsMap.keySet()){
            if (terms.containsKey( word )){
                contentTfIdf.put( terms.get( word ), getWordTF( word, contentTermsMap ) );
            }
        }

        for (Integer key : contentTfIdf.keySet()){
            contentFature += key + ":" + contentTfIdf.get( key ) + " ";
        }

        return contentFature.trim();
    }
View Code

第三步根據上述方法進行分類計算,main方法代碼以下:函數

public static void main(String[] args){
        String s = "&nbsp&nbsp&nbsp&nbsp依照上海證券交易所發佈的《關於證券公司創設白雲機場權證有關事項的\n" +
                "通知》,光大證券股份有限公司向上海證券交易所申請註銷白雲機場認沽權證並\n" +
                "已獲覈准,中國證券登記結算有限責任公司上海分公司已辦理相應登記手續。本\n" +
                "公司這次獲准註銷的白雲機場認沽權證數量爲1,500萬份,該權證的條款與原白\n" +
                "雲機場認沽權證(交易簡稱機場JTP一、交易代碼58099八、行權代碼582998)的條\n" +
                "款徹底相同。\n" +
                "&nbsp&nbsp&nbsp&nbsp\n";
        Map<String, Integer> terms = LibSvmDataProcess.getModelTerms( "/Users/zhouyh/work/yanfa/xunlianji/UTF8/heji/terms.txt" );
        String contentFeature = LibSvmDataProcess.getContentFeature( s, terms);
        svm_model model = GetSvmModel.getSvmModelInstance().getModel( "/Users/zhouyh/work/yanfa/xunlianji/UTF8/heji/model.txt" );
        int label = libSvmPredict(model, contentFeature);
        System.out.println(label);
    }
View Code

測試結果如圖,財經類和咱們選擇的語料類別也一致,以下圖所示:測試

 

最後,此代碼僅爲將libsvm如何在工程中實踐作了下流程走通,後續要在工程中使用,還須要作不少的調整。spa

相關文章
相關標籤/搜索