k-近邻算法学习

参考: http://blog.csdn.net/tjusxh/article/details/51052319

k-近邻算法:简单地说就是采用测量不同特征值之间的距离进行分类的方法。

三个基本要素:K值的选择、距离度量、分类决策规则

优点:精度高、对异常值不敏感、无数据输入假定。

缺点:计算复杂度高、空间复杂度高。

kNN算法的一般流程:

1.导入数据

2.为保证特征权重相同,进行数值归一化

3.距离计算

4.对距离进行排序,选择前K个距离,求出标签出现最多的类别

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<sstream>
#include<fstream>
#include<cmath>
using namespace std;

//建立一个数据结构,元素为距离、标签
struct Node{
    double dis;
    double labels;
    Node(){}
    Node(double Dis, double Labels) :dis(Dis), labels(Labels){}
};

bool cmp(Node a, Node b){
    return a.dis<b.dis;
}

//第一步,导入数据
vector<vector<double>> getFile(ifstream&in)
{
    vector<vector<double>> dataMat;            //用于返回的二维容器
    vector<double>item;                        //一维容器,用于压缩到二维容器中
    string s;
    istringstream str;
    while (getline(in, s))                    //将数据按行输入
    {
        str.str(s);
        double tmp;
        while (str >> tmp)
            item.push_back(tmp);
        dataMat.push_back(item);
        item.clear();
        str.clear();
    }
    return dataMat;
}

void printf(vector<vector<double>>data)
{
    int n = data.size();        //这里 n 是样本的数量
    int m = data[0].size();     //特征 + 标签
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
            cout << data[i][j] << " ";
        cout << endl;
    }
}

//数值归一化
vector<vector<double>>makeOne(vector<vector<double>>theData)
{
    vector<vector<double>>dataMat = theData;
    int numRows = theData.size();
    int numColumns = theData[0].size();
    //找出每一列的最大值与最小值
    vector<double>Max;
    vector<double>Min;
    vector<double>ranges;
    for (int i = 0; i < numColumns - 1; i++)    //因为每行最后一个元素是标签,所以要减 1
    {
        double max = theData[i][0];
        double min = theData[i][0];
        for (int j = 1; j < numRows; j++)
        {
            if (theData[j][i] >max)
                max = theData[j][i];
            if (theData[j][i] <min)
                min = theData[j][i];
        }
        Max.push_back(max);
        Min.push_back(min);
    }
    for (int i = 0; i < numColumns - 1; i++)
      for (int j = 0; j < numRows; j++)
      {
          dataMat[j][i] = (theData[j][i] - Min[i]) / (Max[i] - Min[i]);
      }
      return dataMat;
}

//输入待测样本
vector<double>getX(vector<vector<double>>dataMat)
{
    int m = dataMat[0].size();
    vector<double>inputX;
    cout << "请输入待测样本 (特征数是" << m - 1 << "个)" << endl;
    for (int i = 0; i < m - 1; i++)
    {
        double temp;
        cin >> temp;
        inputX.push_back(temp);
    }
    return inputX;
}
//计算出 input 到样本点的距离
Node getLabel(vector<double>input, vector<double>Asample)
{
    Node node1;
    int m = input.size();
    node1.labels = Asample[m];
    double dis = 0;
    for (int i = 0; i < m; i++)
        dis += pow(input[i] - Asample[i], 2.0);
    node1.dis = dis;
    return node1;
}

//对所有的样本点距离进行排序,选择前 K 个,并找出前 K 个出现最多的标签
double makeComp(vector<Node>nodes)
{
    int k;
    double l = 0;
    sort(nodes.begin(), nodes.end(), cmp);             //对距离按升序排序
    cout << "请输入K:" << " ";
    cin >> k;
    int max = 0;
    double label[100] = { 0 };
    for (int i = 0; i<k; i++){                        //前 K 个所处的标签
        label[int(nodes[i].labels)]++;
    }
    for (int i = 0; i < k; i++)                       //用于统计出现次数最多的标签
    {
        if (max < label[i]){
            l = i;
            max = label[i];
        }
    }
    return l;
}

int main()
{
    vector<vector<double>>dataMat;
    ifstream file("datingTestSet2.txt");
    dataMat = getFile(file);
    dataMat = makeOne(dataMat);
    int numOfSamples = dataMat.size();
    while (1)
    {
        vector<Node>dis_label;
        vector<double>input = getX(dataMat);             //输入待测例子
        //计算input到每一个样本点的距离,输入为 input,样本点, 输出是:距离,标签
        for (int i = 0; i < numOfSamples; i++)
        {
            Node A = getLabel(input, dataMat[i]);
            dis_label.push_back(A);                               //计算出 input 到所有样本点的距离
        }
        double classfy = makeComp(dis_label);
        cout << classfy << endl;
    }
    return 0;
}
时间: 2025-01-16 14:35:42

k-近邻算法学习的相关文章

机器学习2—K近邻算法学习笔记

Python3.6.3下修改代码中def classify0(inX,dataSet,labels,k)函数的classCount.iteritems()为classCount.items(),另外print在Python新版本下是函数,print后面需加上一对括号,否则执行会报错.第二章代码修改如下. from numpy import * import operator from os import listdir def classify0(inX, dataSet, labels, k)

02-16 k近邻算法

[TOC] 更新.更全的<机器学习>的更新网站,更有python.go.数据结构与算法.爬虫.人工智能教学等着你:https://www.cnblogs.com/nickchen121/ k近邻算法 k近邻算法(k-nearest neighbors,KNN)是一种基本的分类和回归方法,本文只探讨分类问题中的k近邻算法,回归问题通常是得出最近的$k$个实例的标记值,然后取这$k$实例标记值的平均数或中位数. k近邻算法经常被人们应用于生活当中,比如傅玄曾说过"近朱者赤近墨者黑&quo

R语言学习笔记—K近邻算法

K近邻算法(KNN)是指一个样本如果在特征空间中的K个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性.即每个样本都可以用它最接近的k个邻居来代表.KNN算法适合分类,也适合回归.KNN算法广泛应用在推荐系统.语义搜索.异常检测. KNN算法分类原理图: 图中绿色的圆点是归属在红色三角还是蓝色方块一类?如果K=5(离绿色圆点最近的5个邻居,虚线圈内),则有3个蓝色方块是绿色圆点的"最近邻居",比例为3/5,因此绿色圆点应当划归到蓝色方块一类:如果

K 近邻算法

声明: 1,本篇为个人对<2012.李航.统计学习方法.pdf>的学习总结,不得用作商用,欢迎转载,但请注明出处(即:本帖地址). 2,因为本人在学习初始时有非常多数学知识都已忘记,所以为了弄懂当中的内容查阅了非常多资料.所以里面应该会有引用其它帖子的小部分内容,假设原作者看到能够私信我,我会将您的帖子的地址付到以下. 3.假设有内容错误或不准确欢迎大家指正. 4.假设能帮到你.那真是太好了. 描写叙述 给定一个训练数据集,对新的输入实例.在训练数据集中找到与该实例最邻近的K个实例,若这K个实

从K近邻算法、距离度量谈到KD树、SIFT+BBF算法

从K近邻算法.距离度量谈到KD树.SIFT+BBF算法 从K近邻算法.距离度量谈到KD树.SIFT+BBF算法 前言 前两日,在微博上说:“到今天为止,我至少亏欠了3篇文章待写:1.KD树:2.神经网络:3.编程艺术第28章.你看到,blog内的文章与你于别处所见的任何都不同.于是,等啊等,等一台电脑,只好等待..”.得益于田,借了我一台电脑(借他电脑的时候,我连表示感谢,他说“能找到工作全靠你的博客,这点儿小忙还说,不地道”,有的时候,稍许感受到受人信任也是一种压力,愿我不辜负大家对我的信任)

统计学习方法 (第3章)K近邻法 学习笔记

第3章 K近邻法 k近邻算法简单.直观:给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的k个实例,这k个实例的多数属于某个类,就把该输入实例分为这个类.当K=1时,又称为最近邻算法,这时候就是将训练数据集中与x最邻近点作为x的类. 3.1 k近邻模型 模型由三个基本要素--距离度量.k值得选择.和分类决策规则决定. 3.1.1 距离度量 p=2时,称为欧式距离,p=1时,称为曼哈顿距离. 3.1.2 k值的选择 k 值的选择会对k 近邻法的结果产生重大影响.如果选择较小的k

K近邻算法

1.1.什么是K近邻算法 何谓K近邻算法,即K-Nearest Neighbor algorithm,简称KNN算法,单从名字来猜想,可以简单粗暴的认为是:K个最近的邻居,当K=1时,算法便成了最近邻算法,即寻找最近的那个邻居.为何要找邻居?打个比方来说,假设你来到一个陌生的村庄,现在你要找到与你有着相似特征的人群融入他们,所谓入伙. 用官方的话来说,所谓K近邻算法,即是给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的K个实例(也就是上面所说的K个邻居),这K个实例的多数属

K近邻算法-KNN

何谓K近邻算法,即K-Nearest Neighbor algorithm,简称KNN算法,单从名字来猜想,可以简单粗暴的认为是:K个最近的邻居,当K=1时,算法便成了最近邻算法,即寻找最近的那个邻居.为何要找邻居?打个比方来说,假设你来到一个陌生的村庄,现在你要找到与你有着相似特征的人群融入他们,所谓入伙. 用官方的话来说,所谓K近邻算法,即是给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的K个实例(也就是上面所说的K个邻居),这K个实例的多数属于某个类,就把该输入实例分

k近邻算法理论(一)

时间 :2014.07.05 地点:基地 ----------------------------------------------------------------------------------- 一.简述 K近邻法(k-nearest neighbor,kNN)是一种基本分类与回归方法.k近邻的输入为实例的特征向量,对应特征空间中的点,输出为实例的类别.k近邻算法的基本思想是:给定训练数据集,实例类别已定,在对目标实例进行分类时,我们根据与目标实例k个最近邻居的训练实例的类别,通过

基本分类方法——KNN(K近邻)算法

在这篇文章 http://www.cnblogs.com/charlesblc/p/6193867.html 讲SVM的过程中,提到了KNN算法.有点熟悉,上网一查,居然就是K近邻算法,机器学习的入门算法. 参考内容如下:http://www.cnblogs.com/charlesblc/p/6193867.html 1.kNN算法又称为k近邻分类(k-nearest neighbor classification)算法. 最简单平凡的分类器也许是那种死记硬背式的分类器,记住所有的训练数据,对于