plspm

A Python 3 implementation of the Partial Least Squares Path Modeling (PLS-PM) algorithm.

https://github.com/googlecloudplatform/plspm-python

Science Score: 13.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
  • DOI references
  • Academic publication links
  • Committers with academic emails
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (14.9%) to scientific vocabulary
Last synced: 11 months ago · JSON representation

Repository

A Python 3 implementation of the Partial Least Squares Path Modeling (PLS-PM) algorithm.

Basic Info
  • Host: GitHub
  • Owner: GoogleCloudPlatform
  • License: gpl-3.0
  • Language: Python
  • Default Branch: trunk
  • Homepage: https://plspm.readthedocs.io/
  • Size: 232 KB
Statistics
  • Stars: 47
  • Watchers: 31
  • Forks: 15
  • Open Issues: 5
  • Releases: 15
Created over 7 years ago · Last pushed about 2 years ago
Metadata Files
Readme Contributing License

README.md

PLSPM: A library implementing Partial Least Squares Path Modeling PyPI version

Please note: This is not an officially supported Google product.

plspm is a Python 3 package dedicated to Partial Least Squares Path Modeling (PLS-PM) analysis. It is a port of the R package plspm, with additional features adopted from the R package seminr

PLSPM (partial least squares path modeling) is a correlation-based structural equation modeling (SEM) algorithm. It allows for estimation of complex cause-effect or prediction models using latent/manifest variables.

PLSPM may be preferred to other SEM methods for several reasons: it is a method that is appropriate for exploratory research, can be used with small-to-medium sample sizes (as well as large data sets), and does not require assumptions of multivariate normality. (See Hulland, J. (1999). Use of partial least squares (PLS) in strategic management research: a review of four recent studies. Strategic management journal, 20(2), 195-204.) In contrast to covariance-based SEM (CBSEM), goodness of fit is less important, because the purpose of the algorithm is to optimize for prediction of the dependent variable vs. fit of data to a predetermined model. (See "goodness of fit" vs "goodness of model" in Chin, W. W. (2010). How to write up and report PLS analyses. In Handbook of partial least squares (pp. 655-690). Springer, Berlin, Heidelberg.)

Features

  • Uses variance-based PLS esimation to model composite constructs using Mode A and Mode B
  • Uses a natural-feeling, domain specific language to build and estimate structural equation models, including second-order constructs
  • Supports centroid, factorial, and path schemes
  • Supports metric and non-metric numerical data (including nominal and ordinal)
  • Handles missing data
  • Bootstrapping with multi-core support
  • Tested against seminr, which is, in turn, tested against SmartPLS (Ringle et al., 2015) and ADANCO (Henseler and Dijkstra, 2015), as well as other R packages such as semPLS (Monecke and Leisch, 2012) and matrixpls (Rönkkö, 2016).

Planned but not yet implemented

  • Native modeling of moderation
  • Improved assessment measures such as HTMT, VIF, f^2, Q^2, and q^2
  • Modeling formative constructs using the PLS consistent (PLSc) algorithm

Installation

You can install the latest version of this package using pip:

sh python3 -m pip install --user plspm

It's hosted on pypi: https://pypi.org/project/plspm/

Use

plspm expects to get a Pandas DataFrame containing your data. You start by creating a Config object with the details of the model, and then pass it, along with the data and optionally some further configuration, to an instance of Plspm. Use the examples below to get started, or browse the documentation (start with Config and Plspm)

Examples

PLS-PM with metric data

Typical example with a Customer Satisfaction Model

```py

!/usr/bin/env python3

import pandas as pd, plspm.config as c from plspm.plspm import Plspm from plspm.scheme import Scheme from plspm.mode import Mode

satisfaction = pd.readcsv("file:tests/data/satisfaction.csv", indexcol=0)

structure = c.Structure() structure.addpath(["IMAG"], ["EXPE", "SAT", "LOY"]) structure.addpath(["EXPE"], ["QUAL", "VAL", "SAT"]) structure.addpath(["QUAL"], ["VAL", "SAT"]) structure.addpath(["VAL"], ["SAT"]) structure.add_path(["SAT"], ["LOY"])

config = c.Config(structure.path(), scaled=False) config.addlvwithcolumnsnamed("IMAG", Mode.A, satisfaction, "imag") config.addlvwithcolumnsnamed("EXPE", Mode.A, satisfaction, "expe") config.addlvwithcolumnsnamed("QUAL", Mode.A, satisfaction, "qual") config.addlvwithcolumnsnamed("VAL", Mode.A, satisfaction, "val") config.addlvwithcolumnsnamed("SAT", Mode.A, satisfaction, "sat") config.addlvwithcolumnsnamed("LOY", Mode.A, satisfaction, "loy")

plspmcalc = Plspm(satisfaction, config, Scheme.CENTROID) print(plspmcalc.innersummary()) print(plspmcalc.path_coefficients()) ```

This will produce the output: ``` type rsquared blockcommunality mean_redundancy ave EXPE Endogenous 0.335194 0.616420 0.206620 0.616420 IMAG Exogenous 0.000000 0.582269 0.000000 0.582269 LOY Endogenous 0.509923 0.639052 0.325867 0.639052 QUAL Endogenous 0.719688 0.658572 0.473966 0.658572 SAT Endogenous 0.707321 0.758891 0.536779 0.758891 VAL Endogenous 0.590084 0.664416 0.392061 0.664416

      IMAG      EXPE      QUAL       VAL       SAT  LOY

IMAG 0.000000 0.000000 0.000000 0.000000 0.000000 0 EXPE 0.578959 0.000000 0.000000 0.000000 0.000000 0 QUAL 0.000000 0.848344 0.000000 0.000000 0.000000 0 VAL 0.000000 0.105478 0.676656 0.000000 0.000000 0 SAT 0.200724 -0.002754 0.122145 0.589331 0.000000 0 LOY 0.275150 0.000000 0.000000 0.000000 0.495479 0 ```

Specifying higher-order constructs

Example using seminr's mobile industry data set:

```py mobi = pd.readcsv("file:tests/data/mobi.csv", indexcol=0)

structure = c.Structure() structure.addpath(["Expectation", "Quality"], ["Satisfaction"]) structure.addpath(["Satisfaction"], ["Complaints", "Loyalty"])

config = c.Config(structure.path(), defaultscale=Scale.NUM) config.addhigherorder("Satisfaction", Mode.A, ["Image", "Value"]) config.addlvwithcolumnsnamed("Expectation", Mode.A, mobi, "CUEX") config.addlvwithcolumnsnamed("Quality", Mode.B, mobi, "PERQ") config.addlvwithcolumnsnamed("Loyalty", Mode.A, mobi, "CUSL") config.addlvwithcolumnsnamed("Image", Mode.A, mobi, "IMAG") config.addlvwithcolumnsnamed("Complaints", Mode.A, mobi, "CUSCO") config.addlvwithcolumns_named("Value", Mode.A, mobi, "PERV")

mobi_pls = Plspm(mobi, config, Scheme.PATH, 100, 0.00000001)

print(plspmcalc.innermodel()) ```

This will produce the output: from to estimate std error t p>|t| index Quality -> Satisfaction Quality Satisfaction 0.743041 0.046318 16.042102 3.633866e-40 Expectation -> Satisfaction Expectation Satisfaction 0.089572 0.046318 1.933832 5.427626e-02 Satisfaction -> Loyalty Satisfaction Loyalty 0.627940 0.049420 12.706272 7.996788e-29 Satisfaction -> Complaints Satisfaction Complaints 0.486696 0.055472 8.773752 2.841768e-16

PLS-PM with nonmetric data

Example with the classic Russett data (original data set)

```py

!/usr/bin/env python3

import pandas as pd, plspm.config as c from plspm.plspm import Plspm from plspm.scale import Scale from plspm.scheme import Scheme from plspm.mode import Mode

russa = pd.readcsv("file:tests/data/russa.csv", indexcol=0)

structure = c.Structure() structure.add_path(["AGRI", "IND"], ["POLINS"])

config = c.Config(structure.path(), defaultscale=Scale.NUM) config.addlv("AGRI", Mode.A, c.MV("gini"), c.MV("farm"), c.MV("rent")) config.addlv("IND", Mode.A, c.MV("gnpr"), c.MV("labo")) config.addlv("POLINS", Mode.A, c.MV("ecks"), c.MV("death"), c.MV("demo"), c.MV("inst"))

plspmcalc = Plspm(russa, config, Scheme.CENTROID, 100, 0.0000001) print(plspmcalc.innersummary()) print(plspmcalc.effects()) ```

This will produce the output: ``` type rsquared blockcommunality mean_redundancy ave AGRI Exogenous 0.000000 0.739560 0.000000 0.739560 IND Exogenous 0.000000 0.907524 0.000000 0.907524 POLINS Endogenous 0.592258 0.565175 0.334729 0.565175

from to direct indirect total 0 AGRI POLINS 0.225639 0.0 0.225639 1 IND POLINS 0.671457 0.0 0.671457 ```

Example 2: Different Scaling

PLS-PM using data set russa, and different scaling

```py

!/usr/bin/python3

import pandas as pd, plspm.config as c, plspm.util as util from plspm.plspm import Plspm from plspm.scale import Scale from plspm.scheme import Scheme from plspm.mode import Mode

russa = pd.readcsv("file:tests/data/russa.csv", indexcol=0)

structure = c.Structure() structure.addpath(["AGRI", "IND"], ["POLINS"]) config = c.Config(structure.path(), defaultscale=Scale.NUM) config.addlv("AGRI", Mode.A, c.MV("gini"), c.MV("farm"), c.MV("rent")) config.addlv("IND", Mode.A, c.MV("gnpr", Scale.ORD), c.MV("labo", Scale.ORD)) config.add_lv("POLINS", Mode.A, c.MV("ecks"), c.MV("death"), c.MV("demo", Scale.NOM), c.MV("inst"))

plspm_calc = Plspm(russa, config, Scheme.CENTROID, 100, 0.0000001) ```

Example 3: Missing Data

```py

!/usr/bin/env python3

import pandas as pd, plspm.config as c from plspm.plspm import Plspm from plspm.scale import Scale from plspm.scheme import Scheme from plspm.mode import Mode

russa = pd.readcsv("file:tests/data/russa.csv", indexcol=0) russa.iloc[0, 0] = np.NaN russa.iloc[3, 3] = np.NaN russa.iloc[5, 5] = np.NaN

structure = c.Structure() structure.addpath(["AGRI", "IND"], ["POLINS"]) config = c.Config(structure.path(), defaultscale=Scale.NUM) config.addlv("AGRI", Mode.A, c.MV("gini"), c.MV("farm"), c.MV("rent")) config.addlv("IND", Mode.A, c.MV("gnpr"), c.MV("labo")) config.add_lv("POLINS", Mode.A, c.MV("ecks"), c.MV("death"), c.MV("demo"), c.MV("inst"))

plspm_calc = Plspm(russa, config, Scheme.CENTROID, 100, 0.0000001) ```

Maintainers

Jez Humble (humble at google.com)

Nicole Forsgren (nicolefv at github.com)

Owner

  • Name: Google Cloud Platform
  • Login: GoogleCloudPlatform
  • Kind: organization

GitHub Events

Total
  • Issues event: 1
  • Watch event: 2
  • Fork event: 1
Last Year
  • Issues event: 1
  • Watch event: 2
  • Fork event: 1

Committers

Last synced: almost 3 years ago

All Time
  • Total Commits: 117
  • Total Committers: 3
  • Avg Commits per committer: 39.0
  • Development Distribution Score (DDS): 0.239
Past Year
  • Commits: 0
  • Committers: 0
  • Avg Commits per committer: 0.0
  • Development Distribution Score (DDS): 0.0
Top Committers
Name Email Commits
Jez Humble j****z@j****t 89
Jez Humble h****e@g****m 26
nicole n****v@g****m 2
Committer Domains (Top 20 + Academic)

Issues and Pull Requests

Last synced: about 1 year ago

All Time
  • Total issues: 13
  • Total pull requests: 2
  • Average time to close issues: 5 months
  • Average time to close pull requests: 14 days
  • Total issue authors: 12
  • Total pull request authors: 2
  • Average comments per issue: 3.62
  • Average comments per pull request: 0.5
  • Merged pull requests: 1
  • Bot issues: 0
  • Bot pull requests: 0
Past Year
  • Issues: 2
  • Pull requests: 0
  • Average time to close issues: 12 days
  • Average time to close pull requests: N/A
  • Issue authors: 2
  • Pull request authors: 0
  • Average comments per issue: 1.0
  • Average comments per pull request: 0
  • Merged pull requests: 0
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
  • holder-fo (2)
  • jamilous (1)
  • MastersMasterM (1)
  • Olecranon (1)
  • LWackerle (1)
  • TasosR83 (1)
  • skiparmler (1)
  • tsamanh (1)
  • LeonieBorne (1)
  • jezhumble (1)
  • lessapwb (1)
  • DhineshRET (1)
Pull Request Authors
  • jhorzek (2)
  • renovate-bot (1)
Top Labels
Issue Labels
bug (5) enhancement (2) wontfix (1)
Pull Request Labels

Packages

  • Total packages: 1
  • Total downloads:
    • pypi 846 last-month
  • Total dependent packages: 0
  • Total dependent repositories: 1
  • Total versions: 24
  • Total maintainers: 1
pypi.org: plspm

A library implementing the Partial Least Squares Path Model algorithm

  • Versions: 24
  • Dependent Packages: 0
  • Dependent Repositories: 1
  • Downloads: 846 Last month
Rankings
Dependent packages count: 10.0%
Forks count: 10.2%
Downloads: 10.6%
Stargazers count: 11.0%
Average: 12.7%
Dependent repos count: 21.7%
Maintainers (1)
Last synced: 11 months ago

Dependencies

requirements.txt pypi
  • m2r *
  • numpy *
  • pandas *
  • pytest *
  • scikit-learn *
  • scipy *
  • setuptools *
  • sphinx *
  • sphinxcontrib-napoleon *
  • statsmodels *
  • twine *
  • wheel *
setup.py pypi
  • numpy *
  • pandas *
  • scikit-learn *
  • scipy *
  • statsmodels *
docs/requirements.txt pypi
  • m2r *
  • sphinx *
  • sphinx-rtd-theme *