机器学习之有监督学习

监督学习的目标

  利用一组带有标签的数据,学习从输入到输出的映射,然后将这种映射关系应用到未知数据上,达到分类或回归的目的。

分类:当输出是离散的,学习任务为分类任务。

回归:当输出是连续的,学习任务为回归任务。

分类学习

输入:一组有标签的训练数据(也称观察和评估),标签表明了这些数据(观察)的所属类别。

输出:分类模型根据这些训练数据,训练自己的模型参数,学习出一个适合这数据的分类器,当有新数据(非训练数据)需要进行类别判断,就可以将这组新数据作为输入送给学好的分类器进行判断。

分类学习-评价

训练集:顾名思义用来训练模型的已标注数据,用来建立模型,发现规律。

测试集:也是已标注数据,通常做法是将标注隐藏,输送给训练好的模型,通过结果与真实标注进行对比,评估模型的学习能力。

训练集/测试集的划分方法:根据已有标注数据,随机选出一部分(70%)数据作为训练结果,余下的作为测试数据,此外还有交叉验证法、自助法用来评估分类模型。

分类学习-评价标准

精确率:精确率是针对我们预测结果而言的,(以二分类为例),它表示的是预测为正的样本中有多少是真正的正样本。那么预测为正就有两种可能了,一种就是把正类预测为正类(TP),另一种是把父类预测为正类(FP)。故精确率就是TP/(TP+FP)。

召回率:是针对我们原来的样本而言的,它表示的是样本中的正例有多少被预测正确了,那也有两种可能,一种是把原来的正类预测为正类(TN),另一种是把原来的正类预测为父类(FN)。R=TN/(TN+FN)。

Sklearn vs.分类

与聚类算法被统一封装在sklearn.cluster不同,sklearn库中的分类算法并未被统一封装在一个子模块中,因此对分类算法的impo-rt方式各有不同。

Sklearn提供的分类函数包括:

K近邻(knn)、朴素贝叶斯(naivebayes)、支持向量机(svm)、决策树(decision tree)、神经网络模型(Neural networ-k)等,这其中有线性分类器也有非线性分类器。

分类算法的应用

金融:贷款是否批准进行评估

医疗诊断:判断一个肿瘤是恶性还是良性

欺诈检测:判断一笔银行的交易是否涉嫌欺诈

网页分类:判断网页的所属类别,财经或是娱乐?

回归分析

回归:回归是统计学分析数据的方法, 目的在于了解两个或多个变数间是否相关、研究其相关方向与强度,并建立数学模型以便观察特定变数来预测研究者感兴趣的变数。回归分析帮助我们了解在自变量变化时因变量的变化量。一般来说,通过回归分析我们可以由给出的自变量估计因变量的条件期望。

Sklearn vs.回归

Sklearn提供的回归函数主要被封装在两个子模块中,分别是sklearn.linear_model和sklearn——preprocessing。sklear.linea-r_modlel封装的是一些线性函数。

线性回归函数:普通线性回归函数(LinearRegression)、岭回归(Ridge)、Lasso(Lasso)

非线性回归函数:如多项式回归则通过调用sklearn.preprocessing子模块进行拟合。

回归应用

回归方法适合对一些带有时序信息的数据进行预测或者趋势拟合,常用在金融及其他涉及时间序列分析的领域。

例如:股票趋势和交通流量的预测。

人体运动状态预测-实例分析

KNN算法应用的简单实例:

from sklearn.neighbors import KNeighborsClassifier

#创建一组数据X和它对应的标签y
X=[[0],[1],[2],[3]]
y=[0,0,1,1]

#使用3个邻居作为分类的依据,其他参数保持默认值
neigh=KNeighborsClassifier(n_neighbors=3)
#调用fit函数,将训练数据X和标签y送入分类器进行学习
neigh.fit(X,y)
#调用predict()函数,对未知分类样本[1.1]分类,可以
#直接并将需要分类的数据构造为数组形式作为参数传入,
#得到分类标签作为返回值。
print(neigh.predict([[1.1]]))

样例的输出值为0。

决策树分类器的简单实例:

from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
#导入计算交叉验证值的函数
from sklearn.model_selection import cross_val_score

#使用默认参数,创建一棵基于基尼系数的决策树,并将该决策树分类器赋值给clf
clf=DecisionTreeClassifier()
#将鸢尾花数据赋值为iris
iris=load_iris()
'''
这里我们将决策树分类器作为待评估的模型,iris.data
鸢尾花数据作为特征,iris.target鸢尾花分类标签作为目标
结果,通过设定cv为10,使用10折交叉验证,得到最终的交叉验证得分。
'''
print(cross_val_score(clf,iris.data,iris.target,cv=10))
#或者仿照之前的K近邻分类器的使用方法,利用fit()函数训练模型
#并使用predict()函数预测:
#clf.fit(X,y)
#clf.predict(x)

输出:

 

朴素贝叶斯的简单实例:

import numpy as np
from sklearn.naive_bayes import GaussianNB

#构造训练数据X和y
X=np.array([[-1,-1],[-2,-1],[-3,-2],[1,1],[2,1],[3,2]])
Y=np.array([1,1,1,2,2,2])
#使用默认参数创建一个高斯朴素贝叶斯分类器,并将该分类器赋给变量clf
clf=GaussianNB(priors=None)
clf.fit(X,Y)
print(clf.predict([[-0.8,-1]]))

输出为[1].

在简单了解了常见几种分类算法后,接下来就是基于分类问题的代码编写了。

三种算法的简单对比:

import numpy as np
import pandas as pd

#从sklearn库中导入预处理模块Imputer
from sklearn.preprocessing import Imputer
#导入自动生成训练集和测试集的模块train_test_split
from sklearn.model_selection import train_test_split
#导入预测结果评估模块classification_report
from sklearn.metrics import classification_report
#导入k近邻分类器
from sklearn.neighbors import KNeighborsClassifier
#决策树分类器
from sklearn.tree import DecisionTreeClassifier
#高斯朴素贝叶斯函数
from sklearn.naive_bayes import GaussianNB

'''
编写数据导入函数,设置传入两个参数,分别是特征文件的
列表feature_paths和标签文件的列表label_paths
定义feature数组变量,列数量和特征维度一致为41;定义
空的标签变量,列数量和标签维度一致为1.
'''

def load_dataset(feature_paths,label_paths):
    feature=np.ndarray(shape=(0,41))
    label=np.ndarray(shape=(0,1))
    for file in feature_paths:
        #使用pandas库的read_table函数读取一个特征文件的内容,
        #其中指定分隔符为逗号,缺失值为问号且文件不包含表头行
        df=pd.read_table(file,delimiter=',',na_values='?',header=None)
        #使用平均值补全缺失值,然后将数据进行补全
        imp=Imputer(missing_values='NaN',strategy='mean',axis=0)
        #fit函数用于训练预处理器
        imp.fit(df)
        #transform函数用于生成预处理结果
        df=imp.transform(df)
        #将新读入的数据合并到数据集中
        feature=np.concatenate((feature,df))
    for file in label_paths:
        #读取标签数据,文件中不含有表头
        df=pd.read_table(file,header=None)
        #将新读入的数据合并到标签集合中
        label=np.concatenate((label,df))
    #将标签归整为一维向量
    label=np.ravel(label)
    return feature,label

if __name__ == "__main__":
    #设置数据路径
    feature_paths=['A.feature','B.feature','C.feature','D.feature','E.feature']
    label_paths=['A.label','B.label','C.label','D.label','E.label']

    #将前四个数据作为训练集输入
    x_train,y_train=load_dataset(feature_paths[:4],label_paths[:4])
    #将最后一个数据作为测试集读入
    x_test,y_test=load_dataset(feature_paths[4:],label_paths[4:])
    #使用全量数据作为数据集,借助train_test_split函数将训练数据打乱
    x_train,x_,y_train,y_=train_test_split(x_train,y_train,test_size=0.1)
    #创建k近邻分类器,并在测试集上进行预测
    print("Start training knn")
    knn=KNeighborsClassifier().fit(x_train,y_train)
    print("Training done!")
    answer_knn=knn.predict(x_test)
    print("Prediction done!")
    #创建决策树分类器,并在测试集上进行预测
    print("Start training DT")
    dt=DecisionTreeClassifier().fit(x_train,y_train)
    print("Training Done!")
    answer_dt=dt.predict(x_test)
    print("Prediction done!")
    #创建贝叶斯分类器,并在测试集上进行预测
    print("Start training Bayes")
    gnb=GaussianNB().fit(x_train,y_train)
    print("Training Done!")
    answer_gnb=gnb.predict(x_test)
    print("Prediction done!")
    #计算准确率与召回率
    print("\n\nThe classification report for knn:")
    print(classification_report(y_test,answer_knn))
    print("\n\nThe classification report for dt:")
    print(classification_report(y_test,answer_dt))
    print("\n\nThe classification report for gnb:")
    print(classification_report(y_test,answer_gnb))

输出结果:

           

实例二(使用SVM算法):

import pandas as pd
import numpy as np
from sklearn import svm
from sklearn import model_selection

#数据加载&数据预处理
data=pd.read_csv('000777.csv',encoding='gbk',parse_dates=[0],index_col=0)
data.sort_index(0,ascending=True,inplace=True) #data按照时间升序排列


dayfeature=150 #选取150天的数据
featurenum=5*dayfeature #选取的5个特征*天数
'''
data.shape[0]-dayfeature意思是因为我们要用150天数据做训练,对于条目为
200条的数据,只有50条数据是由前150天的数据来训练的,所以训练集的大小就是
200-150,对于每一条数据,他的特征是前150天的所有特征数据,即150*5,+1是将
当天的开盘价引入作为一条特征数据。
'''
x=np.zeros((data.shape[0]-dayfeature,featurenum+1)) #记录150天的5个特征值
y=np.zeros((data.shape[0]-dayfeature)) #记录涨或者跌

for i in range(0,data.shape[0]-dayfeature):
    #将数据中的‘收盘价’‘最高价’‘开盘价’‘成交量’存入x数组中
    x[i,0:featurenum]=np.array(data[i:i+dayfeature]\
        [[u'收盘价',u'最高价',u'最低价',u'开盘价',u'成交量']]).reshape((1,featurenum))
    #最后一列记录当日的开盘价
    x[i,featurenum]=data.ix[i+dayfeature][u'开盘价']

for i in range(0,data.shape[0]-dayfeature):
    #如果当天的收盘价高于开盘价,y[i]=1代表涨,0代表跌
    if data.ix[i+dayfeature][u'收盘价']>=data.ix[i+dayfeature][u'开盘价']:
        y[i]=1
    else:
        y[i]=0

#创建svm进行交叉验证
#调用svm函数,并设置kernel参数,默认为rbf,其他:'linear','poly','sigmoid'
clf=svm.SVC(kernel='rbf')
result=[]
for i in range(5):
    #x和y的验证集和测试集,切分80%-20%的测试集
    x_train,x_test,y_train,y_test=model_selection.train_test_split(x,y,test_size=0.2)
    #训练数据进行训练
    clf.fit(x_train,y_train)
    #将预测数据和测试集的验证数据对比
    result.append(np.mean(y_test==clf.predict(x_test)))
print("svm classfier accuacy.")
print(result)

线性回归

房价与房屋尺寸关系的线性拟合

import matplotlib.pyplot as plt
from sklearn import linear_model
import numpy as np

#加载训练数据,建立回归方程
datasets_X=[]
datasets_Y=[]
fr=open('prices.txt','r')
lines=fr.readlines()
for line in lines:
    items=line.strip().split(',')
    datasets_X.append(int(items[0]))
    datasets_Y.append(int(items[1]))
length=len(datasets_X)
#将datasets_X转化为数组,并变为二维,以符合线性回归拟合函数输入参数要求
datasets_X=np.array(datasets_X).reshape([length,1])
datasets_Y=np.array(datasets_Y)

minX=min(datasets_X)
maxX=max(datasets_X)
#以数据datasets_X的最大值和最小值为范围,建立等差数列,方便后续画图
X=np.arange(minX,maxX).reshape([-1,1])

#调用线性回归模块,建立回归方程,拟合数据
linear=linear_model.LinearRegression()
linear.fit(datasets_X,datasets_Y)

#可视化处理
'''
scatter函数用于绘制数据点
plot函数宿用于绘制直线
'''
plt.scatter(datasets_X,datasets_Y,color='red')
plt.plot(X,linear.predict(X),color='blue')
plt.xlabel('Area')
plt.ylabel('Price')
plt.show()

                          

如图可知,大致呈线性关系,因此可以根据房屋尺寸预测房屋价格。

多项式回归(房价与房屋尺寸关系的非线性拟合)

                                     

import matplotlib.pyplot as plt
from sklearn import linear_model
from sklearn.preprocessing import PolynomialFeatures
import numpy as np

datasets_X=[]
datasets_Y=[]
fr=open('prices.txt','r')
lines=fr.readlines()
for line in lines:
    items=line.strip().split(',')
    datasets_X.append(int(items[0]))
    datasets_Y.append(int(items[1]))
length=len(datasets_X)
datasets_X=np.array(datasets_X).reshape([length,1])
datasets_Y=np.array(datasets_Y)
minX=min(datasets_X)
maxX=max(datasets_X)
X=np.arange(minX,maxX).reshape([-1,1])
#degree=2表示建立datasets_X的二次多项式特征X_poly
#然后创建线性回归,使用线性模型学习Xpoly和datasets_Y
#之间的映射关系(即参数)
poly_reg=PolynomialFeatures(degree=2)
x_poly=poly_reg.fit_transform(datasets_X)
lin_reg_2=linear_model.LinearRegression()
lin_reg_2.fit(x_poly,datasets_Y)

plt.scatter(datasets_X,datasets_Y,color='red')
plt.plot(X,lin_reg_2.predict(poly_reg.fit_transform(X)),color='blue')
plt.xlabel('Area')
plt.ylabel('Price')
plt.show()

                                 

      

import numpy as np
from sklearn.linear_model import Ridge
#通过sklearn_model加载岭回归方法
from sklearn import model_selection
#加载交叉验证模块,加载matplotilib模块
import matplotlib.pyplot as plt
from sklearn.preprocessing import PolynomialFeatures
#通过sklearn_preprocessing加载PolynomialFeatures用于创建多项式特征,如ab,a^2,b^2

#数据加载
#使用numpy的方法从txt文件中加载数据
data=np.loadtxt('岭回归.txt',delimiter=',',usecols=(1,2,3,4,5))
#使用plt展示车流量信息
#plt.plot(data[:,4])

#数据处理
#X用于保存0-3维数,即属性
X=data[:,:4]
#y用于保存第四维数据,即车流量
y=data[:,4]
#用于创建最高次数6次方的多项式特征,多次试验后决定采用6次
poly=PolynomialFeatures(6)
#X为创建的多项式特征
X=poly.fit_transform(X)

#划分训练集和测试集
#将所有数据划分为训练集和测试集,test_size表示测试集的比例
#random_state是随机种子
train_set_X,test_set_X,train_set_Y,test_set_Y=model_selection.train_test_split(X,y,test_size=0.3,random_state=0)

#创建回归器,并进行训练
#创建岭回归实例
clf=Ridge(alpha=1.0,fit_intercept=True)
#调用fit函数使用训练集训练回归器
clf.fit(train_set_X,train_set_Y)
#利用测试集计算回归曲线的拟合优度,clf.score返回值为0.7375
#拟合优度,用于评价拟合好坏,最大为1,无最小值,当对所有输入都输出同一个值时,拟合优度为0
clf.score(test_set_X,test_set_Y)

#画出拟合曲线
#接下来画一段200到300范围内的拟合曲线
start=200
end=300
#调研predict函数的拟合值
y_pre=clf.predict(X)
time=np.arange(start,end)
#展示真实数据(蓝色)以及拟合的曲线(红色)
plt.plot(time,y[start:end],'b',label="real")
plt.plot(time,y_pre[start:end],'r',label='predict')
#设置图例的位置
plt.legend(loc='upper left')
plt.show()

车流量信息          

                                    

拟合结果:  

                                    

实例:手写识别

import numpy as np
#使用listdir模块,用于访问本地文件
from os import listdir
from sklearn.neural_network import MLPClassifier

#加载训练数据
def img2vector(filename):
    retMat=np.zeros([1024],int) #定义返回的矩阵,大小为1*1024
    fr=open(filename) #打开包含32*32大小的数字文件
    lines=fr.readlines() #读取文件的所有行
    for i in range(32):
        for j in range(32):
            retMat[i*32+j]=lines[i][j]
    return retMat

def readDataSet(path):
    fileList=listdir(path) #获取文件夹下的所有文件
    numFiles=len(fileList) #统计需要读取的文件的数目
    dataSet=np.zeros([numFiles,1024],int) #用于存放所有的数字文件
    hwLabels=np.zeros([numFiles,10]) #用于存放对应的标签one-hot
    for i in range(numFiles): #遍历所有的文件
        filePath=fileList[i] #获取文件名称/路径
        digit=int(filePath.split('_')[0]) #通过文件名获取标签
        hwLabels[i][digit]=1.0 #将对应的one-hot标签置1
        dataSet[i]=img2vector(path+'/'+filePath) #读取文件内容
    return dataSet,hwLabels

#加载训练数据
train_dataSet,train_hwLabels=readDataSet('trainingDigits')

#训练神经网络
#构建神经网络:设置网络的隐藏层数、各隐藏层神经元个数、激活函数、学习率、优化方法、最大迭代次数
#设置含100个神经元的隐藏层
#hidden_layer_sizes存放的是一个元组,表示第i层隐藏层里神经元的个数
#使用logistic激活函数和adam优化方法,并令学习率为0.0001,迭代2000次
clf=MLPClassifier(hidden_layer_sizes=(100,),activation='logistic',solver='adam',learning_rate_init=0.0001,max_iter=2000)
#fit函数能够根据训练集及对应标签集自动设置多层感知机的输入与输出层的神经元个数
clf.fit(train_dataSet,train_hwLabels)

#测试集的评价
dataSet,hwLabels=readDataSet('testDigits')
res=clf.predict(dataSet) #对测试集进行预测
error_num=0
num=len(dataSet) #测试集的数目
for i in range(num):
    #比较长度为10的数组,返回包含01的数组,0为不同,1为相同
    #若预测结果与真实结果相同,则10个数字全为1;否则不全为1
    if np.sum(res[i]==hwLabels[i])<10:
        error_num+=1
print("Total num:",num," Wrong num:",error_num," WrongRate:",error_num/float(num))


输出结果:

                                         

KNN实现“手写识别”

import numpy as np
from os import listdir #使用listdir模块,用于访问本地文件
from sklearn import neighbors

#加载训练数据
def img2vector(fileName):
    retMat=np.zeros([1024],int) #定义返回的矩阵,大小为1*1024
    fr=open(fileName)
    lines=fr.readlines()
    for i in range(32):
        for j in range(32):
            retMat[i*32+j]=lines[i][j]
    return retMat

def readDataSet(path):
    fileList=listdir(path)
    numFiles=len(fileList)
    dataSet=np.zeros([numFiles,1024],int)
    hwLabels=np.zeros([numFiles])
    for i in range(numFiles):
        filePath=fileList[i]
        digit=int(filePath.split('_')[0])
        hwLabels[i]=digit #直接存放数字
        dataSet[i]=img2vector(path+'/'+filePath)
    return dataSet,hwLabels

train_dataSet,train_hwLabels=readDataSet('trainingDigits')
#构建KNN分类器
knn=neighbors.KNeighborsClassifier(algorithm='kd_tree',n_neighbors=3)
knn.fit(train_dataSet,train_hwLabels)
dataSet,hwLabels=readDataSet('testDigits')
res=knn.predict(dataSet)
error_num=np.sum(res!=hwLabels)
num=len(dataSet)
print("Total num:",num," Wrong num:",error_num," Wrong Rate:",error_num/float(num))

                                         

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值