机器学习基础知识学习笔记1

一. 机器学习基本概念

机器学习-致力于研究如何通过计算的手段,利用经验(历史数据)来改善系统自身的性能[机器学习]。
从数据中产生模型的算法,即“学习算法”。

在这里插入图片描述
基本术语:

学习(训练):从数据中学得模型的过程
训练集:参与模型训练的样本集合
测试:学得模型后,使用其样本进行预测的过程
测试集:被预测的样本集合
假设:学得模型对应的关于数据的某种潜在规律
分类:输出结果是离散值
回归:输出结果是连续值
监督学习:训练样本有标记
无监督学习:训练样本无标记
泛化能力:学得模型适用于新样本的能力
独立同分布:样本空间的全体样本都服从一个未知的分布,且相互独立
误差:模型输出与样本真实值之间的差异
错误率:分类错误样本数占总样本数比例
精度:1-错误率
训练误差:模型在训练集上的误差
泛化误差:模型在新样本上的误差
过拟合:用力过猛
欠拟合:用力不足

模型性能度量

查准率/准确率(precision): P = TP/(TP+FP)
查全率/召回率/灵敏度(recall):R = TP/(TP+FN)
“1”代表正例,“0”代表反例
在这里插入图片描述

from sklearn.metrics import precision_score
from  sklearn.metrics import confusion_matrix
from  sklearn.metrics import classification_report
y_true=[1,0,1,1,0]
y_pred=[1,0,1,0,0]
print(precision_score(y_true,y_pred,average=None))
print(confusion_matrix(y_true, y_pred))#混淆矩阵
print(classification_report(y_true, y_pred))

在这里插入图片描述

二. 相关技术:

1.回归分析(Regression Analysis)

线性回归

sklearn.linear_model中的LinearRegression可实现线性回归
LinearRegression 的构造方法:
LinearRegression( fit_intercept=True, #默认值为 True,表示 计算随机变量,False 表示不计算随机变量 normalize=False, #默认值为 False,表示在回归前是否对回归因子X进行归一化True 表示是 , copy_X=True)
LinearRegression 的常用方法有:
decision_function(X) #返回 X 的预测值 y
fit(X,y[,n_jobs]) #拟合模型
get_params([deep]) #获取 LinearRegression 构造方法的参数信息
predict(X) #求预测值 #同 decision_function

1.使用Python实现下面输入与输出的线性回归
输入:[[0, 0], [1, 1], [2, 2]]——两个输入
输出:[0, 1, 2]
预测:[3, 3]

from sklearn.linear_model import LinearRegression
clf = LinearRegression()#线性回归
clf.fit([[0, 0], [1, 1], [2, 2]], [0, 1, 2])  # 模型训练x和y,二维
pre = clf.predict([[3, 3]])   # 模型预测,二维即一行两列
clf.coef_       #x和y的系数
clf.intercept_  #截距项
print(pre)      #[3.]
'''
y = 0.5*x1 + 0.5*x2 #学习得到的模型
'''

2.波士顿房价数据集(Boston House Price Dataset)包含对房价的预测,以千美元计,给定的条件是房屋及其相邻房屋的详细信息。
该数据集是一个回归问题。每个类的观察值数量是均等的,共有 506 个观察,13 个输入变量和1个输出变量。
sklearn库的datasets包含该数据集( load_boston)
直觉告诉我们:第6列(住宅平均房间数)与最终房价一般是成正比的,具有某种线性关系。我们利用线性回归来验证想法。
同时,作为一个二维的例子,可以在平面上绘出图形,进一步观察图形。

# 波士顿房价数据回归分析
from sklearn.datasets import load_boston
from sklearn.linear_model import LinearRegression
import matplotlib.pyplot as plt
bosten = load_boston()  # 实例化
x = bosten.data[:, 5:6]#进行切片取第6列,保持二维结构
clf = LinearRegression()
clf.fit(x, bosten.target)   # 模型训练
#clf.coef_   # 回归系数
y_pre = clf.predict(x)   # 模型输出值
plt.scatter(x, bosten.target)  # 样本实际分布
plt.plot(x, y_pre, color='red')   # 绘制拟合曲线
plt.show()

在这里插入图片描述
逻辑回归(解决分类问题)
在这里插入图片描述
研究生入学录取预测:
在这里插入图片描述

import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report

data = pd.read_csv('LogisticRegression.csv')
data_tr, data_te, label_tr, label_te = train_test_split(data.iloc[:, 1:], data['admit'], test_size=0.2)
clf = LogisticRegression()
clf.fit(data_tr, label_tr)
pre = clf.predict(data_te)
res = classification_report(label_te, pre)
print(res)

结果:
在这里插入图片描述

2.决策树(Decision Tree)

在这里插入图片描述
属性选择的先后顺序
熵值
信息增益
信息增益率

问题:对于给定样本集,如何判断应该在哪个属性上进行拆分
每次拆分都存在多种可能,哪个才是较好的选择呢?
理想情况:在拆分过程中,当叶节点只拥有单一类别时,将不必继续拆分。
目标是寻找较小的树,希望递归过程尽早停止
较小的树意味着什么?
当前最好的拆分属性产生的拆分中目标类的分布应该尽可能地单一(单纯),多数类占优。

如果能测量每一个节点的纯度,就可以选择能产生最纯子节点的那个属性进行拆分;
决策树算法通常按照纯度的增加来选择拆分属性。

纯度的概念
纯度度量
当样本中没有两项属于同一类:0
当样本中所有项都属于同一类:1
最佳拆分可以转化为选择拆分属性使纯度度量最大化的优化问题

拆分增加了纯度,但如何将这种增加量化呢,或者如何与其他拆分进行比较呢?
用于评价拆分分类目标变量的纯度度量包括
基尼(Gini,总体发散性) CART
熵(entropy,信息量)
信息增益(Gain) ID3
信息增益率 C4.5,C5.0
改变拆分准则(splitting criteria)导致树的外观互不相同

熵(entropy)
信息论中的熵:是信息的度量单位,是一种 对属性“不确定性的度量”。
属性的不确定性越大,把它搞清楚所需要的信息量也就越大,熵也就越大。
如果一个数据集D有N个类别,则该数据集的熵为:
在这里插入图片描述

在这里插入图片描述
打球数据集的熵为:
在这里插入图片描述

信息增益(gain):对纯度提升的程度
若离散属性a有V个取值,则其信息增益为:
在这里插入图片描述
在这里插入图片描述
天气属性的信息增益
晴:打球记录2条,不打球记录为3条
在这里插入图片描述
阴:打球记录4条,不打球记录0条
在这里插入图片描述
雨:打球记录3条,不打球记录2条
在这里插入图片描述
天气属性的信息增益:
在这里插入图片描述
ID3算法实现

ID3算法的详细实现步骤如下:
在这里插入图片描述
ID3算法是决策树系列中的经典算法之一,它包含了决策树作为机器学习算法的主要思想缺点是:
由于ID3决策树算法采用信息增益作为选择拆分属性的标准,
会偏向于选择取值较多的,即所谓高度分支属性,
而这类属性并不一定是最优的属性。

ID3算法只能处理离散属性,对于连续型的属性,
在分类前需要对其进行离散化。

实例—使用scikit-learn建立基于信息熵的决策树模型
这个例子是经典的Kaggle101问题——泰坦尼克生还预测,部分数据如下:
在这里插入图片描述

为了说明的方便,数据集有许多属性被删除了。通过观察可知:列Survived是指是否存活,是类别标签,属于预测目标;列Sex的取值是非数值型的。我们在进行数据预处理时应该合理应用Pandas的功能,让数据能够被模型接受。

泰坦尼克生还预测代码:

import pandas as pd
from sklearn.tree import DecisionTreeClassifier, export_graphviz
from sklearn.metrics import classification_report
import graphviz

# 1.导入数据
data = pd.read_csv('titanic_data.csv')

# 2.数据预处理
data.drop('PassengerId', axis=1, inplace=True)   # 删除PassengerId 列,且对源数据进行处理
#通过标签索引
data.loc[data['Sex'] == 'male', 'Sex'] = 1       # 用数值1来代替male,用0来代替female
data.loc[data['Sex'] == 'female', 'Sex'] = 0
#fillna()填充缺失值
data.fillna(data['Age'].mean(), inplace=True)    # 用均值来填充缺失值

# 3.模型的构建
Dtc = DecisionTreeClassifier(max_depth=5, random_state=8)    # 构建决策树模型,树的最大深度是5,随机种子8
#fit(样本自变量(二维)—即所有行的后三列,目标变量即Survived列)
Dtc.fit(data.iloc[:, 1:], data['Survived'])       # 模型训练
pre = Dtc.predict(data.iloc[:, 1:])               # 模型预测
pre == data['Survived']                           # 比较模型预测值与样本实际值是否一致
classification_report(data['Survived'], pre)      # 分类报告

# 4.决策树的可视化
dot_data = export_graphviz(Dtc, feature_names=['Pclass', 'Sex', 'Age'], class_names='Survived')#feature_names是指属性名称即列名称
graph = graphviz.Source(dot_data)       # 决策树可视化
graph


如要将决策树可视化,还需要安装Graphviz(跨平台的、基于命令行的绘图工具),并将安装路径\bin\dot.exe添加至系统变量
*https://graphviz.gitlab.io/_pages/Download/Download_windows.html *
生成的效果图如下:(jupyter notebook)
在这里插入图片描述

3.人工神经网络(Artificial Neural Network)

单个神经元结构
在这里插入图片描述

xj为输入信号, f 为传递函数,wi,j表示与神经元xj 连接的权值,yi 表示输出值,表示阈值

经典网络结构
BP网络结构
在这里插入图片描述
一个小例子:
在这里插入图片描述
在这里插入图片描述

梯度下降法

网络训练目标:
找出合适的权值和阈值,
使得误差 E 最小
在这里插入图片描述
在这里插入图片描述

激活函数
在这里插入图片描述
网络训练过程

输入:训练集数据、学习速率yita
过程:
在(0,1)范围内随机初始化网络中所有连接权和阈值
repeat
根据网络输入和当前参数计算网络输出值y
根据输出值和实际值得误差计算输出层神经元梯度项gj
计算隐层神经元梯度项eh
更新连接权值和阈值
until达到停止条件(即误差足够小或达到最大训练轮数)
输出:连接权值和阈值

BP神经网络实现
在这里插入图片描述

训练集数据:BPdata_tr.txt
测试集数据:BPdata_te.txt
在这里插入图片描述
在这里插入图片描述
网络结构
在这里插入图片描述
其中-1表达的是减去(-1)*阈值,即加上阈值
隐层神经元的个数是4(自己设置的)
数据结构
在这里插入图片描述

修正量公式:
在这里插入图片描述
映射函数
在这里插入图片描述
在这里插入图片描述

import math
import numpy as np
import pandas as pd
from pandas import DataFrame,Seres
	def sigmoid(x):  #映射函数
    return 1/(1+math.exp(-x))

中间层神经元输入和输出层神经元输入

#中间层神经元输入和输出层神经元输入
Net_in = np.array([0,0,-1])
Out_in = np.array([0,0,0,0,-1])

中间层和输出层神经元权值及其变化量

#中间层和输出层神经元权值及其变化量
w_mid = np.zeros([3,4])
w_out = np.array([0.3,0.3,0.3,0.3,0.3])
delta_w_mid = np.zeros([3,4])
delta_w_out = np.array([0,0,0,0,0])

中间层的输出

#中间层的输出
for i in range(4):    
	Out_in[i] = sigmoid(sum(w_mid[:,i]*Net_in))
#输出层的输出/网络输出
res = sigmoid(sum(Out_in*w_out))
error = abs(res-real)

输出层权值变化量
在这里插入图片描述

#输出层权值变化量
delta_w_out = yita*res*(1-res)*(real-res)*Out_indelta_w_out[4] = -(yita*res*(1-res)*(real-res))
w_out = w_out+delta_w_out

中间层权值变化量
在这里插入图片描述

#中间层权值变化量
for i in range(4):    
	delta_w_mid[:,i] = yita*Out_in[i]*(1-Out_in[i])*w_out[i]*res*(1-res)*(real-res)*Net_in    
	delta_w_mid[2,i] = -(yita*Out_in[i]*(1-Out_in[i])*w_out[i]*res*(1-res)*(real-res))w_mid = w_mid+delta_w_mid

全样本网络代码实现

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

def sigmoid(x):    # 定义网络激活函数
    return 1/(1+np.exp(-x))

data_tr = pd.read_csv('BPdata_tr.txt')  # 训练集样本
data_te = pd.read_csv('BPdata_te.txt')  # 测试集样本
n = len(data_tr)
yita = 0.85  # 自己设置学习速率

out_in = np.array([0.0, 0, 0, 0, -1])   # 输出层的输入,即隐层的输出
w_mid = np.zeros([3, 4])  # 隐层神经元的权值&阈值
w_out = np.zeros([5])     # 输出层神经元的权值&阈值

delta_w_out = np.zeros([5])      # 输出层权值&阈值的修正量
delta_w_mid = np.zeros([3, 4])   # 中间层权值&阈值的修正量
Err = []
'''
模型训练
'''
for j in range(1000):
    error = []
    for it in range(n):
        net_in = np.array([data_tr.iloc[it, 0], data_tr.iloc[it, 1], -1])  # 网络输入
        real = data_tr.iloc[it, 2]
        for i in range(4):
            out_in[i] = sigmoid(sum(net_in * w_mid[:, i]))  # 从输入到隐层的传输过程
        res = sigmoid(sum(out_in * w_out))   # 模型预测值
        error.append(abs(real-res))#误差

        # print(it, '个样本的模型输出:', res, 'real:', real)
        delta_w_out = yita*res*(1-res)*(real-res)*out_in  # 输出层权值的修正量
        delta_w_out[4] = -yita*res*(1-res)*(real-res)     # 输出层阈值的修正量
        w_out = w_out + delta_w_out   # 更新,加上修正量

        for i in range(4):
            delta_w_mid[:, i] = yita*out_in[i]*(1-out_in[i])*w_out[i]*res*(1-res)*(real-res)*net_in   # 中间层神经元的权值修正量
            delta_w_mid[2, i] = -yita*out_in[i]*(1-out_in[i])*w_out[i]*res*(1-res)*(real-res)         # 中间层神经元的阈值修正量,2行是阈值
        w_mid = w_mid + delta_w_mid   # 更新,加上修正量
    Err.append(np.mean(error))
plt.plot(Err)#训练集上每一轮的平均误差
plt.show()
plt.close()

'''
将测试集样本放入训练好的网络中去
'''
error_te = []
for it in range(len(data_te)):
    net_in = np.array([data_te.iloc[it, 0], data_te.iloc[it, 1], -1])  # 网络输入
    real = data_te.iloc[it, 2]
    for i in range(4):
        out_in[i] = sigmoid(sum(net_in * w_mid[:, i]))  # 从输入到隐层的传输过程
    res = sigmoid(sum(out_in * w_out))   # 模型预测值
    error_te.append(abs(real-res))
plt.plot(error_te)#测试集上每一轮的误差
plt.show()
np.mean(error_te)

结果—训练集上每一轮的平均误差
在这里插入图片描述

结果—测试集上每一轮的误差
在这里插入图片描述
调用sklearn实现神经网络算法
API文档对方法以及参数详细介绍:
https://scikitlearn.org/stable/modules/generated/sklearn.neural_network.MLPClassifier.html?highlight=mlp#sklearn.neural_network.MLPClassifier

'''
调用sklearn实现神经网络算法
'''

data_tr = pd.read_csv('BPdata_tr.txt')  # 训练集样本
data_te = pd.read_csv('BPdata_te.txt')  # 测试集样本
#hidden_layer_sizes是隐藏神经元的个数,max_iter是迭代次数,learning_rate_init是学习速率,random_state是随机种子
model = MLPRegressor(hidden_layer_sizes=(10,), random_state=10, max_iter=800, learning_rate_init=0.3)  # 构建模型
model.fit(data_tr.iloc[:, :2], data_tr.iloc[:, 2])    # 模型训练
pre = model.predict(data_te.iloc[:, :2])              # 模型预测
err = np.abs(pre - data_te.iloc[:, 2]).mean()         # 模型预测误差
print(err)

结果:0.038157725482174526

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值