# Loda Data & Data Analysis
from sklearn.datasets import load_boston
dataset = load_boston()# load the dataset
dir(dataset)# show the form of the dataset
dataset['feature_names']# show the tag of the dataset
# we can see the introdcution about these tags by print(dataset['CRIM'])
# define the problem
# if you are the state salesman,you have to konw the price of the state
# (given some description data about the state to konw its price)
import pandas as pd
# pandas means panel data set面板数据-excel数据处理-更方便编程
dataframe = pd.DataFrame(dataset['data']) # put the dataset into the pd
# we can use dataframe.head() to show up how many data we have
# use len(dataframe) to see the total number of the dataset
# only input the dataframe can output 10
dataframe.columns = dataset['feature_names']# show the name of all the columns
dataframe['price'] = dataset['target'] # can show the price of these states
# and the name "price" is rename from "target"
dataframe
# What's the most significant(salient) feature of the house price?
%matplotlib inline
dataframe.corr()# caculate the relation of these data
# use print(dataset['DESCR']) can show the descrblie of these tags
import seaborn as sns # the tool about Data visualization
sns.heatmap(dataframe.corr(),annot = True, fmt = '.1f') # 颜色越深越不相关
# 基于以上分析,发现房屋卧室个数和房价酒最呈正相关
# 简单化:如何根据房屋卧室数量来估计房子的面积?
# 1970S的一个想法:save the data
X_rm = dataframe['RM'].values
Y = dataframe['price'].values
#做字典映射
rm_to_price = {r:y for r, y in zip(X_rm,Y)}
rm_to_price
rm_to_price[5.727]# 当输入的数据在字典里查不到的时候,就会报错
import numpy as np
# 所以,在输入数据在字典里查不到的时候,可以在字典中查找最接近的数据输出他的值
def find_price_by_similar(history_price,query_x, topn=3):
# 给房屋排序,按照x和sorted的距离来排序,输出时取最接近的值
# return np.mean([p for x, p in sorted(history_price.items(),key = lambda x_y:(x_y[0] - query_x)**2)[:topn]])
most_similar_items = sorted(history_price.items(),key=lambda e:(e[0] - query_x)**2)[:topn]
most_similar_prices = [price for rm, price in most_similar_items]
average_prices = np.mean(most_similar_prices)
return average_prices
find_price_by_similar(rm_to_price,7)
这样,当输入值不在数据集的tag中,就会取和其值相近的tag的数据作为输出。
K-Neighbor-Nearest =>KNN
非常经典的机器学习算法。 KNN方法比较低效,在处理数据量比较大时(还有其他的问题)
# A More Efficient Learning Method
# if we can find the relationship between X_rm and y
# every time when we want to caculate ,input the function ,and we get the predicted value
import matplotlib.pyplot as plt
plt.scatter(X_rm,Y)# 画出散点图,直观展示x,y的关系
x与y的关系就变成了y=kx+b,其实就是求最优的k和b,找到拟合效果最好
什么叫做拟合效果好?
怎么评估预测值和实际值之间的关系,哪个预测值更好?
需要定义一个函数:Loss函数(均方误差:MSE)
L
o
s
s
(
y
,
y
^
)
=
1
n
∑
i
∈
N
(
y
i
^
−
y
i
)
2
Loss(y, \hat{y}) = \frac{1}{n} \sum_{i \in N} (\hat{y_i} - y_i) ^ 2
Loss(y,y^)=n1i∈N∑(yi^−yi)2
举个例子:调用loss函数,值越接近0,说明其效果更好
real_y = [3,6,7]
y_hats = [3,4,7]
y_hats_2 = [3,6,6]
def loss(y,y_hat):
return np.mean((np.array(y) - np.array(y_hat))**2)
loss(real_y,y_hats)
loss(real_y,y_hats_2)# 比较发现yhats_2效果更好
求的最优k和b
方法1,直接用微积分的方法做计算。(最小二乘法)
方法2,用随机模拟的方法来做计算
import random
VAR_MAX,VAR_MIN = 100,-100
min_loss = float('inf')
best_k,best_b = None,None
def model(x,k,b):
return x * k + b
total_times = 100 # 迭代次数100
for t in range(total_times):
k,b = random.randint(VAR_MIN,VAR_MAX),random.randint(VAR_MIN,VAR_MAX)
loss_ = loss(Y,model(X_rm,k,b))
print("i'm looking for~")# 可以看到,在不停的寻找好的k/b值
# 刚开始,更新会更加发、频繁;随着迭代次数的增加,更新的越来越慢
if loss_ < min_loss:
min_loss = loss_
best_k,best_b = k,b
print('在{}时刻我找到了更好的k:{}和b:{},这时候loss是:{}'.format(t,k,b,loss_))
这样我们可以观察到每次迭代找到的k和b值。
通过图像表示,就可以观察到拟合得到的线性模型
plt.scatter(x, y)
plt.scatter(x, [best_k * rm + best_b for rm in x])
如何使更新更快?
蒙特卡洛模拟
通常蒙特卡洛模拟通过构造符合一定规则的随机数来解决数学上的各种问题。对于那些由于计算过于复杂而难以得到解析解或者根本没有解析解的问题,蒙特卡洛模拟是一种有效的求出数值解的方法。一般蒙特卡洛模拟在数学中最常见的应用就是蒙特卡洛积分。
Supervisor
L
o
s
s
(
k
,
b
)
=
1
n
∑
i
∈
N
(
(
k
∗
r
m
i
+
b
)
−
y
i
)
2
Loss(k, b) = \frac{1}{n} \sum_{i \in N} ((k * rm_i + b) - y_i) ^ 2
Loss(k,b)=n1i∈N∑((k∗rmi+b)−yi)2
∂
l
o
s
s
(
k
,
b
)
∂
k
=
2
n
∑
i
∈
N
(
k
∗
r
m
i
+
b
−
y
i
)
∗
r
m
i
\frac{\partial{loss(k, b)}}{\partial{k}} = \frac{2}{n}\sum_{i \in N}(k * rm_i + b - y_i) * rm_i
∂k∂loss(k,b)=n2i∈N∑(k∗rmi+b−yi)∗rmi
∂
l
o
s
s
(
k
,
b
)
∂
b
=
2
n
∑
i
∈
N
(
k
∗
r
m
i
+
b
−
y
i
)
\frac{\partial{loss(k, b)}}{\partial{b}} = \frac{2}{n}\sum_{i \in N}(k * rm_i + b - y_i)
∂b∂loss(k,b)=n2i∈N∑(k∗rmi+b−yi)
代码实现:
def partial_k(k, b, x, y):
return 2 * np.mean((k * x + b - y) * x)
def partial_b(k, b, x, y):
return 2 * np.mean(k * x + b - y)
k, b = random.random(), random.random()
min_loss = float('inf')
best_k, bes_b = None, None
learning_rate = 1e-2
for step in range(2000):
k, b = k + (-1 * partial_k(k, b, x, y) * learning_rate), b + (-1 * partial_b(k, b, x, y) * learning_rate)
y_hats = k * x + b
current_loss = loss(y_hats, y)
if current_loss < min_loss:
min_loss = current_loss
best_k, best_b = k, b
print('在第{}步,我们获得了函数 f(rm) = {} * rm + {}, 此时loss是: {}'.format(step, k, b, current_loss))
# 这样可以得到最优的k和b
best_k, best_b
#图像表示
plt.scatter(x, y)
plt.scatter(x, [best_k * rm + best_b for rm in x])
Supervised Learning
如果我们要做更加精细的模型,于是加入学习算法。
f
(
x
)
=
k
∗
x
+
b
f(x) = k * x + b
f(x)=k∗x+b
f
(
x
)
=
k
2
∗
σ
(
k
1
∗
x
+
b
1
)
+
b
2
f(x) = k2 * \sigma(k_1 * x + b_1) + b2
f(x)=k2∗σ(k1∗x+b1)+b2
σ
(
x
)
=
1
1
+
e
(
−
x
)
\sigma(x) = \frac{1}{1 + e^(-x)}
σ(x)=1+e(−x)1
引入激活函数的概念
def sigmoid(x):
return 1 / (1 + np.exp(-x))
sub_x = np.linspace(-10, 10)
plt.plot(sub_x, sigmoid(sub_x))
激活函数图像如图所示:sigmoid函数
def random_linear(x):
k, b = random.random(), random.random()
return k * x + b
def complex_function(x):
return (random_linear(x))
for _ in range(10):
index = random.randrange(0, len(sub_x))
sub_x_1, sub_x_2 = sub_x[:index], sub_x[index:]
new_y = np.concatenate((complex_function(sub_x_1), complex_function(sub_x_2)))
plt.plot(sub_x, new_y)
我们可以通过简单的、基本的模块,经过反复的叠加,来实现更加复杂的函数。
面向越来越越复杂的函数?计算机如何求导?
- 什么是机器学习?
- KNN这种方法的缺陷,提出线性拟合的背景是什么
- 怎么样通过监督的方法,来获得更快的函数权值更新
- 非线性函数和线性函数的结合,可以拟合出非常复杂的函数
- 深度学习我们可以通过基本的函数模块,来拟合更加复杂的函数