吴恩达:机器学习里面的作业1遇到的

基于:https://www.kesci.com/mw/project/5da16a37037db3002d441810

让我们开始吧。

首先的首先,至少得学一点点numpy,我不得不承认的是,“遇到再学”这种学习方法虽然很能偷懒,但是很不利于在脑内建立索引。真的吃太多亏了。

首先,这里所有的x都是横着排布的——什么意思呢?每一行代表一个example,所有的example竖着排列,具体样例可以看ex1给的数据。y都是竖着排布的——每一列代表一个result。theta都是横着的。

然后我自己的话用的是在Windows下的vscode,装了杂七杂八一堆插件。什么intelligence,pylance的。

输出单位矩阵

第一个是输出单位矩阵,我想这个是不难的,代码如下:

import numpy
a = numpy.identity(5)
print(a)

读取数据

然后就是读取数据,并将其以散点图的形式可视化,代码如下:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
path = "作业/1/data/ex1data1.txt"
data = pd.read_csv(path, header=None, names=['Population', 'Profit'])
print(data.head())

data.plot(kind='scatter', x='Population', y='Profit', figsize=(12,8))
plt.show()

这里有几个点我觉得很需要讲一讲,首先就是这个path变量,这个斜杠形式要记住,不是“/”,而是“\”。然后就是这个read_csv了,虽然我们读的是txt,但好像也可以。然后是header和names,初次接触可能会有点陌生,记得去必应就好。我个人觉得,初学者没必要听大佬们讲直接读英文啥的,可以先看中文,看csdn,简书的东西——当然看英文好,看官方文档自然最好,只是太劝退了。英语极佳者可以忽略。
结果就不说了,有兴趣的可以把header,names啊这些参数随便弄一弄,看看会发生什么。

演示Cost Function

代码如下:

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


def model(x, theta):
    return np.dot(x,theta.T)


def cost_function(x, y, theta):
    inner = np.power(model(x, theta)-y, 2)
    return np.sum(inner)/(2*len(x))


path = "作业/1/data/ex1data1.txt"
data = pd.read_csv(path,names=['Population', 'Profit'])
#print(data)

x = pd.DataFrame(data.Population)
x.insert(0,"default",1)
#print(x)

y = pd.DataFrame(data.Profit)
#print(y)

theta = np.matrix(np.array([0,0]))
#print(theta.shape)
print(cost_function(x,y,theta))

我们这里使用Mean Squared Error这项公式来计算偏差/误差啥的。关注函数cost_function,这就是对原始公式:

\[J(\theta) = \frac{1}{2m}\sum^{m}_{i=1}(h_\theta(x^i)-y^i)^2 \]

的直接翻译,当然如果你嫌代码本身的这个太麻烦了,巧妙使用矩阵直接np.dot()也是可以的。当然,你要问为什么不用别的方法,以及这个mse的优越性,那就得学数学了,很抱歉我不会(逃

演示梯度下降

先把整个代码放出来:

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


def model(x, theta):
    return np.dot(x, theta.T)


def cost_function(x, y, theta):
    inner = np.power(model(x, theta)-y, 2)
    return np.sum(inner)/(2*len(x))


def error(x, y, theta):
    return model(x, theta)-y


def gradient_descent(x, y, theta, alpha, iters):
    for i in range(iters):
        theta = theta - alpha * (1/len(x)*np.dot(error(x, y, theta).transpose(), x)) #我讨厌矩阵操作……好难
    return theta


path = "作业/1/data/ex1data1.txt"
data = pd.read_csv(path, names=['Population', 'Profit'])
#print(data)

x = pd.DataFrame(data.Population)
x.insert(0, "default", 1)
#print(x)

y = pd.DataFrame(data.Profit)
#print(y)

theta = np.matrix(np.array([0, 0]))
#print(theta.shape)

model = gradient_descent(x, y, theta, 0.01, 1500)

print([1,3.5]*model.T)
print([1,7]*model.T)

x = np.linspace(data.Population.min(),data.Population.max())
print(x)
f = model[0,0]+(model[0,1]*x)

fig, ax = plt.subplots(figsize = (12, 8))
ax.plot(x, f, 'r', label='Prediction')
ax.scatter(data.Population, data.Profit, label='Traning Data')
ax.legend(loc=2)
ax.set_xlabel('Population')
ax.set_ylabel('Profit')
ax.set_title('Predicted Profit vs. Population Size')
plt.show()

然后慢慢来。

其实这里很多涉及的部分就是公式翻译成代码,没啥更多的。真正的精髓是为什么是这个公式。这就要去看Coursera上面的原文了。进一步的,可以看一下西瓜书和统计学习方法啥的。

原文这里使用的技术……对不起我没看懂,所以我换个了方法,就是这个:

x = pd.DataFrame(data.Population)
x.insert(0, "default", 1)
#print(x)

y = pd.DataFrame(data.Profit)
#print(y)

当然,这是因为这里只有一个x和一个y,所以可以这么偷懒:直接拿出来之后再包装一下。不过对于我这个第一次用py的人来说,我第一次看到直接惊呆了。
另外就是插入,我在这里给0这个索引这里插入了一个1,用于计算。记得我们这里所用的是一个线性模型,latex懒得打了,就是一条线。为了方便统一,加多一个\(x_0 = 1\)好了。

还有就是初始化\(\theta\),我们这里就很简单了,包装成矩阵就好。由于梯度下降的特性,直接全取0就很合理。往下走吧,就是
这个梯度下降主函数了。看向里面,就只有几行:

def gradient_descent(x, y, theta, alpha, iters):
    for i in range(iters):
        theta = theta - alpha * (1/len(x)*np.dot(error(x, y, theta).transpose(), x)) #我讨厌矩阵操作……好难
    return theta

这个也只是一个简单的翻译罢了:

\[\theta_j := \theta_j - \alpha\frac{\partial(\ J(\theta_0,\theta_1))}{\partial \theta_j} \]

其中,这个\({\partial(\ J(\theta_0,\theta_1))}\)就是这个:

\[{\partial(\ J(\theta_0,\theta_1))} = \frac{1}{m}\sum^{m}_{i=1}{(h_\theta(x^i)-y^i)}x^i \]

当然,还没完。公式翻译成代码本身也是颇有难度的,因此,里面有些东西是需要关注一下的。我这里还是使用的点乘,用来方便地表示这个累加操作。先横后竖,这是矩阵右乘那边的一个简单的方法,本质的话看mit网课,请(

对对对我知道还有error函数,但那玩意看一下代码不就好了(逃
不过注意一下“首先,这里所有的x都是横着排布的——什么意思呢?每一行代表一个example,所有的example竖着排列,具体样例可以看ex1给的数据。y都是竖着排布的——每一列代表一个result。theta都是横着的。”

算完之后就是放图了,我觉得没啥好说的,不会的多必应就好。顺便吐个槽,之前做Games 101的作业1解析的时候,本来想事无巨细的写,毕竟真的给某些教材那种不讲人话,硬塞概念,Fly Bitch的方法搞得很恶心,想着尽可能详细点,结果写崩了,现在也就烂尾了,唉可能就画线算法要写一写吧。所以这里点到为止,主要是懒。

这玩意应该可以应付多变量的,毕竟差不多全是矩阵操作了。

对多变量的特征归一化,同时完成多变量的梯度下降

代码如下:

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


def model(x, theta):
    return np.dot(x, theta.T)


def cost_function(x, y, theta):
    inner = np.power(model(x, theta)-y, 2)
    return np.sum(inner)/(2*len(x))


def error(x, y, theta):
    return model(x, theta)-y


def gradient_descent(x, y, theta, alpha, iters):
    for i in range(iters):
        theta = theta - alpha * (1/int(x.shape[0]))*np.dot(error(x, y, theta).transpose(), x) #我讨厌矩阵操作……好难
    return theta
    

data = pd.read_csv("作业/1/data/ex1data2.txt",header=None,names=['Size', 'Bedrooms', 'Price'])
print(data.head())

print(data.mean())
print("   ")
print(data.std())

data = (data - data.mean())/data.std()
print(data.head())


x = pd.DataFrame([data.Size,data.Bedrooms]).T
x.insert(0,"default",1)
print(x.head())
y = pd.DataFrame([data.Price]).T
print(y.head())

theta = np.matrix(np.array([0,0,0]))

model = gradient_descent(x,y,theta,0.01,1500)
print(model)

关键就是这几行:

data = (data - data.mean())/data.std()

没了。

正规方程演示

代码如下:

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

def normal_equation(x,y):
    temp_1 = np.linalg.pinv(x.T.dot(x))
    temp_2 = x.T.dot(y)
    return temp_1.dot(temp_2)
'''
data = pd.read_csv("作业/1/data/ex1data2.txt",header=None,names=['Size', 'Bedrooms', 'Price'])
print(data.head())

print(data.mean())
print("   ")
print(data.std())

data = (data - data.mean())/data.std()
print(data.head())


x = pd.DataFrame([data.Size,data.Bedrooms]).T
x.insert(0,"default",1)
print(x.head())
y = pd.DataFrame([data.Price]).T
print(y.head())

print(normal_equation(x,y))
'''
path = "作业/1/data/ex1data1.txt"
data = pd.read_csv(path, names=['Population', 'Profit'])
#print(data)

x = pd.DataFrame(data.Population)
x.insert(0, "default", 1)
#print(x)

y = pd.DataFrame(data.Profit)
#print(y)
print(normal_equation(x,y))

一样,翻译公式,网站就是这个:
https://eli.thegreenplace.net/2015/the-normal-equation-and-matrix-calculus/
解释了一下公式咋来的,以及矩阵求导咋搞。老实说我还是不会,就看了个热闹(逃

posted @ 2021-03-14 19:39  Lemon-GPU  阅读(109)  评论(0编辑  收藏  举报