首頁 > 軟體

基於Java實現中文分詞系統的範例程式碼

2022-07-08 14:06:42

1.問題描述

中文分詞 (Chinese Word Segmentation) 指的是將一個漢字序列切分成一個一個單獨的詞。分詞就是將連續的字序列按照一定的規範重新組合成詞序列的過程。我們知道,在英文的行文中,單詞之間是以空格作為自然分界符的,而中文只是字、句和段能通過明顯的分界符來簡單劃界,唯獨詞沒有一個形式上的分界符,雖然英文也同樣存在短語的劃分問題,不過在詞這一層上,中文比之英文要複雜的多、困難的多。

而對於中文分詞也有很多種演演算法,基本演演算法主要分為基於詞典的方法、基於統計的方法和基於規則的方法。

基於詞典的方法是指按照一定策略將待分析的漢字串與一個“大機器詞典”中的詞條進行匹配,若在詞典中找到某個字串,則匹配成功。按照掃描方向的不同包括正向匹配和逆向匹配,按照長度的不同分為最大匹配和最小匹配。在基於詞典的方法中,我們採用了正向最大匹配和逆向最大匹配的方法進行分詞。

而基於統計的分詞方法,沒有詞典,主要思想是在上下文中,相鄰的字同時出現的次數越多,就越可能構成一個詞,因此字與字相鄰出現的概率或頻率能較好的反映詞的可信度。主要的統計模型包括N元文法模型(N-gram),隱馬爾科夫模型(Hidden Markov Model, HMM)。在基於統計的分詞方法中,我們使用了隱馬爾科夫模型來進行分詞。

基於規則的方法,主要思想就是通過模擬人對句子的理解,達到識別詞的效果,基本思想是語意分析,句法分析,利用句法資訊和語意資訊對文字進行分詞。自動推理,並完成對未登入詞的補充是其優點。但是這種方法現在發展還不成熟,需要繼續發展和研究。

因此在我們的中文分詞系統中,採用了基於詞典的方法:正向最大匹配和逆向最大匹配,以及基於統計的方法中的隱馬爾科夫(HMM)模型。

2.相關工作

現如今已經有很多的開源中分分詞系統,而且效果都還不錯。下面介紹幾種比較常見的中文分詞專案。

SCWS,Hightman開發的一套基於詞頻詞典的機械中文分詞引擎,它能將一整段的漢字基本正確的切分成詞。採用的是採集的詞頻詞典,並輔以一定的專有名稱,人名,地名,數位年代等規則識別來達到基本分詞,經小範圍測試大概準確率在 90% ~ 95% 之間,已能基本滿足一些小型搜尋引擎、關鍵字提取等場合運用。45Kb左右的文字切詞時間是0.026秒,大概是1.5MB文字/秒,支援PHP4和PHP 5。

ICTCLAS,這是最早的中文開源分詞專案之一,ICTCLAS在國內973專家組組織的評測中活動獲得了第一名,在第一屆國際中文處理研究機構SigHan組織的評測中都獲得了多項第一名。ICTCLAS3.0分詞速度單機996KB/s,分詞精度98.45%,API不超過200KB,各種詞典資料壓縮後不到3M。ICTCLAS全部採用C/C++編寫,支援Linux、FreeBSD及Windows系列作業系統,支援C/C++、C#、Delphi、Java等主流的開發語言。

HTTPCWS,是一款基於HTTP協定的開源中文分詞系統,目前僅支援Linux系統。HTTPCWS 使用“ICTCLAS 3.0 2009共用版中文分詞演演算法”的API進行分詞處理,得出分詞結果。HTTPCWS 將取代之前的 PHPCWS 中文分詞擴充套件。

3.系統框架和演演算法設計

3.1系統整體框架

系統主要包括選擇分詞演演算法和進行資料的測試。首先需要選擇進行分詞的演演算法,包括基於HMM模型的分詞演演算法,正向最大匹配分詞演演算法和逆向最大匹配分詞演演算法。選擇了分詞演演算法之後即可進行分詞操作。

若選擇的是基於HMM模型的分詞演演算法,需要先進行訓練集的訓練,得到訓練的統計資料,然後再進行資料測試。資料測試包括了檔案輸入測試,進行大規模資料的測試,也包括了直接輸入測試,測試一句話或多句話進行簡單測試。

對於正向最大匹配和逆向最大匹配則不需要進行訓練集的訓練,因為其是基於詞典的方法,需要詞典,而詞典我們已經事先載入程式中了。正向最大匹配和逆向最大匹配也包括了檔案輸入測試和直接輸入測試。

系統的整體框架如圖3-1所示。

部分程式碼如下:

package mainframe;
import hmm.hmmmain.hmmmain;

import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.StringTokenizer;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;

import lexicon.Segment;


@SuppressWarnings("serial")
public class CWS_frame extends JFrame{
	
	//定義元件
	JLabel label_title=new JLabel("CWJT中文分詞系統");
	
	JPanel algorithm_select_panel;
	JRadioButton algorithm_jrb_hmm;
	JRadioButton algorithm_jrb_zhengxiang;
	JRadioButton algorithm_jrb_nixiang;
	ButtonGroup bg_algorithm;
	
	JLabel label_showalgorithm=new JLabel("你選擇的演演算法是: 基於HMM模型");
	
	
	JPanel input_panel;
	
	JTabbedPane hmm_tabbe=new JTabbedPane();
	
	JPanel hmm_tabbe_pane_train=new JPanel();
	JPanel hmm_tabbe_pane_fileinput=new JPanel();
	JPanel hmm_tabbe_pane_input=new JPanel();
	
	
	JLabel label_train_title = new JLabel("選擇訓練集");
	static JTextField jTextField_train=new JTextField();
	JButton scan_train=new JButton("瀏覽檔案");
	JButton train_start=new JButton("點選訓練");
	
	JLabel label_test_title = new JLabel("選擇測試集");
	JLabel label_result_title = new JLabel("結果集儲存目錄");
	JButton scan_test=new JButton("瀏覽檔案");
	JButton scan_result=new JButton("瀏覽目錄");
	JButton test_start = new JButton("開始分詞");
	static JTextField jTextField_test=new JTextField();
	static JTextField jTextField_result=new JTextField();
	
	JLabel label_inputdata = new JLabel("輸入測試資料:");
	JTextArea textarea_input = new JTextArea();
	JLabel label_outputdata = new JLabel("輸出結果:");
	JTextArea textarea_ouptput = new JTextArea();
	JButton seg_start = new JButton("開始分詞");
	
	
	static JLabel label_wait ;
	JLabel label_train_wait;
	//定義一個定時器
	Timer wait_time = null, seg_threadtime=null;
	static int count_dot=0;
	Timer train_wait_time=null,train_time=null;
	int train_count_dot = 0;
	
	//設定卷軸用於裝簡訊內容文字域,使其產生卷軸效果
	JScrollPane scrollPane;
	JScrollPane outscrollPane;
	static JPanel main_panel; 
	
	//建構函式
	public CWS_frame(){
		
		setTitle("中文分詞系統");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setResizable(false);
		int width=550;
		int height=500;
		setSize(width,height);
		//設定表單在螢幕出現的位置
		setLocation(400, 100);
		
	
		//設定title
		int label_title_x=200;
		int label_title_y=25;
		int label_title_width=250;
		int label_title_height=30;
		
		int label_train_x=60;
		int label_train_y=50;
		int label_train_width=80;
		int label_train_height=25;
		
		int label_test_x=50;
		int label_test_y=40;
		int label_test_width=100;
		int label_test_height=25;
		
		int label_result_x=50;
		int label_result_y=70;
		int label_result_width=100;
		int label_result_height=25;
		
		int JTextField_train_x=140;
		int JTextField_train_y=50;
		int JTextField_train_width=150;
		int JTextField_train_height=25;
		
		int JTextField_test_x=150;
		int JTextField_test_y=40;
		int JTextField_test_width=150;
		int JTextField_test_height=25;
		
		int JTextField_result_x=150;
		int JTextField_result_y=70;
		int JTextField_result_width=150;
		int JTextField_result_height=25;
		
		
		int alg_select_x=40;
		int alg_select_y=60;
		int alg_select_width=450;
		int alg_select_height=80;
		
		int label_showalg_x=180;
		int label_showalg_y=140;
		int label_showalg_width=200;
		int label_showalg_height=20;
		
		int input_x=40;
		int input_y=170;
		int input_width=450;
		int input_height=250; 
		
		int scan_train_x=300;
		int scan_train_y=50;
		int scan_train_width=80;
		int scan_train_height=23;
		
		int train_start_x=180;
		int train_start_y=110;
		int train_start_width=90;
		int train_start_height=25;
		
		int test_start_x=180;
		int test_start_y=130;
		int test_start_width=90;
		int test_start_height=25;
		
		int scan_test_x=310;
		int scan_test_y=40;
		int scan_test_width=80;
		int scan_test_height=23;
		
		int scan_result_x=310;
		int scan_result_y=70;
		int scan_result_width=80;
		int scan_result_height=23;
		
		int label_inputdata_x=20;
		int label_inputdata_y=10;
		int label_inputdata_width=100;
		int label_inputdata_height=20;
		
		int textarea_input_x=20;
		int textarea_input_y=30;
		int textarea_input_width=180;
		int textarea_input_height=120;
		
		int label_outputdata_x=230;
		int label_outputdata_y=10;
		int label_outputdata_width=100;
		int label_outputdata_height=20;
		
		int textarea_output_x=230;
		int textarea_output_y=30;
		int textarea_output_width=180;
		int textarea_output_height=120;
		
		int seg_start_x=180;
		int seg_start_y=160;
		int seg_start_width=90;
		int seg_start_height=25;
		
		int label_wait_x=170;
		int label_wait_y=160;
		int label_wait_width=120;
		int label_wait_height=25;
		
		int label_train_wait_x=170;
		int label_train_wait_y=150;
		int label_train_wait_width=120;
		int label_train_wait_height=25;
		
		main_panel=new JPanel();
		//main_panel.setLayout(new FlowLayout(FlowLayout.CENTER,10,10));
		main_panel.setLayout(null);
		
		algorithm_select_panel=new JPanel();
		algorithm_select_panel.setBorder(new TitledBorder(new EtchedBorder(), "選擇分詞演演算法"));
		bg_algorithm=new ButtonGroup();
		
		algorithm_jrb_hmm=new JRadioButton("基於HMM模型");
		algorithm_jrb_zhengxiang=new JRadioButton("正向最大匹配");
		algorithm_jrb_nixiang=new JRadioButton("逆向最大匹配");
		algorithm_jrb_hmm.setSelected(true);
		bg_algorithm.add(algorithm_jrb_hmm);
		bg_algorithm.add(algorithm_jrb_zhengxiang);
		bg_algorithm.add(algorithm_jrb_nixiang);
		
		
		input_panel=new JPanel();
		//input_panel.setLayout(null);
		input_panel.setLayout(new GridLayout(1, 1));
		input_panel.setBorder(new TitledBorder(new EtchedBorder(), "輸入資料"));
		
		scrollPane=new JScrollPane(textarea_input);
		outscrollPane=new JScrollPane(textarea_ouptput);
		textarea_ouptput.setEnabled(false);
		hmm_tabbe_pane_train.setLayout(null);
		hmm_tabbe_pane_fileinput.setLayout(null);
		hmm_tabbe_pane_input.setLayout(null);
		hmm_tabbe.addTab("使用訓練集訓練", hmm_tabbe_pane_train);
		hmm_tabbe.addTab("檔案輸入測試集", hmm_tabbe_pane_fileinput);
		hmm_tabbe.addTab("直接輸入測試資料", hmm_tabbe_pane_input);
		//hmm_tabbe.setTabPlacement(LEFT_ALIGNMENT);
		label_title.setFont(new Font("",Font.BOLD,15));
		
		label_wait = new JLabel("");
		label_train_wait=new JLabel("");
		//定位
		label_title.setBounds(label_title_x, label_title_y, label_title_width, label_title_height);
		
		
		algorithm_select_panel.setBounds(alg_select_x, alg_select_y, alg_select_width, alg_select_height);		
		label_showalgorithm.setBounds(label_showalg_x, label_showalg_y, label_showalg_width, label_showalg_height);
		input_panel.setBounds(input_x, input_y, input_width, input_height);
		//algorithm_jrb_hmm.setLocation(alg_hmm_x, alg_hmm_y);
	//	algorithm_jrb_hmm.setBounds(alg_hmm_x, alg_hmm_y, alg_hmm_width, alg_hmm_height);
	//	algorithm_jrb_zhengxiang.setBounds(alg_zhengxiang_x, alg_zhengxiang_y, alg_zhengxiang_width, alg_zhengxiang_height);
		label_train_title.setBounds(label_train_x, label_train_y, label_train_width, label_train_height);
		label_test_title.setBounds(label_test_x, label_test_y, label_test_width, label_test_height);
		label_result_title.setBounds(label_result_x, label_result_y, label_result_width, label_result_height);
		jTextField_train.setBounds(JTextField_train_x, JTextField_train_y, JTextField_train_width, JTextField_train_height);
		jTextField_test.setBounds(JTextField_test_x, JTextField_test_y, JTextField_test_width, JTextField_test_height);
		jTextField_result.setBounds(JTextField_result_x, JTextField_result_y, JTextField_result_width, JTextField_result_height);
		
		scan_train.setBounds(scan_train_x, scan_train_y, scan_train_width, scan_train_height);
		train_start.setBounds(train_start_x, train_start_y, train_start_width, train_start_height);
		scan_result.setBounds(scan_result_x, scan_result_y, scan_result_width, scan_result_height);
		scan_test.setBounds(scan_test_x, scan_test_y, scan_test_width, scan_test_height);
		test_start.setBounds(test_start_x, test_start_y, test_start_width, test_start_height);
		
		label_inputdata.setBounds(label_inputdata_x, label_inputdata_y, label_inputdata_width, label_inputdata_height);
		scrollPane.setBounds(textarea_input_x, textarea_input_y, textarea_input_width, textarea_input_height);
		label_outputdata.setBounds(label_outputdata_x, label_outputdata_y, label_outputdata_width, label_outputdata_height);
		outscrollPane.setBounds(textarea_output_x, textarea_output_y, textarea_output_width, textarea_output_height);
		seg_start.setBounds(seg_start_x, seg_start_y, seg_start_width, seg_start_height);
		
		label_wait.setBounds(label_wait_x, label_wait_y, label_wait_width, label_wait_height);
		label_train_wait.setBounds(label_train_wait_x, label_train_wait_y, label_train_wait_width, label_train_wait_height);
		//將元件加入到容器中
		main_panel.add(label_title);
		main_panel.add(algorithm_select_panel);
		main_panel.add(input_panel);
		
		algorithm_select_panel.add(algorithm_jrb_hmm);
		algorithm_select_panel.add(algorithm_jrb_zhengxiang);
		algorithm_select_panel.add(algorithm_jrb_nixiang);
		input_panel.add(hmm_tabbe);
		hmm_tabbe_pane_train.add(label_train_title);
		hmm_tabbe_pane_train.add(jTextField_train);
		hmm_tabbe_pane_train.add(scan_train);
		hmm_tabbe_pane_train.add(train_start);
		hmm_tabbe_pane_train.add(label_train_wait);
		
		hmm_tabbe_pane_fileinput.add(label_test_title);
		hmm_tabbe_pane_fileinput.add(label_result_title);
		hmm_tabbe_pane_fileinput.add(test_start);
		hmm_tabbe_pane_fileinput.add(scan_test);
		hmm_tabbe_pane_fileinput.add(scan_result);
		hmm_tabbe_pane_fileinput.add(jTextField_test);
		hmm_tabbe_pane_fileinput.add(jTextField_result);
		hmm_tabbe_pane_fileinput.add(label_wait);
		
		hmm_tabbe_pane_input.add(label_inputdata);
		hmm_tabbe_pane_input.add(scrollPane);
		hmm_tabbe_pane_input.add(label_outputdata);
		hmm_tabbe_pane_input.add(outscrollPane);
		hmm_tabbe_pane_input.add(seg_start);
		
		main_panel.add(label_showalgorithm);
		//將容器加入到表單中
		add(main_panel);
		
	/*	wait_time = new Timer(500,new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				if(count_dot==0)
					label_wait.setText("正在分詞,請稍等");
				else if(count_dot==1)
					label_wait.setText("正在分詞,請稍等.");
				else if(count_dot==2)
					label_wait.setText("正在分詞,請稍等. .");
				else if(count_dot==3)
					label_wait.setText("正在分詞,請稍等. . .");
				
				JOptionPane.showMessageDialog(null,
	                    "test","提示",
	                    JOptionPane.INFORMATION_MESSAGE);
				
				//count_dot=(count_dot+1)%4;
			//	System.out.println(count_dot);
			}
		});*/
		
		algorithm_jrb_hmm.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				if(algorithm_jrb_hmm.isSelected()){
					label_showalgorithm.setText("你選擇的演演算法是: 基於HMM模型");
					
					hmm_tabbe.removeAll();
					hmm_tabbe.addTab("使用訓練集訓練", hmm_tabbe_pane_train);
					hmm_tabbe.addTab("檔案輸入測試集", hmm_tabbe_pane_fileinput);
					hmm_tabbe.addTab("直接輸入測試資料", hmm_tabbe_pane_input);
					hmm_tabbe.revalidate(); 
					hmm_tabbe.repaint();
					
				}
				if(algorithm_jrb_zhengxiang.isSelected()){
					
					label_showalgorithm.setText("你選擇的演演算法是: 正向最大匹配");
					
					
				}
				if(algorithm_jrb_nixiang.isSelected()){
					label_showalgorithm.setText("你選擇的演演算法是: 逆向最大匹配");
				} 
			}
		});
		
		algorithm_jrb_zhengxiang.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				if(algorithm_jrb_hmm.isSelected()){
					label_showalgorithm.setText("你選擇的演演算法是: 基於HMM模型");
				}
				if(algorithm_jrb_zhengxiang.isSelected()){
					label_showalgorithm.setText("你選擇的演演算法是: 正向最大匹配");
					
					hmm_tabbe.removeAll();
					//hmm_tabbe.addTab("使用訓練集訓練", hmm_tabbe_pane_train);
					hmm_tabbe.addTab("檔案輸入測試集", hmm_tabbe_pane_fileinput);
					hmm_tabbe.addTab("直接輸入測試資料", hmm_tabbe_pane_input);
					hmm_tabbe.revalidate(); 
					hmm_tabbe.repaint();
					
				}
				if(algorithm_jrb_nixiang.isSelected()){
					label_showalgorithm.setText("你選擇的演演算法是: 逆向最大匹配");
				}
			}
		});
		
		algorithm_jrb_nixiang.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				if(algorithm_jrb_hmm.isSelected()){
					label_showalgorithm.setText("你選擇的演演算法是: 基於HMM模型");
				}
				if(algorithm_jrb_zhengxiang.isSelected()){
					label_showalgorithm.setText("你選擇的演演算法是: 正向最大匹配");
				}
				if(algorithm_jrb_nixiang.isSelected()){
					label_showalgorithm.setText("你選擇的演演算法是: 逆向最大匹配");
					
					hmm_tabbe.removeAll();
					//hmm_tabbe.addTab("使用訓練集訓練", hmm_tabbe_pane_train);
					hmm_tabbe.addTab("檔案輸入測試集", hmm_tabbe_pane_fileinput);
					hmm_tabbe.addTab("直接輸入測試資料", hmm_tabbe_pane_input);
					hmm_tabbe.revalidate(); 
					hmm_tabbe.repaint();
				}
			}
		});
		//輸入hmm模型的訓練集檔案進行訓練
		scan_train.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				File dicFile = openFile();
				if(dicFile == null)
					return;
				
				
				jTextField_train.setText(dicFile.getAbsolutePath());
				//寫要執行的操作
				//loadDic(dicFile);
				
				
				return;
			}
		});
		//輸入測試集檔案
		scan_test.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				
				File dicFile = openFile();
				if(dicFile == null)
					return;
				
				
				jTextField_test.setText(dicFile.getAbsolutePath());
			}
		});
		//輸入儲存結果集目錄
		scan_result.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				File dicDir = openDir();
				if(dicDir == null)
					return;
				
				
				jTextField_result.setText(dicDir.getAbsolutePath());
			}
		});
		
		//點選通過選擇輸入檔案進行分詞的按鈕,通過載入測試集檔案進行大規模資料的分詞
		test_start.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				String temp_test_str = jTextField_test.getText();
				if(temp_test_str.equals("")){
					JOptionPane.showMessageDialog(null,
		                    "請選擇測試集檔案!","提示",
		                    JOptionPane.INFORMATION_MESSAGE);
					return ;
				}
				
				String temp_result_str = jTextField_result.getText();
				if(temp_result_str.equals("")){
					JOptionPane.showMessageDialog(null,
		                    "請選擇儲存結果集目錄!","提示",
		                    JOptionPane.INFORMATION_MESSAGE);
					return ;
				}
				
				count_dot = 0;
				//有兩種定義定時器的方法,分別在不同的java包內
				//定義等待提示的定時器
				wait_time=new Timer(true);
				TimerTask task=new TimerTask() {
					
					@Override
					public void run() {
						// TODO Auto-generated method stub
						label_wait.setText(wait_seg());
					//	 System.out.println(wait_seg());  
					}
				};
				
				wait_time.schedule(task, 0, 1000);
				//再定義個定時器,相當於再開一個執行緒
				seg_threadtime = new Timer(true);
				TimerTask task2 = new TimerTask() {
					
					@Override
					public void run() {
						// TODO Auto-generated method stub
						//進行分詞
						Segmentation();
					}
				};
				seg_threadtime.schedule(task2, 0);
		
				
			}
		});
		
		//通過直接輸入資料進行分詞
		seg_start.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				String jtextarea_str = textarea_input.getText();
				
				if(jtextarea_str.equals("")){
					JOptionPane.showMessageDialog(null,
		                    "請輸入要測試的資料!","提示",
		                    JOptionPane.INFORMATION_MESSAGE);
					return ;
				}
				
				if(algorithm_jrb_zhengxiang.isSelected()||algorithm_jrb_nixiang.isSelected()){
					
					//token,沒有指定分隔符預設情況下是空格換行等
					StringTokenizer tokens = new StringTokenizer(jtextarea_str);
					//建立分詞類的物件
					Segment seg=new Segment();
					String output_str="";
					while(tokens.hasMoreElements()){
						//System.out.println(tokens.nextToken());
						String temp_str=tokens.nextToken();
						String temp_seg="";
						//如果選中的是最大正向匹配
						if(algorithm_jrb_zhengxiang.isSelected()){
							
							temp_seg=seg.forwardSegment(temp_str);
						}
						//如果選中的是最大逆向匹配
						if(algorithm_jrb_nixiang.isSelected()){
							temp_seg=seg.backwardSegment(temp_str);
						}
						
						output_str += temp_seg;
						output_str += "n";
						
					}
					textarea_ouptput.setText(output_str);
				}
				
				//使用hmm模型進行分詞
				if(algorithm_jrb_hmm.isSelected()){
				//	String jtextarea_str = textarea_input.getText();
					//System.out.println(testfile);
					String output="";
					hmmmain hmmmodel = new hmmmain();
					output = hmmmodel.Inputtest(jtextarea_str);
					textarea_ouptput.setText(output);
					
				}
			}
		});
		
		
		//hmm模型訓練
		train_start.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				
				String temp_train_str = jTextField_train.getText();
				if(temp_train_str.equals("")){
					JOptionPane.showMessageDialog(null,
		                    "請選擇訓練集檔案!","提示",
		                    JOptionPane.INFORMATION_MESSAGE);
					return ;
				}
				
				train_count_dot = 0;
				//定義等待提示的定時器
				train_wait_time=new Timer(true);
				TimerTask task=new TimerTask() {
					
					@Override
					public void run() {
						// TODO Auto-generated method stub
						label_train_wait.setText(train_wait());
					//	 System.out.println(wait_seg());  
					}
				};
				
				train_wait_time.schedule(task, 0, 500);
				//再定義個定時器,相當於再開一個執行緒
				train_time = new Timer(true);
				TimerTask task2 = new TimerTask() {
					
					@Override
					public void run() {
						// TODO Auto-generated method stub
						//進行訓練
						hmmmain hmmmodel = new hmmmain();
						String train_str = jTextField_train.getText();
						hmmmodel.Trainset(train_str);
						
						JOptionPane.showMessageDialog(null,
			                    "訓練結束,可進行分詞","提示",
			                    JOptionPane.INFORMATION_MESSAGE);
						
						label_train_wait.setText("");
						train_wait_time.cancel();
					}
				};
				train_time.schedule(task2, 0);
				
				return ;
			}
		});
	}
	

	//同步
	public static synchronized String wait_seg(){  
		String show_wait = "";
		if(count_dot==0)
			show_wait = "正在分詞,請稍等";
	//		label_wait.setText("正在分詞,請稍等");
		else if(count_dot==1)
			show_wait = "正在分詞,請稍等.";
		//	label_wait.setText("正在分詞,請稍等.");
		else if(count_dot==2)
			show_wait = "正在分詞,請稍等. .";
		//	label_wait.setText("正在分詞,請稍等. .");
		else if(count_dot==3)
			show_wait = "正在分詞,請稍等. . .";
		//	label_wait.setText("正在分詞,請稍等. . .");
		count_dot = (count_dot+1)%4;
      //  System.out.println(count_dot);  
		return show_wait;
		//repaint();
		//revalidate();
	//	JOptionPane.showMessageDialog(null,
      //          "test","提示",
     //           JOptionPane.INFORMATION_MESSAGE);
		
    }
	
	
	public synchronized String train_wait(){
		String show_wait = "";
		if(train_count_dot==0)
			show_wait = "正在訓練,請稍等";
		else if(train_count_dot==1)
			show_wait = "正在訓練,請稍等.";
		else if(train_count_dot==2)
			show_wait = "正在訓練,請稍等. .";
		else if(train_count_dot==3)
			show_wait = "正在訓練,請稍等. . .";
		train_count_dot = (train_count_dot+1)%4;
		return show_wait;
	}
	//通過輸入測試集檔案進行大規模資料的分詞
	private void Segmentation(){
		if(algorithm_jrb_zhengxiang.isSelected()||algorithm_jrb_nixiang.isSelected()){

			//建立分詞類的物件
			Segment seg=new Segment();
			InputStreamReader inputdata;
			BufferedReader in;
			String str;
			String testfile=jTextField_test.getText();
			System.out.println(testfile);
			String resultdir=jTextField_result.getText();
			try {
				inputdata = new InputStreamReader (new FileInputStream(testfile),"UTF-8");
				in = new BufferedReader(inputdata);
				FileOutputStream out = null;
				resultdir += "\CWS_truth_utf8";
				out = new FileOutputStream(new File(resultdir));  
				while((str=in.readLine())!= null){
					String temp_seg="";
					if(algorithm_jrb_zhengxiang.isSelected()){
						temp_seg=seg.forwardSegment(str);
					}
					if(algorithm_jrb_nixiang.isSelected()){
						temp_seg=seg.backwardSegment(str);
					}
					
					out.write(temp_seg.getBytes("UTF-8"));   
					out.write("rn".getBytes("UTF-8"));
				}
				//關閉定時器
			//	wait_time.stop();
				inputdata.close();
				out.close();
				
				JOptionPane.showMessageDialog(null,
	                    "分詞結束,請在"+resultdir+"查詢","提示",
	                    JOptionPane.INFORMATION_MESSAGE);
				
			} catch (UnsupportedEncodingException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			} catch (FileNotFoundException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
		
		//使用hmm模型進行分詞
		if(algorithm_jrb_hmm.isSelected()){
			String testfile=jTextField_test.getText();
			//System.out.println(testfile);
			String resultdir=jTextField_result.getText();
			resultdir += "\CWS_truth_utf8";
			hmmmain hmmmodel = new hmmmain();
			hmmmodel.Testset(testfile, resultdir);
			JOptionPane.showMessageDialog(null,
                    "分詞結束,請在"+resultdir+"查詢","提示",
                    JOptionPane.INFORMATION_MESSAGE);
		}
		
		//
		label_wait.setText("");
		wait_time.cancel();
	}
	
	//開啟檔案(資料、詞典或者語料庫)
	private File openFile(){
		JFileChooser chooser = new JFileChooser();//檔案選擇對話方塊
        int ret = chooser.showOpenDialog(this);

        if (ret != JFileChooser.APPROVE_OPTION) {
        	return null;
        }

        File f = chooser.getSelectedFile();
        if (f.isFile() && f.canRead()) 
        {
        	return f;
        } 
        else 
        {
            JOptionPane.showMessageDialog(this,
                    "Could not open file: " + f,
                    "Error opening file",
                    JOptionPane.ERROR_MESSAGE);
            return null;
        }
        
	}
	
	//開啟目錄
	private File openDir(){
		JFileChooser parseDir = new JFileChooser();
	    parseDir.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
	    int ret = parseDir.showOpenDialog(this);
	    if(ret !=JFileChooser.APPROVE_OPTION)
	    	return null;
	    
	    File f=parseDir.getSelectedFile();
	    if(f.exists())
	    	return f;
	    else{
	    	JOptionPane.showMessageDialog(this,
                    "Could not open directory: " + f,
                    "Error opening directory",
                    JOptionPane.ERROR_MESSAGE);
            return null;
	    }
	}
	
	
	//重寫JPanel容器新增背景圖片
	class MainPanel extends JPanel{

		ImageIcon background = new ImageIcon("images\backimg.jpg");//載入圖片
		Image im=Toolkit.getDefaultToolkit().getImage("images\backimg.jpg");
		public void paintComponent(Graphics g) {
		g.drawImage(im, 0, 0, this);
		}
	}
	
	
}

效果圖展示 

到此這篇關於基於Java實現中文分詞系統的範例程式碼的文章就介紹到這了,更多相關Java中文分詞系統內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com