您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Model Center   Code  
会员   
   
 
     
   
 订阅
  捐助
Python机器学习与实践——简介篇
 
   次浏览      
 2018-1-16 
 
编辑推荐:
来源于csdn,一开始介绍为主,然后介绍的概念为主,最后结合医疗实例详细介绍的,希望对大家有帮助。

周四晚上胡哥给大家简单培训了一下nlp的一些算法,感觉受益匪浅。回去之后反省了一下,有段时间没看机器学习的东西了,nlp要抓,机器学习也要学。开个坑,记录和分享一下学习内容(书籍为《python机器学习及实践》)。

首先先以介绍为主。

1959年,美国的前IBM员工塞缪尔开发了一个西洋棋程序,这个程序可以在于人类棋手对弈的过程中,不断改善自己的棋艺。在4年之后,这个程序战胜了设计者本人;并且又过了3年,战胜了美国一位保持8年常胜不败的专业棋手。

最近谷歌的DeepMind研究团队正式宣布其创造和撰写的机器学习程序AlphaGo以4:1的总比分击败了世界顶级选手李世石,后来进化后的AlphaGo又以3:0的总比分击败了世界排名第一的柯洁。

根据机器学习理论先驱、缪赛尔先生的说法,他并没有编写具体的程序告诉西洋棋程序如何行棋。事实上,这也是不可能的,因为下棋策略千变万化,我们无法通过编写完备的,哪怕是固定的执行规程来挑战人类棋手。从塞缪尔的西洋棋程序,到谷歌的AlphaGo,我们可以总结出机器学习系统的如下特点:

1)许多机器学习系统所解决的都是无法直接使用固定规则或者流程代码完成的问题,通常这类问题对人类而言很简单。比如,计算机和手机里的计算器就不属于具备智能的系统,因为里面的计算方法都有清楚而且固定的规程;但是如果要求一台机器去辨别一张相片中有哪些人和物体,这对人来讲很容易,机器却很难做到。

2)所谓具备“学习”能力的程序都是指它能够不断地从经历和数据中吸取经验教训,从而应对未来的预测任务。我们习惯把这种对为未知的预测能力叫做泛化力。

3)机器学习更加诱人的地方在于,它具备不断改善自身应对具体任务的能力。我们习惯把这种完成任务的能力称为性能。塞缪尔的西洋棋程序和谷歌的AlphaGo都是典型的借助过去对弈的经验或棋谱,不断提高自身性能的机器学习系统。

以上是通过西洋棋程序的例子总结的一些机器学习系统所具备的特效,但是这里再引述一下美国卡内基梅隆大学(大学学的课程是几年前引入的cmu的教程。。话说很羡慕去cmu读研的小伙伴,最近还拿了微软的special offer)机器学习领域的著名教授Tom Mitchell的经典定义来阐述机器学习理论的开篇:

英文原话这里就不打了,感兴趣可以自己去百度,此处放翻译:如果一个程序在使用既有的经验(E)执行某类任务(T)的过程中被认定为“具备学习能力的”,那么它一定需要展现出:利用现有的经验(E),不断改善其完成既定任务(T)的性能(P)的特质。

说白了,就是说“只有能利用现有经验不断完善自身性能的程序才有资格称为机器学习程序。”

继续以介绍为主

任务:

机器学习的任务有很多,这里我们侧重于对两类经典的任务进行讲解和实践:监督学习和非监督学习。关于这两者的概念,不清楚的可以去看监督学习和非监督学习的区别。

这里补充一点非监督学习的内容,非监督学习常用的技术包括数据降维和聚类问题等。主要补充数据降维的概念,数据降维是对事物的特性进行压缩和筛选,这项任务相对比较抽象。如果我们没有特定的领域知识,是无法预先先确定采样哪些数据的;而如今,传感设备的采样成本相对较低,相反,筛选有效信息的成本更高。比如,在识别图像中人脸的任务中,我们可以直接读取到图像像素信息,若是直接使用这些像素信息,那么数据的维度会非常高,特别是在图像分辨率越来越高的今天。因此,我们通常会使用数据降维的技术对图像进行降维,保留最具有区分度的像素组合。

经验:

我们习惯性地把数据视作经验;事实上,只有那些对学习任务有用的特定信息才会被列入考虑范围。而我们通常把这些反映数据内在规律的信息叫做特征。比如前面提到的人脸图像识别任务中,我们很少直接把图像最原始的像素信息作为经验交给学习系统;而是通过降维,甚至一些更为复杂的数据处理方法得到更加有助于人脸识别的轮廓特征。

对于监督学习问题,我们所拥有的经验包括特征和标记/目标两个部分。我们一般用一个特征向量来描述一个数据样本;标记/目标的表现形式则取决于监督学习的种类。

无监督学习问题自然没有标记/目标,因此无法从事预测任务,却更适合对数据结构的分析。正是因为这个区别,我们经常可以获得大量的无监督数据;而监督数据的标注因为经常耗费大量的时间、金钱和人力,所以数据量相对较少。

性能:

所谓性能,便是评价所完成任务质量的指标。为了评价学习模型完成任务的质量,我们需要具备相同特征的数据,并将模型的预测结果同相对应的正确答案进行比对。我们称这样的数据集为测试集。而且更为重要的是,我们需要保证,出现在测试集中的数据样本一定不能被用于模型训练。简而言之,训练集和测试集之间是互斥的。

对于预测性质的问题,我们经常关注预测的精度。具体来讲:分类问题,我们要根据预测正确类别的百分比来评价其性能,这个指标通常被称作准确性;回归问题则无法使用类似的指标,我们通常会衡量预测值与实际值之间的偏差大小。

以下就要结合具体python代码和烂大街的肿瘤预测问题了。

根据上述的描述,大家可以确定“良/恶性乳腺癌肿瘤预测”的问题属于二分类任务。待预测的类别分别是良性乳腺癌肿瘤和恶性乳腺癌肿瘤。通常我们使用离散的整数来代表类别。如下表,“肿瘤类型”一列列出了肿瘤的类型;0代表良性,1代表恶性。

完整的数据集肿瘤的特征不止这两个,但是在这个例子中我们只取这两个特征,并且测试集数量为175条。我们先看一下这175条肿瘤样本在二维特征空间的分布情况,如下图所示。X代表恶性肿瘤,O代表良性肿瘤。

绘制这张图的代码如下:

# -*- coding:utf-8 -*-
# 导入pandas包,别名为pd
import pandas as pd

# 使用pandas的read_csv函数,将训练集读取进来并存至变量df_train
df_train = pd.read_csv('breast-cancer-train.csv')

# 使用pandas的read_csv函数,将测试集读取进来并存至变量df_test
df_test = pd.read_csv('breast-cancer-test.csv')

# 选取Clump Thickness和Cell Size作为特征,构建测试集中的正负分类样本
df_test_negative = df_test.loc[df_test['Type'] == 0][['Clump Thickness', 'Cell Size']]
df_test_positive = df_test.loc[df_test['Type'] == 1][['Clump Thickness', 'Cell Size']]

# 导入matplotlib工具包中的pyplot并命名为plt
import matplotlib.pyplot as plt
# 绘制图中的良性肿瘤样本点,标记为红色的o
plt.scatter(df_test_negative['Clump Thickness'], df_test_negative['Cell Size'], marker='o', s=200, c='red')
# 绘制图中的恶心肿瘤样本点,标记为黑色的x
plt.scatter(df_test_positive['Clump Thickness'], df_test_positive['Cell Size'], marker='x', s=150, c='black')
# 绘制x,y轴说明
plt.xlabel('Clump Thickness')
plt.ylabel('Cell Size')
# 显示图
plt.show()

随后我们随机初始化一个二类分类器,这个分类器用一条直线来划分良/恶性肿瘤。决定这条直线的走向有两个因素:直线的斜率和截距。这些被我们称为模型的参数,也是分类器需要通过学习从训练数据中得到的。最初,随机初始化参数的分类器的性能表现如下图所示:

绘制这张图的代码如下:

<span style="font-size:12px;"># -*- coding:utf-8 -*-
# 导入pandas包,别名为pd
import pandas as pd
# 导入matplotlib工具包中的pyplot并命名为plt
import matplotlib.pyplot as plt
# 使用pandas的read_csv函数,将训练集读取进来并存至变量df_train
df_train = pd.read_csv('breast-cancer-train.csv')
# 使用pandas的read_csv函数,将测试集读取进来并存至变量df_test
df_test = pd.read_csv('breast-cancer-test.csv')
# 选取Clump Thickness和Cell Size作为特征,构建测试集中的正负分类样本
df_test_negative = df_test.loc[df_test['Type'] == 0][['Clump Thickness', 'Cell Size']]
df_test_positive = df_test.loc[df_test['Type'] == 1][['Clump Thickness', 'Cell Size']]
# 导入numpy工具包,重命名为np
import numpy as np
# 利用numpy中的random函数随机采样直线的截距和系数
intercept = np.random.random([1])
coef = np.random.random([2])
lx = np.arange(0, 12)
ly = (-intercept - lx * coef[0]) / coef[1]
# 绘制一条随机直线
plt.plot(lx, ly, c='yellow')
plt.scatter(df_test_negative['Clump Thickness'], df_test_negative['Cell Size'], marker='o', s=200, c='red')
plt.scatter(df_test_positive['Clump Thickness'], df_test_positive['Cell Size'], marker='x', s=150, c='black')
plt.xlabel('Clump Thickness')
plt.ylabel('Cell Size')
plt.show()</span>

随后我们使用一定量训练样本,分类器所表现的性能有了大幅度的提示,如下图:

绘制这张图的代码如下:

<span style="font-size:12px;"># -*- coding:utf-8 -*-
# 导入pandas包,别名为pd
import pandas as pd
# 导入numpy工具包,重命名为np
import numpy as np
# 导入matplotlib工具包中的pyplot并命名为plt
import matplotlib.pyplot as plt
# 导入sklearn中的逻辑斯蒂回归分类器
from sklearn.linear_model import LogisticRegression
# 使用pandas的read_csv函数,将训练集读取进来并存至变量df_train
df_train = pd.read_csv('breast-cancer-train.csv')
# 使用pandas的read_csv函数,将测试集读取进来并存至变量df_test
df_test = pd.read_csv('breast-cancer-test.csv')
# 选取Clump Thickness和Cell Size作为特征,构建测试集中的正负分类样本
df_test_negative = df_test.loc[df_test['Type'] == 0][['Clump Thickness', 'Cell Size']]
df_test_positive = df_test.loc[df_test['Type'] == 1][['Clump Thickness', 'Cell Size']]
lr = LogisticRegression()
# 使用前10条训练样本学习直线的系数和截距
lr.fit(df_train[['Clump Thickness', 'Cell Size']][:10], df_train['Type'][:10])
print 'Testing accuracy (10 training samples):', lr.score(df_test[['Clump Thickness', 'Cell Size']], df_test['Type'])
intercept = lr.intercept_
coef = lr.coef_[0, :]
lx = np.arange(0, 12)
# 原本这个分类面应该是lx*coef[0] + ly*coef[1] + intercept=0 映射到2维平面上之后,应该是:
ly = (-intercept - lx * coef[0]) / coef[1]
plt.plot(lx, ly, c='green')
plt.scatter(df_test_negative['Clump Thickness'], df_test_negative['Cell Size'], marker='o', s=200, c='red')
plt.scatter(df_test_positive['Clump Thickness'], df_test_positive['Cell Size'], marker='x', s=150, c='black')
plt.xlabel('Clump Thickness')
plt.ylabel('Cell Size')
plt.show()</span>

print的值为:Testing accuracy (10 training samples): 0.868571428571

如上图所示,当学习了10条训练样本时,分类器的性能改进了一些,测试集上的分类准确性为86.9%;我们继续学习所有训练样本,分类器的性能进一步提升,在测试集上的分类准确性最终达到93.7%,如下图:

绘制这张图的代码如下:

# -*- coding:utf-8 -*-
# 导入pandas包,别名为pd
import pandas as pd
# 导入numpy工具包,重命名为np
import numpy as np
# 导入matplotlib工具包中的pyplot并命名为plt
import matplotlib.pyplot as plt
# 导入sklearn中的逻辑斯蒂回归分类器
from sklearn.linear_model import LogisticRegression
# 使用pandas的read_csv函数,将训练集读取进来并存至变量df_train
df_train = pd.read_csv('breast-cancer-train.csv')
# 使用pandas的read_csv函数,将测试集读取进来并存至变量df_test
df_test = pd.read_csv('breast-cancer-test.csv')
# 选取Clump Thickness和Cell Size作为特征,构建测试集中的正负分类样本
df_test_negative = df_test.loc[df_test['Type'] == 0][['Clump Thickness', 'Cell Size']]
df_test_positive = df_test.loc[df_test['Type'] == 1][['Clump Thickness', 'Cell Size']]
lr = LogisticRegression()
# 使用前10条训练样本学习直线的系数和截距
lr.fit(df_train[['Clump Thickness', 'Cell Size']], df_train['Type'])
print 'Testing accuracy (10 training samples):', lr.score(df_test[['Clump Thickness', 'Cell Size']], df_test['Type'])
intercept = lr.intercept_
coef = lr.coef_[0, :]
lx = np.arange(0, 12)
# 原本这个分类面应该是lx*coef[0] + ly*coef[1] + intercept=0 映射到2维平面上之后,应该是:
ly = (-intercept - lx * coef[0]) / coef[1]
plt.plot(lx, ly, c='green')
plt.scatter(df_test_negative['Clump Thickness'], df_test_negative['Cell Size'], marker='o', s=200, c='red')
plt.scatter(df_test_positive['Clump Thickness'], df_test_positive['Cell Size'], marker='x', s=150, c='black')
plt.xlabel('Clump Thickness')
plt.ylabel('Cell Size')
plt.show()

print的值为Testing accuracy (10 training samples): 0.937142857143

这份代码只是帮大家理清一下最为基础的python编程要素,方便对后面的实例进行理解和实践。

数据地址http://pan.baidu.com/s/1jI00k8Q,大家可以去下载。

   
次浏览       
相关文章

手机软件测试用例设计实践
手机客户端UI测试分析
iPhone消息推送机制实现与探讨
Android手机开发(一)
相关文档

Android_UI官方设计教程
手机开发平台介绍
android拍照及上传功能
Android讲义智能手机开发
相关课程

Android高级移动应用程序
Android系统开发
Android应用开发
手机软件测试