机器学习

机器学习基本概念

名词解释

  • 样本集:一般就是一个表格数据 ,我们研究数据的集合,每一列就是样本的一条属性,每一行就是一个数据样本

  • 样本标签:我们要研究的数据指标, 可能是数据的一条属性

  • 训练集:从样本集中,拆分出来的一部分样本,样本个数多 8:2 9:1 7:3,用来训练算法模型的数据集合

  • 测试集:从样本集中,拆分出来的一部分样本,样本个数少 8:2 9:1 7:3,用来测试模型学习效果的集合

  • 算法模型:我们选择一个算法对象 .fit()训练的函数 .predidct()预测的函数

  • 表示方法

    • 样本集:samples train 标准的二维数组
      训练集:X_train
      测试集:X_test
    • 样本标签:target y
      训练集标签:y_train
      测试集标签:y_test
    • 预测结果:y_
  • 有监督学习:样本集、测试集、训练集都有对应的标签

    • 分类(预测男女):样本标签一般是离散值(A\B、红黄蓝、男\女)
      • KNN Logistic SVC 决策树…
    • 回归(房价预测):样本标签一般是连续值(1.2,1.5,1.8.2.3.2.6)在一个数据区间的任意取值
      • LinearRegression、SVR、Ridge、Lasso
  • 无监督学习:样本集、测试集、训练集都没有有对应的标签

  • 聚类 :KMeans

  • 半监督学习:

  • 深度学习

  • 特征空间:由样本集的特征,展开的空间,称为特征空间。所有的样本都属于这个特征空间

  • 过拟合:,当学习器把训练样本学得"太好"了的时候,很可能巳经把训练样本自身的一些特点当作了所有潜在样本都 会具有的一般性质,这样就会导致泛化性能下降这种现象在机器学习中称为

    “过拟合” (overfitting).

  • 欠拟合:对数据学习的太简陋,没有学习到共性特征,导致模型的泛化能力变弱。

  • 经验误差:学习器的实际预测输出与样本的真实输出之间的差异称为"误差" (error), 学习器在训练集上的误差称为"训练误差" (training error) 或"经验误差" (empirical error)

  • 泛化误差:在新样本上的误差称为"泛化误差" (generalization

    error).

  • 鲁棒性:Huber从稳健统计的角度系统地给出了鲁棒性3个层面的概念:

    • 模型具有较高的精度或有效性,这也是对于机器学习中所有学习模型的基本要求;
    • 对于模型假设出现的较小偏差,只能对算法性能产生较小的影响; 主要是:噪声(noise)
    • 对于模型假设出现的较大偏差,不可对算法性能产生“灾难性”的影响;主要是:离群点(outlier)

k-近邻算法(kNN)

原理

简单地说,K-近邻算法采用测量不同特征值之间的距离方法进行分类。

  • 优点:精度高、对异常值不敏感、无数据输入假定。
  • 缺点:时间复杂度高、空间复杂度高。
  • 适用数据范围:数值型和标称型。

k近邻(k Nearest eighbo ,简称 kNN )学习是一种常用的监督学习 方法, 其工作机制非常简单 给定测试样本,基于某种距离度量找出 练集中 与其最 靠近的k 个训练样本,然后基于这 个k"邻居 “的信息来进行预测 在分 类任务中可使用"投票法” 即选择这 k个样本中出现最多的类别标记作为预 测结果;在回归任务中时使用"平均法" ,即将 k个样本的实值输出标记 平均值作为预测结果;还可基于距离远近进行加权平均或加权投票,距离越近 的样本权重越大.

  • 欧几里得距离(Euclidean Distance)

在这里插入图片描述
欧氏距离是最常见的距离度量,衡量的是多维空间中各个点之间的绝对距离。公式如下:

在scikit-learn库中使用k-近邻算法,用于分类

  • 用途:对离散型的数据进行分类

  • 分类问题:from sklearn.neighbors import KNeighborsClassifier

电影案例分析
#导包
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
from pandas import Series,DataFrame
#读取xlsx文件
train = pd.read_excel('film.xlsx')[0:9] ==>
	电影名称	爱情	动作	电影类别
0	大话西游	3.0	9.0	动作
1	星语心愿	10.0	2.0	爱情
2	叶问	2.0	11.0	动作
3	黄飞鸿	2.0	9.0	动作
4	最好的我们	11.0	3.0	爱情


#删除不关联的特征
train.drop(labels=["电影名称"],axis=1, inplace=True)

# 获取样本集和标签
# 标签
y = train["电影类别"]
# 样本集
X = train[["爱情","动作"]]

#绘制样本特征之间的散点图(图一)
X1 = X[y == "动作"]
X2 = X[y == "爱情"]
plt.scatter(X1["爱情"],X1["动作"], label="ACTION FILM", color="green")
plt.scatter(X2["爱情"],X2["动作"], label="LOVE FILM", color="black")
plt.xlabel("LOVE")
plt.ylabel("ACTION")
plt.legend()


# 1、构建一个算法模型,本案例适合分类模型
from sklearn.neighbors import KNeighborsClassifier,KNeighborsRegressor
## k必须是一个奇数
# 经验值:不要超过样本个数的平方根
knnclf = KNeighborsClassifier(n_neighbors=5)
#2、训练模型
# 有监督学习的fit函数,都接收两个参数,X 样本集  应该保证 样本分布比较均匀,y 样本标签
knnclf.fit(X, y)
#3、预测
#(1),对样本集(学习过的)预测      经验误差(回归模型)   
# (2),对未知(没学习过的)数据预测  泛化误差(回归模型)  
y_ = knnclf.predict(X)		==>
array(['动作', '爱情', '动作', '动作', '爱情', '爱情', '动作', '爱情', '动作'], dtype=object)
# 4、准确率 求得的是在训练集上的准确率
accuracy_rate = (y == y_).sum()/y.size

#泛化数据的预测绘图(图二)
# 【注意】要使用二维数组作为测试数据
X_test = np.array([[5,8],[11,5]])
plt.scatter(X_test[:,0], X_test[:,1], label="Predict", color="orange")
plt.legend()

# 预测函数中,只接收测试集,不接收标签
knnclf.predict(X_test)		==>
array(['动作', '爱情'], dtype=object)

图一
在这里插入图片描述
图二
在这里插入图片描述

系统现有数据:鸢尾花的品种分析
# 导入系统中的数据
from sklearn.datasets import load_iris
#1、获取样本集和标签
iris = load_iris()
data = iris.data
target = iris.target
target_names = iris.target_names
feature_names = iris.feature_names
df = DataFrame(data=data, columns=feature_names)
df.shape		==>(150, 4)
# 样本集
train = data
# 样本标签
target = target
	
#2、均匀的拆分训练集和测试集
from sklearn.model_selection import train_test_split
# random_state 随机数种子  种子固定,随机数就固定
# 如果设定random_state,每一次分割的样本集都一样,这样可以横向比较不同算法的效果好坏
# 如果不设定random_state,每一次分割的样本集都不一样,这样可以多次训练和预测同一个模型,来查看该模型的综合效果

#封装函数得到训练集和测试集的平均得分
#准确率只能用在分类模型的评价上
def knn_score(k):
    # 记录测试机评分
    scores = [] 
    # 记录训练集的评分
    scores1 = []
    for _ in range(100):
        X_train,X_test,y_train,y_test = train_test_split(train, target, test_size=0.2)
        knn = KNeighborsClassifier(n_neighbors=k)
        # 训练集进行训练
        knn.fit(X_train, y_train)
        # 测试集进行预测
        y_ = knn.predict(X_test
        # 训练集进行预测
        y1_ = knn.predict(X_train)
        scores.append((y_ == y_test).sum()/y_.size)
        scores1.append((y1_ == y_train).sum()/y1_.size)
#     print("测试集得分:%.3f, 训练集得分:%.3f"%(np.array(scores).mean(), np.array(scores1).mean()))
    return (np.array(scores).mean(), np.array(scores1).mean())

#3、测试不同的k值对平均值的影响
ks = np.arange(3,13,step=2)
train_scores = []
test_scores = []
# 训练集得分和测试集得分越相近越好
for k in ks:
    print(k)
    train_s, test_s = knn_score(k)
    train_scores.append(train_s)
    test_scores.append(test_s)

# 绘制k值和平均准确率的关系图(图三)
# 根据图像,发现当k=3时候,经验误差和泛化误差最接近,说明此时算法模型表现最好
plt.plot(ks, np.array(train_scores),color="green", label="train_scores")
plt.plot(ks, np.array(test_scores), color="black", label="test_scores")
plt.legend()

图三
在这里插入图片描述

定义KNN分类
# 获取样本空间所有点,绘出背景色
xmin, xmax = train[:,0].min(), train[:,0].max()
ymin, ymax = train[:,1].min(), train[:,1].max()
x = np.linspace(xmin, xmax, 100)
y = np.linspace(ymin, ymax, 100)
#使用meshgrid对一维数据升维,变为(100,100)
xx, yy = np.meshgrid(x, y)
X_test = np.concatenate((xx.reshape(-1,1), yy.reshape(-1,1)),axis=1)

# 选择算法模型,进行训练
knn = KNeighborsClassifier(n_neighbors=3)
knn.fit(train, target)
#得到样本空间所有点的标签
y_ = knn.predict(X_test)

#绘出分类图
from matplotlib.colors import ListedColormap
plt.scatter(X_test[:,0], X_test[:,1],c = y_, cmap = ListedColormap(np.random.random(size=(3,3))))
plt.scatter(train[:,0], train[:,1], c = target, cmap=cmap)

在这里插入图片描述

  • 总结:
  1. 样本集要拆分的均匀,不影响预测结果
  2. 模型应该多次预测取均值,更能说明模型的综合能力
  3. 经验误差和泛化误差应尽量接近,算法的泛化能力才更强
  4. 算法稳定性可以多次训练预测模型,看评分的标准方差,越小说明算法越稳定(受数据的影响波动不大)

KNN算法用于回归

  • 用途:回归用于对趋势的预测
  • 回归问题:from sklearn.neighbors import KNeighborsRegressor
  • 用正弦函数作为分析案例
# 1、生成样本数据
X = np.linspace(0,2*np.pi,60)
y = np.sin(X)
#对标签加上适当的噪音 模拟现实数据
noise = np.random.random(size=30)*0.4 - 0.2
y[::2] += noise
plt.scatter(X, y)

# 2、生成测试数据的结果
from sklearn.neighbors import KNeighborsRegressor(解决回归问题)
knn = KNeighborsRegressor()
knn.fit(X.reshape(-1,1), y)
X_test = np.linspace(0,np.pi*2,52)
y_ = knn.predict(X_test.reshape(-1,1))

#3、绘制真实值和回归模型的分布图
plt.plot(X_test, y_, color="green",label="PREDICT")
plt.scatter(X, y, color="black", label="TRUE")
plt.legend()


#4、使用不同的k值训练相同的数据,观察不同的结果
knn1 = KNeighborsRegressor(n_neighbors=1)
knn2 = KNeighborsRegressor(n_neighbors=5)
knn3 = KNeighborsRegressor(n_neighbors=15)
X = X.reshape(-1,1)
#分别训练
knn1.fit(X,y)
knn2.fit(X,y)
knn3.fit(X,y)
#得到测试标签
X_test = X_test.reshape(-1,1)
y1 = knn1.predict(X_test)
y2 = knn2.predict(X_test)
y3 = knn3.predict(X_test)

#5、绘制三种k值的图像,进行比较
plt.figure(figsize=(16,4))
ax1 = plt.subplot(1,3,1)
#k=1
ax1.set_title("K=1")
plt.plot(X_test, y1, color="green", label="Predict")
plt.scatter(X, y, color="black", label="TRUE")
ax2 = plt.subplot(1,3,2)
#k=5
ax2.set_title("K=5")
plt.plot(X_test, y2, color="green", label="Predict")
plt.scatter(X, y, color="black", label="TRUE")
ax3 = plt.subplot(1,3,3)
#k=15
ax3.set_title("K=15")
plt.plot(X_test, y3, color="green", label="Predict")
plt.scatter(X, y, color="black", label="TRUE")

#结论:当k=5时经验误差和泛化误差都相对较小

在这里插入图片描述
在这里插入图片描述

线性回归

  • 先复习一下大学的函数的导数及运算
    ① C’=0(C为常数);
    ② (xn)’=nx(n-1) (n∈Q);
    ③ (sinx)’=cosx;
    ④ (cosx)’=-sinx;
    ⑤ (ex)’=ex;
    ⑥ (ax)’=axIna (ln为自然对数)
    ⑦ loga(x)’=(1/x)loga(e)
  • 导数的运算
    ①(u±v)’=u’±v’
    ②(uv)’=u’v+uv’
    ③(u/v)’=(u’v-uv’)/ v^2
    ④[u(v)]’=[u’(v)]*v’ (u(v)为复合函数f[g(x)])
  • 最小二乘法(又称最小平方法)是一种数学优化技术。它通过最小化误差的平方和寻找数据的最佳函数匹配。利用最小二乘法可以简便地求得未知的数据,并使得这些求得的数据与实际数据之间误差的平方和为最小。最小二乘法还可用于曲线拟合。
    注: xT 表示的是向量
    在这里插入图片描述
    在这里插入图片描述
  • 矩阵的阶:一个m行n列的矩阵简称为mn矩阵,特别把一个nn的矩阵成为n阶正方阵,或者n阶矩阵
  • 矩阵的秩:用初等行变换将矩阵A化为阶梯形矩阵, 则矩阵中非零行的个数就定义为这个矩阵的秩, 记为r(A)
  • 满秩矩阵:满秩矩阵(non-singular matrix): 设A是n阶矩阵, 若r(A) = n, 则称A为满秩矩阵。但满秩不局限于n阶矩阵。若矩阵秩等于行数,称为行满秩;若矩阵秩等于列数,称为列满秩。既是行满秩又是列满秩则为n阶矩阵即n阶方阵。行满秩矩阵就是行向量线性无关,列满秩矩阵就是列向量线性无关;所以如果是方阵,行满秩矩阵与列满秩矩阵是等价的。满秩有行满秩和列满秩,既是行满秩又是列满秩的话就一定是是方阵
  • 奇异矩阵:奇异矩阵是线性代数的概念,就是该矩阵的秩不是满秩。首先,看这个矩阵是不是方阵(即行数和列数相等的矩阵。若行数和列数不相等,那就谈不上奇异矩阵和非奇异矩阵)
#计算矩阵的秩
a = np.array([[3,3.5,2],[3.2,3.6,3],[6,7,4]])
np.linalg.matrix_rank(a)
  • 矩阵求逆:AA-¹=A-¹A=E(单位矩阵)
  • 逆矩阵的作用:逆矩阵是经常遇到的一个概念。教科书中讲解了逆矩阵的求法,但是没有说清楚为何需要逆矩阵,逆矩阵的意义是什么。逆矩阵可以类比成数字的倒数,比如数字5的倒数是1/5,矩阵A的“倒数”是A的逆矩阵。5*(1/5)=1, A*(A的逆矩阵) = I,I是单位矩阵。引入逆矩阵的原因之一是用来实现矩阵的除法。比如有矩阵X,A,B,其中XA = B,我们要求X矩阵的值。本能来说,我们只需要将B/A就可以得到X矩阵了。但是对于矩阵来说,不存在直接相除的概念。我们需要借助逆矩阵,间接实现矩阵的除法。具体的做法是等式两边在相同位置同时乘以矩阵A的逆矩阵,如下所示,XA*(A的逆矩阵)= B*(A的逆矩阵)。由于A*(A的逆矩阵) = I,即单位矩阵,任何矩阵乘以单位矩阵的结果都是其本身。所以,我们可以得到X = B*(A的逆矩阵)。
#numpy求逆矩阵
a_ = np.linalg.inv(a)
  • 求算法的系数和截距
# 算法的系数
lr.coef_

# 截距
lr.intercept_

【普通线性回归求解过程】

  • 求解的过程 f(x) = WX + b
  • 普通线性回归、Ridge、Loasso又叫 狭义线性回归
  • 确定一个估计函数 f(x) = WX
  • 带入数据,构造一个损失函数cost (y-y’)**2
  • 对损失函数求最优解 对w求导数等于0
  • 如果有截距,就是用梯度下降法求最优解

普通线性回归LinearRegression(狭义线性回归

  • 原理:分类的目标变量是标称型数据,而回归将会对连续型的数据做出预测。
  • 适用场景:一般来说,只要我们觉得数据有线性关系,LinearRegression类是我们的首先。如果发现拟合或者预测的不好,再考虑用其他的线性回归库。如果是学习线性回归,推荐先从这个类开始第一步的研究。
接下来就以糖尿病数据做线性回归分析
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
import matplotlib.pyplot as plt
%matplotlib inline

#1、获取数据
from sklearn.datasets import load_diabetes
diabetes = load_diabetes()
# 样本集
data = diabetes.data
# 样本标签
target = diabetes.target
#简便写法(直接获取样本集和样本标签)
# X, y = load_diabetes(return_X_y=True)

#2、抽取训练数据和预测数据
#创建数学模型
from sklearn.linear_model import LinearRegression
lr = LinearRegression()
#分割样本集得到训练集合测试集
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(data, target, test_size=0.2, random_state=1)
#训练
lr.fit(X_train, y_train)
#预测
y_ = lr.predict(X_test)

#3、绘制残差图
# 一般使用损失来评价回归模型
# 可以使用残差直方图来观察数据的预测结果
errs = (y_ - y_test)
plt.hist(errs, bins=10)

# 4、线性回归和Knn回归算法比较(通过绘图)
from sklearn.neighbors import KNeighborsRegressor
#计算KNN算法误差
knn = KNeighborsRegressor()
knn.fit(X_train, y_train)
y1_ = knn.predict(X_test)
errs1 = (y1_ - y_test)
errs = (y_ - y_test)
#绘图
plt.hist(errs, bins=10, label="Lieaner",alpha=0.5, color="y")
plt.hist(errs1, bins=10, label="KNN",alpha=0.5, color="m")
plt.legend()



# 5、均方误差MSE来比较回归模型的好坏
from sklearn.metrics import mean_squared_error
# mean_squared_error传入两个参数:真值和预测值
lr_score = mean_squared_error(y_test, y_)
knn_score = mean_squared_error(y_test, y1_)
# 误差越小越好 这里LR优于KNN
print(lr_score, knn_score)		==>
2992.55768145 3957.18292135

LinearRegression残差图
在这里插入图片描述
KNN和LinearRegression比较
在这里插入图片描述

  • 单独查看某一个特征对结果的影响
feature_names = diabetes.feature_names
df = DataFrame(data=data, columns=feature_names)		==>

	age	sex	bmi	bp	s1	s2	s3	s4	s5	s6
0	0.038076	0.050680	0.061696	0.021872	-0.044223	-0.034821	-0.043401	-0.002592	0.019908	-0.017646
1	-0.001882	-0.044642	-0.051474	-0.026328	-0.008449	-0.019163	0.074412	-0.039493	-0.068330	-0.092204
#这里研究BMI(体重指数)对结果的影响
#1、获取数据
train = df["bmi"]
target = target
X_train, X_test, y_train, y_test = train_test_split(train, target, test_size=0.2)

#2、抽取训练数据和预测数据(使用普通线性回归)
lr = LinearRegression()
#lr.fit(X_train.reshape(-1,1), y_train)
#lr.predict(X_test.reshape(-1,1))
#训练全部样本
lr.fit(train.reshape(-1,1), target)
#测试线性数据
X_test = np.linspace(train.min(), train.max(),100).reshape(-1,1)
y_ = lr.predict(X_test)

# 3、绘制真值和线性回归图
plt.scatter(train, target, color="black", alpha=0.5, label="True")
plt.plot(X_test, y_, color="green", label="Predict")
plt.legend()
plt.xlabel("BMI")
plt.ylabel("Target")

在这里插入图片描述

岭回归Ridge:L2正则项

  • 原理:缩减系数来“理解”数据
    如果数据的特征比样本点还多应该怎么办?是否还可以使用线性回归和之前的方法来做预测?
    答案是否定的,即不能再使用前面介绍的方法。这是因为输入数据的矩阵X不是满秩矩阵。非满秩矩阵在求逆时会出现问题。
    为了解决这个问题,统计学家引入了岭回归(ridge regression)的概念
    在这里插入图片描述
  • 优点:缩减方法可以去掉不重要的参数,因此能更好地理解数据。此外,与简单的线性回归相比,缩减法能取得更好的预测效果
  • 岭回归是加了二阶正则项的最小二乘,主要适用于过拟合严重或各变量之间存在多重共线性的时候,岭回归是有bias的,这里的bias是为了让variance更小。
  • 缺点:这个类最大的缺点是每次我们要自己指定一个超参数α,然后自己评估α的好坏,比较麻烦
  • 总结:
    1.岭回归可以解决特征数量比样本量多的问题
    2.岭回归作为一种缩减算法可以判断哪些特征重要或者不重要,有点类似于降维的效果
    3.缩减算法可以看作是对一个模型增加偏差的同时减少方差
  • 使用场景:
    1.数据点少于变量个数
    2.变量间存在共线性(最小二乘回归得到的系数不稳定,方差很大)
    3.应用场景就是处理高度相关的数据
  • 参数alpha对系数的影响
from sklearn.linear_model import Ridge
# 1、存储每一个alpha训练出来的每一组系数
alphas = np.logspace(-10,-2,100,endpoint=False)
coefs = []
ridge = Ridge()
for alpha in alphas:
    ridge.set_params(alpha=alpha)
    ridge.fit(X,y)
    #coef_函数可以获取机器学习模型中各个特征值的系数
    coef = ridge.coef_
    coefs.append(coef)
#2、绘制alpha和coefs的关系图
plt.figure(figsize=(10,6))
plt.plot(alphas, coefs)
plt.xscale("log")
plt.xlabel("ALPHA")
plt.ylabel("COEFS")

在这里插入图片描述

  • 结论:
  1. alpha值的选择如果太大:无限趋向于0,算法没有意义
  2. 如果太小:系数波动太大,算法不稳定
  3. 应该选择在0左右,比较稳定的区间

lasso回归:L1正则项

  • 原理:与岭回归类似,它也是通过增加惩罚函数来判断、消除特征间的共线性。
    【拉格朗日乘数法】
    对于参数w增加一个限定条件,能到达和岭回归一样的效果:
    在lambda足够小的时候,一些系数会因此被迫缩减到0

一般来说,对于高维的特征数据,尤其线性关系是稀疏的,我们会采用Lasso回归。或者是要在一堆特征里面找出主要的特征,那么Lasso回归更是首选了。但是Lasso类需要自己对α调优,所以不是Lasso回归的首选,一般用到的是下一节要讲的LassoCV类。

对比各个算法的训练数据系数coef
#使用numpy创建数据X,创建系数,对系数进行处理,对部分系数进行归零化操作,然后根据系数进行矩阵操作求得目标值

# 1、获取数据
#样本数
n_samples = 50
#特征数
n_featrues = 200
X = np.random.random(size=(n_samples, n_featrues))
#系数
w = np.random.random(size=200)
# 在200个系数中,随机选择一些有效系数,而其他系数就清零
index = np.random.permutation(200)
idx = index[10:]
w[idx] = 0
#样本标签
y = np.dot(X,w)

# 2、训练数据和测试数据
lr = LinearRegression()
ridge = Ridge(alpha=6)
lasso = Lasso(alpha=0.0001)
lr.fit(X,y)
ridge.fit(X,y)
lasso.fit(X,y)

#3、数据视图,此处获取各个算法的训练数据的coef_:系数
coefs = [w, lr.coef_, ridge.coef_, lasso.coef_]
models = ["True","Linear","Ridge", "Lasso"]
plt.figure(figsize=(12,8))
loc = 1
for coef, model in zip(coefs, models):
    ax = plt.subplot(2,2,loc)
    loc += 1
    ax.set_title(model)
    ax.plot(coef, color=np.random.random(size=3))

在这里插入图片描述

波士顿房价的影响因素分析

import numpy as np
import pandas as pd
from pandas import Series,DataFrame
import matplotlib.pyplot as plt
%matplotlib inline
from sklearn.datasets import load_boston
#导入数据
boston = load_boston()
data = boston.data
target = boston.target
feature_names = boston.feature_names
df = DataFrame(data=data, columns=feature_names)
df.head()		==>
	CRIM	ZN	INDUS	CHAS	NOX	RM	AGE	DIS	RAD	TAX	PTRATIO	B	LSTAT
0	0.00632	18.0	2.31	0.0	0.538	6.575	65.2	4.0900	1.0	296.0	15.3	396.90	4.98
1	0.02731	0.0	7.07	0.0	0.469	6.421	78.9	4.9671	2.0	242.0	17.8	396.90	9.14
2	0.02729	0.0	7.07	0.0	0.469	7.185	61.1	4.9671	2.0	242.0	17.8	392.83	4.03
#分割训练数据和测试数据
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(data, target, test_size=0.2)
from sklearn.linear_model import LinearRegression, Ridge, Lasso
from sklearn.neighbors import KNeighborsRegressor
from sklearn.metrics import mean_squared_error


#封装函数多次查看模型的均方误差的平均值、
def model_mse(model):
    X_train, X_test, y_train, y_test = train_test_split(data, target, test_size=2)
    model.fit(X_train, y_train)
    #测试误差
    test_err = mean_squared_error(y_test, model.predict(X_test))
    #训练误差
    train_err = mean_squared_error(y_train, model.predict(X_train))
    return test_err, train_err
    
#计算100次训练的平均误差
def ave_err(model):
    ridge = model
    test_errs = []
    train_errs = []
    for i in range(100):
        ret = model_mse(ridge)
        test_errs.append(ret[0])
        train_errs.append(ret[1])
    print("经验误差:%.2f, 泛化误差:%.2f"%(np.array(train_errs).mean(), np.array(test_errs).mean()))
    return np.array(train_errs).mean(), np.array(test_errs).mean()
#岭回归
r = Ridge(alpha=3)
ave_err(r)		==>经验误差:22.33, 泛化误差:21.88
# KNN回归
knn = KNeighborsRegressor()
ave_err(knn)	==>经验误差:23.92, 泛化误差:41.64
#普通线性回归
lr = LinearRegression()
ave_err(lr)	==>经验误差:21.89, 泛化误差:24.97
#劳斯回归
lasso = Lasso()
ave_err(lasso)	==>lasso = Lasso()
ave_err(lasso)
lasso = Lasso()
ave_err(lasso)
经验误差:26.82, 泛化误差:23.35

#以上可以看出【岭回归】更适合
# 算法调参
alphas = [0.1,0.5,1,3,5,10,20]
errs_train = []
errs_test = []
for alpha in alphas:
    ridge = Ridge(alpha=alpha)
    print("alphe = {}".format(alpha))
    train_err, test_err = ave_err(ridge)
    errs_train.append(train_err)
    errs_test.append(test_err)		==>
    
alphe = 0.1
经验误差:21.54, 泛化误差:24.49
alphe = 0.5
经验误差:21.86, 泛化误差:23.73
alphe = 1
经验误差:21.66, 泛化误差:24.99
alphe = 3
经验误差:22.31, 泛化误差:23.91
alphe = 5
经验误差:22.28, 泛化误差:24.80
alphe = 10
经验误差:22.46, 泛化误差:24.95
alphe = 20
经验误差:22.59, 泛化误差:25.34
plt.plot(alphas, errs_train, lab


# 绘制误差随着alpha参数的变化曲线
plt.plot(alphas, errs_train, label = "train err", color="green")
plt.plot(alphas, errs_test, label = "test err", color="black")
plt.legend()

经验误差和泛化误差曲线图 :

鲍鱼年龄预测
# 需求: 找出预测鲍鱼年龄的最佳算法并且对该算法进行调参

import numpy as np
import pandas as pd
from pandas import Series,DataFrame
import matplotlib.pyplot as plt
%matplotlib inline
# 1、获取样本集和样本标签
abalone = pd.read_csv('abalone.txt',sep='\t',header=None)
#样本集
train = abalone.loc[:,0:7]
#样本标签
target = abalone[8]
#查看数据信息
abalone.shape
abalone.describe()
abalone.info()
target.unique()

#分析数据的出此问题是线性回归问题
#选择线性回归模型并计算各个模型的均方误差进行比较
from sklearn.linear_model import LinearRegression, Ridge, Lasso
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
#1.封装函数进行算法比较
# 算法选择
def model_err(model):
    test_errs = []
    train_errs = []
    for i in range(10):
        X_train, X_test, y_train, y_test = train_test_split(train, target, test_size=0.2)
        model.fit(X_train, y_train)
        test_err = mean_squared_error(y_test, model.predict(X_test))
        train_err = mean_squared_error(y_train, model.predict(X_train))
        test_errs.append(test_err)
        train_errs.append(train_err)
    return np.array(test_errs).mean(), np.array(train_errs).mean()

# 普通线性回归
model_err(LinearRegression())</
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值