社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  机器学习算法

温州大学《机器学习》课程代码(二)(回归)

机器学习初学者 • 4 年前 • 377 次点击  

温州大学《机器学习》课程代码(二)(回归)

代码修改并注释:黄海广,haiguang2000@wzu.edu.cn

课件   视频

下载地址:https://github.com/fengdu78/WZU-machine-learning-course

单变量线性回归

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei'#用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
path = 'data/regress_data1.csv'
data = pd.read_csv(path)
data.head()

人口收益
06.110117.5920
15.52779.1302
28.518613.6620
37.003211.8540
45.85986.8233
data.describe()

人口收益
count97.00000097.000000
mean8.1598005.839135
std3.8698845.510262
min5.026900-2.680700
25%5.7077001.986900
50%6.5894004.562300
75%8.5781007.046700
max22.20300024.147000

看下数据长什么样子

data.plot(kind='scatter', x='人口', y='收益', figsize=(12,8))
plt.xlabel('人口', fontsize=18)
plt.ylabel('收益', rotation=0, fontsize=18)
plt.show()


现在让我们使用梯度下降来实现线性回归,以最小化代价函数。

首先,我们将创建一个以参数为特征函数的代价函数

其中:

def computeCost(X, y, w):
    inner = np.power(((X * w.T) - y), 2 )# (m,n) @ (n, 1) -> (n, 1)
#     return np.sum(inner) / (2 * len(X))
    return np.sum(inner) / (2 * X.shape[0])

让我们在训练集中添加一列,以便我们可以使用向量化的解决方案来计算代价和梯度。

data.insert(0'Ones'1)
data

Ones人口收益
016.110117.59200
115.52779.13020
218.518613.66200
317.003211.85400
415.85986.82330
............
9215.87077.20290
9315.30541.98690
9418.29340.14454
95113.39409.05510
9615.43690.61705

97 rows × 3 columns

现在我们来做一些变量初始化。




    
# set X (training data) and y (target variable)
cols = data.shape[1]
X = data.iloc[:,:cols-1]#X是所有行,去掉最后一列
y = data.iloc[:,cols-1:]#X是所有行,最后一列

观察下 X (训练集) and y (目标变量)是否正确.

X.head()#head()是观察前5行

Ones人口
016.1101
115.5277
218.5186
317.0032
415.8598
y.head()

收益
017.5920
19.1302
213.6620
311.8540
46.8233

代价函数是应该是numpy矩阵,所以我们需要转换X和Y,然后才能使用它们。我们还需要初始化w。

X = np.matrix(X.values)
y = np.matrix(y.values)
w = np.matrix(np.array([0,0]))

w 是一个(1,2)矩阵

w
matrix([[0, 0]])

看下维度




    
X.shape, w.shape, y.shape
((97, 2), (1, 2), (97, 1))

计算代价函数 (theta初始值为0).

computeCost(X, y, w)
32.072733877455676

Batch Gradient Decent(批量梯度下降)


def batch_gradientDescent(X, y, w, alpha, iters):
    temp = np.matrix(np.zeros(w.shape))
    parameters = int(w.ravel().shape[1])
    cost = np.zeros(iters)

    for i in range(iters):
        error = (X * w.T) - y

        for j in range(parameters):
            term = np.multiply(error, X[:, j])
            temp[0, j] = w[0, j] - ((alpha / len(X)) * np.sum(term))

        w = temp
        cost[i] = computeCost(X, y, w)

    return w, cost

初始化一些附加变量 - 学习速率α和要执行的迭代次数。

alpha = 0.01
iters = 1000

现在让我们运行梯度下降算法来将我们的参数θ适合于训练集。

g, cost = batch_gradientDescent(X, y, w, alpha, iters)
g
matrix([[-3.24140214,  1.1272942 ]])

最后,我们可以使用我们拟合的参数计算训练模型的代价函数(误差)。

computeCost(X, y, g)
4.515955503078912

现在我们来绘制线性模型以及数据,直观地看出它的拟合。

x = np.linspace(data['人口'].min(), data['人口'].max(), 100)
f = g[00] + (g[01] * x)

fig, ax = plt.subplots(figsize=(128))
ax.plot(x, f, 'r', label='预测值')
ax.scatter(data['人口'], data['收益'], label='训练数据')
ax.legend(loc=2)
ax.set_xlabel('人口', fontsize=18)
ax.set_ylabel('收益', rotation=0, fontsize=18)
ax.set_title('预测收益和人口规模', fontsize=18)
plt.show()





由于梯度方程式函数也在每个训练迭代中输出一个代价的向量,所以我们也可以绘制。请注意,代价总是降低 - 这是凸优化问题的一个例子。

fig, ax = plt.subplots(figsize=(128))
ax.plot(np.arange(iters), cost, 'r')
ax.set_xlabel('迭代次数', fontsize=18)
ax.set_ylabel('代价', rotation=0, fontsize=18)
ax.set_title('误差和训练Epoch数', fontsize=18)
plt.show()



多变量线性回归

练习还包括一个房屋价格数据集,其中有2个变量(房子的大小,卧室的数量)和目标(房子的价格)。我们使用我们已经应用的技术来分析数据集。

path = 'data/regress_data2.csv'
data2 = pd.read_csv(path)
data2.head()

面积房间数价格
021043399900
116003329900
224003369000
314162232000
430004539900

对于此任务,我们添加了另一个预处理步骤 - 特征归一化。这个对于pandas来说很简单

data2 = (data2 - data2.mean()) / data2.std()
data2.head()

面积房间数价格
00.130010-0.2236750.475747
1-0.504190-0.223675-0.084074
20.502476-0.2236750.228626
3-0.735723-1.537767-0.867025
41.2574761.0904171.595389

现在我们重复第1部分的预处理步骤,并对新数据集运行线性回归程序。




    
# add ones column
data2.insert(0'Ones'1)

# set X (training data) and y (target variable)
cols = data2.shape[1]
X2 = data2.iloc[:,0:cols-1]
y2 = data2.iloc[:,cols-1:cols]

# convert to matrices and initialize theta
X2 = np.matrix(X2.values)
y2 = np.matrix(y2.values)
w2 = np.matrix(np.array([0,0,0]))

# perform linear regression on the data set
g2, cost2 = batch_gradientDescent(X2, y2, w2, alpha, iters)

# get the cost (error) of the model
computeCost(X2, y2, g2)
0.13070336960771892

我们也可以快速查看这一个的训练进程。

fig, ax = plt.subplots(figsize=(12,8))
ax.plot(np.arange(iters), cost2, 'r')
ax.set_xlabel('迭代次数', fontsize=18)
ax.set_ylabel('代价', rotation=0, fontsize=18)
ax.set_title('误差和训练Epoch数', fontsize=18)
plt.show()



我们也可以使用scikit-learn的线性回归函数,而不是从头开始实现这些算法。我们将scikit-learn的线性回归算法应用于第1部分的数据,并看看它的表现。

from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(X, y)
LinearRegression()

scikit-learn model的预测表现

x = np.array(X[:, 1].A1)
f = model.predict(X).flatten()

fig, ax = plt.subplots(figsize=(128))
ax.plot(x, f, 'r', label='预测值')
ax.scatter(data['人口'], data['收益'], label='训练数据')
ax.legend(loc=2, fontsize=18)
ax.set_xlabel('人口', fontsize=18)
ax.set_ylabel('收益', rotation=0, fontsize=18)
ax.set_title('预测收益和人口规模', fontsize=18)
plt.show()


正则化

,此时称作Ridge Regression

from


    
 sklearn.linear_model import Ridge
model = Ridge()
model.fit(X, y)
Ridge()
x2 = np.array(X[:, 1].A1)
f2 = model.predict(X).flatten()

fig, ax = plt.subplots(figsize=(128))
ax.plot(x2, f2, 'r', label='预测值Ridge')
ax.scatter(data['人口'], data['收益'], label='训练数据')
ax.legend(loc=2, fontsize=18)
ax.set_xlabel('人口', fontsize=18)
ax.set_ylabel('收益', rotation=0, fontsize=18)
ax.set_title('预测收益和人口规模', fontsize=18)
plt.show()


正则化:

,此时称作Lasso Regression

from sklearn.linear_model import Lasso
model = Lasso()
model.fit(X, y)
Lasso()
x3= np.array(X[:, 1].A1)
f3 = model.predict(X).flatten()

fig, ax = plt.subplots(figsize=(128))
ax.plot(x3, f3, 'r', label='预测值Lasso')
ax.scatter(data['人口'], data['收益'], label='训练数据')
ax.legend(loc=2, fontsize=18)
ax.set_xlabel('人口', fontsize=18)
ax.set_ylabel('收益', rotation=0, fontsize=18)
ax.set_title('预测收益和人口规模', fontsize=18)
plt.show()



调参

from sklearn.model_selection import cross_val_score
alphas = np.logspace(-3250)
test_scores = []
for alpha in alphas:
    clf = Ridge(alpha)
    test_score = np.sqrt(-cross_val_score(clf, X, y, cv=5, scoring='neg_mean_squared_error'))
    test_scores.append(np.mean(test_score))
import matplotlib.pyplot as plt
plt.plot(alphas, test_scores)
plt.title("Alpha vs CV Error");
plt.show()



最小二乘法(LSM)

最小二乘法的需要求解最优参数

已知:目标函数

其中:

将向量表达形式转为矩阵表达形式,则有 ,其中列的矩阵(为样本个数,为特征个数),行1列的矩阵(包含了),行1列的矩阵,则可以求得最优参数

梯度下降与最小二乘法的比较:

梯度下降: 需要选择学习率,需要多次迭代,当特征数量大时也能较好适用,适用于各种类型的模型

最小二乘法: 不需要选择学习率,一次计算得出,需要计算,如果特征数量较大则运算代价大,因为矩阵逆的计算时间复杂度为,通常来说当小于10000 时还是可以接受的,只适用于线性模型,不适合逻辑回归模型等其他模型

# 正规方程
def LSM(X, y):
    w = np.linalg.inv(X.T@X)@X.T@y #X.T@X等价于X.T.dot(X)
    return w
final_w2=LSM(X, y)#感觉和批量梯度下降的theta的值有点差距
final_w2
matrix([[-3.89578088],
[ 1.19303364]])
#梯度下降得到的结果是matrix([[-3.24140214,  1.1272942 ]])

参考

  • 机器学习,吴恩达
  • 《统计学习方法》,李航
  • 机器学习课程,邹博


往期 精彩回顾





本站qq群851320808,加入微信群请扫码:

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/110502
 
377 次点击