2016-06-07 17:20:09 owen7500 阅读数 10581
  • 从零开始学习机器学习视频教程

    零基础入门机器学习视频培训课程概况:机器学习数学基础、Python基础、机器学习算法(线性回归、逻辑回归、聚类算法、EM算法),机器学习项目实战(Kmeans篮球数据分析、贝叶斯算法训练)、推荐算法、项目实战。  任务作业:很多人都喜欢看NBA,也喜欢拿实力相近的球员进行比较,你能利用机器学习的方式进行分析吗?动手的机会来了!请 结合课程【项目实战】章节中的【Kmeans篮球数据分类】。从NBA网站中随机拿到30名篮球运动员的得分和助攻(尽量数据间隔较大)。用python对数据进行处理(换算成每分钟的得分和助攻)。然后用Kmeans对获取的球员进行分类。看看自己心仪的球员属于哪一类~  (温馨提示: 注意 作业需写在CSDN博客中,请把作业链接贴在评论区,老师会定期逐个批改~~)

    5424 人正在学习 去看看 陆永剑

kmeans是非常经典的聚类算法,至今也还保留着较强的生命力,图像处理中经常用到kmeans算法或者其改进算法进行图像分割操作,在数据挖掘中kmeans经常用来做数据预处理。opencv中提供了完整的kmeans算法,其函数原型为:

double kmeans( InputArray data, int K, InputOutputArray bestLabels, TermCriteria criteria, int attempts, int flags, OutputArray centers = noArray() );

其中data表示用于聚类的数据,是N维的数组类型(Mat型),必须浮点型;

K表示需要聚类的类别数;

bestLabels聚类后的标签数组,Mat型;

criteria迭代收敛准则(MAX_ITER最大迭代次数,EPS最高精度);

attemps表示尝试的次数,防止陷入局部最优;

flags 表示聚类中心的选取方式(KMEANS_RANDOM_CENTERS 随机选取,KMEANS_PP_CENTERS使用Arthur提供的算法,KMEANS_USE_INITIAL_LABELS使用初始标签);

centers 表示聚类后的类别中心。

关于kmeans的理论可以参考:基本Kmeans算法介绍及其实现

下面给出一个关于图像聚类的示例:

#include <opencv.hpp>
using namespace cv;


Scalar colorTab[] =     //10个颜色
{
	Scalar(0, 0, 255),
	Scalar(0, 255, 0),
	Scalar(255, 100, 100),
	Scalar(255, 0, 255),
	Scalar(0, 255, 255),
	Scalar(255, 0, 0),
	Scalar(255, 255, 0),
	Scalar(255, 0, 100),
	Scalar(100, 100, 100),
	Scalar(50, 125, 125)
};

class ClusterPixels
{
private:
	Mat image;			//待聚类图像
	Mat labels;			//聚类后的标签
	int clusterCounts;	//分类数,不得大于10,只是颜色定义只有10类,并不是算法限制

public:
	ClusterPixels() :clusterCounts(0){}
	ClusterPixels(const Mat& src, int clusters = 5) :clusterCounts(clusters){ image = src.clone(); }

	void setImage(const Mat& src){ image = src.clone(); };
	void setClusters(int clusters){ clusterCounts = clusters; }

	Mat getLabels()	{return labels;	};		//返回聚类后的标签

	Mat clusterGrayImageByKmeans()
	{
		//转换成灰度图
		if (image.channels() != 1)
			cvtColor(image, image, COLOR_BGR2GRAY);

		int rows = image.rows;
		int cols = image.cols;
		
		//保存聚类后的图片
		Mat clusteredMat(rows, cols, CV_8UC3);
		clusteredMat.setTo(Scalar::all(0));

		Mat pixels(rows*cols, 1, CV_32FC1);	//pixels用于保存所有的灰度像素

		for (int i = 0; i < rows;++i)
		{
			const uchar *idata = image.ptr<uchar>(i);
			float *pdata = pixels.ptr<float>(0);
			for (int j = 0; j < cols;++j)
			{
				pdata[i*cols + j] = idata[j];
			}
		}

		kmeans(pixels, clusterCounts, labels, TermCriteria(TermCriteria::EPS + TermCriteria::MAX_ITER, 10, 0), 5, KMEANS_PP_CENTERS);

		for (int i = 0; i < rows;++i)
		{
			for (int j = 0; j < cols;++j)
			{
				circle(clusteredMat, Point(j,i), 1, colorTab[labels.at<int>(i*cols + j)]);		//标记像素点的类别,颜色区分
			}
		}

		return clusteredMat;
	}

	Mat clusterColorImageByKmeans()
	{
		assert(image.channels() != 1);

		int rows = image.rows;
		int cols = image.cols;
		int channels = image.channels();

		//保存聚类后的图片
		Mat clusteredMat(rows, cols, CV_8UC3);
		clusteredMat.setTo(Scalar::all(0));

		Mat pixels(rows*cols, 1, CV_32FC3);	//pixels用于保存所有的灰度像素
		pixels.setTo(Scalar::all(0));

		for (int i = 0; i < rows; ++i)
		{
			const uchar *idata = image.ptr<uchar>(i);
			float *pdata = pixels.ptr<float>(0);

			for (int j = 0; j < cols*channels; ++j)
			{
					pdata[i*cols*channels + j] = saturate_cast<float>(idata[j]);			
			}
		}

		kmeans(pixels, clusterCounts, labels, TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 10, 0), 5, KMEANS_PP_CENTERS);

		for (int i = 0; i < rows; ++i)
		{
			for (int j = 0; j < cols*channels; j += channels)
			{
				circle(clusteredMat, Point(j/channels,i), 1, colorTab[labels.at<int>(i*cols + (j/channels))]);		//标记像素点的类别,颜色区分
			}
		}

		return clusteredMat;
	}
};


主函数:

#include "clusterImagePixels.hpp"

int main()
{
	Mat testImage = imread("E:\\testImage\\board.jpg");
	if (testImage.empty())
	{
		return -1;
	}

	ClusterPixels clusterPix(testImage,3);

	Mat colorResults = clusterPix.clusterColorImageByKmeans();
	Mat grayResult = clusterPix.clusterGrayImageByKmeans();

	if (!colorResults.empty())
	{
		hconcat(testImage, colorResults, colorResults);
		imshow("clusterImage", colorResults);
	}

	if (!grayResult.empty())
	{
		hconcat(testImage, grayResult, grayResult);
		imshow("grayCluster", grayResult);
	}

	if (waitKey() == 27)
		return 0;
}


效果图:

采用灰度聚类的结果:


采用RGB颜色聚类得到的效果图:


Kmeans
2013-04-22 23:56:40 a952213390 阅读数 483
  • 从零开始学习机器学习视频教程

    零基础入门机器学习视频培训课程概况:机器学习数学基础、Python基础、机器学习算法(线性回归、逻辑回归、聚类算法、EM算法),机器学习项目实战(Kmeans篮球数据分析、贝叶斯算法训练)、推荐算法、项目实战。  任务作业:很多人都喜欢看NBA,也喜欢拿实力相近的球员进行比较,你能利用机器学习的方式进行分析吗?动手的机会来了!请 结合课程【项目实战】章节中的【Kmeans篮球数据分类】。从NBA网站中随机拿到30名篮球运动员的得分和助攻(尽量数据间隔较大)。用python对数据进行处理(换算成每分钟的得分和助攻)。然后用Kmeans对获取的球员进行分类。看看自己心仪的球员属于哪一类~  (温馨提示: 注意 作业需写在CSDN博客中,请把作业链接贴在评论区,老师会定期逐个批改~~)

    5424 人正在学习 去看看 陆永剑

基本思想

KMeans算法的基本思想就是将未知的数据集通过一定的相似性度量将未知类别的数据集自然地划分为K个数据集合,使得衡量标准达到比较好的值或者数据集合中心(采用均值)不变。也就是n的对象根据他们的属性分为k个分割,k < n。它与处理混合正态分布的最大期望算法很相似,因为他们都试图找到数据中自然聚类的中心。它假设对象属性来自于空间向量,并且目标是使各个群组内部的均方误差总和最小。

举例

KMeans是典型的物以类聚思想

理论支持

4算法步骤

1) 将数据分为k个非空子集

2) 计算每个类中心点(k-means中用所有点的平均值,K-medoid用离该平均值最近的一个点)center

3)将每个object聚类到最近的center

4) 返回2,当聚类结果不再变化的时候stop

实验

实验使用了iris数据,思路是将训练数据单独训练聚类,然后用已有的标签对照,计算准确率。

function [X,center,iter,accuracy] = trainkmeans( traindata,trainlabel,k )
%UNTITLED Summary of this function goes here
%   Detailed explanation goes here
[traindata_m,traindata_n]=size(traindata);
[trainlabel_m,trainlabel_n]=size(trainlabel);
 
 
%将训练数据保存结构体形式
for i=1:1:traindata_m
    X(i).data=traindata(i,:);
    X(i).label=0;
end
%初始化K个均值中心
center(1)=X(10);center(1).label=1;
center(2)=X(60);center(2).label=2;
center(3)=X(120);center(3).label=3;
newcenter(1)=X(10);newcenter(1).label=1;
newcenter(2)=X(60);newcenter(2).label=2;
newcenter(3)=X(120);newcenter(3).label=3;
%迭代求取最终的K个数据集合
change=1;iter=0;
while change~=0  
  for i=1:1:traindata_m%计算每个点到每个中心的距离,归为最小的
    for j=1:1:k
       D(j)=norm(X(i).data-center(j).data);
    end
       [temp,index]=min(D);
       X(i).label=index;
  end
  
  for i=1:1:k %重新计算中心值
    for j=1:1:traindata_n
        sum=0;count=0;
        for t=1:1:traindata_m
            if X(t).label==center(i).label
                 sum=sum+X(t).data(j);
                 count=count+1;
            end
        end
        newcenter(i).data(j)=sum/count;
    end
    if newcenter(i).data~=center(i).data
        change=change+1;iter=iter+1;
    else
        change=0;
    end
  end
 
  for i=1:1:k 
    center(i)=newcenter(i);
  end
end  
 
accuracy=0;
for i=1:1:trainlabel_m
    if X(i).label==trainlabel(i,1)
        accuracy=accuracy+1;
    end
end
accuracy=accuracy/trainlabel_m;
 
end


实验结果

对K值的选取确实很麻烦的,并且初始的中心选取也很麻烦。开始指定同一个类里面的三个数据作为最初的三个中心结果效果很差iter=33,准确率却只有0.4467,。然后在三个不同的类里面指定数据,迭代次数19,准确率却上升为0.8867.

6优势和劣势

优势:自然地聚类,方法简单

劣势:K值的选取困难、对初始中心敏感。

在实际应用中往往会已知一些数据,可以以这些数据为初始的中心点,然后按聚类算法聚类计算。

7主要应用

搜索引擎的爬虫后对网页的处理,聚类分析

8改进

1K值的选取通过观察误差准则的变化趋势判断,随着K值的增大误差准则慢慢变小,开始时候变化程度比较大,到达一定值后变化速度放慢,当K等于N时,误差准则等于0,转折点可作为K值的选取。

2ISODATA



2017-05-19 11:40:38 skyztttt 阅读数 1191
  • 从零开始学习机器学习视频教程

    零基础入门机器学习视频培训课程概况:机器学习数学基础、Python基础、机器学习算法(线性回归、逻辑回归、聚类算法、EM算法),机器学习项目实战(Kmeans篮球数据分析、贝叶斯算法训练)、推荐算法、项目实战。  任务作业:很多人都喜欢看NBA,也喜欢拿实力相近的球员进行比较,你能利用机器学习的方式进行分析吗?动手的机会来了!请 结合课程【项目实战】章节中的【Kmeans篮球数据分类】。从NBA网站中随机拿到30名篮球运动员的得分和助攻(尽量数据间隔较大)。用python对数据进行处理(换算成每分钟的得分和助攻)。然后用Kmeans对获取的球员进行分类。看看自己心仪的球员属于哪一类~  (温馨提示: 注意 作业需写在CSDN博客中,请把作业链接贴在评论区,老师会定期逐个批改~~)

    5424 人正在学习 去看看 陆永剑

引子

最近在看机器学习相关的视频教程,其中讲到了通过kmeans进行聚类算法,于是萌生了研究下该算法并通过python来一步一步展现算法的整个过程的想法。

原理

kmeans的具体原理发现晚上有一个教程较为清晰地展现了kmeans,参考如下: http://www.csdn.net/article/2012-07-03/2807073-k-means

运用python展示

一个良好的数据组织和展示可以极大的加强我们对算法的理解,于是第一步为如何展示一组基本数据。

数据源

自己也就不去造数据源了,拿了一个中国大学mooc给出了一个kmeans的测试数据:http://www.icourse163.org/learn/BIT-268001?tid=1002001005#/learn/content?type=detail&id=1002613060&cid=1002856188,另外也可以从我的github中进行下载:https://github.com/skyztt/kmeans-python.git

操作

  • 通过numpy读取原始输入,可以使用np.loadtxt读取出文件,读取后的数据如下(之前没有理解原始数据,认为原始数据只表示y坐标,后面查找如何将数据降维道一维,也算多 理解了一个api吧,可以通过flatten将其转化为一维数据):
[[ 1.658985  4.285136]
 [-3.453687  3.424321]
 [ 4.838138 -1.151539]
 ..., 
 [-4.561235 -4.563214]
 [ 5.461454 -5.123464]
 [ 4.012356 -4.985623]]
  • 展示出来:
    这里使用matplot进行展示,但这里需要从原始数据中抽取出x,y坐标,于是使用到了numpy的切片:(附上一个当时参考的博文http://blog.csdn.net/liangzuojiayi/article/details/51534164,其中一张图很好地说明了这个问题)
    这里写图片描述
    附上代码,短短几句原始数据打印成功~
import numpy as np
import matplotlib.pyplot as plt

a = np.loadtxt(".\\testSet.txt")
plt.scatter(a[:,:1], a[:,1:2])
plt.show()

这里写图片描述

2017-03-06 16:14:40 laotumingke 阅读数 3377
  • 从零开始学习机器学习视频教程

    零基础入门机器学习视频培训课程概况:机器学习数学基础、Python基础、机器学习算法(线性回归、逻辑回归、聚类算法、EM算法),机器学习项目实战(Kmeans篮球数据分析、贝叶斯算法训练)、推荐算法、项目实战。  任务作业:很多人都喜欢看NBA,也喜欢拿实力相近的球员进行比较,你能利用机器学习的方式进行分析吗?动手的机会来了!请 结合课程【项目实战】章节中的【Kmeans篮球数据分类】。从NBA网站中随机拿到30名篮球运动员的得分和助攻(尽量数据间隔较大)。用python对数据进行处理(换算成每分钟的得分和助攻)。然后用Kmeans对获取的球员进行分类。看看自己心仪的球员属于哪一类~  (温馨提示: 注意 作业需写在CSDN博客中,请把作业链接贴在评论区,老师会定期逐个批改~~)

    5424 人正在学习 去看看 陆永剑

Kmeans是十分常见的数据挖掘算法,其逻辑较为简单,应用范围广。通过百度搜索java实现的Kmeans算法,可参考的版本很多,比如:
http://blog.csdn.net/jdplus/article/details/23960127
还有:
http://www.cnblogs.com/chaoku/p/3748456.html

虽然作者都表示亲测有效,不会有任何问题,然而在实际应用中每个人的环境不同,尤其是hadoop版本的不同,总会出现这样或者那样的问题。不过他们的算法给了很好的参考,按照他们的逻辑照虎画猫,也是可行的。
我的hadoop版本较为老旧,其中最为突出的问题就是在老版本的hadoop中并没有

org.apache.hadoop.mapreduce.Job;

这个包,这个版本上的差别照成了并不能直接拿大牛们的代码复制过来就用。随后在参考了hadoop官网中的案例重新对Kmeans算法进行了实现,代码参考“潇洒子弦”较多,也容纳我的思考,主要有耽三个大方面的不同:

  1. 实现的版本不同,基于低级版本的hadoop予以实现。

  2. 在计算距离上有了变化,采用了欧式距离,按照原来的实现方案并不能有效聚类成需要的组别数呢。

  3. 将中心点写入新文件中语句也有变动,按照原始的写法,似乎会覆盖掉。

以下是主要代码:

package mykmeans;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.util.LineReader;

public class CopyOfUtils {

    //读取中心文件的数据
    public static ArrayList<ArrayList<Double>> getCentersFromHDFS(String centersPath,boolean isDirectory) throws IOException{

        ArrayList<ArrayList<Double>> result = new ArrayList<ArrayList<Double>>();

        Path path = new Path(centersPath);

        Configuration conf = new Configuration();

        FileSystem fileSystem = path.getFileSystem(conf);

        if(isDirectory){    
            FileStatus[] listFile = fileSystem.listStatus(path);
            for (int i = 0; i < listFile.length; i++) {
                result.addAll(getCentersFromHDFS(listFile[i].getPath().toString(),false));
            }
            return result;
        }

        FSDataInputStream fsis = fileSystem.open(path);
        LineReader lineReader = new LineReader(fsis, conf);

        Text line = new Text();

        while(lineReader.readLine(line) > 0){
            //ArrayList<Double> tempList = textToArray(line);
            ArrayList<Double> tempList = new ArrayList<Double>();
            String[] fields = line.toString().replaceAll("\t", "").split(",");
            for(int i=0;i<fields.length;i++){
                tempList.add(Double.parseDouble(fields[i]));
            }
            result.add(tempList);
        }
        lineReader.close();
        return result;
    }

    //删掉文件
    public static void deletePath(String pathStr) throws IOException{
        Configuration conf = new Configuration();
        Path path = new Path(pathStr);
        FileSystem hdfs = path.getFileSystem(conf);
        hdfs.delete(path ,true);
    }

    public static ArrayList<Double> textToArray(Text text){
        ArrayList<Double> list = new ArrayList<Double>();
        String[] fileds = text.toString().replaceAll("\t", "").split("/,");
        for(int i=0;i<fileds.length;i++){
            list.add(Double.parseDouble(fileds[i]));
        }
        return list;
    }

    public static boolean compareCenters(String centerPath,String newPath) throws IOException{
        System.out.println("比较两个中心点是否相等");
        List<ArrayList<Double>> oldCenters = CopyOfUtils.getCentersFromHDFS(centerPath,false);
        List<ArrayList<Double>> newCenters = CopyOfUtils.getCentersFromHDFS(newPath,true);


        int size = oldCenters.size();
        int fildSize = oldCenters.get(0).size();

        double distance = 0;
        for(int i=0;i<size;i++){
            for(int j=0;j<fildSize;j++){
                double t1 = Math.abs(oldCenters.get(i).get(j));
                double t2 = Math.abs(newCenters.get(i).get(j));
                distance += Math.pow((t1 - t2) / (t1 + t2), 2);
            }
        }

        if(distance <= 0.00001){
            //删掉新的中心文件以便最后依次归类输出
            CopyOfUtils.deletePath(newPath);
            return true;
        }else{
            //先清空中心文件,将新的中心文件复制到中心文件中,再删掉中心文件

            CopyOfUtils.deletePath(centerPath);
            Configuration conf = new Configuration();
            Path outPath = new Path(centerPath);
            FileSystem fileSystem = outPath.getFileSystem(conf);            
            FSDataOutputStream out = fileSystem.create(outPath);
            //out.
            //将newCenter的内容写到文件里面



            Path inPath = new Path(newPath);

            FileStatus[] listFiles = fileSystem.listStatus(inPath);
            for (int i = 0; i < listFiles.length; i++) {                

                FSDataInputStream in = fileSystem.open(listFiles[i].getPath());

                int byteRead = 0;
                byte[] buffer = new byte[256];
                while ((byteRead = in.read(buffer)) > 0) {
                    out.write(buffer, 0, byteRead);
                }
                in.close();
            }
                out.close();

            //删掉新的中心文件以便第二次任务运行输出
            CopyOfUtils.deletePath(newPath);
        }

        return false;
    }
}
package mykmeans;

import java.io.*;
import java.text.DecimalFormat;
import java.util.*;

import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.filecache.DistributedCache;
import org.apache.hadoop.conf.*;
import org.apache.hadoop.io.*;
import org.apache.hadoop.mapred.*;
import org.apache.hadoop.util.*;



public class CopyOfNewMapReduce extends Configured implements Tool{

    public static class Map extends MapReduceBase implements Mapper<LongWritable, Text, IntWritable, Text>{


        // private String centerpath;
         public ArrayList<ArrayList<Double>> centers = null;
         public int k = 3;
         public void configure(JobConf job){
             String center = job.get("map.center.file");
             try {
                centers = Utils.getCentersFromHDFS(center,false);
                k = centers.size();
                System.out.println("centers point is: "+centers.toString());

            } catch (IOException e) {
                System.err.println("cannot find the map center file!");
                e.printStackTrace();
            }

         }

        @Override
        public void map(LongWritable key, Text value,
                OutputCollector<IntWritable, Text> output, Reporter report)
                throws IOException {
            //读取一行数据

            ArrayList<Double> fileds = new ArrayList<Double>();
            String[] temp = value.toString().replaceAll("\t", "").split(",");
            for(int i = 0; i<temp.length;i++){
                fileds.add(Double.parseDouble(temp[i]));
            }

            int sizeOfFileds = fileds.size();

            double minDistance = 99999999;
            int centerIndex = 0;

            //依次取出k个中心点与当前读取的记录做计算
            for(int i=0;i<k;i++){
                double currentDistance = 0;
                for(int j=0;j<sizeOfFileds;j++){

                    double centerPoint = centers.get(i).get(j);
                    double filed = fileds.get(j);
                    currentDistance += (centerPoint-filed)*(centerPoint-filed);

                }
                currentDistance = Math.sqrt(currentDistance);
                //循环找出距离该记录最接近的中心点的ID
                if(currentDistance<minDistance){
                    minDistance = currentDistance;
                    centerIndex = i;
                }
            }
            //以中心点为Key 将记录原样输出
            output.collect(new IntWritable(centerIndex+1), value);

        }

    }


     public static class Reduce extends MapReduceBase implements Reducer<IntWritable, Text, Text, Text> {

        @Override
        public void reduce(IntWritable key, Iterator<Text> value,
                OutputCollector<Text, Text> output, Reporter report)
                throws IOException {
ArrayList<ArrayList<Double>> filedsList = new ArrayList<ArrayList<Double>>();
DecimalFormat df0 = new DecimalFormat("###.000000");

            //依次读取记录集,每行为一个ArrayList<Double>
            System.out.println(key+":  "+value.toString());
            while(value.hasNext()){

                ArrayList<Double> tempList = new ArrayList<Double>();
                String[] temp0 = value.next().toString().replaceAll("\t", "").split(",");
                for(int i = 0; i< temp0.length; i++){
                    tempList.add(Double.parseDouble(df0.format(Double.parseDouble(temp0[i]))));
                }
                filedsList.add(tempList);
            }

            //计算新的中心
            //每行的元素个数
            int filedSize = filedsList.get(0).size();
            double[] avg = new double[filedSize];
            for(int i=0;i<filedSize;i++){
                //求没列的平均值
                double sum = 0;
                int size = filedsList.size();
                for(int j=0;j<size;j++){
                    sum += filedsList.get(j).get(i);
                }
                avg[i] = sum / size;
                avg[i] = Double.parseDouble(df0.format(avg[i]));
            }
            output.collect(new Text("") , new Text(Arrays.toString(avg).replace("[", "").replace("]", "").replaceAll("\t", "")));

        }


     }



    @Override
    public int run(String[] args) throws Exception {
        JobConf conf = new JobConf(getConf(), CopyOfNewMapReduce.class);
         conf.setJobName("kmeans");

         conf.setMapperClass(Map.class);
         conf.setMapOutputKeyClass(IntWritable.class);
         conf.setMapOutputValueClass(Text.class);



         if(!"false".equals(args[3])||"true".equals(args[3])){
             conf.setReducerClass(Reduce.class);
             conf.setOutputKeyClass(Text.class);
             conf.setOutputValueClass(Text.class);
         }

         FileInputFormat.setInputPaths(conf, new Path(args[0]));
         FileOutputFormat.setOutputPath(conf, new Path(args[1]));
         conf.set("map.center.file", args[2]);


         JobClient.runJob(conf);
         return 0;
    }
    public static void main(String[] args)throws Exception{
        int count = 0;
        int res = 0;
        while(true){
            res = ToolRunner.run(new Configuration(), new CopyOfNewMapReduce(), args);
            System.out.println(" 第 " + ++count + " 次计算 ");
            if(Utils.compareCenters(args[2],args[1] )){

                String lastarg[] = new String[args.length];
                for(int i=0; i < args.length-1; i++){
                    lastarg[i] = args[i];
                    }
                lastarg[args.length-1] = "false";
                res = ToolRunner.run(new Configuration(), new CopyOfNewMapReduce(), lastarg);
                break;
                }

            }


        System.exit(res);
    }


}

编译后,打成jar包,注意java版本的一致性。
在hadoop客户端执行:

~hadoop>bin/hadoop jar MyKmeans.jar mykmeans.CopyOfNewMapReduce /xxxx/kmeans/input*.file /xxx/output /xxx/kmeans/cluster.file true 

需要保证输入的数据内容以逗号“,”隔开,初始中心点需要自行设置,而不是随机取的,同样以逗号“,”隔开。
最后实现的效果在output文件夹下,每个聚类在一个文件中,输出的数据格式截图如下:
代码结果截图

如此便实现了低版本的hadoop上kmeans算法的实现,有问题欢迎交流。

引用:MapReduce Kmeans聚类算法.http://www.cnblogs.com/chaoku/p/3748456.html

2015-07-05 18:01:16 Claire_Bear7 阅读数 1186
  • 从零开始学习机器学习视频教程

    零基础入门机器学习视频培训课程概况:机器学习数学基础、Python基础、机器学习算法(线性回归、逻辑回归、聚类算法、EM算法),机器学习项目实战(Kmeans篮球数据分析、贝叶斯算法训练)、推荐算法、项目实战。  任务作业:很多人都喜欢看NBA,也喜欢拿实力相近的球员进行比较,你能利用机器学习的方式进行分析吗?动手的机会来了!请 结合课程【项目实战】章节中的【Kmeans篮球数据分类】。从NBA网站中随机拿到30名篮球运动员的得分和助攻(尽量数据间隔较大)。用python对数据进行处理(换算成每分钟的得分和助攻)。然后用Kmeans对获取的球员进行分类。看看自己心仪的球员属于哪一类~  (温馨提示: 注意 作业需写在CSDN博客中,请把作业链接贴在评论区,老师会定期逐个批改~~)

    5424 人正在学习 去看看 陆永剑

这篇文章总结一下大数据处理模块与导出模块:

大数据处理

功能

这个模块实现了对大数据的处理,用户选择处理方法并上传需要处理的数据集,系统将利用Hadoop集群与R对数据进行分析处理,并将结果显示给用户。

实现原理

模块使用Hadoop框架搭建了一个分布式集群,用于大数据的并行处理。并将Kmeans聚类算法与朴素贝叶斯分类算法用MapReduce编程框架实现。

  • Kmeans聚类算法的MapReduce化
    该过程包括预处理、Kmeans聚类迭代两个过程的MapReduce化。

    • 数据的预处理MapReduce化:将输入的文本文件按行切分,生成(文件行offset,一行文本)形式的键/值对。
    • Kmeans聚类迭代的MapReduce化:计算当前文档与各个类簇中心距离,选择最近的中心作为新的文档中心。
      • Map阶段首先将输入的(文件行offset,一行文本)形式的键值对。Mapper类的map函数计算每一条样本距离哪个类簇中心最近,并归到距离最近的类簇中,输出(cluster,样本)的键值对。
      • Reduce阶段中Reducer类的reduce函数重新计算每个类簇的中心。当一次迭代结束后,计算类簇中心是否收敛,若收敛则结束迭代,否则继续迭代。
  • 朴素贝叶斯的MapReduce化
    该过程包括预处理、模型训练和分类三大过程的MapReduce化。

    • 数据的预处理MapReduce化:将输入的文本文件按行切分,生成(文件行offset,一行文本)形式的键/值对,然后进行具体的并行化处理,以完成对类名、属性值、属性个数的提取等操作。
      • Map阶段首先输入上述(文件行offset,一行文本)形式的键值对。Mapper类的map函数提取出所有出现的样本类名和样本个数,生成(class,1)的中间结果键值对。
      • Reduce阶段是将上述Map阶段生成的中间结果键值对进行归并处理,统计每个类别的个数。
  • 模型训练MapReduce化主要做统计计算的工作,求出各个属性的各个取值的先验概率。

    • Map阶段中Mapper类调用map函数的统计程序对输入的键值对(key/value)进行统计后,生成的中间结果键值对以(“class_name,attr_name,attr_value”,1)的形式传递给Reduce 。
    • Reduce阶段主要做累加操作,Reducer类调用reduce函数对Map阶段所产生的中间结果键值对中拥有相同Key的Value进行累加,计算出各Key的出现次数。
    • 该阶段结束时,模型训练完成,包括的内容有:1.属性个数;2.类的个数;3.每个属性的所有取值;4.类名列表;5.类的先验概率:P(Ci);6.联合概率:类Cj的属性Ai取值为ai的条件概率:P(Ai=ai|Cj);
  • 分类MapReduce化主要是分析测试集的每一个样本属于哪一类。

    • Map阶段是读入一行测试样本信息,生成包含样本id及相应类别概率值的键值对。Mapper类调用map函数对输入的样本信息抽取出各个属性的属性值,并对每个属性值读取其对应所有类别的联合概率(个数等于类别数),并将这些概率分别乘到对应类别的先验概率中;对样本属于各类的概率进行归一化,并按照从大到小的顺序排序,取概率最大的类别作为该样本的归属类,并输出(class,样本信息)的键值对。

    数据导出模块

    流程图

    这里写图片描述

    功能

    本模块实现了分析结果的导出,用户可以选择导出分析图表、分析报告,或分析的结果数据集,选择下载相应的图像、PDF以及xls文件,获取分析过程的内容和结果。

    原理

    系统使用R语言向设备中存储图片的形式对图像进行保存,使用struts2实现图片从网页中下载到本地。
    具体指令如下:

Setwd();    //设置存储目录
JPEG(file = “fileName”) //设置图像名称
/*
*画图语句
*/ 
Dev.off();  //关闭画图设备

系统使用iText进行分析报告的写入,在用户登录到系统后即新建一个pdf对象,在用户软件分析的每一步骤均将分析过程及结果写入该pdf中,当用户点击导出分析报告后,关闭pdf,下载写好的pdf。

系统使用Strus2下载功能进行分析数据的下载,用户点击导出分析数据后,即可产生分析数据的列表,点击download即可将其下载到本地。

笔记_KMeans聚类

阅读数 119

没有更多推荐了,返回首页