机器学习入门——实战篇之监督学习

这是本篇文章是《机器学习入门》系列文章的第二篇,该系列有如下文章:
《机器学习入门——基础篇》
《机器学习入门——实战篇之监督学习》
《机器学习入门——实战篇之非监督学习》
《机器学习入门——实战篇之深度学习》
《机器学习入门——实战篇之强化学习》

闲话少说,言归正传。

大家还记得我们提到过监督学习里面的几个名词,线性回归,感知器,决策树,朴素贝叶斯,支持向量机。下文中我们就一一来看看在Python中怎么使用这些工具。

说到Python,相信在攻城狮领域已经不用过多介绍,它可谓是当红炸子鸡,忽如一夜春风来,千人万人学Python。为什么能够这么热,跟这门语言的平易近人有很大关系,乍一看,语法简单,调用简单,没有C++那么多恐怖的特性,也不强调什么对象不对象的,但好像也啥都能干。这就是许多服务器端脚本语言的特点,并且也是动态语言的特点,灵活方便,尤其是网络协议和工具封装的好。并且,它还赶上了机器学习的又一次大潮(我为什么用了又字……好吧,历史上确实有好几次大潮,周期性呈现……),很好的实现了TensorFlow的API,可谓一路高歌猛进。好了,还不懂Python的同学可以简单学习一下,本文要求有一定的Python基础,并且最好安装一个Python环境,一边探讨一边做实验。

一、线性回归

前文我提到过这么一幅图:

1-线性回归-股市大盘.jpg

对了,就是预测股市大盘的这个曲线,我们通过年初和年中两个点,预测出了年末大盘走势。当然了,这只是一个理想形态。不管怎么说,还是表现出了线性回归的特性。我们看看Python里面怎么实现这种预测。

# 引入一个计算向量数据很方便的工具pandas
import pandas as pd
# 再引入一个我们要的线性回归库 LinearRegression
from sklearn.linear_model import LinearRegression
# 用刚才的pandas读取一个文件,这个文件可以理解成有许多的散列点(x, y)
# CSV文件就是用逗号分开的一些值,按行排好
data = pd.read_csv("file.csv")
# 实例化一个线性回归模型
model = LinearRegression()
# 把数据导入这个模型,让模型适应,也就是训练啦,一个fit搞定
# 其中这个X和Y可以理解为两个向量,就是两列数,一一对应起来
model.fit(data[['X']], data[['Y']])
# 然后我们给出一个值,并用print看看预测数来的值,一切搞定!
laos_life_exp = bmi_life_model.predict(21.07931)
print(laos_life_exp)

是不是简单清晰,不过想要实验的同学,需要自己准备一份数据文件,把数据读进去,然后自己调用试一试。

二、感知器

这个东西比线性回归稍微复杂一些,我们还是先回顾一下基础篇提到的图:

2-感知器.jpg

就是这个图了,一条红线,分开了正常人和疯子。我们来看看类似的问题怎么用Python来实现。

# 这次我们又换了一种工具,叫numpy,也是一个数据处理库,比pandas更加底层一些
import numpy as np
# 设置一个随机数的种子,用来生成随机数,为什么是42呢,因为这是宇宙最终极的答案
# 参考电影《银河系漫游指南》
np.random.seed(42)

# 定义一个函数,很简单,正数返回1,负数返回0
def oneStep(t):
    if t >= 0:
        return 1
    return 0

# 定义一个预测函数
def prediction(X, W, b):
    # 这是一个矩阵相乘函数np.matmul
    return oneStep((np.matmul(X,W)+b)[0])

# 这里就是我们的真实大Boss所在了,感知函数
# 感知器的核心思想就是把一条线摆在两堆不同种类的样本中间
# 从而实现让两堆样本分开的结果
# X是一大堆数值,对应一大堆表示y,W就是权重
# 每次取出一个X的值,乘以权重,加上一个b值,不就是一条一元一次的直线嘛
# 看看这条线是不是摆对了位置,如果不对,就调整一下
# 重复以上的步骤直到满意
def perceptronStep(X, y, W, b, learn_rate = 0.01):
    # Fill in code
    for item_x, item_y in zip(X, y):
        y_p = prediction(item_x, W, b)
        if item_y - y_p == 1:
            W[0] += item_x[0]*learn_rate
            W[1] += item_x[1]*learn_rate
            b += learn_rate
        elif item_y - y_p == -1:
            W[0] -= item_x[0]*learn_rate
            W[1] -= item_x[1]*learn_rate
            b -= learn_rate
    return W, b
    
# 下面就开始寻找我们想要的那个线
# 这里有个学习速率0.01,就是决定每次移动的幅度的
def trainPerceptron (X, y, learn_rate = 0.01, num_epochs = 25):
    x_min, x_max = min(X.T[0]), max(X.T[0])
    y_min, y_max = min(X.T[1]), max(X.T[1])
    W = np.array(np.random.rand(2,1))
    b = np.random.rand(1)[0] + x_max
    # 下面就要调用我们准备好的函数
    boundary_lines = []
    # 一遍一遍的迭代,25次
    for i in range(num_epochs):
        W, b = perceptronStep(X, y, W, b, learn_rate)
        boundary_lines.append((-W[0]/W[1], -b/W[1]))
    return boundary_lines

不管你看懂了没有,秘诀就在于,反复的实验,并且把里面的数据结构打印出来对比学习。

三、决策树

老规矩,从复习决策树的图形开始:

3-垃圾分类.jpg

对,就是这个图,我们举例用了决策树做垃圾分类,实际上,决策树可以干的事情可多了,例如,它居然可以被用来预测一次灾难的生还率。下面,我们就用决策树来预测“泰坦尼克号”乘客的生还率!

# 先是引入两个我们已经熟悉的库
import numpy as np
import pandas as pd
# 再引入一个用于显示数据的库
from IPython.display import display # Allows the use of display() for DataFrames

# 仍然是随机数
import random
random.seed(42)

# 读入数据文件
in_file = 'data.csv'
full_data = pd.read_csv(in_file)

# 这里我们可以简单看一看数据长什么样子
display(full_data.head())

数据项目如下:
乘客ID
是否生还
客舱级别
名字
性别
年纪
同行兄弟姐妹人数
同行父母子女人数
票号
票价
仓号
登陆港口

# 因为是否生还属于一个结果属性,我们把它单拎出来,然后把结果去掉
outcomes = full_data['Survived']
features_raw = full_data.drop('Survived', axis = 1)

# 先对数据进行one-hot编码,也有人翻译成独热编码,好吧
# 不管什么名字就是类似于这样,001表示男,010表示女,100表示不知道
# 也就是用三个bit表示了三种情况,每个情况下只有一个bit被置位了
features = pd.get_dummies(features_raw)
# 这一步是把空的地方加上0
features = features.fillna(0.0)

# 下面动真格的了,引入了一个至关重要的库,能把训练集和测试集分开,就像图里这样
# 等等,啥是训练集,啥是测试集?训练集合就是用来训练模型的数据
# 但是训练好以后,模型到底能得多少分啊,那就测试一下,于是还需要测试集
# 之所以把两部分数据分开,就是为了防止过拟合……好吧,啥是过拟合
# 就好比考试先看了答案再考,能考不好么……,为了防止看答案,就把测试集先藏起来
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(features, outcomes, test_size=0.2, random_state=42)

# 引入主角决策树类库
from sklearn.tree import DecisionTreeClassifier

# 真正的训练就这么一下子!搞定
model = DecisionTreeClassifier()
model.fit(X_train, y_train)

# 模型训练完了,分别在训练集和测试集上预测一下嘛
y_train_pred = model.predict(X_train)
y_test_pred = model.predict(X_test)

# 看看准确率,你会发现训练的准确率奇高,基本全对
# 但是拿出来测试集一试,就露馅了,只有0.8左右,但是也算足够好了
from sklearn.metrics import accuracy_score
train_accuracy = accuracy_score(y_train, y_train_pred)
test_accuracy = accuracy_score(y_test, y_test_pred)

到这里,大家是不是对一个训练加模型评分的过程有了全局性的认识呢?就是这么简单!

四、朴素贝叶斯

挑战越来越难啦,复习公式:

P(A|B) = P(B|A)P(A)/P(B)

这就是贝叶斯大魔王的定理,含义不再复述,可以查看我的前一篇文章,机器学习入门——基础篇。

这一次,我们要用贝叶斯大定理生成的模型来做垃圾邮件分类。垃圾邮件分类是一个二分问题,通常垃圾邮件的用词有其特殊性,我们就用模型来找到这种特殊性,从而以后再碰到类似邮件就可以分辨出来。

数据预处理的部分不再赘述,和前面的部分相去不大。关键是,为了引用贝叶斯模型,我们要用到另一个东西,“词袋”模型。简单说,就是许多的数学模型都要求输入数字,但是我们面对的是文本啊,像什么邮件啊,文章啊,都是文本,那么我们就简单的把这些文本里面的词做一个词频计数,不就变成了数字嘛!这就是词袋模型,像是把词放进袋子里,再数一数的意思。

# 引进相应的库
from sklearn.feature_extraction.text import CountVectorizer
# 然后用专门的方法就能得到最后的结果,这里我们引入了参数
# 分别是说处理英语,并且告知了英语单词的分隔方式
count_vector = CountVectorizer(documents, lowercase=True, token_pattern='(?u)\\b\\w\\w+\\b', stop_words='english')

# 然后我们就用这个“计数向量”这么fit一下
count_vector.fit(documents)

# 中间一大堆数据维度处理的过程我们省去,进入关键的代码
# 下面开始分割训练集和测试集
from sklearn.cross_validation import train_test_split
X_train, X_test, y_train, y_test = train_test_split(df['sms_message'],                                                     df['label'],                                                     random_state=1)

# 来到关键的贝叶斯部分,动用了sklearn的贝叶斯模型
from sklearn.naive_bayes import MultinomialNB
naive_bayes = MultinomialNB()
# 简单的一个fit,又搞定了
naive_bayes.fit(training_data, y_train)

最后的评估部分我们省略了,可以自行去查看,提示,可以调用sklearn库的accuracy_score, precision_score, recall_score, f1_score这些东西看看。

贝叶斯大魔王也不过如此,我们继续,监督学习的最后一部分,支持向量机的实现。

五、支持向量机

闲言碎语不多讲,直接来到sklearn

# 引入支持向量机库
from sklearn.svm import SVC
# 实例化一个模型
model = SVC()
# 训练!
model.fit(x_values, y_values)

# 然后我们假设有一组数,那就可以预测啦
model.predict([ [0.2, 0.8], [0.5, 0.4] ])

上面这个过程如果太简单了,那我们就来一个有参数的

# kernel表示用什么计算核心,我们用多项式
# 如果内核是多项式,则此degree参数为内核中的最大单项式次数。
# C参数是惩罚参数,大了那么对于数据的拟合就会精准一点,但是,也可能过拟合,反之可推
model = SVC(kernel='poly', degree=4, C=0.1)

当然了,除了这样的一组参数,还可以选别的核,比如rbf核,对应gamma参数,可以自行去学习含义。

同样,最后可以用accuracy_score来评价模型训练的好坏。

这是本篇文章是《机器学习入门》系列文章的第二篇,该系列有如下文章:
《机器学习入门——基础篇》
《机器学习入门——实战篇之监督学习》
《机器学习入门——实战篇之非监督学习》
《机器学习入门——实战篇之深度学习》
《机器学习入门——实战篇之强化学习》

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,142评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,298评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,068评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,081评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,099评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,071评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,990评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,832评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,274评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,488评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,649评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,378评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,979评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,625评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,643评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,545评论 2 352

推荐阅读更多精彩内容