2016-08-04 29 views
2

ich eine einfache lineare Regression durchgeführt, und ich möchte, um es auszuprobieren, indem ein nicht lineares Modell passendDer Versuch, eine einfache Funktion plotten - Python

speziell versuche ich, ein Modell für die Funktion y = x^3 + 5 zum Beispiel

zu passen

dies ist mein Code

import numpy as np 
import numpy.matlib 
import matplotlib.pyplot as plt 

def predict(X,W): 
    return np.dot(X,W) 

def gradient(X, Y, W, regTerm=0): 
    return (-np.dot(X.T, Y) + np.dot(np.dot(X.T,X),W))/(m*k) + regTerm * W /(n*k) 

def cost(X, Y, W, regTerm=0): 
    m, k = Y.shape 
    n, k = W.shape 
    Yhat = predict(X, W) 
    return np.trace(np.dot(Y-Yhat,(Y-Yhat).T))/(2*m*k) + regTerm * np.trace(np.dot(W,W.T))/(2*n*k) 

def Rsquared(X, Y, W): 
    m, k = Y.shape 
    SSres = cost(X, Y, W) 
    Ybar = np.mean(Y,axis=0) 
    Ybar = np.matlib.repmat(Ybar, m, 1) 
    SStot = np.trace(np.dot(Y-Ybar,(Y-Ybar).T)) 

    return 1-SSres/SStot 

m = 10 
n = 200 
k = 1 

trX = np.random.rand(m, n) 
trX[:, 0] = 1 

for i in range(2, n): 
    trX[:, i] = trX[:, 1] ** i 

trY = trX[:, 1] ** 3 + 5 
trY = np.reshape(trY, (m, k)) 

W = np.random.rand(n, k) 

numIter = 10000 
learningRate = 0.5 

for i in range(0, numIter): 
    W = W - learningRate * gradient(trX, trY, W) 

domain = np.linspace(0,1,100000) 
powerDomain = np.copy(domain) 
m = powerDomain.shape[0] 
powerDomain = np.reshape(powerDomain, (m, 1)) 
powerDomain = np.matlib.repmat(powerDomain, 1, n) 

for i in range(1, n): 
    powerDomain[:, i] = powerDomain[:, 0] ** i 

print(Rsquared(trX, trY, W)) 
plt.plot(trX[:, 1],trY,'o', domain, predict(powerDomain, W),'r') 
plt.show() 

die R^2 ich bin immer sehr nahe an 1 ist, was bedeutet, ich eine sehr gute Anpassung an die Trainingsdaten gefunden, aber es ist nicht auf den Stellplätzen gezeigt. Wenn ich die Daten plotten, es sieht in der Regel wie folgt aus:

enter image description here

sieht es aus, als ob ich die Daten underfitting, aber mit einer solchen komplexen Hypothese, mit 200 Merkmale (dh erlauben i Polynome bis zu x^200) und nur 10 Trainingsbeispiele, ich sollte ganz klar Daten überarbeiten, also erwarte ich, dass die rote Linie alle blauen Punkte passiert und zwischen ihnen wild wird.

Das ist nicht was ich bekomme, was für mich verwirrend ist. Was ist los?

+0

Als Erstes, fixiere das: 'trX = np.random.rand (m) ** np.bereich (n)' – Julien

+0

und 'powerDomain = domain ** np.arange (n)' – Julien

Antwort

0

Sie haben vergessen, powerDomain[:,0]=1 einzustellen, deshalb geht Ihre Handlung bei 0 falsch. Und ja, Sie sind übermäßig fit: Schauen Sie, wie schnell Ihre Handlung startet, sobald Sie Ihre Trainings-Domain verlassen.