本文来自同步博客

P.S. 不知道怎么显示数学公式以及排版文章。所以如果觉得文章下面格式乱的话请自行跳转到上述链接。后续我将不再对数学公式进行截图,毕竟行内公式截图的话排版会很乱。看原博客地址会有更好的体验。

本文内容介绍机器学习的K近邻算法,用它处理分类问题。分类问题的目标是利用采集到的已经经过分类处理的数据来预测新数据属于何种类别。

K近邻算法

K近邻算法对给定的某个新数据,让它与采集到的样本数据点分别进行比较,从中选择最相似的K个点,然后统计这K个点中出现的各个类别的频数,并判定频数最高的类别作为新数据所属的类别。

这里有个问题是如何判定样本数据与新数据是否相似。常用的一种计算方法叫欧几里得距离。

欧几里得距离(Euclidean Distance)

假设有两个数据分别是:$- X = (x_1,x_2,...,x_n) -$和$- Y = (y_1,y_2,...,y_n) -$。则$-X-$与$-Y-$的距离为:

$$ D = \sqrt{\sum_{i=1}{n}(x_i-y_i)2} $$

Python实现这个式子代码如下:

def euclidean_distance(x, y):
if len(x) != len(y):
warnings.warn('Input error')
return sqrt( sum( [(x[i] - y[i])**2 for i in range(0, len(x))] ) ) print(euclidean_distance([1,2,3], [2,4,5]))

NumPy提供则可以用下面方法计算两个ndarray的距离:

np.linalg.norm(np.array([1,2,3]) - np.array([2,4,5]))

实现K近邻算法

接下来依照上面描述的算法原理实现K近邻算法。先定义一下输入数据的格式:

#二维测试数据的格式
dataset = {'k': [[1,2],[2,3],[3,1]], 'r':[[6,5],[7,7],[8,6]]}
new_features = [5,7]

我们假定样本数据的结构如dataset为一个字典类型的数据,字典的元素的关键字为类型名称,元素值为一个包含该类型所有样本点的列表。新数据为一个数据点。

所以K近邻算法的实现如下:

# KNN实现
def k_nearest_neighbors(data, predict, k=3):
if len(data) >= k:
warnings.warn('K less than total voting groups')
# 计算距离
distances = []
for group in data:
for features in data[group]:
#distance = euclidean_distance(features, predict)
distance = np.linalg.norm(np.array(features)-np.array(predict))
distances.append([distance, group])
# 排序后取前k项数据类别构成新数组
votes = [i[1] for i in sorted(distances)[:k]]
# 统计数组中频数最高的类别
vote_result = Counter(votes).most_common(1)[0][0]
return vote_result # 调用KNN
result = k_nearest_neighbors(dataset, new_features, k=3)
print(result)

使用真实数据测试

UCI网站的机器学习数据库中可以找到Breast Cancer Wisconsin(Original)的真实统计数据。数据可以从这个链接下载,数据的描述可以看这个链接

看到数据描述中提到了数据每一列的定义如下:

 
乳癌数据描述

这份数据的预测目标是判断给定特征数据对应的乳癌情况,2表示良性、4表示恶性。

根据描述我们先处理一下下载到的数据,给它的每一列加上个列名。这样在Python里面就可以把它当成一个CSV文件处理。我这里把它保存到了一个名为breast-cancer-wisconsin.data的文件里。形状如下:

 
数据格式

数据里面还有一些统计不到的数据,用英文问号?表示。还有一个很奇怪的现象是数据读取进来后有些数字会被处理成字符串类型,如'1'这样的数据。这些都需要我们提前处理一下。

df = pd.read_csv('./dataset/breast-cancer-wisconsin.data')
# 处理问号
df.replace('?', -99999, inplace=True)
# id字段不应该当成一个统计特征字段,因此去除该列的内容
df.drop(['id'], 1, inplace=True)
# 源数据有部分数据是字符串,如'1',这对我们的模型有影响,所以整理一下类型
# 用列表存放数据
full_data = df.astype(float).values.tolist()
random.shuffle(full_data) # 洗乱数据

接下来生成训练数据集和统计数据集,代码如下:

# 生成训练数据集和统计数据集
test_size = 0.2
train_set = {2:[], 4:[]} # 训练集,占80%
test_set = {2:[], 4:[]} # 统计集,占20%
train_data = full_data[:-int(test_size*len(full_data))]
test_data = full_data[-int(test_size*len(full_data)):]
for i in train_data:
train_set[i[-1]].append(i[:-1])
for i in test_data:
test_set[i[-1]].append(i[:-1])

最后,利用上述KNN函数统计测试数据的准确性。

correct = 0
total = 0
for group in test_set:
for data in test_set[group]:
vote = k_nearest_neighbors(train_set, data, k=5)
if group == vote:
correct += 1
total += 1
# 打印结果
print('correct: ', correct)
print('total: ', total)
print('Accuracy: ', correct/total)

完整代码请查看github链接

sklearn的K近邻算法

同样需要先处理一下数据并生成符合sklearn的输入格式的数据集。

from sklearn import model_selection
# 读取乳癌统计数据
df = pd.read_csv('./dataset/breast-cancer-wisconsin.data')
# 处理问号
df.replace('?', -99999, inplace=True)
# 因为ID字段与分类无关,所以去除他先,稍后我们看一下它的影响
df.drop(['id'], 1, inplace=True)
df = df.astype(float) # 生成数据集
X = np.array(df.drop(['class'], 1))
y = np.array(df['class'])
X_train, X_test, y_train, y_test = model_selection.train_test_split(X, y, test_size=0.2)

然后生成KNN模型对象,用数据训练模型,评估模型准确性。

from sklearn import neighbors
# 构建模型与训练
clf = neighbors.KNeighborsClassifier()
clf.fit(X_train, y_train) # 计算精确度
accuracy = clf.score(X_test, y_test)
print('Accuracy: ', accuracy) # 预测我们自己构造的数据属于哪个类型
example_measures = np.array([[4,2,1,1,1,2,3,2,1],[2,3,4,4,1,2,3,4,1]])
prediction = clf.predict(example_measures)
print('Predict resuct: ', prediction)

完整代码请查看github链接

 

机器学习03:K近邻算法的更多相关文章

  1. 机器学习之K近邻算法(KNN)

    机器学习之K近邻算法(KNN) 标签: python 算法 KNN 机械学习 苛求真理的欲望让我想要了解算法的本质,于是我开始了机械学习的算法之旅 from numpy import * import ...

  2. 【机器学习】k近邻算法(kNN)

    一.写在前面 本系列是对之前机器学习笔记的一个总结,这里只针对最基础的经典机器学习算法,对其本身的要点进行笔记总结,具体到算法的详细过程可以参见其他参考资料和书籍,这里顺便推荐一下Machine Le ...

  3. 第四十六篇 入门机器学习——kNN - k近邻算法(k-Nearest Neighbors)

    No.1. k-近邻算法的特点 No.2. 准备工作,导入类库,准备测试数据 No.3. 构建训练集 No.4. 简单查看一下训练数据集大概是什么样子,借助散点图 No.5. kNN算法的目的是,假如 ...

  4. 机器学习之K近邻算法

    K 近邻 (K-nearest neighbor, KNN) 算法直接作用于带标记的样本,属于有监督的算法.它的核心思想基本上就是 近朱者赤,近墨者黑. 它与其他分类算法最大的不同是,它是一种&quo ...

  5. 机器学习实战-k近邻算法

    写在开头,打算耐心啃完机器学习实战这本书,所用版本为2013年6月第1版 在P19页的实施kNN算法时,有很多地方不懂,遂仔细研究,记录如下: 字典按值进行排序 首先仔细读完kNN算法之后,了解其是用 ...

  6. 【机器学习】K近邻算法——多分类问题

    给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的K个实例,这K个实例的多数属于某个类,就把该类输入实例分为这个类. KNN是通过测量不同特征值之间的距离进行分类.它的的思路是:如 ...

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

    Python3.6.3下修改代码中def classify0(inX,dataSet,labels,k)函数的classCount.iteritems()为classCount.items(),另外p ...

  8. [机器学习] k近邻算法

    算是机器学习中最简单的算法了,顾名思义是看k个近邻的类别,测试点的类别判断为k近邻里某一类点最多的,少数服从多数,要点摘录: 1. 关键参数:k值 && 距离计算方式 &&am ...

  9. 机器学习:k-NN算法(也叫k近邻算法)

    一.kNN算法基础 # kNN:k-Nearest Neighboors # 多用于解决分裂问题 1)特点: 是机器学习中唯一一个不需要训练过程的算法,可以别认为是没有模型的算法,也可以认为训练数据集 ...

随机推荐

  1. [知了堂学习笔记]_记一次BootStrap的使用

    效果图如下: 一.简介: 什么是Bootstrap?  Bootstrap 是一个用于快速开发 Web 应用程序和网站的前端框架. 什么是响应式布局? 引用一句Bootstrap的标题语 " ...

  2. Django中的F和Q函数

    内容简介: 介绍Django中的F和Q作用以及使用方法 一.F介绍 作用:操作数据表中的某列值,F()允许Django在未实际链接数据的情况下具有对数据库字段的值的引用,不用获取对象放在内存中再对字段 ...

  3. 手把手教学系列:从零开始配置VPS服务器

    1.什么是VPS? 百度百科:VPS(Virtual Private Server 虚拟专用服务器)技术,将一台服务器分割成多个虚拟专享服务器的优质服务. 通俗地讲,可以认为就是一台放在机房机架上的服 ...

  4. linux_快照和克隆

    什么是快照? 操作虚拟机时候,想保存当前状态为以后操作失误快速那时保存的系统状态,想当于对系统的版本管理,每个节点之间可以互相切换 什么是克隆? 可以选择快照和当前状态,可选择链接克隆和完整克隆 链接 ...

  5. linux_运维职责

    运维准则: 不要删文件,移动文件,可以复原,一个月后什么事没有,删除 运维人员主要关注哪些方面? CPU:对计算机工作速度和效率起决定性作用(intel amd) 内存: 临时存放数据:容量和处理速度 ...

  6. python_判断变量类型

    需求: 已知有一个变量,我想对他进行预处理判断,如果这个变量是字符串,则在字符串后面加上后缀'_str',如果整形就让其加5,还比如我要求这个变量是整形或者字符串,都行 如何做? #!/usr/bin ...

  7. CDuiString和String的转换

    很多时候 难免用到CDuiString和string的转换. 我们应该注意到,CDuiString类有个方法: LPCTSTR GetData() const; 可以通过这个方法,把CDuiStrin ...

  8. springmvc配置文件配置的事务作用范围

    作用于service,不是controller,也不是mapper.所以,要保证原子性,就放在一个serviceimpl里,而不要放在一个controller 里 第一次与数据库打交道时,事务开启,s ...

  9. printf,sprintf,fprintf的比较

    1 printf,是把格式字符串输出到标准输出(一般是屏幕,可以重定向).2 sprintf,是把格式字符串输出到指定字符串中,所以参数比printf多一个char*.那就是目标字符串地址.3 fpr ...

  10. HTML5之Notification简单使用

    var webNotification = { init: function() { if(!this.isSupport()) { console.log('不支持通知'); return; } t ...