📄 detreesvmdlg.cpp
字号:
/*==========================================================
*
* Copyright (c) 2008
* All rights reserved.
*
* 文件名称: DeTreeSVMDlg.cpp
* 摘 要: 主对话框
*
* 当前版本: 1.0
* 作 者: 祝美莲
* 创建日期: 2008-5-10
*
*==========================================================
*/
// DeTreeSVMDlg.cpp : implementation file
//
#include "stdafx.h"
#include "DeTreeSVM.h"
#include "DeTreeSVMDlg.h"
#include "EvaluateDlg.h"
#include "WaitDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
extern CDeTreeSVMDlg *p;
/////////////////////////////////////////////////////////////////////////////
// CDeTreeSVMDlg dialog
CDeTreeSVMDlg::CDeTreeSVMDlg(CWnd* pParent /*=NULL*/)
: CDialog(CDeTreeSVMDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CDeTreeSVMDlg)
//}}AFX_DATA_INIT
m_pToolTip = NULL;//显示提示信息
}
CDeTreeSVMDlg::~CDeTreeSVMDlg()
{
if(m_pToolTip)
delete m_pToolTip; //添加一个析构函数,清理之前申请的内存。
}
/********************************************************************
// 创建日期 : 2008-5-19 16:11:51
// 作 者 : 祝美莲<zml123818@163.com>
// 函数名称 : CDeTreeSVMDlg::DoDataExchange
// 函数功能 : 控件与变量转换
// 返回类型 : void
// 函数参数 : CDataExchange* pDX
********************************************************************/
void CDeTreeSVMDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDeTreeSVMDlg)
DDX_Control(pDX, IDC_TREE, m_TreeCtrl);
DDX_Control(pDX, IDC_LIST, m_listCtrl);
DDX_Control(pDX, IDC_PROGRESS, m_progress);
DDX_Control(pDX, IDCANCEL, m_ButtonCancel);
DDX_Control(pDX, IDC_BUTTON_EVA, m_Button_Eva);
DDX_Control(pDX, IDC_BUTTON_TRAIN, m_Button_Train);
DDX_Control(pDX, IDC_BUTTON_TEST, m_Button_Test);
DDX_Control(pDX, IDC_BUTTON_DISPLAY, m_Button_Display);
DDX_Control(pDX, IDC_BUTTON_READTRAINSET, m_Button_Read);
DDX_Text(pDX, IDC_STATIC_TEXT, m_strText);
DDX_Text(pDX, IDC_STATIC_TIME, m_time);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CDeTreeSVMDlg, CDialog)
//{{AFX_MSG_MAP(CDeTreeSVMDlg)
ON_BN_CLICKED(IDC_BUTTON_READTRAINSET, OnButtonReadtrainset)
ON_BN_CLICKED(IDC_BUTTON_EVA, OnButtonEva)
ON_BN_CLICKED(IDC_BUTTON_DISPLAY, OnButtonDisplay)
ON_BN_CLICKED(IDC_BUTTON_TEST, OnButtonTest)
ON_BN_CLICKED(IDC_BUTTON_TRAIN, OnButtonTrain)
ON_NOTIFY(NM_DBLCLK, IDC_TREE, OnDblclkTree)
ON_NOTIFY(NM_DBLCLK, IDC_LIST, OnDblclkList)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDeTreeSVMDlg message handlers
/********************************************************************
// 创建日期 : 2008-5-19 16:12:42
// 作 者 : 祝美莲<zml123818@163.com>
// 函数名称 : CDeTreeSVMDlg::OnButtonDisplay
// 函数功能 : 显示分类结果,主要是显示分类后每类网页的个数
// 返回类型 : void
********************************************************************/
void CDeTreeSVMDlg::OnButtonDisplay()
{
// TODO: Add your control notification handler code here
//删除表头
int nHeadNum = m_listCtrl.GetHeaderCtrl()->GetItemCount();
//因为表头会自动向前添加,所以要从后向前删除
for(int i=nHeadNum-1;i>=0;i--)
m_listCtrl.DeleteColumn(i);
m_listCtrl.DeleteAllItems();//显示之前先清空列表
//重设表头
m_listCtrl.InsertColumn(0,"网页类别",LVCFMT_IMAGE|LVCFMT_CENTER);
m_listCtrl.SetColumnWidth(0,155);
m_listCtrl.InsertColumn(1," 网页数目统计",LVCFMT_CENTER);
m_listCtrl.SetColumnWidth(1,160);
CString str;
CImageList m_l;
m_l.Create(1,25,TRUE|ILC_COLOR32,1,0);
m_listCtrl.SetImageList(&m_l,LVSIL_SMALL); //设置行高
char pBuf[MAX_PATH];//存放路径的变量
char pBuf0[MAX_PATH];
int sum=0,nFileNumber=0;
strcpy(pBuf,pPath);
strcat(pBuf,"\\结果文件夹\\");
//添加第一行
int nItem=m_listCtrl.InsertItem(1,"教育类网页");
//设置路径
strcpy(pBuf0,pBuf);
strcat(pBuf0,"1类网页");
//获得文件个数
nFileNumber = GetFileNumber(pBuf0);
sum += nFileNumber;
str.Format("%d",nFileNumber);
str=str+"个网页";
//输出显示
m_listCtrl.SetItemText(nItem, 1, str);
//添加第二行
nItem=m_listCtrl.InsertItem(2,"娱乐类网页");
//设置路径
str.Empty();
strcpy(pBuf0,pBuf);
strcat(pBuf0,"2类网页");
//获得文件个数
nFileNumber = GetFileNumber(pBuf0);
sum += nFileNumber;
str.Format("%d",nFileNumber);
str=str+"个网页";
//输出显示
m_listCtrl.SetItemText(nItem, 1, str);
//添加第三行
nItem=m_listCtrl.InsertItem(3,"时尚类网页");
//设置路径
str.Empty();
strcpy(pBuf0,pBuf);
strcat(pBuf0,"3类网页");
//获得文件个数
nFileNumber = GetFileNumber(pBuf0);
sum += nFileNumber;
str.Format("%d",nFileNumber);
str=str+"个网页";
//输出显示
m_listCtrl.SetItemText(nItem, 1, str);
//添加第四行
nItem=m_listCtrl.InsertItem(4,"计算机类网页");
//设置路径
str.Empty();
strcpy(pBuf0,pBuf);
strcat(pBuf0,"4类网页");
//获得文件个数
nFileNumber = GetFileNumber(pBuf0);
sum += nFileNumber;
str.Format("%d",nFileNumber);
str=str+"个网页";
//输出显示
m_listCtrl.SetItemText(nItem, 1, str);
//添加总的网页个数
nItem=m_listCtrl.InsertItem(5,"测试集网页总数");
//获得文件个数
str.Format("%d",sum);
str=str+"个网页";
//输出显示
m_listCtrl.SetItemText(nItem, 1, str);
}
/********************************************************************
// 创建日期 : 2008-5-19 16:19:03
// 作 者 : 祝美莲<zml123818@163.com>
// 函数名称 : CDeTreeSVMDlg::OnButtonReadtrainset
// 函数功能 : 读取特征向量表示的训练集
// 返回类型 : void
********************************************************************/
void CDeTreeSVMDlg::OnButtonReadtrainset()
{
// TODO: Add your control notification handler code here
m_strText = "选择训练集......";
UpdateData(FALSE);//更新显示
CString str;
str = pPath;
str = str + "\\训练集\\train.txt";
//打开文件对话框
CFileDialog dlg(TRUE, NULL, str, NULL , "Train Files(.txt)|*.txt|All files|*.*||");
if( dlg.DoModal() == IDOK )
{
//得到训练集的存放地址
m_strPath = dlg.GetPathName();
m_strText = "读取训练集......";
UpdateData(FALSE);
//设置进度条
m_progress.SetRange(0,127);//设置进度条的范围
m_progress.SetPos(0);
//变量初始化
nPageNumber = 0;
nVectorItemNumber = 0;
for( int i = 0; i < KINDNUMBER + 1; i++ )
{
nKindNumber[i] = 0;
}
for( i = 0; i < VECTORITEMNUMBER; i++ )
{
nTNumber[i] = 0;
}
ReadFile();//调用读取文件的函数
//统计训练集中出现的网页类别数
for( int j = 1; j < KINDNUMBER + 1; j++ )
{
if( nKindNumber[j] > 0 )
nKindNumber[0]++;
}
m_strText = "读取训练集完毕!";
UpdateData(FALSE);
AfxMessageBox("训练集读取完毕!",MB_OK);
m_progress.SetPos(0);
nFlag=1;//已经读取完数据
nFlag1=1;
//设置按钮状态
m_Button_Train.EnableWindow(TRUE);
}
else
{
m_strText = "没有正确打开文件,返回!";
UpdateData(FALSE);
}
}
/********************************************************************
// 创建日期 : 2008-5-19 16:21:12
// 作 者 : 祝美莲<zml123818@163.com>
// 函数名称 : CDeTreeSVMDlg::ReadFile
// 函数功能 : 读取文件的内容
// 返回类型 : void
********************************************************************/
void CDeTreeSVMDlg::ReadFile()
{
Page = new CPageInfo[PAGENUMBER];//分配空间
VectorItem vi;//临时变量,存放特征向量的一个分量
CStdioFile mFile; //准备文件操作
CString strFileName = m_strPath;//文件名
CString str;//临时变量
//判断文件是否正确打开
if(mFile.Open(strFileName,CFile::modeRead)==0)
{
AfxMessageBox("文件打开失败", MB_ICONSTOP);
return ;
}
else
{
char seps[] = "(;:,)";
char *token;//临时变量
int i=0;
int m_Type;
mFile.ReadString(str); //从文件中读取一行内容到str中
while(!str.IsEmpty( ))
{
char string[10000];
sprintf( string,"%s",str ); //定义字符数组string,将cstr复制到string中
//strtok函数将seps指定的内容去掉以后得到剩下的,此时得到第一个有效数据type值
token = strtok( string, seps );
m_Type = atoi( token );
nKindNumber[m_Type]++;//统计该类网页的总数
//strtok函数首次使用时赋值为字符串,再调用时赋值为NULL
token = strtok( NULL, seps );
while( token != NULL )
{
if(i%2 == 0)
{
vi.nIndex = atoi( token );//定义i记数,当i为偶数时,保存关键词的索引
//统计特征向量的最大维数
if( nVectorItemNumber < vi.nIndex )
nVectorItemNumber = vi.nIndex;
//统计出现第nIndex个特征词的文档数
nTNumber[vi.nIndex]++;
}
if(i%2 == 1)
{
vi.dPower = atof( token );//当i为奇数时,保存权重
Page[nPageNumber].SetType(m_Type);
Page[nPageNumber].SetCharacterVector( vi );
}
token = strtok( NULL, seps );//取得下一个有效数据
i++;
}
mFile.ReadString(str);//读取文件中下一行数据
m_progress.SetPos(nPageNumber);//进度条加一
nPageNumber++;//统计网页总数
}
nVectorItemNumber++;
mFile.Close(); //关闭文件
}
}
/********************************************************************
// 创建日期 : 2008-5-19 16:23:16
// 作 者 : 祝美莲<zml123818@163.com>
// 函数名称 : CDeTreeSVMDlg::OnButtonTrain
// 函数功能 : 训练向量机
// 返回类型 : void
********************************************************************/
void CDeTreeSVMDlg::OnButtonTrain()
{
// TODO: Add your control notification handler code here
/*首先要对文件排序,按照网页数量的多少进行降序排列;
调用子SVM分类器进行训练;然后循环,直到全部训练完成;*/
if(nFlag==0)//判断是否已经成功读取了训练集信息
{
AfxMessageBox("请先读取训练集!",MB_ICONSTOP);
}
else
{
m_strText = "训练中......";
UpdateData(FALSE);
//创建一个等待无模式对话框,播放动画等待程序结束
CWaitDlg dlg;
dlg.Create( IDD_DIALOG_WAIT ) ;
dlg.ShowWindow( SW_SHOW );
dlg.UpdateWindow();
AfxGetApp()->BeginWaitCursor(); //沙漏光标
m_progress.SetRange(0,150);//设置进度条
m_progress.SetPos(0);
int j=1;
CTime m_Time1 = CTime::GetCurrentTime(); //得到当前时间
for(int i=0; i<KINDNUMBER+1; i++)//将数据转存进行运算
{
nTemp[i] = nKindNumber[i];
}
//排序,找出最大值
while(nTemp[0] != 1)
{
int max=0;//临时变量
int index=0;
//找出样本数量最多的类别
for(int i=1;i<=4;i++)
{
if(max<nTemp[i])
{
max=nTemp[i];
index=i;
}
}
nTemp[index]=0;
//构造一个对象
CTrain train(Page,nTemp[0],nVectorItemNumber,nPageNumber);
train.Training(index,j);//训练向量机
DeletePage(index,max);//删除
nPageNumber = nPageNumber - max;
nTemp[0]--;//网页类别数减1
m_progress.SetPos(j*50);
j++;
}
CTime m_Time2 = CTime::GetCurrentTime(); //得到当前时间
strClaTime=m_Time2-m_Time1; //计算分类用时
m_time = "分类用时:";
m_time += strClaTime.Format("%H:%M:%S");//转化格式
dlg.DestroyWindow();//销毁等待对话框
AfxGetApp()->EndWaitCursor();//光标恢复为箭头
m_strText = "训练完毕!";
nFlag=0;
UpdateData(FALSE);
AfxMessageBox("训练完毕!",MB_OK);
m_Button_Test.EnableWindow(TRUE);
}
}
/********************************************************************
// 创建日期 : 2008-5-19 16:27:01
// 作 者 : 祝美莲<zml123818@163.com>
// 函数名称 : CDeTreeSVMDlg::OnButtonTest
// 函数功能 : 测试向量机
// 返回类型 : void
********************************************************************/
void CDeTreeSVMDlg::OnButtonTest()
{
// TODO: Add your control notification handler code here
//判断是否读取训练集
if(nFlag1==0)
{
AfxMessageBox("请先读取训练集!",MB_ICONSTOP);
}
else
{
CString strNameTest,strNameMdl;//存放文件路径
strNameTest = "\\测试集\\向量表示\\";
strNameTest = pPath+strNameTest;
strNameMdl = "\\向量机模型";
strNameMdl =pPath+strNameMdl;
CFileFind f;
BOOL bWorking=f.FindFile(strNameMdl);
if(!bWorking)//没有找到模型文件
{
AfxMessageBox("没有得到模型文件,请先训练!",MB_ICONSTOP);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -