梯度降低訓練迴歸模型

# coding:UTF-8
'''
Date:20160901
@author: zhaozhiyong
'''
import numpy as np

def load_data(file_name):
    '''導入訓練數據
    input:  file_name(string)訓練數據的位置
    output: feature_data(mat)特徵
            label_data(mat)標籤
    '''
    f = open(file_name)  # 打開文件
    feature_data = []   # 存放測試值
    label_data = []     # 存放標籤值

    for line in f.readlines():
        # print(line)
        # exit()
        feature_tmp = []
        lable_tmp = []

        lines = line.strip().split("\t")  # 讀取的第一行文本字符串,按空格分割爲數組
        feature_tmp.append(1)  # 偏置項

        for i in range(len(lines) - 1):
            feature_tmp.append(float(lines[i]))
        lable_tmp.append(float(lines[-1]))  # 將標籤值單獨存放

        feature_data.append(feature_tmp)
        label_data.append(lable_tmp)
    f.close()  # 關閉文件
    return np.mat(feature_data), np.mat(label_data)

def sig(x):
    '''Sigmoid函數
    input:  x(mat):feature * w
    output: sigmoid(x)(mat):Sigmoid值
    '''
    return 1.0 / (1 + np.exp(-x))

def lr_train_bgd(feature, label, maxCycle, alpha):
    '''利用梯度降低法訓練LR模型
    input:  feature(mat)特徵
            label(mat)標籤
            maxCycle(int)最大迭代次數
            alpha(float)學習率
    output: w(mat):權重
    '''
    n = np.shape(feature)[1]  # 特徵個數
    w = np.mat(np.ones((n, 1)))  # 初始化權重
    i = 0
    while i <= maxCycle:  # 在最大迭代次數的範圍內
        i += 1  # 當前的迭代次數
        h = sig(feature * w)  # 計算Sigmoid值,sig(特徵值*權重)
        err = label - h     #
        if i % 100 == 0:
            print("\t---------iter=" + str(i) + " , train error rate= " + str(error_rate(h, label)))
        w = w + alpha * feature.T * err  # 權重修正
    return w

def error_rate(h, label):
    '''計算當前的損失函數值
    input:  h(mat):預測值
            label(mat):實際值
    output: err/m(float):錯誤率
    '''
    m = np.shape(h)[0]
    
    sum_err = 0.0
    for i in range(m):
        if h[i, 0] > 0 and (1 - h[i, 0]) > 0:
            sum_err -= (label[i,0] * np.log(h[i,0]) + \
                        (1-label[i,0]) * np.log(1-h[i,0]))
        else:
            sum_err -= 0
    return sum_err / m

def save_model(file_name, w):
    '''保存最終的模型
    input:  file_name(string):模型保存的文件名
            w(mat):LR模型的權重
    '''
    m = np.shape(w)[0]
    f_w = open(file_name, "w")
    w_array = []
    for i in range(m):
        w_array.append(str(w[i, 0]))
    f_w.write("\t".join(w_array))
    f_w.close()           


if __name__ == "__main__":
    # 一、導入訓練數據
    print("---------- 1.load data ------------")
    feature, label = load_data("data.txt")
    # 二、訓練LR模型
    print("---------- 2.training ------------")
    w = lr_train_bgd(feature, label, 5000, 0.01)
    # 三、保存最終的模型
    print("---------- 3.save model ------------")
    save_model("weights", w)

通過5000次的訓練,該模型的錯誤率已經很低了,能夠使用該模型進行分類預測了數組

# coding:UTF-8
'''
Date:20160901
@author: zhaozhiyong
'''
import numpy as np


def load_weight(w):
    '''導入LR模型
    input:  w(string)權重所在的文件位置
    output: np.mat(w)(mat)權重的矩陣
    '''
    f = open(w)
    w = []
    for line in f.readlines():
        lines = line.strip().split("\t")
        w_tmp = []
        for x in lines:
            w_tmp.append(float(x))
        w.append(w_tmp)    
    f.close()
    return np.mat(w)


def load_data(file_name, n):
    '''導入測試數據
    input:  file_name(string)測試集的位置
            n(int)特徵的個數
    output: np.mat(feature_data)(mat)測試集的特徵
    '''
    f = open(file_name)
    feature_data = []
    for line in f.readlines():
        feature_tmp = []
        lines = line.strip().split("\t")

        if len(lines) != n - 1:
            continue
        feature_tmp.append(1)
        for x in lines:
            # print x
            feature_tmp.append(float(x))
        feature_data.append(feature_tmp)
    f.close()
    return np.mat(feature_data)


def sig(x):
    '''Sigmoid函數
    input:  x(mat):feature * w
    output: sigmoid(x)(mat):Sigmoid值
    '''
    return 1.0 / (1 + np.exp(-x))


def predict(data, w):
    '''對測試數據進行預測
    input:  data(mat)測試數據的特徵
            w(mat)模型的參數
    output: h(mat)最終的預測結果
    '''
    h = sig(data * w.T)     # sig
    m = np.shape(h)[0]
    for i in range(m):
        if h[i, 0] < 0.5:  # sigmoid函數值{0,1},這裏取0.5做爲邊界
            h[i, 0] = 0.0
        else:
            h[i, 0] = 1.0
    return h


def save_result(file_name, result):
    '''保存最終的預測結果
    input:  file_name(string):預測結果保存的文件名
            result(mat):預測的結果
    '''
    m = np.shape(result)[0]
    # 輸出預測結果到文件
    tmp = []
    for i in range(m):
        tmp.append(str(result[i, 0]))
    f_result = open(file_name, "w")
    f_result.write("\t".join(tmp))
    f_result.close()    


if __name__ == "__main__":
    # 一、導入LR模型
    print("---------- 1.load model ------------")
    w = load_weight("weights")
    n = np.shape(w)[1]      # shape(w)=(1,3),權重矩陣一行三列,n =3

    # 二、導入測試數據
    print("---------- 2.load data ------------")
    testData = load_data("test_data", n)
    # 三、對測試數據進行預測
    print("---------- 3.get prediction ------------")
    h = predict(testData, w)    # 進行預測
    # 四、保存最終的預測結果
    # print(h)
    # exit()  成功分類將數據分類爲{0,1}兩種結果
    print("---------- 4.save prediction ------------")
    save_result("result", h)

用第一段代碼訓練好的模型,進行數據的分類,場景如:是不是垃圾郵件等app

相關文章
相關標籤/搜索