Luglio 2015

Volume 30 numero 7

Linguaggio di programmazione R - Introduzione a R per i programmatori c#

Da James McCaffrey

Linguaggio R viene utilizzato da programmatori e gli scienziati i dati per il calcolo statistico. In parte a causa delle crescente quantità di dati raccolti da sistemi software e la necessità di analizzare i dati, R è una delle tecnologie più rapida crescita tra i miei colleghi che utilizzano c#. Una familiarità con R può essere una preziosa aggiunta al vostro set di abilità tecnica.

La lingua di R è un progetto GNU ed è software libero. R è stato derivato da un linguaggio chiamato S (per "statistiche"), che è stato creato presso i Bell Laboratories negli anni settanta. Ci sono molti ottimi tutorial online per R, ma la maggior parte di questi tutorial presume che sei uno studente universitario, studiare le statistiche. Questo articolo è rivolto ad aiutare i programmatori c# arrivare fino a velocità con R più rapidamente possibile.

Il modo migliore per vedere dove è diretto questo articolo è di dare un'occhiata alla sessione di esempio R in Figura 1. La sessione di esempio ha due argomenti non correlati. Il primo set di alcuni dei comandi Visualizza quello che ha chiamato un test chi-quadro (chiamato anche il test chi quadrato) per una distribuzione uniforme. Il secondo set di comandi viene illustrato un esempio di regressione lineare, che a mio parere è la tecnica di Hello World di calcolo statistico.

una sessione di esempio R
Figura 1 una sessione di esempio R

Si trova presso il sito Web R r-project.org. Il sito ha collegamenti a diversi siti di specchio dove è possibile scaricare e installare R. L'installazione è un semplice file eseguibile autoestraente. R è ufficialmente supportata su Windows XP e versioni successive e anche su piattaforme non Windows più comuni. Ho installato R su macchine Windows 7 e Windows 8 senza problemi. Per impostazione predefinita il processo di installazione ti dà le versioni sia a 32-bit e 64-bit.

Questo articolo presuppone che avete abilità (quindi si possono capire le spiegazioni delle analogie e differenze tra c# e R) di programmazione c# almeno intermedio, ma non assumere che si sa nulla di R. Presenta un programma demo c# nella sua interezza, che è disponibile anche il file di download che accompagna questo articolo.

Il Test chi-quadro con R

Guardando Figura 1, la prima cosa da notare è che l'utilizzo di R è abbastanza un po' diverso dall'utilizzo di c#. Sebbene sia possibile scrivere script R, R è più spesso utilizzato in modo interattivo in una shell di comando. Il primo esempio di R è un'analisi per vedere se un normale dado a sei facce è giusto o no. Quando rotolato molte volte, un dado equo dovrebbe dare circa lo stesso conteggio per ciascuno dei sei possibili risultati.

La R prompt è indicato dal token di (>) nella shell. La prima istruzione digitata in Figura 1 inizia con il carattere (#), che è il token di R per indicare un commento.

Il primo comando effettivo nella sessione di esempio è:

> observed <- c(20, 28, 12, 32, 22, 36)

Questo crea un vettore denominato osservati utilizzando il c (per concatenare) funzione. Un vettore contiene gli oggetti con lo stesso tipo di dati. Sarebbe una grosso modo equivalente istruzione c#:

var observed = new int[] { 20, 28, 12, 32, 22, 36 };

Il primo valore, 20, è il numero di volte che si è verificato un uno-spot, 28 è il numero di volte una modalità si è verificato e così via. La somma dei sei conti è 20 + 28 +. . + 36 = 150. Ci si aspetterebbe un dado equo per avere circa 150/6 = 25 conteggi per ogni possibile risultato. Ma il numero di osservati tre-spot (12) sembra sospettosamente basso.

Dopo aver creato il vettore, viene eseguito un test chi-quadrato utilizzando la funzione chisq.test:

> chisq.test(observed)

In R, il carattere punto (.) viene spesso utilizzato anziché il carattere di sottolineatura (_) per creare nomi di variabili e funzioni che sono più facili da leggere. Il risultato della chiamata alla funzione chisq.test è un po ' di testo:

Test chi quadrato per dato probabilità

data:  observed
X-squared = 15.28, df = 5, p-value = 0.009231

In termini di c#, la maggior parte R funzioni restituiscono una struttura dati che può essere ignorata, ma contenga anche molte console. WriteLine istruzioni equivalenti che espongono uscita. Si noti che esso è a voi per decifrare il significato di R output. Più avanti in questo articolo, vi mostrerò come creare il test del chi quadro equivalente usando raw (senza librerie) codice c#.

In questo esempio, il valore di "X-squared" di 15,28 è la statistica del chi quadrato calcolata (la lettera greca chi assomiglia a maiuscola X). Un valore pari a 0,0 indica che i valori osservati sono esattamente ciò che vi aspettereste se il dado è stato equo. I maggiori valori del chi quadrato indicano una probabilità crescente che i conteggi osservati non sarebbe potuto accadere per caso, se il dado è stato equo. Il valore di df di 5 è "gradi di libertà", che è una minore del numero di valori osservati. Il df non è troppo importante per questa analisi.

Il p-valore di 0.009231 è la probabilità che i conteggi osservati potrebbero accadere per caso se il dado è stato equo. Poiché il valore di p è così piccolo, meno dell'1%, si concluderebbe che i valori osservati sono molto improbabili da accadere per caso e, di conseguenza, c'è evidenza statistica che il dado in questione molto probabilmente è prevenuto.

R mediante analisi di regressione lineare

Il secondo set di istruzioni in Figura 1 Mostra un esempio di regressione lineare. Regressione lineare è una tecnica statistica utilizzata per descrivere la relazione tra una variabile numerica (chiamato la variabile dipendente nelle statistiche) e uno o più variabili esplicative (chiamate le variabili indipendenti) che possono essere numerico o categorico. Quando c'è una sola variabile esplicativa/preannunciatore indipendente, la tecnica si chiama regressione lineare semplice. Quando sono presenti due o più variabili indipendenti, come nell'esempio di demo, la tecnica si chiama regressione lineare multipla.

Prima di fare l'analisi di regressione lineare, ho creato un file di testo delimitato da virgola otto-elemento denominato DummyData.txt nella directory C:\IntroToR con questo contenuto:

Color,Length,Width,Rate
blue, 5.4, 1.8, 0.9
blue, 4.8, 1.5, 0.7
blue, 4.9, 1.6, 0.8
pink, 5.0, 1.9, 0.4
pink, 5.2, 1.5, 0.3
pink, 4.7, 1.9, 0.4
teal, 3.7, 2.2, 1.4
teal, 4.2, 1.9, 1.2

Questo file è supposto per rappresentare dati di fiore con il colore del fiore, la lunghezza e la larghezza del petalo e il tasso di crescita. L'idea è di stimare i valori di tasso (nell'ultima colonna) dai valori di larghezza, lunghezza e colore. Dopo un'istruzione di commento, i primi tre comandi di R nell'analisi di regressione lineare sono:

> setwd("C:\\IntroToR")
> data <- read.table("DummyData.txt",
  header=TRUE, sep=",")
> print(data)

Il primo comando imposta la directory di lavoro in modo che non avrei bisogno di qualificare completamente il percorso al file di dati di origine. Invece di utilizzare il token (\) come è comune con c#, potrei used (/) come è comune su piattaforme non-Windows.

Il secondo comando carica i dati in memoria in un oggetto tabella denominato data. Si noti che R vengono utilizzati parametri denominati. Il parametro di intestazione indica se la prima riga è informazioni di intestazione (TRUE, o T nella forma ridotta) o no (FALSE o F). R è case-sensitive e solitamente è possibile utilizzare sia il (<-) operatore per assegnare i valori, o l'operatore (=). La scelta è principalmente una questione di preferenze personali. Io in genere uso (<-) per l'assegnazione dell'oggetto e (=) per l'assegnazione del valore di parametro.

Il parametro di sep (separatore) indica come valori in ciascuna riga sono separati. Per esempio, (\t) indica valori delimitati da tabulazioni, e (" ") indicherebbe valori delimitati.

La funzione di stampa consente di visualizzare la tabella di dati in memoria. La funzione di stampa ha molti parametri facoltativi. Si noti che l'output in Figura 1 consente di visualizzare gli indici di elemento di dati a partire da 1. Per gli indici di matrice, matrice e oggetto, R è un linguaggio basato su 1, piuttosto che come linguaggio c# basato su 0.

L'analisi di regressione lineare viene eseguita con questi due comandi di R:

> model <- lm(data$Rate ~ (data$Color + data$Length + data$Width))
> summary(model)

È possibile interpretare il primo comando come, "Store in un oggetto denominato modello il risultato dell'analisi di funzione lm (modello lineare) dove la variabile dipendente da prevedere è la colonna di tasso nell'oggetto tabella (dati$ Rate), e le variabili del preannunciatore indipendente sono larghezza, lunghezza e colore." Il secondo comando significa, "Visualizza solo i risultati di base dell'analisi archiviate nell'oggetto denominato modello".

La funzione lm genera una grande quantità di informazioni. Si supponga che si voleva stimare il valore di tasso quando i valori di input sono colore = rosa, lunghezza = 5.0 e larghezza = 1,9. (Si noti che questo corrisponde all'elemento di dati [4], che ha un valore di tasso effettivo di 0,4). Per fare una previsione si utilizzerà i valori della colonna di stima:

Coefficients:
               Estimate Std. Error t value Pr(>|t|)
(Intercept)    -0.14758    0.48286  -0.306  0.77986
data$Colorpink -0.49083    0.04507 -10.891  0.00166 **
data$Colorteal  0.35672    0.09990   3.571  0.03754 *
data$Length     0.04159    0.07876   0.528  0.63406
data$Width      0.45200    0.11973   3.775  0.03255 *

Se X rappresenta i valori della variabile indipendente, e se Y rappresenta la frequenza stimata, quindi:

X = (blue = NA, pink = 1, teal = 0, Length = 5.0, Width = 1.9)
Y = -0.14758 + (-0.49083)(1) + (0.35672)(0) + (0.04159)(5.0) + (0.45200)(1.9)
  = -0.14758 + (-0.49083) + (0) + (0.20795) + (0.85880)
  = 0.42834

Si noti che il predetto tasso, 0,43, è abbastanza vicino il tasso effettivo, 0.40.

In parole, per fare una previsione utilizzando il modello, si calcola una somma lineare di prodotti dei valori di stima moltiplicati X loro corrispondenti valori. Il valore dell'intercetta è una costante non associata a qualsiasi variabile. Quando avete categoriche variabili esplicative, uno dei valori viene eliminato (in questo caso blu).

Le informazioni nella parte inferiore della visualizzazione dell'output indicano quanto bene le variabili indipendenti, colore, lunghezza e larghezza, spiegare la variabile dipendente, tasso:

Residual standard error: 0.05179 on 3 degrees of freedom
Multiple R-squared:  0.9927,    Adjusted R-squared:  0.9829
F-statistic: 101.6 on 4 and 3 DF,  p-value: 0.00156

Il valore di R al quadrato più (0.9927) è la percentuale di variazione della variabile dipendente spiegata dalla combinazione lineare delle variabili indipendenti. Mettere in modo leggermente diverso, R-squared è un valore compreso tra 0 e 1 dove i valori più alti significano un modello predittivo meglio. Qui, il valore di R al quadrato è estremamente alto, che indica il colore, la lunghezza e la larghezza può predire tasso molto accuratamente. La statistica F, valore di R al quadrato regolato e p-valore sono altre misure del modello fit.

Uno dei punti di questo esempio è che quando nella programmazione in R, la sfida più grande di gran lunga è capire le statis­TIC dietro le funzioni di lingua. La maggior parte delle persone imparano R in modo incrementale, aggiungendo conoscenza della uno tecnica alla volta, come necessario per rispondere a qualche domanda specifica. Un'analogia c# sarebbe apprendere i vari oggetti di raccolta nello spazio dei nomi Collections.Generic, quali le classi Hashtable e coda. Maggior parte degli sviluppatori imparare la struttura di dati su una alla volta, piuttosto che cercando di memorizzare informazioni su tutte le classi prima di utilizzare qualsiasi di loro in un progetto.

Un altro Test chi-quadro

Il tipo di test chi quadrato in Figura 1 è spesso chiamato un test per una distribuzione uniforme perché verifica se i dati osservati tutti hanno uguali conteggi; cioè, se i dati vengono distribuiti uniformemente. Ci sono diversi altri tipi di test chi-quadrato, tra cui uno chiamato un test chi-quadrato di indipendenza.

Si supponga che si dispone di un gruppo di 100 persone e siete interessati se il sesso (maschio, femmina) è indipendente dall'affiliazione ad un partito politico (democratico, repubblicano, altri). Immaginate i dati sono in una matrice di contingenza come mostrato Figura 2. Sembra che forse i maschi sono più probabili essere repubblicano che le femmine sono.

Figura 2 matrice di contingenza

  Dem Rep Altri  
Uomo 15 25 10 50
Donna 30 15 5 50
  45 40 15 100

Per utilizzare R per verificare se i due fattori, il sesso e affiliazione, sono statisticamente indipendenti, si sarebbero prima inserire i dati in una matrice numerica con questo comando:

> cm <- matrix( c(15,30,25,15,10,5), nrow=2, ncol=3 )

Si noti che in R, vengono archiviati dati di matrice da colonne (alto verso il basso, da sinistra a destra) anziché righe (da sinistra a destra, dall'alto verso il basso) come in c#.

Il comando di test chi-quadro R è:

> chisq.test(cm)

Il risultato del test p-valore è 0.01022, che indica che con il livello di significatività del 5 per cento, i due fattori non sono indipendenti. In altre parole, c'è una relazione statistica tra sesso e affiliazione.

Si noti che nel primo esempio dadi chi-quadrato, il parametro di input è un vettore, ma nel secondo esempio di affiliazione del sesso, l'input è una matrice. La funzione di chisq.test ha un totale di sette parametri, uno obbligatorio (un vettore o una matrice), seguita da sei opzionale parametri denominati.

Come molti metodi c# negli spazi dei nomi di Microsoft .NET Framework, la maggior parte delle funzioni di R sono pesantemente sovraccaricate. In c#, sovraccarico viene solitamente implementata utilizzando più metodi con lo stesso nome ma con parametri diversi. L'uso di farmaci generici è anche una forma di sovraccarico. In R, sovraccarico viene implementata utilizzando una singola funzione con molteplici optional parametri denominati.

Grafici con R

Come un programmatore c#, quando voglio fare un grafico di qualche programma di uscita dati, io in genere eseguire il mio programma, copiare i dati di output, Ctrl + V incolla che dati nel blocco note per rimuovere i caratteri di controllo strano, copiare i dati, incollarlo in Excel e quindi creare un grafico utilizzando Excel. Questo è tipo di hacky, ma funziona bene nella maggior parte delle situazioni.

Uno dei punti di forza del sistema R è la sua capacità nativa per generare grafici. Date un'occhiata a un esempio in Figura 3. Si tratta di un tipo di grafico che non è possibile in Excel senza il componente aggiuntivo di qualche tipo.

grafico 3D utilizzando R
Figura 3 grafico 3D utilizzando R

Oltre al programma shell mostrato Figura 1, R ha anche un'interfaccia semi-GUI, RGui.exe, per l'uso quando si vuole fare grafici.

Il grafico in Figura 3 Mostra la funzione z = f = x * e ^ (-(x ^ 2 + y ^ 2)). I primi tre comandi di R per generare il grafico sono:

> rm(list=ls())
> x <- seq(-2, 2, length=25)
> y <- seq(-2, 2, length=25)

La funzione di rm consente di eliminare un oggetto dall'area di lavoro corrente in memoria. Il comando utilizzato è un incantesimo di magia R per eliminare tutti gli oggetti. Il secondo e il terzo comando crea vettori di 25 valori, distribuiti uniformemente, da -2 a + 2 all inclusive. Potrei hai utilizzato la funzione c invece.

I due comandi sono:

> f <- function(x,y) { x * exp(-(x^2
  + y^2)) }
> z <- outer(x,y,f)

Il primo comando viene illustrato come definire una funzione in R utilizzando la parola chiave function. La funzione incorporata di R denominato esterno crea una matrice di valori utilizzando vettori x e y e una definizione di funzione f. Il risultato è una matrice di 25 x 25, dove il valore in ogni cella è il valore della funzione f che corrisponde a x e y.

I due comandi sono:

> nrz <- nrow(z)
> ncz <- ncol(z)

Le funzioni nrow e ncol restituisce il numero di righe o il numero di colonne nella loro argomento di matrice. Qui, entrambi i valori sarebbe 25.

Il successivo comando di R utilizza la funzione colorRampPalette per creare una palette sfumatura di colore personalizzato per disegnare il grafico:

> jet.colors <- colorRampPalette(c("midnightblue", "blue",
+ "cyan", "green", "yellow", "orange", "red", "darkred"))

Quando si digita una lunga fila R, se colpisci il < Invio > chiave, il sistema verrà saltare il cursore fino alla riga successiva e un carattere come un prompt per indicare il comando non è ancora completo +. Successivo:

> nbcol <- 64
> color <- jet.colors(nbcol)

Il risultato di questi due comandi è un vettore che contiene 64 valori di colore diverso colore denominato che vanno da un blu molto scuro, tra verde e giallo, a rosso molto scuro. Successivo:

> zfacet <- z[-1,-1] + z[-1,-ncz] + z[-nrz,-1] + z[-nrz,-ncz]
> facetcol <- cut(zfacet,nbcol)

Se si osserva attentamente il grafico in Figura 3, vedrete che la superficie è costituita da 25 x 25 = 625 piccola quadrati o sfaccettature. I due comandi precedenti creano una matrice di 25 x 25, dove il valore in ogni cella è uno dei 64 colori da utilizzare per il facet superficie corrispondente.

Infine, viene visualizzato il grafico 3D usando la funzione persp (grafico di prospettiva):

> persp(x,y,z, col=color[facetcol], phi=20, theta=-35,
+ ticktype="detailed", d=5, r=1, shade=0.1, expand=0.7)

La funzione persp ha un sacco di optional, parametri denominati. Il parametro col è il colore, o colori, da utilizzare. Theta e phi di parametri è possibile impostare l'angolo di visione (sinistra e destra e su e giù) del grafico. Controlli ticktype parametri come valori x, vengono visualizzati gli assi y e z. D e r parametri controllano la distanza occhio percepito per il grafico e l'effetto 3D percepito. Il parametro denominato ombra controlli simulato l'ombreggiatura da una sorgente di luce virtuale. Il parametro denominato espandere controlli il rapporto tra l'altezza e la larghezza del grafico. La funzione persp ha molti più parametri, ma quelli usati qui sarà sufficienti nella maggior parte delle situazioni.

Questo esempio evidenzia che R ha molto potente e flessibile funzionalità grafiche native, ma tendono ad essere relativamente basso livello e richiedono una notevole quantità di sforzo.

Il Test chi-quadrato in C#

Per acquisire una comprensione delle somiglianze e differenze tra R lingua analisi e c# linguaggio di programmazione, è utile esaminare un'implementazione c# di un test del chi-quadrato. Inoltre, il codice c# può fare una bella aggiunta alla libreria di codice personale. Guardate il programma demo c# in Figura 4.

Test chi-quadro utilizzando c#
Figura 4 Test chi-quadro utilizzando c#

Approssima il programma demo mostrato test di dadi del chi quadro di lingua R Figura 1. Notare che i valori di uscita della demo c# sono esattamente gli stessi di quelli nella sessione R.

Per creare il programma demo, ho lanciato Visual Studio e creato un nuovo progetto applicazione console di c# denominato ChiSquare. Dopo il codice del modello caricati nell'editor, nella finestra Esplora soluzioni I selezionata sul file Program.cs e rinominato ChiSquareProgram.cs e ha permesso di Visual Studio rinominare automaticamente classe programma per ChiSquareProgram.

Il programma di demo c# completo è elencato Figura 5. Si noterà che il codice sorgente è più tempo di quanto ci si potrebbe aspettare. Implementazione statistica usando raw di programmazione c# non è eccessivamente difficile, ma il codice tendono ad essere lunghi.

Figura 5 C# chi-quadrato Demo programma

using System;
namespace ChiSquare
{
  class ChiSquareProgram
  {
    static void Main(string[] args)
    {
      try
      {
        Console.WriteLine("\nBegin Chi-square test using C# demo\n");
        Console.WriteLine(
          "Goal is to see if one die from a set of dice is biased or not\n");
        int[] observed = new int[] { 20, 28, 12, 32, 22, 36 };
        Console.WriteLine("\nStarting chi-square test");
        double p = ChiSquareTest(observed);
        Console.WriteLine("\nChi-square test complete");
        double crit = 0.05;
        if (p < crit)
        {
          Console.WriteLine("\nBecause p-value is below critical value of " +
            crit.ToString("F2"));
          Console.WriteLine("the null hypothsis is rejected and we conclude");
          Console.WriteLine("the data is unlikely to have happened by chance.");
        }
        else
        {
          Console.WriteLine("\nBecause p-value is not below critical value of " +
            crit.ToString("F2"));
          Console.WriteLine(
            "the null hypothsis is accepted (not rejected) and we conclude");
          Console.WriteLine("the observed data could have happened by chance.");
        }
        Console.WriteLine("\nEnd\n");
        Console.ReadLine();
      }
      catch (Exception ex)
      {
        Console.WriteLine(ex.Message);
        Console.ReadLine();
      }
    } // Main
    static void ShowVector(int[] v)
    {
      for (int i = 0; i < v.Length; ++i)
        Console.Write(v[i] + " ");
      Console.WriteLine("");
    }
    static double ChiSquareTest(int[] observed)
    {
      Console.WriteLine("Observed frequencies are: ");
      ShowVector(observed);
      double x = ChiSquareStatistic(observed);
      Console.WriteLine("\nX-squared = " + x.ToString("F2"));
      int df = observed.Length - 1;
      Console.WriteLine("\ndf = " + df);
      double p = ChiSquareProb(x, df);
      Console.WriteLine("\np-value = " + p.ToString("F6"));
      return p;
    }
    static double ChiSquareStatistic(int[] observed)
    {
      double sumObs = 0.0;
      for (int i = 0; i < observed.Length; ++i)
        sumObs += observed[i];
      double expected = (int)(sumObs / observed.Length);
      double result = 0.0;
      for (int i = 0; i < observed.Length; ++i)
      {
        result += ((observed[i] - expected) *
         (observed[i] - expected)) / expected;
      }
      return result;
    }
    public static double ChiSquareProb(double x, int df)
    {
      // x = a computed chi-square value. df = degrees of freedom.
      // output = prob. the x value occurred by chance.
      // So, for example, if result < 0.05 there is only a 5% chance
      // that the x value occurred by chance and, therefore,
      // we conclude that the actual data which produced x is
      // NOT the same as the expected data.
      // This function can be used to create a ChiSquareTest procedure.
      // ACM Algorithm 299 and update ACM TOMS June 1985.
      // Uses custom Exp() function below.
      if (x <= 0.0 || df < 1)
        throw new Exception("parameter x must be positive " +
        "and parameter df must be 1 or greater in ChiSquaredProb()");
      double a = 0.0; // 299 variable names
      double y = 0.0;
      double s = 0.0;
      double z = 0.0;
      double e = 0.0;
      double c;
      bool even; // Is df even?
      a = 0.5 * x;
      if (df % 2 == 0) even = true; else even = false;
      if (df > 1) y = Exp(-a); // ACM update remark (4)
      if (even == true) s = y; else s = 2.0 * Gauss(-Math.Sqrt(x));
      if (df > 2)
      {
        x = 0.5 * (df - 1.0);
        if (even == true) z = 1.0; else z = 0.5;
        if (a > 40.0) // ACM remark (5)
        {
          if (even == true) e = 0.0;
          else e = 0.5723649429247000870717135;
          c = Math.Log(a); // log base e
          while (z <= x)
          {
            e = Math.Log(z) + e;
            s = s + Exp(c * z - a - e); // ACM update remark (6)
            z = z + 1.0;
          }
          return s;
        } // a > 40.0
        else
        {
          if (even == true) e = 1.0;
          else e = 0.5641895835477562869480795 / Math.Sqrt(a);
          c = 0.0;
          while (z <= x)
          {
            e = e * (a / z); // ACM update remark (7)
            c = c + e;
            z = z + 1.0;
          }
          return c * y + s;
        }
      } // df > 2
      else
      {
        return s;
      }
    } // ChiSquare()
    private static double Exp(double x) // ACM update remark (3)
    {
      if (x < -40.0) // ACM update remark (8)
        return 0.0;
      else
        return Math.Exp(x);
    }
    public static double Gauss(double z)
    {
      // input = z-value (-inf to +inf)
      // output = p under Normal curve from -inf to z
      // e.g., if z = 0.0, function returns 0.5000
      // ACM Algorithm #209
      double y; // 209 scratch variable
      double p; // result. called 'z' in 209
      double w; // 209 scratch variable
      if (z == 0.0)
        p = 0.0;
      else
      {
        y = Math.Abs(z) / 2;
        if (y >= 3.0)
        {
          p = 1.0;
        }
        else if (y < 1.0)
        {
          w = y * y;
          p = ((((((((0.000124818987 * w
            - 0.001075204047) * w + 0.005198775019) * w
            - 0.019198292004) * w + 0.059054035642) * w
            - 0.151968751364) * w + 0.319152932694) * w
            - 0.531923007300) * w + 0.797884560593) * y * 2.0;
        }
        else
        {
          y = y - 2.0;
          p = (((((((((((((-0.000045255659 * y
            + 0.000152529290) * y - 0.000019538132) * y
            - 0.000676904986) * y + 0.001390604284) * y
            - 0.000794620820) * y - 0.002034254874) * y
            + 0.006549791214) * y - 0.010557625006) * y
            + 0.011630447319) * y - 0.009279453341) * y
            + 0.005353579108) * y - 0.002141268741) * y
            + 0.000535310849) * y + 0.999936657524;
        }
      }
      if (z > 0.0)
        return (p + 1.0) / 2;
      else
        return (1.0 - p) / 2;
    } // Gauss()
  } // Program class
} // ns

Il metodo principale consiste principalmente di istruzioni WriteLine. Il codice chiamante essenziale è:

int[] observed = new int[] { 20, 28, 12, 32, 22, 36 };
double p = ChiSquareTest(observed);
double crit = 0.05;
if (p < crit) {
  // Messages
} else {
  // Messages
}

Il test del chi-quadrato C# accetta una matrice di valori osservati, calcola il valore della statistica chi-quadrato e visualizzarla; calcola e Visualizza i gradi di libertà; calcola e restituisce il valore di p.

Metodo ChiSquareTest chiama tre metodi di supporto:

ShowVector(observed);
double x = ChiSquareStatistic(observed);
int df = observed.Length - 1;
double p = ChiSquareProb(x, df);

Metodo ShowVector Visualizza il vettore d'ingresso, simile all'approccio utilizzato dalla funzione R chisq.test di riecheggiando input param­eter valori. Metodo ChiSquareStatistic restituisce il chi-quadro calcolato ("X-squared" nell'output di R) e metodo ChiQuadro­Prob utilizza il ritorno da ChiSquareStatistic per calcolare una probabilità (il "p-valore" nell'output di R).

Metodo ChiSquareStatistic è un semplice test per una distribuzione uniforme. L'equazione di statistiche per la statistica del chi quadrato è:

chi-squared = Sum( (observed - expected)^2 / expected )

Quindi, prima di calcolare chi quadrato, è necessario calcolare i valori attesi connessi con i valori osservati. Come spiegato in precedenza, per fare questo che si aggiunge il valore di conteggio nella matrice osservata (150 nella demo), poi dividere tale somma per il numero di valori nella matrice (6 nella demo), per dare il valore previsto (25) per tutte le celle.

La parte più difficile della scrittura di un test del chi-quadrato è il calcolo del p-valore. Se si esegue la scansione la definizione del metodo ChiQuadro­Prob in Figura 5, vi renderete rapidamente conto profondo, richiede la conoscenza specializzata. Inoltre, il metodo chiama un metodo di supporto denominato Gauss che è altrettanto complessa.

Funzioni numeriche complicate di codifica è in realtà abbastanza semplice perché la maggior parte delle funzioni sono stati risolti per decenni. Due delle mie risorse utilizzate più di frequente sono l'associazione per repository Computing Machinery (ACM) raccolti algoritmi e il "manuale delle funzioni matematiche" da Abramowitz e Stegun (Dover Publications, 1965) — così ben noto è spesso semplicemente chiamato "A & S." Entrambi i riferimenti sono liberamente disponibili in diversi luoghi sul Web.

Ad esempio, il metodo ChiSquareProb implementa ACM algoritmo #299 e implementa il metodo di supporto, Gauss, ACM algoritmo n. 209. È un'alternativa a ACM #209 A & S equazione #7.1.26 oltre un semplice avvolgimento istruzione.

Molte delle funzioni negli algoritmi di ACM e A & S imple­to in c# librerie esistenti; Tuttavia, la maggior parte di queste librerie sono abbastanza grande. Quando possibile, preferisco codice da zero, utilizzando solo i metodi necessità ed evitando dipendenze esterne.

Alcuni commenti

Questo articolo viene illustrato solo una minuscola frazione della lingua R ma dovrebbe essere sufficiente per ottenere installato e funzionante. Programmatori c# tendono a venire in contatto con R in due modi. In primo luogo, è possibile utilizzare R per eseguire la propria analisi statistiche. Come illustrato in questo articolo, utilizzando R è abbastanza facile, supponendo che hai afferrato le statistiche sottostanti. In secondo luogo, potrebbe essere necessario interagire con qualcuno che utilizza R come loro lingua primaria e pertanto è necessario comprendere l'ambiente di R e la terminologia.

Ci sono alcuni strumenti di sviluppo di linguaggio integrato di R è possibile utilizzare. Un progetto ben noto è chiamato RStudio. Io generalmente preferisco utilizzando la console di R nativa. Numerosi prodotti Microsoft funzionano con R. Ad esempio, il servizio di Microsoft Azure Machine Learning può utilizzare script di linguaggio di R e ho il sospetto che il supporto per R verrà aggiunto al Visual Studio a un certo punto.


Dr. James McCaffrey lavora per Microsoft Research in Redmond, WA  Ha lavorato su diversi prodotti Microsoft, inclusi Internet Explorer e Bing. Dr. McCaffrey può essere raggiunto a jammc@microsoft.com.

Grazie all'esperto tecnico Microsoft Research seguente per la revisione di questo articolo: Dan Liebling e Robin Reynolds-Haertle
Robin Reynolds-Haertle scrive la documentazione per lo sviluppo multipiattaforma con Visual Studio. Suoi interessi sono Core .NET, c#, Swift e R