Coder Social home page Coder Social logo

sem-in-r / seminr Goto Github PK

View Code? Open in Web Editor NEW
58.0 11.0 19.0 9.47 MB

Natural feeling domain-specific language for building structural equation models in R for estimation by covariance-based methods (like LISREL/Lavaan) or partial least squares (like SmartPLS)

R 100.00%
pls-models common-factors composites construct r

seminr's Introduction

CRAN_Status_Badge metacran downloads

SEMinR allows users to easily create and modify structural equation models (SEM). It allows estimation using either covariance-based SEM (CBSEM, such as LISREL/Lavaan), or Partial Least Squares Path Modeling (PLS-PM, such as SmartPLS/semPLS).

First Look

Main features of using SEMinR:

  • A natural feeling, domain-specific language to build and estimate SEMs in R
  • High-level functions to quickly specify interactions and complicated structural models
  • Modular design of models that promotes reuse of model components
  • Encourages best practices by use of smart defaults and warnings

Take a look at the easy syntax and modular design:

# Define measurements with famliar terms: reflective, composite, multi-item constructs, etc.
measurements <- constructs(
  reflective("Image",       multi_items("IMAG", 1:5)),
  composite("Expectation", multi_items("CUEX", 1:3)),
  composite("Loyalty",     multi_items("CUSL", 1:3), weights = mode_B),
  composite("Complaints",  single_item("CUSCO"))
)

# Create four relationships (two regressions) in one line!
structure <- relationships(
  paths(from = c("Image", "Expectation"), to = c("Complaints", "Loyalty"))
)

# Estimate the model using PLS estimation scheme (Consistent PLS for reflectives)
pls_model <- estimate_pls(data = mobi, measurements, structure)
#> Generating the seminr model
#> All 250 observations are valid.

# Re-estimate the model as a purely reflective model using CBSEM
cbsem_model <- estimate_cbsem(data = mobi, as.reflective(measurements), structure)
#> Generating the seminr model for CBSEM

SEMinR can plot models using the semplot (for CBSEM models) or DiagrammeR (for PLS models) packages with a simple plot method.

plot(pls_model, title = "PLS Model")
save_plot("myfigure.pdf")

SEMinR allows various estimation methods for constructs and SEMs:

  • Covariance-based Structural Equation Modeling (CBSEM)
    • Covariance-based estimation of SEM using the popular Lavaan package
    • Currently supports mediation and moderation models with constructs
    • Easily specify interactions between constructs
    • Adds ten Berge factor score extraction to get same correlation patterns as latent factors
    • Adds VIF and other validity assessments
  • Confirmatory Factor Analysis (CFA) using Lavaan
    • Uses Lavaan package and returns results and syntax
    • Adds ten Berge factor score extraction to get same correlation patterns as latent factors
  • Partial Least Squares Path Modeling (PLS-PM)
    • Uses non-parametric variance-based estimation to construct composites and common-factors
    • Automatically estimates using Consistent PLS (PLSc) when emulating reflective common factors
    • Adjusts for known biases in interaction terms in PLS models
    • Continuously tested against leading PLS-PM software to ensure parity of outcomes: SmartPLS, ADANCO, semPLS, and matrixpls
    • High performance, multi-core bootstrapping function

Researchers can now create a SEM and estimate it using different techniques (CBSEM, PLS-PM).

Installation

You can install SEMinR from R with:

install.packages("seminr")

Usage and Examples

Load the SEMinR package:

library(seminr)

Describe measurement and structural models and then estimate them. See the various examples below for different use cases:

  1. CFA + CBSEM Example with Common Factors
  2. Consistent-PLS (PLSc) Example with Common Factors
  3. PLS-PM Example with Composites
  4. Comparing CBSEM and PLS-PM Example

CFA + CBSEM Example with Common Factors

Note that CBSEM models reflective common-factor constructs, not composites. SEMinR uses the powerful Lavaan package to estimate CBSEM models – you can even inspect the more complicated Lavaan syntax that is produced.

Describe reflective constructs and interactions:

# Distinguish and mix composite or reflective (common-factor) measurement models
# - composite measurements will have to be converted into reflective ones for CBSEM (see below)
measurements <- constructs(
  reflective("Image",       multi_items("IMAG", 1:5)),
  reflective("Expectation", multi_items("CUEX", 1:3)),
  interaction_term(iv = "Image", moderator = "Expectation", method = two_stage),
  reflective("Loyalty",     multi_items("CUSL", 1:3)),
  reflective("Complaints",  single_item("CUSCO"))
)

Describe the causal relationships between constructs and interactions:

# Quickly create multiple paths "from" and "to" sets of constructs
structure <- relationships(
  paths(from = c("Image", "Expectation", "Image*Expectation"), to = "Loyalty"),
  paths(from = "Image", to = c("Complaints"))
)

Put the above elements together to estimate the model using Lavaan:

# Evaluate only the measurement model using Confirmatory Factor Analysis (CFA)
cfa_model <- estimate_cfa(data = mobi, measurements)
summary(cfa_model)

# Dynamically compose full SEM models from individual parts
# - if measurement model includes composites, convert all constructs to reflective using:
#     as.reflective(measurements)
cbsem_model <- estimate_cbsem(data = mobi, measurements, structure)
sum_cbsem_model <- summary(cbsem_model)
sum_cbsem_model$meta$syntax # See the Lavaan syntax if you wish

Consistent-PLS (PLSc) Example with Common Factors

Models with reflective common-factor constructs can also be estimated in PLS-PM, using Consistent-PLS (PLSc). Note that the popular SmartPLS software models constructs as composites rather than common-factors (see below) but can also do PLSc as a special option.

We will reuse the measurement and structural models from earlier:

# Optionally inspect the measuremnt and structural models
measurements
structure

Estimate full model using Consistent-PLS and bootstrap it for confidence intervals:

# Models with reflective constructs are automatically estimated using PLSc
pls_model <- estimate_pls(data = mobi, measurements, structure)
summary(pls_model)

# Use multi-core parallel processing to speed up bootstraps
boot_estimates <- bootstrap_model(pls_model, nboot = 1000, cores = 2)
summary(boot_estimates)

PLS-PM Example with Composites

PLS-PM typically models composites (constructs that are weighted average of items) rather than common factors. Popular software like SmartPLS models composites either as Mode A (correlation weights) or Mode B (regression weights). We also support both modes as well as second-order composites. rather than common factors. Popular software like SmartPLS models composites by default, either as Mode A (correlation weights) or Mode B (regression weights). We also support second-order composites.

Describe measurement model for each composite, interaction, or higher order composite:

# Composites are Mode A (correlation) weighted by default
mobi_mm <- constructs(
  composite("Image",        multi_items("IMAG", 1:5)),
  composite("Value",        multi_items("PERV", 1:2)),
  higher_composite("Satisfaction", dimensions = c("Image","Value"), method = two_stage),
  composite("Expectation",  multi_items("CUEX", 1:3)),
  composite("Quality",      multi_items("PERQ", 1:7), weights = mode_B),
  composite("Complaints",   single_item("CUSCO")),
  composite("Loyalty",      multi_items("CUSL", 1:3), weights = mode_B)
)

Define a structural (inner) model for our PLS-PM:

mobi_sm <- relationships(
  paths(from = c("Expectation","Quality"),  to = "Satisfaction"),
  paths(from = "Satisfaction", to = c("Complaints", "Loyalty"))
)

Estimate full model using PLS-PM and bootstrap it for confidence intervals:

pls_model <- estimate_pls(
  data = mobi,
  measurement_model = mobi_mm,
  structural_model = mobi_sm
)

summary(pls_model)

# Use multi-core parallel processing to speed up bootstraps
boot_estimates <- bootstrap_model(pls_model, nboot = 1000, cores = 2)
summary(boot_estimates)

Plotting the model results

SEMinR can plot all supported models using the dot language and the graphViz.js widget from the DiagrammeR package.

# generate a small model for creating the plot
mobi_mm <- constructs(
  composite("Image",        multi_items("IMAG", 1:3)),
  composite("Value",        multi_items("PERV", 1:2)),
  higher_composite("Satisfaction", dimensions = c("Image","Value"), method = two_stage),
  composite("Quality",      multi_items("PERQ", 1:3), weights = mode_B),
  composite("Complaints",   single_item("CUSCO")),
  reflective("Loyalty",      multi_items("CUSL", 1:3))
)
mobi_sm <- relationships(
  paths(from = c("Quality"),  to = "Satisfaction"),
  paths(from = "Satisfaction", to = c("Complaints", "Loyalty"))
)
pls_model <- estimate_pls(
  data = mobi,
  measurement_model = mobi_mm,
  structural_model = mobi_sm
)
#> Generating the seminr model
#> Generating the seminr model
#> All 250 observations are valid.
#> All 250 observations are valid.
boot_estimates <- bootstrap_model(pls_model, nboot = 100, cores = 1)
#> Bootstrapping model using seminr...
#> SEMinR Model successfully bootstrapped

When we have a model, we can plot it and save the plot to files.

plot(boot_estimates, title = "Bootstrapped Model")
save_plot("myfigure.pdf")

Themes

We can customize the plot using an elaborate theme. Themes can be used for individual plots as a parameter or set as a default. Using the seminr_theme_create() function allows to define different themes.

# Tip: auto complete is your friend in finding all possible themeing options.
thm <- seminr_theme_create(plot.rounding = 2, plot.adj = FALSE, 
                           sm.node.fill = "cadetblue1",
                           mm.node.fill = "lightgray")
# change new default theme - valid until R is restarted
seminr_theme_set(thm)

# the new plot
plot(boot_estimates)

Comparing CBSEM and PLS-PM Example

We can re-estimate a composite PLS-PM model as a common-factor CBSEM. Such a comparison might interest researchers seeking to evaluate how their constructs behave when modeled as composites versus common-factors.

# Define measurements with famliar terms: reflective, multi-item constructs, etc.
measurements <- constructs(
  composite("Image",       multi_items("IMAG", 1:5)),
  composite("Expectation", multi_items("CUEX", 1:3)),
  composite("Loyalty",     multi_items("CUSL", 1:3)),
  composite("Complaints",  single_item("CUSCO"))
)

# Create four relationships (two regressions) in one line!
structure <- relationships(
  paths(from = c("Image", "Expectation"), to = c("Complaints", "Loyalty"))
)

# First, estimate the model using PLS
pls_model <- estimate_pls(data = mobi, measurements, structure)

# Reusable parts of the model to estimate CBSEM results
# note: we are using the `as.reflective()` function to convert composites to common factors
cbsem_model <- estimate_cbsem(data = mobi, as.reflective(measurements), structure)

# Re-estimate the model using common factors in Consistent PLS (PLSc)
pls_model <- estimate_pls(data = mobi, as.reflective(measurements), structure)

Documentation

The vignette for Seminr can be found on CRAN or by running the vignette("SEMinR") command after installation.

Demo code for various use cases with SEMinR can be found in the seminr/demo/ folder or by running commands such as demo("seminr-contained") after installation.

Model Specification:

Model Visualization:

Syntax Style:

Sister Projects

  • seminrstudio: A set of addins for RStudio to simplify using SEMinR.

Partner Projects

We communicate and collaborate with several other open-source projects on SEM related issues.

  • plspm package for R: an early and limited PLS path modeling package for R that inspired the development of SEMinR, among others; it is no longer maintained.
  • plspm package for Python: a well-maintained PLS modeling pakage for Python; it is tested against SEMinR and borrows some syntactic ideas from SEMinR.
  • cSEM: a well-maintained and comprehensive composite analysis project implementing PLS and GSCA for R, using Lavaan style syntax

Contact Us

Facebook Group: https://www.facebook.com/groups/seminr

You will find the developers and other users here who might also be able to help or discuss.

Issue Tracker: https://github.com/sem-in-r/seminr/issues

This is the official place to submit potential bugs or request new features for consideration.

About Us

Primary Authors:

Key Contributors:

And many thanks to the growing number of folks who have reached out with feature requests, bug reports, and encouragement. You keep us going!

seminr's People

Contributors

nicholasdanks avatar soumyaray avatar sumidu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

seminr's Issues

Bug in bootstrapped interactions with PLSc

#### FIRST MODEL 1 ####
# Creating our measurement model
model1_mm <- constructs(
  reflective("IP", multi_items("X", 1:21)),
  composite("CO", single_item("PECI"), weights = mode_A),
  reflective("Acquiescence", multi_items("AQ", 1:3)),
  reflective("Compromise", multi_items("COMP", 1:3)),
  reflective("Avoid", multi_items("AVO", 1:3)),
  reflective("Defy", multi_items("DEF", 1:4)),
  reflective("Manipulate", multi_items("MAN", 1:3)),
  reflective("Control", single_item("Control_Var_2"))
  )
# Interaction constructs must be created after the measurement model is defined.
# We are using the orthogonalization method as per Henseler & Chin (2010)
model1_xm <- interactions(
  interaction_ortho("IP", "CO"))
# Structural model
#  note: interactions should be the names of its main constructs joined by a '*' in between.
model1_sm <- relationships(
  paths(from = "IP", to = c("Acquiescence", "Compromise", "Avoid", "Defy", "Manipulate")),
  paths(from = "CO", to = c("Acquiescence", "Compromise", "Avoid", "Defy", "Manipulate")),
  paths(from = "Control", to = c("Acquiescence", "Compromise", "Avoid", "Defy", "Manipulate")),
  paths(from = "IP*CO", to = c("Acquiescence", "Compromise", "Avoid", "Defy", "Manipulate")))
# Load data, assemble model, and estimate using simplePLS
model1_pls <- estimate_pls(data = data,
                         measurement_model = model1_mm,
                         interactions = model1_xm,
                         structural_model = model1_sm,
                         inner_weights = path_weighting)

Gives this error

Generating the seminr model
All 96 observations are valid.
Error in mm[mm[, "construct"] == construct2, ][, "measurement"] :
incorrect number of dimensions

this is my names(data)

names(data)
  [1] "Response_ID"      "IP_Address"       "Timestamp"        "Duplicate"        "Time_Taken"      
  [6] "Seq_Number"       "Country_Code"     "Region"           "Response_Status"  "Browser"         
 [11] "Device"           "Operating_System" "Language"         "Q45"              "Qualificadora"   
 [16] "X1"               "X2"               "X3"               "X4"               "X5"              
 [21] "X6"               "X7"               "X8"               "X9"               "X10"             
 [26] "X11"              "X12"              "X13"              "X14"              "X15"             
 [31] "X16"              "X17"              "X18"              "X19"              "X20"             
 [36] "X21"              "AQ1"              "AQ2"              "AQ3"              "COMP1"           
 [41] "COMP2"            "COMP3"            "AVO1"             "AVO2"             "AVO3"            
 [46] "DEF1"             "DEF2"             "DEF3"             "DEF4"             "MAN1"            
 [51] "MAN2"             "MAN3"             "X38"              "X39"              "X40"             
 [56] "X41"              "X42"              "X43"              "X44"              "X45"             
 [61] "X46"              "X47"              "X48"              "X49"              "X50"             
 [66] "X51"              "X52"              "X53"              "X54"              "X55"             
 [71] "X56"              "X57"              "X58"              "X59"              "X60"             
 [76] "X61"              "X62"              "X63"              "X64"              "X65"             
 [81] "X66"              "X67"              "X68"              "X69"              "X70"             
 [86] "X71"              "X72"              "X73"              "X74"              "X75"             
 [91] "X76"              "X77"              "X78"              "X79"              "X80"             
 [96] "X81"              "X82"              "Priority_Time"    "Priority_Cost"    "Priority_Scope"  
[101] "Control_Var_1"    "Control_Var_2"    "Control_Var_3"    "Opinion_Survey"   "PECI"  

interaction warning for PLSc adjustment

Following warning shows up even if model does not include reflective constructs:

Models with interactions cannot be estimated as PLS consistent
and therefore no adjustment for PLS consistent has been made
For a PLS consistent simple interaction model please refer to PLSc_interact() function

Example: run demo/seminr_contained.R

Should only show up for models with reflective constructs involved in interactions

Update code syntax

Change the syntax for interacting with SEMinR such that:

  • the interactions() function and syntax is deprecated
  • new construct types are created:
  • interaction
  • higher_composite
  • two_stage default for both new constructs
  • instead of a matrix constructs() returns a named list
  • create a print.measurement_model() S3 method to convert named list to matrix for ease of reading

Eg. of code:

mobi_mm <- constructs(
  composite("Image",        multi_items("IMAG", 1:5)),
  composite("Expectation",  multi_items("CUEX", 1:3)),
  composite("Value",        multi_items("PERV", 1:2)),
  composite("Satisfaction", multi_items("CUSA", 1:3)),
  interaction("Image*Expectation", dimensions = c("Image","Satisfaction"), method = two_stage, weights = mode_A),
  interaction("Image*Expectation", dimensions = c("Image","Satisfaction"), method = ortho, weights = mode_A),
  interaction("Image*Expectation", dimensions = c("Image","Satisfaction"), method = scaled, weights = mode_A),
  higher_composite("Value", dimensions = c("Image","Satisfaction"), method = two_stage, weights = mode_A)
)

in rhoC_AVE() error in if_else()

} else {
dgr[i,1] <- NA
dgr[i,2] <- sum(x^2)/length(x)

should be:

ind <- which(x!=0)
x <- x[ind]
dgr[i,1] <- NA
dgr[i,2] <- sum(x^2)/length(x)

Bootstrapping fails for certain model+data: "2 nodes produced errors; first error: system is computationally singular"

User has reported one combination of model+data that causes bootstrapping to fail for nboot >= 300. Contact @soumyaray for example of model+data

I was able to reproduce the error the user reported during repeated bootstrapping tests:

> boot_test_pls <- bootstrap_model(seminr_model = cm_pls, nboot = 400)
Bootstrapping model using seminr...
Bootstrapping encountered this ERROR: 
2 nodes produced errors; first error: system is computationally singular: reciprocal condition number = 0

On rare occasions, I also encountered:

> boot_test_pls <- bootstrap_model(seminr_model = cm_pls, nboot = 400)
Bootstrapping model using seminr...
Bootstrapping encountered this ERROR: 
one node produced an error: missing value where TRUE/FALSE needed

Error does not seem to occur for nboot=100, but rather for nboot=300 or 400

Setting bootstrapping seed (e.g., set.seed(42)) seems to resolve the issue, which leads me to suspect that there are problematic resamples involved.

We have to find a particular resample that causes the problem and identify what is going wrong. If it is truly the fault of the resampled data, we might consider disposing of bad resamples.

Create basic tests

Use demo scripts for scenarios

  • pick simplest demo scenario
  • run demo by hand first, save results in file
  • create first tests to run scenario, check no errors
  • create first tests to run scenario, compare with results

return object naming

in estimate_pls() return object change name of interactions from "mobi_xm" to "interactions"

Reporting correct metrics for correct constructs

Composites:

  • Weights, bootstrap significance, conf interval
  • VIF for items -> construct
  • Sat model SRMR < HI95 quantile

Factors

  • loadings > 0.7
  • rhoA > 0.7 and < 0.95
  • AVE > 0.5
  • Fornell Larcker
  • HTMT < 0.9 OR 0.85 (conservative)
  • Bootstrapped HTMT significantly != 1
  • Sat model SRMR < HI95 quantile

Remove summary scores of common factors

Leave scores in seminr_model object, but remove them from seminr_model_summary

  • For seminr_model_summary, call the scores object: composite_scores
  • Add example to vignette (expressly tell them that common factors do not have determinable scores)

Bootstrap added functions

  • Add bootstrap functionality for weights
  • Add bootstrap functionality for loadings
  • Add bootstrap functionality for htmt
  • Change students bootstrap to BCa bootstrap

minor fixes: renaming and restructuring

  • ltVariables —> construct_names

  • mimic folders in R/ with filenames:

    • estimate_*.R
    • assess_*.R
    • compute_metrics.R (specific stats formula will be performed here)
  • duplicate rho_a (evaluation.R) and rhoA (reliability.R)

  • remove "SEMinR" title from README.md — the logo suffices as the title

  • add TravisCI badge (build passing) to README.md

  • should TravisCI badge link to Travis build page?

  • change interaction item names from con1.con2 to con1*con2

compute_vif() function bug

compute_vif() function cannot handle construct names with a space. eg "Intention Purchase" is not accepted, but "IntentionPurchase" is accepted.
This bug arises from the use of paste() in the formula for lm

compute_vif <- function(target, predictors, model_data) {
  independents_regr <- stats::lm(paste(target," ~."),
                                 data = as.data.frame(model_data[,predictors]))

  r_squared <- summary(independents_regr)$r.squared
  1/(1 - r_squared)
}

Add a test for constructs with spaces in name

rhoC_AVE "x not defined"

function rhoC_AVE has problem here:

    if(measure_mode(i,seminr_model$mmMatrix)=="B"| measure_mode(i,seminr_model$mmMatrix)=="A"){
      x <- seminr_model$outer_loadings[, i]
      ind <- which(x!=0)
      if(length(ind)==1){
        dgr[i,1:2] <- 1
      } else {
       x <- x[ind]
       dgr[i,1] <- sum(x)^2 / (sum(x)^2 + sum(1-x^2))
       dgr[i,2] <- sum(x^2)/length(x)
      }
    } else {
      dgr[i,1] <- N/A
      dgr[i,2] <- sum(x^2)/length(x)
    }

x is defined in if clause but also used in the else clause. this causes it to crash with error if the else clause is reached.

Bootstrap indirect effects for mediation tests.

  • Modify bootstrap_model() method to include indirect effects
  • ??? Modify bootstrap_model method to include total effects
  • Cite Zhao et al (2010)
  • Use Zhao et al (2010) to make conclusion about mediation?
  • Do we need to bootstrap total effects?

Error in bootstrap_model()

  • catch the warnings automatically created by parallel() when the cluster was not closed properly (usually by an error in the previous call on bootstrap_model() which opened the cluster, but failed to close it.
  • consider some type of error handling that automatically closes the cluster when bootstrap_model() hits an error and stops running the code prior to closing the cluster.

Structural model must use every construct of measurement model

It seems our structural model must use every item of our measurement model — must this be the case? It would be nice to create many different structural models from a single measurement model.

E.g.:

library(seminr)

mobi_mm <- constructs(
  composite("Image",        multi_items("IMAG", 1:5)),
  composite("Expectation",  multi_items("CUEX", 1:3)),
  composite("Quality",      multi_items("PERQ", 1:7)),
  composite("Value",        multi_items("PERV", 1:2)),
  composite("Satisfaction", multi_items("CUSA", 1:3)),
  composite("Complaints",   single_item("CUSCO")),
  composite("Loyalty",      multi_items("CUSL", 1:3))
)

antecedents <- c("Image", "Expectation", "Quality")
mediators <- c("Satisfaction", "Value")
outcomes <- c("Loyalty", "Complaints")

non_mediated_sm <- relationships(
  paths(from = antecedents, to = outcomes)
)

mobi_pls <- estimate_pls(data = mobi,
                         measurement_model = mobi_mm,
                         structural_model = non_mediated_sm)

estimate_pls() reports:

Error in warning_struc_meas_model_complete(structural_model, measurement_model,  : 
  The manifest variables must occur as columns in the data.

Multi-group analysis

Able to generate hypotheses testing for multi-group analysis (MGA) including measurement invariance as prerequisite for doing MGA

Create file of published references

A file of published references that we can refer to specific publications for warnings, etc.

Filename: REFERENCES.yaml / .md

Perhaps some Yaml/md format as:

---
- code: [short code here]
  ref: [full academic reference here]
  cite: [preferred citation format]
- code: [short code here]
  ref: [full academic reference here]
  cite: [preferred citation format]

Explicitly define dependencies in DESCRIPTION

An issue to help install 'seminr' package.

install.packages('seminr', dependencies=TRUE, type="source")

perhaps SEMinR's DESCRIPTION file needs the Depends: … line to include parallel or any other packages needed. instead of Imports: ...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.