人工智能

機器學習
a^2+b^2 = c^2
c= np.sqrt(a**2+b**2)
理性主義
經驗主義
    經過大量的數據,讓計算機系統掌握數據之間的內在聯繫,進而對未知的結果作出預測,這樣的系統謂之機器學習過程。
    機器學習的過程就是發現數據之間內在聯繫的過程
    第一步:數據採集、挖掘和清洗 --買菜
    第二步:數據預處理(讓算法簡單一點)--洗菜和切菜
    第三步:模型選擇 -- 制定菜譜
    第四步:模型訓練 -- 烹飪
    第五步:模型測試 -- 試吃
    第六步:使用模型 -- 上桌
1、數據預處理
    一、均值移除(標準化)
                    *2
                  +----+        
        輸入數據->|模型|<-輸出數據
                  +----+
            1                2
            2                4
            3                6
            ...
            100      *2     200     ==200 OK  
                    測試
            1000     *2     2000    ->信任,業務
                    使用
        樣本矩陣  特徵1  特徵2  特徵3  ...  特徵n -->標籤向量
        樣本1       x      x      x    ...    x          y
        樣本2        x      x      x    ...    x          y
        樣本3        x      x      x    ...    x          y
        ...                                             ...
        樣本n        x      x      x    ...    x          y
        一行同樣本,一列一特徵
        年齡    學歷    學校    工做經歷    -->        薪資
         25     專科    普通     沒有                3000
         28     本科    985         2                    6000
         35     博士    211         5                    10000
         ...
         27        碩士    普通     3                    ?
         使樣本矩陣中的各列的平均值爲0,標準差爲1,即將每一個特徵的基準位置和分散度加以統一,在數量級上儘量接近,對模型的預測結果作出均等的貢獻
         體徵i
          a
          b
          c
         m = (a+b+c)/3
         a' = a-m
         b' = b-m
         c' = c-m
         m' = (a'+b'+c')/3
             = (a-m + b-m + c-m)/3
             = (a+b+c)/3 - m
             = 0
         s' = sqrt((a'^2+b'^2+c'^2)/3)
         a''= a'/s'
         b''= b/s'
         c''= c'/s'
         s''=sqrt((a''^2+b''^2+c''^2)/3)
             =sqrt((a'^2/s'^ + b'^2/s'^ + c'^2/s'^)/3)
             =sqrt((a'^2 + b'^2 + c'^2)+/(3s'^2))
             =sqrt(3s'^2/3s'^2)
             =1
        總結:讓每列的值減去這一列的平均值而後在除以這一列數據的標準差,獲取新的列
        安裝:pip instanll scikit-learn
        import sklearn.preprocessing as sp
        sp.scale(原始樣本矩陣)->均值移除樣本矩陣算法

import numpy as np
import sklearn.preprocessing as sp

raw_samples = np.array([
    [3, -1.5, 2, -5.4],
    [0, 4, -0.3, 2.1],
    [1, 3.3, -1.9, -4.3]
])
print(raw_samples)
# axis=0表明垂直方向
# 平均值
mean = raw_samples.mean(axis=0)
print(mean)  # [ 1.33333333  1.93333333 -0.06666667 -2.53333333]
# 標準差
std = raw_samples.std(axis=0)
print(std)  # [ 1.24721913  2.44449495  1.60069429  3.30689515]
# 將每列的元素都減去每列的平均值
std_samples = raw_samples.copy()
std_samples = (std_samples - mean)/std
print(std_samples)
# 平均值變爲0
mean = std_samples.mean(axis=0)
print(mean)  # [  5.55111512e-17  -1.11022302e-16  -7.40148683e-17  -7.40148683e-17]
# 標準差變爲1
std = std_samples.std(axis=0)
print(std)  # [ 1.  1.  1.  1.]
#  使用sklearn
std_samples = sp.scale(raw_samples)
print(std_samples.mean(axis=0))  # [  5.55111512e-17  -1.11022302e-16  -7.40148683e-17  -7.40148683e-17]
print(std_samples.std(axis=0))  # [ 1.  1.  1.  1.]

    二、範圍縮放
                語文    數學    英語(每課的總分不同)
        張三    90        10(100)5(100)
        李四    80        8(80)    2(40)
        王五    100        5(5)    1(20)
        將樣本矩陣中的每一列經過線性變換,使各列的最大值和最小值爲某個給定的值,即分佈在相同的範圍中
        線性變換:kx + b = y
        每列的最小值:k*col_min + 1b = min
        每列的最大值:K*col_max + 1b = max
                    /col_min 1\ * /k\ = /min\
                    \col_max 1/   \b/   \max/
                    ----------    ----   -----
                        a           x      b
                                    =  numpy.linalg.solve(a,b)
        mms = sp.MinMaxScaler(feature_range=(min,max))
        mms.fit_transform(原始樣本矩陣)->範圍縮放樣本矩陣app

import numpy as np
import sklearn.preprocessing as sp


raw_samples = np.array([
    [3, -1.5, 2, -5.4],
    [0, 4, -0.3, 2.1],
    [1, 3.3, -1.9, -4.3]
])
print(raw_samples)
mms_samples = raw_samples.copy()
for col in mms_samples.T:
    col_min = col.min()
    col_max = col.max()
    a = np.array([[col_min, 1],[col_max,1]])
    # 讓每列的數據都砸0和1之間
    b = np.array([0,1])
    x = np.linalg.solve(a, b)
    col *= x[0]
    col += x[1]
print(mms_samples)
mms = sp.MinMaxScaler(feature_range=(0,1))
mms_samples = mms.fit_transform(raw_samples)
print(mms_samples)

    三、歸一化
             C/C++    Java    Python    PHP
        2016    30    40        10        5        /85
        2017    30    35        40        1        /106
        2018    20    30        50        0        /100
        將樣本矩陣中的每一列的特徵值除以一行中總的樣本數,使得每行樣本的總數爲1
        sp.normalize(原始樣本矩陣,norm=‘l1’)-->通過歸一化樣本矩陣
        L1範數: 向量中各元素絕對值之和
        L2範數:向量中各元素的平方之和dom

import numpy as np
import sklearn.preprocessing as sp
raw_samples = np.array([
    [3, -1.5, 2, -5.4],
    [0, 4, -0.3, 2.1],
    [1, 3.3, -1.9, -4.3]
])
print(raw_samples)
nor_samples = raw_samples.copy()
for row in nor_samples:
    # 求每行樣本的總數
    row_absum = abs(row).sum()
    row /= row_absum
print(nor_samples)
# 按行取值
print(abs(nor_samples).sum(axis=1))  # [ 1.  1.  1.]
nor_samples = sp.normalize(raw_samples,norm='l1')
print(nor_samples)
print(abs(nor_samples).sum(axis=1))
nor_samples = sp.normalize(raw_samples,norm='l2')
print(nor_samples)
print(abs(nor_samples).sum(axis=1))

    四、二值化
        根據業務的需求,設定一個閾值,樣本矩陣中大於閾值的元素被置爲1,小於等於閾值的元素被置爲0,整個樣本矩陣被處理爲只有0和1組成樣本空間
        bin = sp.Binarizer(threshold=閾值)
        bin.transform(原始樣本矩陣)-->二值化樣本矩陣機器學習

import numpy as np
import sklearn.preprocessing as sp
raw_samples = np.array([
    [3, -1.5, 2, -5.4],
    [0, 4, -0.3, 2.1],
    [1, 3.3, -1.9, -4.3]
])
print(raw_samples)
bin_samples = raw_samples.copy()
bin_samples[bin_samples <= 1.4] = 0
bin_samples[bin_samples > 1.4] = 1
print(bin_samples)
bin = sp.Binarizer(threshold=1.4)
bin_samples = bin.transform(raw_samples)
print(bin_samples)

    五、獨熱編碼
        1        3        2
        7        5        4
        1        8        6
        7        3        9
        1:10    3:100    2:1000
        7:01    5:010    4:0100
                8:001    6:0010
                        9:0001
        將每一列的特徵值使用1個1和多個0組合表示,0和1的總個數由每列特徵值的數值個數來決定
        ohe = sp.OneHotEncoder(sparse=是否壓縮, dtype=類型)
        ohe.fit_transform(原始樣本矩陣)-->獨熱編碼樣本逆矩陣ide

import numpy as np
import sklearn.preprocessing as sp
raw_samples = np.array([
    [1, 3, 2],
    [7, 5, 4],
    [1, 8, 6],
    [7, 3, 9]
])
# 編碼表
code_tables = []
for col in raw_samples.T:
    code_table = {}
    for val in col:
        code_table[val] = None
    code_tables .append(code_table)
print(code_tables)
for code_table in code_tables:
    # 求出字典鍵的個數
    size = len(code_table)
    for one, key in enumerate(sorted(code_table.keys())):
        code_table[key] = np.zeros(shape=size, dtype=int)
        code_table[key][one] = 1
print(code_tables)
ohe_samples = []
for raw_sample in raw_samples:
    ohe_sample = np.array([], dtype=int)
    for i, key in enumerate(raw_sample):
        # 水平組合
        ohe_sample = np.hstack((ohe_sample, code_tables[i][key]))
    ohe_samples.append(ohe_sample)
ohe_samples = np.array(ohe_samples)
print(ohe_samples)
# 建立獨熱編碼器
ohe = sp.OneHotEncoder(sparse=False, dtype=int)
ohe_samples = ohe.fit_transform(raw_samples)
print(ohe_samples)
'''
sparse=False的結果
[[1 0 1 0 0 1 0 0 0]
 [0 1 0 1 0 0 1 0 0]
 [1 0 0 0 1 0 0 1 0]
 [0 1 1 0 0 0 0 0 1]]
 sparse=True的結果,稀疏矩陣0多1少
  (0, 5)    1 # 表示第0行第5列爲1
  (0, 2)    1
  (0, 0)    1
  (1, 6)    1
  (1, 3)    1
  (1, 1)    1
  (2, 7)    1
  (2, 4)    1
  (2, 0)    1
  (3, 8)    1
  (3, 2)    1
  (3, 1)    1
'''
new_sample = np.array([[1, 5, 6]])
# 此時編碼字典已經存在ohe中,無需調用fit_transform,增長的新樣本能出現行的特徵值
ohe_sample = ohe.transform(new_sample)
print(ohe_sample)

    六、標籤編碼
        年齡    學歷    學校    工做經歷    -->        薪資
         25     專科    普通     沒有                low
         28     本科    985         2                    med
         35     博士    211         5                    high
         ...
         27        碩士    普通     3                    ?
         將字符串形式的特徵值編碼成數字,便於數學運算。
         low    med        high
         排序
         high    low        med
         0        1        2
         編碼:1 2 0
         標籤編碼器:lbe = sp.LabelEncoder()
         lbe.fit_transform(原始樣本矩陣列) -->標籤編碼列,構建字典
         lbe.transform(原始樣本矩陣列) --> 標籤編碼列,使用字典
         lbe.inverse_transform(標籤編碼列) --> 原始樣本列, 使用字典函數

import numpy as np
import sklearn.preprocessing as sp
raw_samples = np.array([
    'audi', 'ford', 'audi', 'toyota','ford', 'bmw', 'toyota', 'ford'
])
print(raw_samples)
lbe = sp.LabelEncoder()
lbe_sample = lbe.fit_transform(raw_samples)
print(lbe_sample)
new_sample = np.array(['bmw', 'audi', 'toyota'])
lbe_sample = lbe.transform(new_sample)
print(lbe_sample)
# 求逆
raw_samples = lbe.inverse_transform(lbe_sample)
print(raw_samples)

2、機器學習基本類型
    一、有監督學習:用已知的輸入和輸出訓練學習模型(f(x)),直到模型給出的預測輸出與已知的實際輸出之間的偏差小到能夠接受程度爲止
        x1 -> y1
        x2 -> y2
        x3 -> y3
        ...
        y=f(x)
        x1 -> y1'
        x2 -> y2'
        x3 -> y3'
        一、迴歸問題:輸出數據是無限可能的連續值
        二、分類問題:輸出數據是有限的幾個離散值
    二、無監督學習:在輸出數據未知的前提下,利用模型自己發現輸入數據的內部特徵,將其劃分爲不一樣的族羣
        聚類問題
    三、半監督學習:利用相對較小的已知集訓練模型,使其得到基本的預測能力,當模型遇到未知輸出的新數據時,能夠根據其與已知集的類似性們預測其輸出
3、線性迴歸
     x    -->    y
    0.5            5.0
    0.6            5.5
    0.8            6.0
    1.1            6.8
    1.4            7.0
    預測函數:yi = w0 + w1x
               SUM([y - (w0 + w1x)]^2)
    loss = -----------------------------------
                        2
    目標:尋找最理想的w0和w1,使loss(損失值)儘量的小。學習

                                       dloss
    loss對w0的偏導 :    ----------    = -SUM(y - (w0 + w1x))
                                       dwo
                                  dloss
    loss對w1的偏導:       ----------  = -SUM([y - (w0 + w1x)]x)
                                       dw1
                               dloss
    w0 = w0 - n(學習率) * ----------
                               dw0
                             dloss
    w1 = w1 - n(學習率)* --------
                             dw1測試

# 本身寫一個類實現上面求解斜率和截距的過程
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
class Linera_model(object):
    def __init__(self):
        # 初始化斜率
        self.w = np.random.randn(1)[0]
        # 初始化截距
        self.b = np.random.randn(1)[0]
        print("-----------初始值",self.w, self.b)
    # 建立函數方程y = wx + b
    def model(self, x):
        return self.w * x + self.b
    def loss(self, x, y):
        cost = ((y - self.model(x))**2)/2
        # 對w求偏導(就是把b看作常量的求導)
        g_w = (y - self.model(x)) * (-x)
        # 對b求偏導
        g_b = (y - self.model(x)) * (-1)
        return g_w, g_b
    # 梯度降低
    def gradient_descend(self, g_w, g_b, step=0.01):
        # 更新斜率和截距, step至關於學習率
        self.w = self.w - g_w * step
        self.b = self.b - g_b * step
        print("-----------",self.w, self.b)
    def fit(self, X, y):
        # 初始化上一次的斜率和截距
        last_w = self.w + 1
        last_b = self.b + 1
        # 設置精度和循環最大次數
        precision = 0.00001
        max_count = 3000
        count = 0
        while True:
            if (np.abs(last_w - self.w) < precision) and (np.abs(last_b - self.b) < precision):
                break
            if count > max_count:
                break
            # 更新斜率和截距
            g_w = 0
            g_b = 0
            size = X.shape[0]
            for xi, yi in zip(X, y):
                g_w += self.loss(xi, yi)[0] / size
                g_b += self.loss(xi, yi)[1] / size
            self.gradient_descend(g_w, g_b)
            count += 1
    @property
    def coef_(self):
        return self.w
    @property
    def intercept_(self):
        return self.b
lm = Linera_model()
X = np.linspace(2.5, 12, 25)
w = np.random.randint(2, 10, size=1)[0]
b = np.random.randint(-5, 5, size=1)[0]
y = X * w + b + np.random.randn(25)*2
plt.scatter(X, y)
lm.fit(X, y)
print(lm.coef_, lm.intercept_)
import numpy as np
import matplotlib.pyplot as mp
from mpl_toolkits.mplot3d import axes3d
train_x = np.array([0.5,0.6,0.8,1.1,1.4])
train_y = np.array([5.0,5.5,6.0,6.8,7.0])
# 迭代次數
n_epoches = 1000
# 學習率
lrate = 0.01
epoches, losses = [],[]
w0, w1 = [1],[1]
for epoch in range(1,n_epoches+1):
    epoches.append(epoch)
    losses.append(((train_y - (w0[-1] + w1[-1]*train_x))**2).sum()/2)
    print('{:4} w0={:.8f}, w1={:8}, loss={:.8f}'.format(epoches[-1],w0[-1],w1[-1],losses[-1]))
    d0 = -(train_y - (w0[-1] + w1[-1]*train_x)).sum()
    d1 = -((train_y - (w0[-1] + w1[-1]*train_x))*train_x).sum()
    w0.append(w0[-1] - lrate *d0)
    w1.append(w1[-1] - lrate *d1)
w0 = np.array(w0[:-1])
w1 = np.array(w1[:-1])
# 排序
sorted_indices = train_x.argsort()
test_x = train_x[sorted_indices]
test_y = train_y[sorted_indices]
pred_test_y = w0[-1] + w1[-1] *test_x
# 畫曲面圖
grid_w0, grid_w1 = np.meshgrid(np.linspace(0, 9, 500),np.linspace(0, 3.5, 500))
flat_w0, flat_w1 = grid_w0.ravel(), grid_w1.ravel()
# 損失值
flat_loss = ((flat_w0 + np.outer(train_x, flat_w1) -train_y.reshape(-1,1))**2).sum(axis=0)/2
# 網格化
grid_loss = flat_loss.reshape(grid_w0.shape)
mp.figure('Linear Regression', facecolor='lightgray')
mp.title('Linear Regression', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
# marker='s'表示方點
mp.scatter(train_x, train_y, marker='s',c='dodgerblue',alpha=0.5,s=80,label='Training')
mp.scatter(test_x, test_y, marker='D',c='orangered',alpha=0.5,s=60,label='Testing')
mp.scatter(test_x, pred_test_y,c='orangered',alpha=0.5,s=80,label='Predicted')
# 偏差
for x, y, pred_y in zip(test_x, test_y, pred_test_y):
    mp.plot([x, x], [y, pred_y], c='orangered', alpha=0.5,linewidth=1)
mp.plot(test_x,pred_test_y,'--', c='limegreen', label='Regression', linewidth=1)
mp.legend()
mp.figure('Training Progress', facecolor='lightgray')
mp.subplot(311)
mp.title("Training Progress", fontsize=20)
mp.ylabel('w0', fontsize=14)
mp.gca().xaxis.set_minor_locator(mp.MultipleLocator(100))
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.plot(epoches, w0, c='dodgerblue', label='w0')
mp.legend()
mp.subplot(312)
mp.ylabel('w1', fontsize=14)
mp.gca().xaxis.set_minor_locator(mp.MultipleLocator(100))
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.plot(epoches, w1, c='limegreen', label='w1')
mp.legend()
mp.subplot(313)
mp.xlabel('epoch',fontsize=14)
mp.ylabel('loss', fontsize=14)
mp.gca().xaxis.set_minor_locator(mp.MultipleLocator(100))
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.plot(epoches, losses, c='orangered', label='loss')
mp.legend()
mp.tight_layout()
mp.figure('Loss Function')
ax = mp.gca(projection='3d')
mp.title('Loss Function', fontsize=20)
ax.set_xlabel('w0', fontsize=14)
ax.set_ylabel('w1', fontsize=14)
ax.set_zlabel('loss', fontsize=14)
mp.tick_params(labelsize=10)
ax.plot_surface(grid_w0, grid_w1, grid_loss, rstride=10, cstride=10, cmap='jet')
ax.plot(w0, w1, losses, 'o-', c='orangered', label='GBD')
mp.legend(loc='lower left')
mp.figure('Batch Gradient Desent', facecolor='lightgray')
mp.title('Batch Gradient Desent', fontsize=20)
mp.xlabel('w0', fontsize=14)
mp.ylabel('w1', fontsize=14)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.contourf(grid_w0, grid_w1, grid_loss, 1000, cmap='jet')
cntr = mp.contour(grid_w0, grid_w1, grid_loss, 10, colors='black', linewidths=0.5)
mp.clabel(cntr, inline_space=0.1, fmt='%.2f', fontsize=8)
mp.plot(w0, w1, 'o-', c='orangered', label='BGD')
mp.legend()
mp.show()


    import sklearn.linear_model as lm
    model = lm.LinearRegression()      # 建立模型
    model.fit(訓練輸入,訓練輸出)      # 訓練模型
    預測輸出 = model.predict(預測輸入) # 預測輸出編碼

import numpy as np
import sklearn.linear_model as lm
import sklearn.metrics as sm
import matplotlib.pyplot as mp
import pickle


x , y = [], []
with open('../data/single.txt', 'r') as f:
    for line in f.readlines():
        data = [float(substr) for substr in line.split(',')]
        x.append(data[:-1])
        y.append(data[-1])
x = np.array(x)
y = np.array(y)
print(x)
print(y)
# 建立模型
model = lm.LinearRegression()
# 訓練模型
model.fit(x, y)
# 預測模型
pred_y = model.predict(x)
print(sm.mean_absolute_error(y, pred_y))
print(sm.mean_squared_error(y, pred_y))
print(sm.median_absolute_error(y, pred_y))
print(sm.r2_score(y, pred_y))  # 越接近1越好
# 保存模型
with open('../data/linear.pkl','wb') as f:
    pickle.dump(model, f)
# 加載模型
with open('../data/linear.pkl', 'rb') as f:
    model = pickle.load(f)
pred_y = model.predict(x)
print(sm.mean_absolute_error(y, pred_y))
print(sm.mean_squared_error(y, pred_y))
print(sm.median_absolute_error(y, pred_y))
print(sm.r2_score(y, pred_y))  # 越接近1越好
mp.figure('Linear Regression', facecolor='lightgray')
mp.title('Linear Regression', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.scatter(x, y, c='dodgerblue', alpha=0.75, s=60, label='Sample')
sorted_indices = x.T[0].argsort()
mp.plot(x[sorted_indices], pred_y[sorted_indices], c='orangered', label='Regression')
mp.legend()
mp.show()


    模型保存:
        import pickle
        with open(模型文件路徑) as f:
            pickle.dump(model, f) # 將學習模型保存到文件
    加載模型
        with open(模型文件路徑) as f:
            model = pickle.load(f) # 從文件中載入學習模型
4、嶺迴歸
    loss = J(w0, w1) + 正則強度(懲罰力度) * 正則項(x,y,w0,w1)
    領回歸就是在線性迴歸的基礎上增長了正則項,有意破壞模型對訓練數據集的擬合效果,客觀上下降了少數異常樣本對模型的牽制做用,
    使得模型對大多數正常樣本表現出更好的擬合效果
    model = lm.Ridge(正則強度,fit_intercept=True,max_iter=最大迭代次數)
    model.fit(訓練輸入,訓練輸出)
    預測輸入 = model.predict(預測輸入)spa

import numpy as np
import sklearn.linear_model as lm
import sklearn.metrics as sm
import matplotlib.pyplot as mp
x , y = [], []
with open('../data/abnormal.txt', 'r') as f:
    for line in f.readlines():
        data = [float(substr) for substr in line.split(',')]
        x.append(data[:-1])
        y.append(data[-1])
x = np.array(x)
y = np.array(y)
print(x)
print(y)
# 建立模型
model_ln = lm.LinearRegression()
# 訓練模型
model_ln.fit(x, y)
# 預測模型
pred_y_ln = model_ln.predict(x)
print(sm.mean_absolute_error(y, pred_y_ln))
print(sm.mean_squared_error(y, pred_y_ln))
print(sm.median_absolute_error(y, pred_y_ln))
print(sm.r2_score(y, pred_y_ln))  # 越接近1越好
# fit_intercept=True時,截距(w0),斜率(w1)都會受到影響。爲False時,隻影響w1
model_rd = lm.Ridge(150, fit_intercept=True, max_iter=10000)
model_rd.fit(x, y)
pred_y_rd = model_rd.predict(x)
print(sm.mean_absolute_error(y, pred_y_rd))
print(sm.mean_squared_error(y, pred_y_rd))
print(sm.median_absolute_error(y, pred_y_rd))
print(sm.r2_score(y, pred_y_rd))
mp.figure('Linear and Ridge', facecolor='lightgray')
mp.title('Linear and Ridge', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.scatter(x, y, c='dodgerblue', alpha=0.75, s=60, label='Sample')
sorted_indices = x.T[0].argsort()
mp.plot(x[sorted_indices], pred_y_ln[sorted_indices], c='orangered', label='Regression')
mp.plot(x[sorted_indices], pred_y_rd[sorted_indices], c='limegreen', label='Ridge')
mp.legend()
mp.show()


5、多項式迴歸
    y = w0 + w1x + w2x^2 + w3x^3 + ... + wnx^n
    x1 = x
    x2 = x^2
    x3 = x^3
    ....
    xn = x^n
    y = w0 + w1x + w2x2 + w3x3 + ... + wnxn
    多項式特徵擴展:增長高次項做爲擴展特徵值;沿用線性迴歸對增補了擴展值後的樣本矩陣進行迴歸
    import sklearn.pipline as pl
    import sklearn.preprocessing as sp
    ....
    sp.PolynomialFeatures(n)->多項式特徵擴展器
    lm.LinearRegression()->線性迴歸
    pl.make_pipline(多項式特徵擴展器,線性迴歸器)->管線
    管線.fit()
    管線.predict()->預測輸出
    x -> 多項式特徵擴展器 ->x1,x2,x3,...,xn ->線性迴歸器 ->w0 w1 ...wn
        \______________________________________________/
                            |
                        管線(流水線)
    欠擬合:模型中的參數並不能以最佳損失值的形式來反映輸入和輸出之間的關係。所以,不管是用訓練集輸入仍是測試集輸入,
            由模型給出的預測輸出都不能以較小的偏差接近實際的輸出
    過擬合:模型中的參數過度依賴或者傾向於訓練數據,反而缺少通常性,即致使泛化程度的缺失。所以當使用訓練集輸入時,模型一般能夠給出
            較高精度的預測輸出,而使用測試集輸入,模型的表現卻很是差

import numpy as np
import sklearn.linear_model as lm
import sklearn.pipeline as pl
import sklearn.preprocessing as sp
import sklearn.metrics as sm
import matplotlib.pyplot as mp
train_x , train_y = [], []
with open('../data/single.txt', 'r') as f:
    for line in f.readlines():
        data = [float(substr) for substr in line.split(',')]
        train_x.append(data[:-1])
        train_y.append(data[-1])
train_x = np.array(train_x)
train_y = np.array(train_y)
print(train_x)
print(train_y)
# 多項式擴展器, 線性迴歸
model =pl.make_pipeline(sp.PolynomialFeatures(10), lm.LinearRegression())
model.fit(train_x, train_y)
pred_train_y = model.predict(train_x)
# 列向量
test_x = np.linspace(train_x.min(), train_x.max(),50)[:,np.newaxis]
pred_test_y = model.predict(test_x)
print(sm.r2_score(train_y, pred_test_y))
mp.figure('Polynomial Regression', facecolor='lightgray')
mp.title('Polynomial Regression', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.scatter(train_x, train_y, c='dodgerblue', alpha=0.75, s=60, label='Sample')
mp.plot(test_x, pred_test_y, c='orangered', label='Regression')
mp.legend()
mp.show()


6、決策樹迴歸和分類
    迴歸問題:輸出標籤分佈於無限連續域
    分類問題:輸出標籤分佈於有限離散域
    核心思想:類似的因致使類似的果
    類似的輸入必會產生類似的輸出。
    年齡:0-青年(20-40),1-中年(40-60),2-老年(60-80)
    性別:0-女性,1-男性
    學歷:0-大專,1-本科,2-碩士,3-博士
    工齡:0-(<3),1-(3-5),2(>5)
    月薪:0-低,1-中 ,2-高
    年齡     性別     學歷     工齡   ->月薪
     0         1          1          0         5000  0
     0         1        0       1      6000  1
     1       0        2       2      8000  1
     2         1        3       2      50000 2
     ...
     1       1        2       1       ?
     迴歸:找出全部樣本爲1121的月薪,而後求平均值          
     分類:找出全部樣本爲1121的月薪,投票選擇
                                     根表
             年齡表0                年齡表1                年齡表2
         性別表0  性別表1   性別表0  性別表1         性別表0  性別表1
         ....
     信息熵:信息熵越大,信息量越大
     徹底決策樹:使用全部的特徵做爲子表劃分的依據,樹狀結構複雜,構建和預測速度慢
     非徹底決策樹:根據信息熵減小量最大的原則(特徵值多的優先),優先選擇部分特徵劃分子表,在輸入類似的條件下,預測類似的輸出
     集合算法:經過不一樣的方式構建出多棵決策樹模型,分別做出預測,將他們給出的預測結果經過平均或投票的方式綜合考慮,得出最終預測結果
     A、自助聚合:從總樣本空間中,以有放回抽樣的方式隨機挑選部分構建決策樹,共構造B棵樹,由這B棵樹分別對未知樣本進行預測,給出B個預測結果
         經由平均或投票產生最後的輸出
     B、隨機森林:在自助聚合算法的基礎上,每次抽樣不但隨機選擇樣本,並且也隨機選擇特徵,來構造B棵決策樹,以此泛化不一樣特徵對預測結果的影響
     C、正向激勵:開始爲每一個樣本去分配初始權重,構建決策樹,對訓練集中的樣本進行預測,針對預測錯誤的樣本,增長其權重,再構造決策樹,重複以上
         過程,共獲得B棵決策樹,由這B棵樹分別對未知樣本進行預測,給出B個預測結果經由平均或投票產生最後的輸出

import sklearn.datasets as sd
import sklearn.utils as su
import sklearn.tree as st
import sklearn.ensemble as se
import sklearn.metrics as sm
boston = sd.load_boston()
print(boston.data.shape)  # (506, 13),506個樣本,13個特徵
print(boston.feature_names)  #['CRIM' 'ZN' 'INDUS' 'CHAS' 'NOX' 'RM' 'AGE' 'DIS' 'RAD' 'TAX' 'PTRATIO' 'B' 'LSTAT']
print(boston.target.shape) # (506,)
x, y = su.shuffle(boston.data, boston.target, random_state=7)  # 打亂順序
train_size = int(len(x)*0.8)  # 用80%的數據做爲訓練,20%的數據做爲測試
train_x, test_x, train_y, test_y = x[:train_size], x[train_size:], y[:train_size], y[train_size:]
# 決策樹對象
model = st.DecisionTreeRegressor(max_depth=4)
model.fit(train_x, train_y)
pred_test_y = model.predict(test_x)
print(sm.r2_score(test_y, pred_test_y))  # 0.820256088941
# n_estimators=決策樹的個數
model = se.AdaBoostRegressor(st.DecisionTreeRegressor(max_depth=4),n_estimators=400,random_state=7)
model.fit(train_x, train_y)
pred_test_y = model.predict(test_x)
print(sm.r2_score(test_y, pred_test_y))  # 0.907096311719

     特徵重要性:決策樹模型在構建樹狀結構時,優先選擇對輸出結果影響最大,便可產生最大信息熵減小量的特徵進行子表劃分,所以該模型能夠按照
         特徵的重要程度進行排序,即特徵重要性序列。不一樣的模型因算法不一樣,所獲得的特徵重要性序列也會有所不一樣。另外,訓練數據的細化程度也會影
         響模型對特徵重要性的判斷

import matplotlib.pyplot as mp
import sklearn.datasets as sd
import sklearn.utils as su
import sklearn.tree as st
import sklearn.ensemble as se
import sklearn.metrics as sm
import numpy as np
boston = sd.load_boston()
x, y = su.shuffle(boston.data, boston.target, random_state=7)  # 打亂順序
feature_names = boston.feature_names
train_size = int(len(x)*0.8)  # 用80%的數據做爲訓練,20%的數據做爲測試
train_x, test_x, train_y, test_y = x[:train_size], x[train_size:], y[:train_size], y[train_size:]
# 決策樹對象
model = st.DecisionTreeRegressor(max_depth=4)
model.fit(train_x, train_y)
fi_dt = model.feature_importances_
print(fi_dt)
pred_test_y = model.predict(test_x)
# n_estimators=決策樹的個數
model = se.AdaBoostRegressor(st.DecisionTreeRegressor(max_depth=4),n_estimators=400,random_state=7)
model.fit(train_x, train_y)
pred_test_y = model.predict(test_x)
fi_ab = model.feature_importances_
print(fi_ab)
mp.figure('Feature Importance', facecolor='lightgray')
mp.subplot(211)
mp.title('Decisopn Tree', fontsize=16)
mp.ylabel('Importance', fontsize=12)
mp.tick_params(labelsize=10)
mp.grid(axis='y', linestyle=':')
sorted_indices = fi_dt.argsort()[::-1]
pos = np.arange(len(sorted_indices))
mp.bar(pos, fi_dt[sorted_indices], facecolor='deepskyblue', edgecolor='steelblue')
mp.xticks(pos, feature_names[sorted_indices], rotation=30)
mp.subplot(212)
mp.title('AdaBoost Decisopn Tree', fontsize=16)
mp.ylabel('Importance', fontsize=12)
mp.tick_params(labelsize=10)
mp.grid(axis='y', linestyle=':')
sorted_indices = fi_ab.argsort()[::-1]
pos = np.arange(len(sorted_indices))
mp.bar(pos, fi_ab[sorted_indices], facecolor='deepskyblue', edgecolor='steelblue')
mp.xticks(pos, feature_names[sorted_indices], rotation=30)
mp.tight_layout()
mp.show()

import csv
import numpy as np
import matplotlib.pyplot as mp
import sklearn.utils as su
import sklearn.ensemble as se
import sklearn.metrics as sm
with open('../data/bike_day.csv', 'r') as f:
    reader = csv.reader(f)
    x, y = [], []
    for row in reader:
        x.append(row[2:13])
        y.append(row[-1])
fn_dy = np.array(x[0])
x = np.array(x[1:], dtype=float)
y = np.array(y[1:], dtype=float)
x, y = su.shuffle(x, y, random_state=7)
train_size = int(len(x)*0.9)
train_x, test_x, train_y, test_y = x[:train_size], x[train_size:], y[:train_size], y[train_size:]
model = se.RandomForestRegressor(max_depth=10, n_estimators=1000, random_state=7, min_samples_split=2)
model.fit(train_x, train_y)
fi_dy = model.feature_importances_
print(fi_dy)
pred_test_y = model.predict(test_x)
print(sm.r2_score(test_y, pred_test_y))
with open('../data/bike_hour.csv', 'r') as f:
    reader = csv.reader(f)
    x, y = [], []
    for row in reader:
        x.append(row[2:13])
        y.append(row[-1])
fn_hr = np.array(x[0])
x = np.array(x[1:], dtype=float)
y = np.array(y[1:], dtype=float)
x, y = su.shuffle(x, y, random_state=7)
train_size = int(len(x)*0.9)
train_x, test_x, train_y, test_y = x[:train_size], x[train_size:], y[:train_size], y[train_size:]
model = se.RandomForestRegressor(max_depth=10, n_estimators=1000, random_state=7, min_samples_split=2)
model.fit(train_x, train_y)
fi_hr = model.feature_importances_
print(fi_hr)
pred_test_y = model.predict(test_x)
print(sm.r2_score(test_y, pred_test_y))
mp.figure('Feature Importance', facecolor='lightgray')
mp.subplot(211)
mp.title('Day', fontsize=16)
mp.ylabel('Importance', fontsize=12)
mp.tick_params(labelsize=10)
mp.grid(axis='y', linestyle=':')
sorted_indices = fi_dy.argsort()[::-1]
pos = np.arange(len(sorted_indices))
mp.bar(pos, fi_dy[sorted_indices], facecolor='deepskyblue', edgecolor='steelblue')
mp.xticks(pos, fn_dy[sorted_indices], rotation=30)
mp.subplot(212)
mp.title('Hour', fontsize=16)
mp.xlabel('Faeture', fontsize=12)
mp.ylabel('Importance', fontsize=12)
mp.tick_params(labelsize=10)
mp.grid(axis='y', linestyle=':')
sorted_indices = fi_hr.argsort()[::-1]
pos = np.arange(len(sorted_indices))
mp.bar(pos, fi_hr[sorted_indices], facecolor='lightcoral', edgecolor='indianred')
mp.xticks(pos, fn_hr[sorted_indices], rotation=30)
mp.tight_layout()
mp.show()


7、簡單分類
    x1 x2 -> y
    3  1     0
    2  5     1
    1  8     1
    6  4     0
    5  2     0
    3  5     1
    4  7     1
    4 -1     0
    模型:if x1 < x2 then y = 1
          if x1 > x2 then y = 0
    2  9     ? ->1
    7  3     ? ->0

import numpy as np
import matplotlib.pyplot as mp
x = np.array([
    [3, 1],
    [2, 5],
    [1, 8],
    [6, 4],
    [5, 2],
    [3, 5],
    [4, 7],
    [4, -1]])
y = np.array([0, 1, 1, 0, 0, 1, 1, 0])
# 畫分界線,左右邊界和步長,上下邊界和步長
l, r, h = x[:, 0].min()-1, x[:, 0].max()+1, 0.005
b, t, v = x[:, 1].min()-1, x[:, 1].max()+1, 0.005
# 網格化
grid_x = np.meshgrid(np.arange(l, r, h), np.arange(b, t, v))
# 扁平化
flat_x = np.c_[grid_x[0].ravel(), grid_x[1].ravel()]
flat_y = np.zeros(len(flat_x), dtype=int)
flat_y[flat_x[:, 0] < flat_x[:, 1]] = 1
grid_y = flat_y.reshape(grid_x[0].shape)
mp.figure('Simple Classification', facecolor='lightgray')
mp.title('Simple Classification', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.pcolormesh(grid_x[0], grid_x[1], grid_y, cmap='gray')
mp.scatter(x[:, 0], x[:, 1], c=y, cmap='brg', s=60)
mp.show()

 8、邏輯迴歸
    x1 x2 -> y
    y = w0 + w1x1 +w2x2
              1
    y = ---------------
           1 + e^-(w0 + w1x1 +w2x2)
    在[0.1-0.5]之間視爲0,(0.5-0.9]視爲1
    model = lm.LogisticRegression(solver='liblinear',C=正則強度)  # liblinear表示w0 + w1x1 +w2x2
    fit訓練/predict預測

import numpy as np
import matplotlib.pyplot as mp
import sklearn.linear_model as lm
x = np.array([
    [3, 1],
    [2, 5],
    [1, 8],
    [6, 4],
    [5, 2],
    [3, 5],
    [4, 7],
    [4, -1]])
y = np.array([0, 1, 1, 0, 0, 1, 1, 0])
model = lm.LogisticRegression(solver='liblinear', C=1)
model.fit(x, y)
# 畫分界線,左右邊界和步長,上下邊界和步長
l, r, h = x[:, 0].min()-1, x[:, 0].max()+1, 0.005
b, t, v = x[:, 1].min()-1, x[:, 1].max()+1, 0.005
# 網格化
grid_x = np.meshgrid(np.arange(l, r, h), np.arange(b, t, v))
# 扁平化
flat_x = np.c_[grid_x[0].ravel(), grid_x[1].ravel()]
flat_y = model.predict(flat_x)
grid_y = flat_y.reshape(grid_x[0].shape)
mp.figure('Logistic Classification', facecolor='lightgray')
mp.title('Logistic Classification', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.pcolormesh(grid_x[0], grid_x[1], grid_y, cmap='gray')
mp.scatter(x[:, 0], x[:, 1], c=y, cmap='brg', s=60)
mp.show()
import numpy as np
import matplotlib.pyplot as mp
import sklearn.linear_model as lm
# 多元分類
x = np.array([
    [4, 7],
    [3.5, 8],
    [3.1, 6.2],
    [0.5, 1],
    [1, 2],
    [1.2, 1.9],
    [6, 2],
    [5.7, 1.5],
    [5.4, 2.2]])
y = np.array([0, 0, 0, 1, 1, 1, 2, 2, 2])
model = lm.LogisticRegression(solver='liblinear', C=100)
model.fit(x, y)
# 畫分界線,左右邊界和步長,上下邊界和步長
l, r, h = x[:, 0].min()-1, x[:, 0].max()+1, 0.005
b, t, v = x[:, 1].min()-1, x[:, 1].max()+1, 0.005
# 網格化
grid_x = np.meshgrid(np.arange(l, r, h), np.arange(b, t, v))
# 扁平化
flat_x = np.c_[grid_x[0].ravel(), grid_x[1].ravel()]
flat_y = model.predict(flat_x)
grid_y = flat_y.reshape(grid_x[0].shape)
mp.figure('Logistic Classification', facecolor='lightgray')
mp.title('Logistic Classification', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.pcolormesh(grid_x[0], grid_x[1], grid_y, cmap='gray')
mp.scatter(x[:, 0], x[:, 1], c=y, cmap='brg', s=60)
mp.show()

9、樸素貝葉斯分類    P(A):A事件發生的機率    P(A,B):A和B兩個事件同時發生的機率,聯合機率    P(A|B):在B事件發生的條件下A事件發生的機率,條件機率    貝葉斯定理:P(A,B) = P(B)*P(A|B)                P(B,A) = P(A)*P(B|A)    P(B)*P(A|B) = P(A)*P(B|A)                P(A)P(B|A)    P(A|B) =  -------------                   P(B)    樸素:條件獨立,全部的特徵值彼此沒有任何依賴性。

相關文章
相關標籤/搜索