【ML代码从零开始实现 - python】回归——线性回归、逻辑斯蒂回归、感知机、最大熵模型

线性回归、逻辑斯帝回归

import numpy as np
import matplotlib.pyplot as plt
from random import random

def sigmond(x):
    return 1 / (1 + np.exp(-x))

def log_cly(p):
    if p >= 0.5:
        return 1
    else:
        return 0

class Regression():
    def __init__(self, learning_rate, max_iter):
        assert learning_rate > 0
        assert learning_rate < 1
        assert isinstance(max_iter, int)

        self.learning_rate = learning_rate
        self.max_iter = max_iter

        super(Regression, self).__init__()

    def fit(self, X, y):
        num_samples = len(X)
        num_features = (X.shape)[1]

        assert len(X) == len(y)

        self.w = np.random.random(num_features)
        self.b = 0

        for i in range(self.max_iter):
            self.w += np.array(self.learning_rate * sum([(yi - self.predict_sample(xi)) * xi 
                               for xi, yi in zip(X, y)])) / num_samples
            self.b += np.array(self.learning_rate * sum([(yi - self.predict_sample(xi)) 
                               for xi, yi in zip(X, y)])) / num_samples
            '''
            l = self.loss(X, y)
            if (i+1) % 100 == 0:
                print("epoch: {0}, loss: {1}".format(i + 1, l))
            '''

    def predict(self, X):
        return [self.predict_sample(xi) for xi in X]

    def predict_sample(self, xi):
        pass

    def loss(self, X, y):
        pass


class LinearRegression(Regression):
    def __init__(self, learning_rate, max_iter):
        super(LinearRegression, self).__init__(learning_rate, max_iter)

    def predict_sample(self, xi):
        return sum(self.w * np.array(xi)) + self.b

    def loss(self, X, y):
        y_pred = np.array([self.predict_sample(xi) for xi in X])
        return sum((y_pred-y) * (y_pred-y))


class LogisticRegression(Regression):
    def __init__(self, learning_rate, max_iter):
        super(LogisticRegression, self).__init__(learning_rate, max_iter)

    def predict_sample(self, xi):
        return sigmond(sum(self.w * np.array(xi)) + self.b)

    def predict_class(self, X):
        y_pred_prob = self.predict(X)
        pred_class = [log_cly(pi) for pi in y_pred_prob]
        return pred_class

    def loss(self, X, y):
        y_pred = [self.predict_sample(xi) for xi in X]
        cross_entropy = -np.array([(yi * np.log(yi_pred) + (1-yi) * np.log(yi_pred)) 
                                   for yi, yi_pred in zip(y, y_pred)])
        return sum(cross_entropy)


# a simple test of linear regression
'''
def create_data(true_w, true_b, num_examples):
    features = np.random.random((num_examples, len(true_w)))
    labels = np.array([sum(fi * true_w) + true_b for fi in features]) + np.random.random() * 0.1
    return features, labels

true_w = [4.2, -2.0, 1.5]
true_b = [1.0]
features, labels = create_data(true_w, true_b, 1000)

LinReg = LinearRegression(0.03, 2000)
LinReg.fit(features, labels)
'''

# a simple test of logistic regression
'''
def create_data(true_w, true_b, num_examples):
    features = np.random.random((num_examples, len(true_w)))
    probs = np.array([sum(fi * true_w) + true_b for fi in features]) + np.random.random() * 0.1
    return features, probs

def create_labels(probs):
    return np.array([log_cly(pi) for pi in probs])

true_w = [4.2, -2.0, 1.5]
true_b = [1.0]
features, probs = create_data(true_w, true_b, 1000)
labels = create_labels(probs)

LogReg = LogisticRegression(0.03, 2000)
LogReg.fit(features, labels)
'''

 

线性回归测试:

 逻辑斯蒂回归测试:

 

感知机

def sign(x):
    if x >= 0:
        return 1
    else:
        return -1

class Perceptron():
    def __init__(self, learning_rate, max_iter):
        assert learning_rate > 0
        assert learning_rate < 1
        assert isinstance(max_iter, int)

        self.learning_rate = learning_rate
        self.max_iter = max_iter

        super(Perceptron, self).__init__()

    def fit(self, X, y):
        num_samples = len(X)
        num_features = (X.shape)[1]

        assert len(X) == len(y)

        self.w = np.random.random(num_features)
        self.b = 0

        for i in range(self.max_iter):
            for xi, yi in zip(X, y):
                if (yi * (sum(self.w * np.array(xi) + self.b)) < 0):
                    self.w += self.learning_rate * yi * np.array(xi)
                    self.b += self.learning_rate * yi
            l = self.loss(X, y)
            print("epoch {0}, loss: {1}".format(i+1, l))

    def predict(self, X):
        return [self.predict_sample(xi) for xi in range(X)]

    def predict_sample(self, xi):
        return sign(self.w * np.array(xi) + self.b)

    def loss(self, X, y):
        loss_sample = []
        for xi, yi in zip(X, y):
            if (yi * (sum(self.w * np.array(xi) + self.b)) < 0):
                loss_sample.append(-yi * (sum(self.w * np.array(xi) + self.b)))
        return sum(loss_sample)


# a simple test of perceptron
'''
X = np.array([[3, 3], [4, 3], [1, 1]])
y = np.array([1, 1, -1])
Per = Perceptron(0.5, 10)
Per.fit(X, y)
print(Per.w)
print(Per.b)
'''

简单的例子:

 

posted @ 2022-02-12 20:04  鱼儿冒个泡  阅读(65)  评论(0编辑  收藏  举报