机器学习实验—K-MEANS聚类

一、实验目的和内容

        1、掌握数据预处理的方法,对数据进行预处理;
        2、掌握基本K-MEANS算法的使用;

二、实验过程

        1、将第二次的实验数据“inout.txt”进行处理,分割成143个文本。
        主要代码如下:

void openFile(char *filename)
{
	cout << "正在打开文档...";
	string goal_str;
	ifstream goal(filename);
	ofstream fileout[N];
	int i = 0;
	while (getline(goal, goal_str))
	{
		char str[25];
		_itoa(i, str, 10);
		strcat(str,".txt");
		fileout[i].open(str);
		fileout[i]<< goal_str << endl;
		i++;
		cout << str << endl;
	}
	cout << endl;
}
        2、将1中处理出来的143个文本计算tf、idf,将结果按照行为每个词项在每个文档的tf*idf,列为每个文档中每个此项对应的tf*idf。输出结果到k-means.txt。主要代码如下:

int _tmain(int argc, _TCHAR* argv[])
{
	int i = 0, j = 0;
	int ni;
	int max[N] = { 0 };					//存放文献使用频率最大词
	char ch;
	char *file[N] = { 0 };				//需要检索的文献
	char *savefile;					//结果存放文档
	clock_t start0, finish0;			//程序运行时间
	double sftime0;
	start0 = clock();
	savefile = "tfidf.txt";
	FILE *cp = fopen("词库.txt", "r");//词库位置

	while (!feof(cp))						 //读取词库
	{
		ch = fgetc(cp);
		for (i = 0; ch != 13 && i<22 && ch != 10; i++)
		{
			word[wordleng][i] = ch;
			ch = fgetc(cp);
		}
		wordleng++;
	}
	fclose(cp);							 //关闭词库
	cout << "----------------------" << endl;
	for (j = 0; jmax[j])
				max[j] = frequency[i][j];
	}
	for (int m = 0; m
        3、运行k-means程序,数据为2中产生的k-means.txt。主要函数如下:

void KMeans(vector& tuples)
{
	vector clusters[k];//k个簇  
	Tuple means[k];//k个中心点  
	int i = 0;
	//一开始随机选取k条记录的值作为k个簇的质心(均值)  
	//srand((unsigned int)time(NULL));
	for (i = 0; i= 0.5) //当新旧函数值相差不到1即准则函数值不发生明显变化时,算法终止  
	{
		cout << "第 " << ++t << " 次迭代开始:" << endl;
		fileout << "第 " << ++t << " 次迭代开始:" << endl;
		for (i = 0; i < k; i++) //更新每个簇的中心点  
		{
			means[i] = getMeans(clusters[i]);
		}
		oldVar = newVar;
		newVar = getVar(clusters, means); //计算新的准则函数值
		for (i = 0; i < k; i++) //清空每个簇  
		{
			clusters[i].clear();
		}
		//根据新的质心获得新的簇  
		for (i = 0; i != tuples.size(); ++i)
		{
			lable = clusterOfTuple(means, tuples[i]);
			clusters[lable].push_back(tuples[i]);
		}
		cout << "此次迭代之后的整体误差平方和为:" << newVar << endl;
		fileout << "此次迭代之后的整体误差平方和为:" << newVar << endl;
	}

	cout << "The result is:\n";
	fileout << "The result is:\n";
	print(clusters);
}

三、实验结果

        1、将数据“inout.txt”进行处理,分割成143个文本:
机器学习实验—K-MEANS聚类_第1张图片

        2、处理产生的tfidf.txt:

机器学习实验—K-MEANS聚类_第2张图片

        3、运行k-means程序:
        结果输出到out.txt:

机器学习实验—K-MEANS聚类_第3张图片
机器学习实验—K-MEANS聚类_第4张图片

        初始的的整体误差平方和为:5213.93
        第 2 次迭代开始:
        此次迭代之后的整体误差平方和为:4939.6
        第 4 次迭代开始:
        此次迭代之后的整体误差平方和为:4808.67
        第 6 次迭代开始:
        此次迭代之后的整体误差平方和为:4789.94
        第 8 次迭代开始:
        此次迭代之后的整体误差平方和为:4780.47
        第 10 次迭代开始:
        此次迭代之后的整体误差平方和为:4780.47
        实验数据“input.txt”中143个文本被分为5个簇。

四、总结

        本次实验刚开始利用的是每篇文档的一个特征向量进行聚类,也能够形成5个类簇,但是考虑到数据只有一维,结果可能不准确,因此计划将文档中每个词都作为一维数据输入。但是考虑到某个词在a文档中出现过,但是在b文档中却没有出现过,那么b文档对于该词项的tf*idf值赋为0。另外本实验分成了三个部分:将“input.txt”分割成143个文本,将这143个文本计算tf*idf,进行k-means聚类。聚类就是我们并不知道数据分布的情况,通过使用聚类中的一种方法k-means来将数据的分布情况展现出来。kmenas算法首先选择K个初始质心,其中K是用户指定的参数,即所期望的簇的个数。选择适当的初始质心是基本kmeans算法的关键步骤。常见的方法是随机的选取初始质心,但是这样簇的质量常常很差。处理选取初始质心问题的一种常用技术是:多次运行,每次使用一组不同的随机初始质心,然后选取具有最小SSE(误差的平方和)的簇集。这种策略简单,但是效果可能不好,这取决于数据集和寻找的簇的个数。常用的距离度量方法包括:欧几里得距离和余弦相似度。两者都是评定个体间差异的大小的。欧几里得距离度量会受指标不同单位刻度的影响,所以一般需要先进行标准化,同时距离越大,个体间差异越大;空间向量余弦夹角的相似度度量不会受指标刻度的影响,余弦值落于区间[-1,1],值越大,差异越小。但是针对具体应用,需要考虑使用欧氏距离合适还是使用余弦相似度合适。对于距离度量不管是采用欧式距离还是采用余弦相似度,簇的质心都是其均值,即向量各维取平均即可。对于距离对量采用其它方式时,这个还没研究过。一般是目标函数达到最优或者达到最大的迭代次数即可终止。本次实验中将前后两次迭代之差的绝对值小瑜0.5定位算法停止的条件。


         注:本博客源代码下载地址:http://download.csdn.net/detail/dmxexcalibur/9920656

你可能感兴趣的:(机器学习)