From 380f64b5781372fc9316ff6269c0ee1c35781bfb Mon Sep 17 00:00:00 2001 From: Xinlan Emily Hu Date: Fri, 20 Dec 2024 15:06:00 -0500 Subject: [PATCH] Small updates to documentation and adding .__version__ parameter (#332) * update examples hierarchy * Closes #318. * provide __version__ variable without setup.py * small fix --------- Co-authored-by: sundy1994 --- docs/build/doctrees/environment.pickle | Bin 335291 -> 335290 bytes docs/build/doctrees/examples.doctree | Bin 172293 -> 172295 bytes docs/build/html/_sources/examples.rst.txt | 38 +++++++-------- docs/build/html/examples.html | 54 +++++++++++----------- docs/build/html/index.html | 2 + docs/source/examples.rst | 38 +++++++-------- pyproject.toml | 6 +-- requirements.txt | 4 +- src/team_comm_tools/__init__.py | 5 +- 9 files changed, 79 insertions(+), 68 deletions(-) diff --git a/docs/build/doctrees/environment.pickle b/docs/build/doctrees/environment.pickle index 73257e4f5430b2ac398dd38708008a7a590030b1..fede4ccd20053f02657dd331f88580059153c503 100644 GIT binary patch delta 22687 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 V7;yg6vR166Dm!g-inWYp{~zbSOh*6! delta 22731 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 E0+)*YZvX%Q delta 15613 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

bE>` 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 b!xsD(!UpmCHp~*H9caVCd*a<4*!lkelQ+!% diff --git a/docs/build/html/_sources/examples.rst.txt b/docs/build/html/_sources/examples.rst.txt index d3c0c97f..e349c7d4 100644 --- a/docs/build/html/_sources/examples.rst.txt +++ b/docs/build/html/_sources/examples.rst.txt @@ -18,8 +18,9 @@ We also have demos available on Google Colab that you can copy and run on your o Finally, this page will walk you through a case study, highlighting top use cases and considerations when using the toolkit. +---------------- Getting Started -================= +---------------- To use our tool, please ensure that you have Python >= 3.10 installed and a working version of `pip `_, which is Python's package installer. Then, in your local environment, run the following: @@ -30,7 +31,7 @@ To use our tool, please ensure that you have Python >= 3.10 installed and a work This command will automatically install our package and all required dependencies. Troubleshooting ------------------ +================ In the event that some dependency installations fail (for example, you may get an error that ``en_core_web_sm`` from Spacy is not found, or that there is a missing NLTK resource), please run this simple one-line command in your terminal, which will force the installation of Spacy and NLTK dependencies: @@ -43,14 +44,14 @@ If you encounter a further issue in which the 'wordnet' package from NLTK is not You can also find a full list of our requirements `here `_. Import Recommendations: Virtual Environment and Pip ------------------------------------------------------ +===================================================== **We strongly recommend using a virtual environment in Python to run the package.** We have several specific dependency requirements. One important one is that we are currently only compatible with numpy < 2.0.0 because `numpy 2.0.0 and above `_ made significant changes that are not compatible with other dependencies of our package. As those dependencies are updated, we will support later versions of numpy. **We also strongly recommend that your version of pip is up-to-date (>=24.0).** There have been reports in which users have had trouble downloading dependencies (specifically, the Spacy package) with older versions of pip. If you get an error with downloading ``en_core_web_sm``, we recommend updating pip. Importing the Package ------------------------ +====================== After you import the package and install dependencies, you can then use our tool in your Python script as follows: @@ -62,13 +63,14 @@ Now you have access to the :ref:`feature_builder`. This is the main class that y *Note*: PyPI treats hyphens and underscores equally, so "pip install team_comm_tools" and "pip install team-comm-tools" are equivalent. However, Python does NOT treat them equally, and **you should use underscores when you import the package, like this: from team_comm_tools import FeatureBuilder**. +------------------------------------------------------- Walkthrough: Running the FeatureBuilder on Your Data -======================================================= +------------------------------------------------------- Next, we'll go through the details of running the FeatureBuilder on your data, discussing each of the specific options / parameters at your disposal. Configuring the FeatureBuilder --------------------------------- +================================ The FeatureBuilder accepts any Pandas DataFrame as the input, so you can read in data in whatever format you like. For the purposes of this walkthrough, we'll be using some jury deliberation data from `Hu et al. (2021) `_. @@ -97,10 +99,10 @@ Now we are ready to call the FeatureBuilder on our data. All we need to do is de jury_feature_builder.featurize() Basic Input Columns -~~~~~~~~~~~~~~~~~~~~ +--------------------- Conversation Parameters -************************** +~~~~~~~~~~~~~~~~~~~~~~~~~ * The **input_df** parameter is where you pass in your dataframe. In this case, we want to run the FeatureBuilder on the juries data that we read in! @@ -206,19 +208,19 @@ Turns Advanced Configuration Columns -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------- More advanced users of the FeatureBuilder should consider the following optional parameters, depending on their needs. Regenerating Vector Cache -*************************** +~~~~~~~~~~~~~~~~~~~~~~~~~~ * The **regenerate_vectors** parameter controls whether you'd like the FeatureBuilder to re-generate the content in the **vector_directory**, even if we have already cached the output of a previous run. It is useful if the underlying data has changed, but you want to give the output file the same name as a previous run of the FeatureBuilder. * By default, **we assume that, if your output file is named the same, that the underlying vectors are the same**. If this isn't true, you should set **regenerate_vectors = True** in order to clear out the cache and re-generate the RoBERTa and SBERT outputs. Custom Features -***************** +~~~~~~~~~~~~~~~~~ * The **custom_features** parameter allows you to specify features that do not exist within our default set. **We default to NOT generating four features that depend on SBERT vectors, as the process for generating the vectors tends to be slow.** However, these features can provide interesting insights into the extent to which individuals in a conversation speak "similarly" or not, based on a vector similarity metric. To access these features, simply use the **custom_features** parameter: @@ -234,7 +236,7 @@ Custom Features * You can chose to add any of these features depending on your preference. Analyzing First Percentage (%) -******************************** +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * The **analyze_first_pct** parameter allows you to "cut off" and separately analyze the first X% of a conversation, in case you wish to separately study different sections of a conversation as it progresses. For example, you may be interested in knowing how the attributes of the first 50% of a conversation differ from the attributes of the entire conversation. Then you can sepcify the following: @@ -247,14 +249,14 @@ Analyzing First Percentage (%) * By default, we will simply analyze 100% of each conversation. Named Entity Recognition -************************** +~~~~~~~~~~~~~~~~~~~~~~~~~~ * The parameters **ner_training_df** and **ner_cutoff** are required if you would like the FeatureBuilder to identify named entities in your conversations. For example, the sentence, "John, did you talk to Michael this morning?" has two named entities: "John" and "Michael." The FeatureBuilder includes a tool that automatically detects these named entities, but it requires the user (you!) to specify some training data with examples of the types of named entities you'd like to recognize. This is because proper nouns can take many forms, from standard Western-style names (e.g., "John") to pseudonymous online nicknames (like "littleHorse"). More information about these parameters can be found in :ref:`named_entity_recognition`. .. _custom_aggregation: Custom Aggregation -******************** +~~~~~~~~~~~~~~~~~~~ Imagine that you, as a researcher, are interested in high-level characteristics of the entire conversation (for example, how much is said), but you only have measures at the (lower) level of each individual utterance (for example, the number of words in each message). How would you "aggregate" information from the lower level to the higher level? @@ -317,7 +319,7 @@ The table below summarizes the different types of aggregation, and the ways in w Example Usage of Custom Aggregation Parameters -+++++++++++++++++++++++++++++++++++++++++++++++ +************************************************ To customize aggregation behavior, simply add the following when constructing your FeatureBuilder: @@ -336,14 +338,14 @@ To turn off aggregation, set the following parameters to ``False``. By default, user_aggregation = False Important Notes and Caveats -++++++++++++++++++++++++++++ +***************************** - **[NOTE 1]** Even when aggregation is disabled, totals of words, messages, and characters are still summarized, as these are required for calculating the Gini Coefficient features. - **[NOTE 2]** Be careful when choosing the "sum" aggregation method, as it is not always appropriate to use the "sum" as an aggregation function. While it is a sensible choice for utterance-level attributes that are *countable* (for example, the total number of words, or other lexical wordcounts), it is a less sensible choice for others (for example, it does not make sense to sum sentiment scores for each utterance in a conversation). Consequently, using the "sum" feature will come with an associated warning. - **[NOTE 3]** In addition to aggregating from the utterance (chat) level to the conversation level, we also aggregate from the speaker (user) level to the conversation level, using the same methods specified in ``convo_methods`` to do so. Cumulative Grouping -********************* +~~~~~~~~~~~~~~~~~~~~ * The parameters **cumulative_grouping** and **within_task** address a special case of having multiple conversational identifiers; **they assume that the same team has multiple sequential conversations, and that, in each conversation, they perform one or more separate activities**. This was originally created as a companion to a multi-stage Empirica game (see: ``_). For example, imagine that a team must complete 3 different tasks, each with 3 different subparts. Then we can model this event in terms of 1 team (High level), 3 tasks (Mid level), and 3 subparts per task (Low level). @@ -460,7 +462,7 @@ Here is some example output (for the RoBERTa sentiment feature): 'bert_sentiment_data': True} Feature Column Names -~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~ Once you call **.featurize()**, you can also obtain a convenient list of the feature columns generated by the toolkit: diff --git a/docs/build/html/examples.html b/docs/build/html/examples.html index 0efbca9c..075879bf 100644 --- a/docs/build/html/examples.html +++ b/docs/build/html/examples.html @@ -49,15 +49,17 @@

  • Introduction
  • The Basics (Get Started Here!)
  • Worked Example
      -
    • Demo / Sample Code
        -
      • Getting Started
          -
        • Troubleshooting
        • -
        • Import Recommendations: Virtual Environment and Pip
        • -
        • Importing the Package
        • +
        • Demo / Sample Code
        • +
        • Getting Started
        • -
        • Walkthrough: Running the FeatureBuilder on Your Data
            -
          • Configuring the FeatureBuilder
          • +
          • Walkthrough: Running the FeatureBuilder on Your Data

            Finally, this page will walk you through a case study, highlighting top use cases and considerations when using the toolkit.

            +
            -

            Getting Started

            +

            Getting Started

            To use our tool, please ensure that you have Python >= 3.10 installed and a working version of pip, which is Python’s package installer. Then, in your local environment, run the following:

            pip install team_comm_tools
             

            This command will automatically install our package and all required dependencies.

            -

            Troubleshooting

            +

            Troubleshooting

            In the event that some dependency installations fail (for example, you may get an error that en_core_web_sm from Spacy is not found, or that there is a missing NLTK resource), please run this simple one-line command in your terminal, which will force the installation of Spacy and NLTK dependencies:

            download_resources
             
            @@ -124,12 +127,12 @@

            Troubleshootinghere.

            -

            Import Recommendations: Virtual Environment and Pip

            +

            Import Recommendations: Virtual Environment and Pip

            We strongly recommend using a virtual environment in Python to run the package. We have several specific dependency requirements. One important one is that we are currently only compatible with numpy < 2.0.0 because numpy 2.0.0 and above made significant changes that are not compatible with other dependencies of our package. As those dependencies are updated, we will support later versions of numpy.

            We also strongly recommend that your version of pip is up-to-date (>=24.0). There have been reports in which users have had trouble downloading dependencies (specifically, the Spacy package) with older versions of pip. If you get an error with downloading en_core_web_sm, we recommend updating pip.

            -

            Importing the Package

            +

            Importing the Package

            After you import the package and install dependencies, you can then use our tool in your Python script as follows:

            from team_comm_tools import FeatureBuilder
             
            @@ -139,10 +142,10 @@

            Importing the Package

            -

            Walkthrough: Running the FeatureBuilder on Your Data

            +

            Walkthrough: Running the FeatureBuilder on Your Data

            Next, we’ll go through the details of running the FeatureBuilder on your data, discussing each of the specific options / parameters at your disposal.

            -

            Configuring the FeatureBuilder

            +

            Configuring the FeatureBuilder

            The FeatureBuilder accepts any Pandas DataFrame as the input, so you can read in data in whatever format you like. For the purposes of this walkthrough, we’ll be using some jury deliberation data from Hu et al. (2021).

            We first import Pandas and read in the dataframe:

            import pandas as pd
            @@ -164,9 +167,9 @@ 

            Configuring the FeatureBuilder -
            Basic Input Columns
            +

            Basic Input Columns

            -
            Conversation Parameters
            +
            Conversation Parameters
            • The input_df parameter is where you pass in your dataframe. In this case, we want to run the FeatureBuilder on the juries data that we read in!

            • The speaker_id_col refers to the name of the column containing a unique identifier for each speaker / participant in the conversation. Here, in the data, the name of our columns is called “speaker_nickname.”

              @@ -207,7 +210,6 @@
              Conversation Parameters
            -
            Vector Directory
              @@ -284,11 +286,12 @@
              Turns
            +
            -
            Advanced Configuration Columns
            +

            Advanced Configuration Columns

            More advanced users of the FeatureBuilder should consider the following optional parameters, depending on their needs.

            -
            Regenerating Vector Cache
            +
            Regenerating Vector Cache
            • The regenerate_vectors parameter controls whether you’d like the FeatureBuilder to re-generate the content in the vector_directory, even if we have already cached the output of a previous run. It is useful if the underlying data has changed, but you want to give the output file the same name as a previous run of the FeatureBuilder.

              @@ -300,7 +303,7 @@
              Regenerating Vector Cache -
              Custom Features
              +
              Custom Features
              • The custom_features parameter allows you to specify features that do not exist within our default set. We default to NOT generating four features that depend on SBERT vectors, as the process for generating the vectors tends to be slow. However, these features can provide interesting insights into the extent to which individuals in a conversation speak “similarly” or not, based on a vector similarity metric. To access these features, simply use the custom_features parameter:

                @@ -321,7 +324,7 @@
                Custom Features -
                Analyzing First Percentage (%)
                +
                Analyzing First Percentage (%)
                • The analyze_first_pct parameter allows you to “cut off” and separately analyze the first X% of a conversation, in case you wish to separately study different sections of a conversation as it progresses. For example, you may be interested in knowing how the attributes of the first 50% of a conversation differ from the attributes of the entire conversation. Then you can sepcify the following:

                  @@ -337,13 +340,13 @@
                  Analyzing First Percentage (%) -
                  Named Entity Recognition
                  +
                  Named Entity Recognition
                  • The parameters ner_training_df and ner_cutoff are required if you would like the FeatureBuilder to identify named entities in your conversations. For example, the sentence, “John, did you talk to Michael this morning?” has two named entities: “John” and “Michael.” The FeatureBuilder includes a tool that automatically detects these named entities, but it requires the user (you!) to specify some training data with examples of the types of named entities you’d like to recognize. This is because proper nouns can take many forms, from standard Western-style names (e.g., “John”) to pseudonymous online nicknames (like “littleHorse”). More information about these parameters can be found in Named Entity Recognition.

            -
            Custom Aggregation
            +
            Custom Aggregation

            Imagine that you, as a researcher, are interested in high-level characteristics of the entire conversation (for example, how much is said), but you only have measures at the (lower) level of each individual utterance (for example, the number of words in each message). How would you “aggregate” information from the lower level to the higher level?

            A simple solution is to sum up to the total number of words per utterance, and group by the conversation identifier. Then, you would have the total number of words for the entire conversation. You can imagine doing similar aggregations for other types of statistics — for example, the average number of words, the variance in the number of words, and so on.

            The FeautureBuilder includes built-in functionality to perform aggregations across different levels of analysis. By default, all numeric attributes generated at the utterance (chat) level are aggregated using the functions mean, max, min, and stdev.

            @@ -415,7 +418,7 @@
            Named Entity Recognition -
            Example Usage of Custom Aggregation Parameters
            +
            Example Usage of Custom Aggregation Parameters

            To customize aggregation behavior, simply add the following when constructing your FeatureBuilder:

            convo_methods = ['max', 'median']  # This aggregates ONLY "positive_bert" at the conversation level using max and median.
             convo_columns = ['positive_bert'],
            @@ -430,7 +433,7 @@ 
            Example Usage of Custom Aggregation Parameters -
            Important Notes and Caveats
            +
            Important Notes and Caveats
            • [NOTE 1] Even when aggregation is disabled, totals of words, messages, and characters are still summarized, as these are required for calculating the Gini Coefficient features.

            • [NOTE 2] Be careful when choosing the “sum” aggregation method, as it is not always appropriate to use the “sum” as an aggregation function. While it is a sensible choice for utterance-level attributes that are countable (for example, the total number of words, or other lexical wordcounts), it is a less sensible choice for others (for example, it does not make sense to sum sentiment scores for each utterance in a conversation). Consequently, using the “sum” feature will come with an associated warning.

            • @@ -439,7 +442,7 @@
              Important Notes and Caveats -
              Cumulative Grouping
              +
              Cumulative Grouping
              • The parameters cumulative_grouping and within_task address a special case of having multiple conversational identifiers; they assume that the same team has multiple sequential conversations, and that, in each conversation, they perform one or more separate activities. This was originally created as a companion to a multi-stage Empirica game (see: https://github.com/Watts-Lab/multi-task-empirica). For example, imagine that a team must complete 3 different tasks, each with 3 different subparts. Then we can model this event in terms of 1 team (High level), 3 tasks (Mid level), and 3 subparts per task (Low level).

                @@ -504,7 +507,6 @@
                Cumulative Grouping

                Additional FeatureBuilder Considerations

                Here are some additional design details of the FeatureBuilder that you may wish to keep in mind:

                diff --git a/docs/build/html/index.html b/docs/build/html/index.html index bc64b98c..de04f500 100644 --- a/docs/build/html/index.html +++ b/docs/build/html/index.html @@ -215,6 +215,8 @@

                Table of ContentsWorked Example

              • Features: Technical Documentation
                  diff --git a/docs/source/examples.rst b/docs/source/examples.rst index d3c0c97f..e349c7d4 100644 --- a/docs/source/examples.rst +++ b/docs/source/examples.rst @@ -18,8 +18,9 @@ We also have demos available on Google Colab that you can copy and run on your o Finally, this page will walk you through a case study, highlighting top use cases and considerations when using the toolkit. +---------------- Getting Started -================= +---------------- To use our tool, please ensure that you have Python >= 3.10 installed and a working version of `pip `_, which is Python's package installer. Then, in your local environment, run the following: @@ -30,7 +31,7 @@ To use our tool, please ensure that you have Python >= 3.10 installed and a work This command will automatically install our package and all required dependencies. Troubleshooting ------------------ +================ In the event that some dependency installations fail (for example, you may get an error that ``en_core_web_sm`` from Spacy is not found, or that there is a missing NLTK resource), please run this simple one-line command in your terminal, which will force the installation of Spacy and NLTK dependencies: @@ -43,14 +44,14 @@ If you encounter a further issue in which the 'wordnet' package from NLTK is not You can also find a full list of our requirements `here `_. Import Recommendations: Virtual Environment and Pip ------------------------------------------------------ +===================================================== **We strongly recommend using a virtual environment in Python to run the package.** We have several specific dependency requirements. One important one is that we are currently only compatible with numpy < 2.0.0 because `numpy 2.0.0 and above `_ made significant changes that are not compatible with other dependencies of our package. As those dependencies are updated, we will support later versions of numpy. **We also strongly recommend that your version of pip is up-to-date (>=24.0).** There have been reports in which users have had trouble downloading dependencies (specifically, the Spacy package) with older versions of pip. If you get an error with downloading ``en_core_web_sm``, we recommend updating pip. Importing the Package ------------------------ +====================== After you import the package and install dependencies, you can then use our tool in your Python script as follows: @@ -62,13 +63,14 @@ Now you have access to the :ref:`feature_builder`. This is the main class that y *Note*: PyPI treats hyphens and underscores equally, so "pip install team_comm_tools" and "pip install team-comm-tools" are equivalent. However, Python does NOT treat them equally, and **you should use underscores when you import the package, like this: from team_comm_tools import FeatureBuilder**. +------------------------------------------------------- Walkthrough: Running the FeatureBuilder on Your Data -======================================================= +------------------------------------------------------- Next, we'll go through the details of running the FeatureBuilder on your data, discussing each of the specific options / parameters at your disposal. Configuring the FeatureBuilder --------------------------------- +================================ The FeatureBuilder accepts any Pandas DataFrame as the input, so you can read in data in whatever format you like. For the purposes of this walkthrough, we'll be using some jury deliberation data from `Hu et al. (2021) `_. @@ -97,10 +99,10 @@ Now we are ready to call the FeatureBuilder on our data. All we need to do is de jury_feature_builder.featurize() Basic Input Columns -~~~~~~~~~~~~~~~~~~~~ +--------------------- Conversation Parameters -************************** +~~~~~~~~~~~~~~~~~~~~~~~~~ * The **input_df** parameter is where you pass in your dataframe. In this case, we want to run the FeatureBuilder on the juries data that we read in! @@ -206,19 +208,19 @@ Turns Advanced Configuration Columns -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------- More advanced users of the FeatureBuilder should consider the following optional parameters, depending on their needs. Regenerating Vector Cache -*************************** +~~~~~~~~~~~~~~~~~~~~~~~~~~ * The **regenerate_vectors** parameter controls whether you'd like the FeatureBuilder to re-generate the content in the **vector_directory**, even if we have already cached the output of a previous run. It is useful if the underlying data has changed, but you want to give the output file the same name as a previous run of the FeatureBuilder. * By default, **we assume that, if your output file is named the same, that the underlying vectors are the same**. If this isn't true, you should set **regenerate_vectors = True** in order to clear out the cache and re-generate the RoBERTa and SBERT outputs. Custom Features -***************** +~~~~~~~~~~~~~~~~~ * The **custom_features** parameter allows you to specify features that do not exist within our default set. **We default to NOT generating four features that depend on SBERT vectors, as the process for generating the vectors tends to be slow.** However, these features can provide interesting insights into the extent to which individuals in a conversation speak "similarly" or not, based on a vector similarity metric. To access these features, simply use the **custom_features** parameter: @@ -234,7 +236,7 @@ Custom Features * You can chose to add any of these features depending on your preference. Analyzing First Percentage (%) -******************************** +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * The **analyze_first_pct** parameter allows you to "cut off" and separately analyze the first X% of a conversation, in case you wish to separately study different sections of a conversation as it progresses. For example, you may be interested in knowing how the attributes of the first 50% of a conversation differ from the attributes of the entire conversation. Then you can sepcify the following: @@ -247,14 +249,14 @@ Analyzing First Percentage (%) * By default, we will simply analyze 100% of each conversation. Named Entity Recognition -************************** +~~~~~~~~~~~~~~~~~~~~~~~~~~ * The parameters **ner_training_df** and **ner_cutoff** are required if you would like the FeatureBuilder to identify named entities in your conversations. For example, the sentence, "John, did you talk to Michael this morning?" has two named entities: "John" and "Michael." The FeatureBuilder includes a tool that automatically detects these named entities, but it requires the user (you!) to specify some training data with examples of the types of named entities you'd like to recognize. This is because proper nouns can take many forms, from standard Western-style names (e.g., "John") to pseudonymous online nicknames (like "littleHorse"). More information about these parameters can be found in :ref:`named_entity_recognition`. .. _custom_aggregation: Custom Aggregation -******************** +~~~~~~~~~~~~~~~~~~~ Imagine that you, as a researcher, are interested in high-level characteristics of the entire conversation (for example, how much is said), but you only have measures at the (lower) level of each individual utterance (for example, the number of words in each message). How would you "aggregate" information from the lower level to the higher level? @@ -317,7 +319,7 @@ The table below summarizes the different types of aggregation, and the ways in w Example Usage of Custom Aggregation Parameters -+++++++++++++++++++++++++++++++++++++++++++++++ +************************************************ To customize aggregation behavior, simply add the following when constructing your FeatureBuilder: @@ -336,14 +338,14 @@ To turn off aggregation, set the following parameters to ``False``. By default, user_aggregation = False Important Notes and Caveats -++++++++++++++++++++++++++++ +***************************** - **[NOTE 1]** Even when aggregation is disabled, totals of words, messages, and characters are still summarized, as these are required for calculating the Gini Coefficient features. - **[NOTE 2]** Be careful when choosing the "sum" aggregation method, as it is not always appropriate to use the "sum" as an aggregation function. While it is a sensible choice for utterance-level attributes that are *countable* (for example, the total number of words, or other lexical wordcounts), it is a less sensible choice for others (for example, it does not make sense to sum sentiment scores for each utterance in a conversation). Consequently, using the "sum" feature will come with an associated warning. - **[NOTE 3]** In addition to aggregating from the utterance (chat) level to the conversation level, we also aggregate from the speaker (user) level to the conversation level, using the same methods specified in ``convo_methods`` to do so. Cumulative Grouping -********************* +~~~~~~~~~~~~~~~~~~~~ * The parameters **cumulative_grouping** and **within_task** address a special case of having multiple conversational identifiers; **they assume that the same team has multiple sequential conversations, and that, in each conversation, they perform one or more separate activities**. This was originally created as a companion to a multi-stage Empirica game (see: ``_). For example, imagine that a team must complete 3 different tasks, each with 3 different subparts. Then we can model this event in terms of 1 team (High level), 3 tasks (Mid level), and 3 subparts per task (Low level). @@ -460,7 +462,7 @@ Here is some example output (for the RoBERTa sentiment feature): 'bert_sentiment_data': True} Feature Column Names -~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~ Once you call **.featurize()**, you can also obtain a convenient list of the feature columns generated by the toolkit: diff --git a/pyproject.toml b/pyproject.toml index 7a8ab6a4..a4cb44e8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [build-system] requires = [ - "setuptools >= 42", "wheel" + "setuptools >= 42", "wheel", "toml" ] build-backend = "setuptools.build_meta" @@ -13,6 +13,7 @@ dependencies = [ "convokit==3.0.0", "emoji==1.7.0", "flask==3.0.3", + "fuzzywuzzy==0.18.0", "gensim>=4.3.3", "matplotlib>=3.0.0", "nltk==3.9.1", @@ -39,8 +40,7 @@ dependencies = [ "transformers==4.44.0", "tqdm>=4.66.5", "tzdata>=2023.3", - "tzlocal==5.2", - "fuzzywuzzy==0.18.0" + "tzlocal==5.2" ] authors = [ {name = "Xinlan Emily Hu", email = "xehu@wharton.upenn.edu"}, diff --git a/requirements.txt b/requirements.txt index c99c5fdd..f2593f54 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,6 +2,7 @@ chardet>=3.0.4 convokit==3.0.0 emoji==1.7.0 flask==3.0.3 +fuzzywuzzy==0.18.0 gensim>=4.3.3 matplotlib>=3.0.0 nltk==3.9.1 @@ -28,5 +29,4 @@ torchvision==0.19.1 transformers==4.44.0 tqdm>=4.66.5 tzdata>=2023.3 -tzlocal==5.2 -fuzzywuzzy==0.18.0 \ No newline at end of file +tzlocal==5.2 \ No newline at end of file diff --git a/src/team_comm_tools/__init__.py b/src/team_comm_tools/__init__.py index ab0556ea..0ad8d062 100644 --- a/src/team_comm_tools/__init__.py +++ b/src/team_comm_tools/__init__.py @@ -1 +1,4 @@ -from .feature_builder import FeatureBuilder \ No newline at end of file +from .feature_builder import FeatureBuilder +from importlib.metadata import version as get_version + +__version__ = get_version("team_comm_tools") \ No newline at end of file