欢迎关注WX公众号:【程序员管小亮】

python学习之路 - 从入门到精通到大师

文章目录

  • 欢迎关注WX公众号:【程序员管小亮】
    • [python学习之路 - 从入门到精通到大师](https://blog.csdn.net/TeFuirnever/article/details/90017382)
    • 一、橙子还是柚子
    • 二、创建推荐系统
      • 1)特征抽取
      • 2)回归
      • 3)挑选合适的特征
    • 三、机器学习简介
      • 1)OCR
      • 2)创建垃圾邮件过滤器
      • 3)预测股票市场
    • 四、总结
    • 参考文章

一、橙子还是柚子

请看下边的水果,是橙子还是柚子呢?

你肯定会说,柚子通常比橙子更大、更红。但是思维过程类似于这样:脑子里有个图表。

一般而言,柚子更大、更红。这个水果又大又红,因此很可能是柚子。但下面这样的水果呢?

如果判断这个水果是橙子还是柚子呢?一种办法是看它的邻居。来看看离它最近的三个邻居。

在这三个邻居中,橙子比柚子多,因此这个水果很可能是橙子。祝贺你,刚才就是使用 K最近邻(k-nearest neighbours,KNN) 算法进行了分类!这个算法非常简单。

KNN算法虽然简单却很有用!要对东西进行分类时,可首先尝试这种算法。下面来看一个更真实的例子。

二、创建推荐系统

假设你是Netflix,要为用户创建一个电影推荐系统。从本质上说,这类似于前面的水果问题!你可以将所有用户都放入一个图表中。

这些用户在图表中的位置取决于其喜好,因此喜好相似的用户距离较近。假设你要向Priyanka推荐电影,可以找出五位与他最接近的用户。

假设在对电影的喜好方面,Justin、JC、Joey、Lance和Chris都与Priyanka差不多,因此他们喜欢的电影很可能Priyanka也喜欢!

有了这样的图表以后,创建推荐系统就将易如反掌:只要是Justin喜欢的电影,就将其推荐给Priyanka。

但还有一个重要的问题没有解决。在前面的图表中,相似的用户相距较近,但如何确定两位用户的相似程度呢?

1)特征抽取

在前面的水果示例中,你根据个头和颜色来比较水果,换言之,你比较的特征是个头和颜色。现在假设有三个水果,你可抽取它们的特征。

再根据这些特征绘图。

从上图可知,水果 A 和 B 比较像。下面来度量它们有多像。要计算两点的距离,可使用毕达哥拉斯公式。

例如,A和B的距离如下。

A 和 B 的距离为1。你还可计算其他水果之间的距离。

这个距离公式印证了你的直觉:A 和 B 很像。

假设你要比较的是Netflix用户,就需要以某种方式将他们放到图表中。因此,你需要将每位用户都转换为一组坐标,就像前面对水果所做的那样。

在能够将用户放入图表后,你就可以计算他们之间的距离了。

下面是一种将用户转换为一组数字的方式。用户注册时,要求他们指出对各种电影的喜欢程度。这样,对于每位用户,都将获得一组数字!

Priyanka和Justin都喜欢爱情片且都讨厌恐怖片。Morpheus喜欢动作片,但讨厌爱情片(他讨厌好好的动作电影毁于浪漫的桥段)。前面判断水果是橙子还是柚子时,每种水果都用2个数字表示,你还记得吗?在这里,每位用户都用5个数字表示。

在数学家看来,这里计算的是五维(而不是二维)空间中的距离,但计算公式不变。

这个公式包含5个而不是2个数字。

这个距离公式很灵活,即便涉及很多个数字,依然可以使用它来计算距离。你可能会问,涉及5个数字时,距离意味着什么呢?这种距离指出了两组数字之间的相似程度。

这是Priyanka和Justin的距离。可以看出Priyanka和Justin很像。而Priyanka和Morpheus的距离为24,上述距离表明,Priyanka的喜好更接近于Justin而不是Morpheus。

太好了!现在要向Priyanka推荐电影将易如反掌:只要是Justin喜欢的电影,就将其推荐给Priyanka,反之亦然。你这就创建了一个电影推荐系统!

如果你是Netflix用户,Netflix将不断提醒你:多给电影评分吧,你评论的电影越多,给你的推荐就越准确。现在你明白了其中的原因:你评论的电影越多,Netflix就越能准确地判断出你与哪些用户类似。

2)回归

假设你不仅要向Priyanka推荐电影,还要预测她将给这部电影打多少分。为此,先找出与她最近的5个人。

顺便说一句,我老说最近的5个人,其实并非一定要选择5个最近的邻居,也可选择2个、10个或10 000个。这就是这种算法名为K最近邻而不是5最近邻的原因!

假设你要预测Priyanka会给电影Pitch Perfect打多少分。Justin、JC、Joey、Lance和Chris都给它打了多少分呢?

求这些人打的分的平均值,结果为4.2。这就是 回归(regression)。你将使用KNN来做两项基本工作——分类回归

  • 分类就是编组;
  • 回归就是预测结果(如一个数字)。

回归很有用。假设你在伯克利开个小小的面包店,每天都做新鲜面包,需要根据如下一组特征预测当天该烤多少条面包:

  • 天气指数1~5(1表示天气很糟,5表示天气非常好);
  • 是不是周末或节假日(周末或节假日为1,否则为0);
  • 有没有活动(1表示有,0表示没有)。

你还有一些历史数据,记录了在各种不同的日子里售出的面包数量。

今天是周末,天气不错。根据这些数据,预测今天能售出多少条面包呢?我们来使用KNN算法,其中的K为4。

首先,找出与今天最接近的4个邻居。

距离如下,因此最近的邻居为A、B、D和E。

将这些天售出的面包数平均,结果为218.75。这就是你今天要烤的面包数!

上面举例中在计算两位用户的距离时,使用的都是距离公式。还有更合适的公式吗?在实际工作中,经常使用余弦相似度(cosine similarity)。
余弦相似度,又称为余弦相似性,是通过计算两个向量的夹角余弦值来评估他们的相似度。余弦相似度将向量根据坐标值,绘制到向量空间中,如最常见的二维空间。
假设有两位品味类似的用户,但其中一位打分时更保守。他们都很喜欢Manmohan Desai的电影Amar Akbar Anthony,但Paul给了5星,而Rowan只给4星。如果你使用距离公式,这两位用户可能不是邻居,虽然他们的品味非常接近。余弦相似度不计算两个矢量的距离,而比较它们的角度,因此更适合处理前面所说的情况。
如果你要使用KNN,就一定要研究研究它!

3)挑选合适的特征

为了推荐电影,让用户指出他对各类电影的喜好程度。如果是让用户给一系列小猫图片打分呢?在这种情况下,你找出的是对小猫图片的欣赏品味类似的用户。对电影推荐系统来说,这很可能是一个糟糕的推荐引擎,因为选择的特征与电影欣赏品味没多大关系。

又假设你只让用户给《玩具总动员》《玩具总动员2》和《玩具总动员3》打分。这将难以让用户的电影欣赏品味显现出来!使用KNN时,挑选合适的特征进行比较至关重要。所谓合适的特征,就是:

  • 与要推荐的电影紧密相关的特征;
  • 不偏不倚的特征(例如,如果只让用户给喜剧片打分,就无法判断他们是否喜欢动作片)。

你认为评分是不错的电影推荐指标吗?我给The Wire的评分可能比House Hunters高,但实际上观看House Hunters的时间更长。该如何改进Netflix的推荐系统呢?

回到面包店的例子:对于面包店,你能找出两个不错和糟糕的特征吗?在报纸上打广告后,你可能需要烤制更多的面包;或者每周一你都需要烤制更多的面包。在挑选合适的特征方面,没有放之四海皆准的法则,你必须考虑到各种需要考虑的因素。

三、机器学习简介

  • 《机器学习实战》学习笔记(二):k-近邻算法

KNN算法真的是很有用,堪称你进入神奇的机器学习领域的领路人!机器学习旨在让计算机更聪明。你见过一个机器学习的例子:创建推荐系统。下面再来看看其他一些例子。

1)OCR

OCR指的是 光学字符识别(optical character recognition),这意味着你可拍摄印刷页面的照片,计算机将自动识别出其中的文字。Google使用OCR来实现图书数字化。OCR是如何工作的呢?来看一个例子,请看下面的数字。

如何自动识别出这个数字是什么呢?可使用KNN。

  1. 浏览大量的数字图像,将这些数字的特征提取出来。
  2. 遇到新图像时,提取该图像的特征,再找出它最近的邻居都是谁!

这与前面判断水果是橙子还是柚子时一样。一般而言,OCR算法提取线段、点和曲线等特征。

遇到新字符时,可从中提取同样的特征。

与前面的水果示例相比,OCR中的特征提取要复杂得多,但再复杂的技术也是基于KNN等简单理念的。这些理念也可用于语音识别和人脸识别。你将照片上传到Facebook时,它有时候能够自动标出照片中的人物,这是机器学习在发挥作用!

OCR的第一步是查看大量的数字图像并提取特征,这被称为 训练(training)。大多数机器学习算法都包含训练的步骤:要让计算机完成任务,必须先训练它。下一个示例是垃圾邮件过滤器,其中也包含训练的步骤。

python版本代码如下,数据集是手写数字识别,仅供参考:

from os import listdir
from numpy import *
import numpy as np
import operator
import datetimedef KNN(test_data,train_data,train_label,k):#已知分类的数据集(训练集)的行数dataSetSize = train_data.shape[0]#求所有距离:先tile函数将输入点拓展成与训练集相同维数的矩阵,计算测试样本与每一个训练样本的距离all_distances = np.sqrt(np.sum(np.square(tile(test_data,(dataSetSize,1))-train_data),axis=1))#print("所有距离:",all_distances)#按all_distances中元素进行升序排序后得到其对应索引的列表sort_distance_index = all_distances.argsort()#print("文件索引排序:",sort_distance_index)#选择距离最小的k个点classCount = {}for i in range(k):#返回最小距离的训练集的索引(预测值)voteIlabel = train_label[sort_distance_index[i]]#print('第',i+1,'次预测值',voteIlabel)classCount[voteIlabel] = classCount.get(voteIlabel,0)+1#求众数:按classCount字典的第2个元素(即类别出现的次数)从大到小排序sortedClassCount = sorted(classCount.items(), key = operator.itemgetter(1), reverse = True)return sortedClassCount[0][0]#文本向量化 32x32 -> 1x1024
def img2vector(filename):returnVect = []fr = open(filename)for i in range(28):lineStr = fr.readline()for j in range(28):returnVect.append(int(lineStr[j]))return returnVect#从文件名中解析分类数字
def classnumCut(fileName):#参考文件名格式为:0_3.txtfileStr = fileName.split('.')[0]classNumStr = int(fileStr.split('_')[0])return classNumStr#构建训练集数据向量,及对应分类标签向量
def trainingDataSet():train_label = []trainingFileList = listdir('trainingDigits')m = len(trainingFileList)train_data = zeros((m,1024))#获取训练集的标签for i in range(m):# fileNameStr:所有训练集文件名fileNameStr = trainingFileList[i]# 得到训练集索引train_label.append(classnumCut(fileNameStr))train_data[i,:] = img2vector('trainingDigits/%s' % fileNameStr)return train_label,train_data#测试函数
def main():t1 = datetime.datetime.now()  # 计时开始Nearest_Neighbor_number = int(input('选取最邻近的K个值,K='))train_label,train_data = trainingDataSet()testFileList = listdir('testDigits')error_sum = 0test_number = len(testFileList)for i in range(test_number):#测试集文件名fileNameStr = testFileList[i]#切片后得到测试集索引classNumStr = classnumCut(fileNameStr)test_data = img2vector('testDigits/%s' % fileNameStr)#调用knn算法进行测试classifierResult = KNN(test_data, train_data, train_label, Nearest_Neighbor_number)print ("第",i+1,"组:","预测值:",classifierResult,"真实值:",classNumStr)if (classifierResult != classNumStr):error_sum += 1.0print ("\n测试集总数为:",test_number)print ("测试出错总数:",error_sum)print ("\n错误率:",error_sum/float(test_number)*100,'%')t2 = datetime.datetime.now()print('耗 时 = ', t2 - t1)if __name__ == "__main__":main()

MATLAB版本代码如下:

function foo = main()addpath('mnistHelper');train_images = loadMNISTImages('train-images-idx3-ubyte');train_labels = loadMNISTLabels('train-labels-idx1-ubyte');test_images = loadMNISTImages('t10k-images-idx3-ubyte');test_labels = loadMNISTLabels('t10k-labels-idx1-ubyte');% showData(train_images, 100, 100);guesses(20, 3, train_images, train_labels, test_images, test_labels);
endfunction foo = showData(images, rows, cols)grid = [];i = 0;for x = 1:rowsimgs = [];for y = 1:colsi = i + 1;imgs = [imgs reshape(images(:, i), 28, 28)];endgrid = [grid; imgs];endimshow(grid);
endfunction d = distance(train_image, test_image)v = train_image - test_image;v = double(v);d = sqrt(v * v');
endfunction result = border(image, value)image = reshape(image, 28, 28);result = zeros(28, 28);result(:, :) = value;result(2:27, 2:27) = image(2:27, 2:27);result = reshape(result, 784, 1);
endfunction foo = guesses(count, k, train_images, train_labels, test_images, test_labels)[foo num_train_images] = size(train_images);[foo num_test_images] = size(test_images);correct = 0;grid = [];for x_ = 1:countx = floor(rand() * num_test_images);test_image = test_images(:, x);        correct_label = test_labels(x);dist = [];num_train_images = 50000;for i = 1:num_train_imagestrain_image = train_images(:, i);d = distance(train_image', test_image');dist = [dist; [d i]];endsorted_ = (sortrows(dist, 1));sorted = sorted_(1:k, :);labels = [];for i = 1:kgrid = [grid train_images(:, sorted(i, 2))];labels = [labels train_labels(sorted(i, 2))];endguess_label = mode(labels);if guess_label == correct_labelcorrect = correct + 1;grid = [grid test_image];elsegrid = [grid border(test_image, 255)];endendcorrectshowData(grid, count, k+1);
end

2)创建垃圾邮件过滤器

垃圾邮件过滤器使用一种简单算法——朴素贝叶斯分类器(Naive Bayes classifier)(《机器学习实战》学习笔记(四):基于概率论的分类方法 - 朴素贝叶斯),你首先需要使用一些数据对这个分类器进行训练。

假设你收到一封主题为“collect your million dollars now!”的邮件,这是垃圾邮件吗?你可研究这个句子中的每个单词,看看它在垃圾邮件中出现的概率是多少。例如,使用这个非常简单的模型时,发现只有单词million在垃圾邮件中出现过。朴素贝叶斯分类器能计算出邮件为垃圾邮件的概率,其应用领域与KNN相似。

例如,你可使用朴素贝叶斯分类器来对水果进行分类:假设有一个又大又红的水果,它是柚子的概率是多少呢?朴素贝叶斯分类器也是一种简单而极其有效的算法。我们钟爱这样的算法!

3)预测股票市场

使用机器学习来预测股票市场的涨跌真的很难。对于股票市场,如何挑选合适的特征呢?股票昨天涨了,今天也会涨,这样的特征合适吗?又或者每年五月份股票市场都以绿盘报收,这样的预测可行吗?在根据以往的数据来预测未来方面,没有万无一失的方法。未来很难预测,由于涉及的变数太多,这几乎是不可能完成的任务。

四、总结

  • KNN用于分类和回归,需要考虑最近的邻居。
  • 分类就是编组。
  • 回归就是预测结果(如数字)。
  • 特征抽取意味着将物品(如水果或用户)转换为一系列可比较的数字。
  • 能否挑选合适的特征事关KNN算法的成败。

参考文章

  • 《算法图解》

《算法图解》学习笔记(十):K 最近邻算法(附代码)相关推荐

  1. 算法图解学习笔记02:递归和栈

    计算机内存原理 要说递归和栈的问题,首先就要说下计算机内存的基本原理.简单理解计算机内存原理可以将一台电脑看作超市的存包柜,每个柜子都有柜号(即计算机中的地址,如0x000000f).当需要将数据存储 ...

  2. 算法图解学习笔记01:二分查找大O表示法

    二分查找 二分查找又称折半查找,其输入的必须是有序的元素列表.二分查找的基本思想是将n个元素分成大致相等的两部分,取a[n/2]与x做比较,如果x=a[n/2],则找到x,算法中止:如果x<a[ ...

  3. 算法图解学习笔记01之二分查找

    不知道可以学到第几章,就不立flag了,容易倒 你要学会的不是写算法而是何时何地用何算法 package 第一章; //数组有序,要求快速查找出数据 public class BinarySearch ...

  4. 算法图解——学习笔记

    文章目录 算法简介 **第二章 选择排序** 数组与链表 排序算法 算法简介 算法:一组完成任务的指令,任何片段都可以视为算法. 第一章 算法集合: 算法种类 定义 二分法 一种查询方法,通过将查找特 ...

  5. 算法图解学习笔记02之选择排序

    package 第二章;import java.util.Arrays;//找出列表中最小(大)的,放入新列表(O(n)),再次找 public class SelectionSort {public ...

  6. 算法导论学习笔记 第2章 算法基础

    本章介绍了一个贯穿本书的框架,后续的算法设计都是在这个框架中进行的. 本章通过插入排序和归并排序两种常见的算法来说明算法的过程及算法分析,在分析插入排序算法时,书中是用了循环不变式证明了算法的正确性, ...

  7. 【算法竞赛学习笔记】莫队算法-超优雅的暴力算法

    title : 莫队算法 tags : ACM,暴力 date : 2021-10-30 author : Linno 普通莫队 常用操作:分块/排序/卡常/离散化等,直接上板子. luoguP270 ...

  8. 《算法图解-像小说一样有趣的算法入门书》最全读书笔记--Binrry(冰蕊)

    点击关注,期待Binrry(冰蕊)带给你更多更全的读书笔记-- 可点击下面链接下载本书具体代码执行辅助学习噢: https://download.csdn.net/download/qq_408598 ...

  9. 算法训练营学习笔记1

    算法训练营学习笔记 贪心算法 心算法总是做出当前最好的选择,期望通过局部最优选择得到全局最优的解决方案.从问题的初始解开始,一步歩地做出当前最好的选择,逐步逼近问题的目标,尽可能得到最优解: 贪心本质 ...

  10. 计算机视觉算法——Transformer学习笔记

    算机视觉算法--Transformer学习笔记 计算机视觉算法--Transformer学习笔记 1. Vision Transformer 1.1 网络结构 1.2 关键知识点 1.2.1 Self ...

最新文章

  1. HMM——维特比算法(Viterbi algorithm)
  2. 怎么用Leangoo管理Bug
  3. 师弟走了,以我们都想不到的方式
  4. 采用Kruskal算法生成最小生成树,并采用并查集的合并优化和查询优化。
  5. Problem F: 结构体--学生信息排序
  6. 《小强升职记》读后感和思维导图
  7. php获取当地时间 time zone
  8. 8月8日白暨豚宣告灭绝
  9. Java/JSP中使用JDBC连接SQL Server 2000/2005
  10. Vue.js的虚拟dom
  11. C++ 内存分配 学习笔记
  12. 零跑C-more收获更多期待,而零跑S01还在追求更多的订单 | 2019 上海车展...
  13. 学计算机信息管理专业的感谢,2014年计算机信息管理专业自荐信
  14. 附下载,《爱分析·中国BI商业智能行业报告》
  15. 链表:头插法与尾插法(简易图解和代码)
  16. [学习报告]《LeetCode零基础指南》(第五讲) 指针-gyro
  17. QQ、微信、新浪 利用refresh_token重新登录
  18. 教你如何在软文中设置关键词
  19. openlayers 展示gif的2种方案
  20. 网页设计标记工具——马克鳗

热门文章

  1. MySQL查询 json 字段中是否包含某个value
  2. vue百度地图api 获取小区边界值
  3. C语言习题:/*键盘输入两个非零整数A和B,如果A和B都是偶数则输出两个数的和,如果A和B都是奇数则输出两个数的差,如果A是奇数B是偶数则输出两数积,如果A是偶数B是奇数输出AVB结果*/
  4. 计算机维修中拆机工具有哪些,秒变专业拆机维修达人,这款工具套装你值得拥有...
  5. 虹膜识别—DeepIrisNet2
  6. Openkruise/rollouts 源码解读
  7. SkipList原理及实现
  8. 当 AI 应用在心理健康领域是怎样的体验? #Woebot Health
  9. puppy linux安装中文包,Puppy Linux 4.00 的中文支持包
  10. exp备份oracle报错1455,EXP-00008 遇到 ORACLE 错误 1455