> ## Documentation Index
> Fetch the complete documentation index at: https://doc.lucidworks.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Logistic Regression Classifier Training Jobs

export const schema = {
  "type": "object",
  "title": "Logistic Regression Classifier Training (deprecated)",
  "description": "Trains a logistic regression model to classify text into labeled groups using Spark. Reads labeled data from a Solr collection specified in `trainingCollection`, vectorizes it using the configured field, and stores the resulting model. Deprecated as of Fusion 5.2.0. Use the Classification job instead.",
  "required": ["id", "trainingCollection", "fieldToVectorize", "dataFormat", "trainingLabelField", "type"],
  "properties": {
    "id": {
      "type": "string",
      "title": "Spark Job ID",
      "description": "The ID for this Spark job. Used in the API to reference this job. Allowed characters: a-z, A-Z, dash (-) and underscore (_).",
      "maxLength": 63,
      "pattern": "[a-zA-Z][_\\-a-zA-Z0-9]*[a-zA-Z0-9]?"
    },
    "sparkConfig": {
      "type": "array",
      "title": "Spark Settings",
      "description": "Spark configuration settings.",
      "hints": ["advanced"],
      "items": {
        "type": "object",
        "required": ["key"],
        "properties": {
          "key": {
            "type": "string",
            "title": "Parameter Name"
          },
          "value": {
            "type": "string",
            "title": "Parameter Value"
          }
        }
      }
    },
    "trainingCollection": {
      "type": "string",
      "title": "Training Collection",
      "description": "Specifies the Solr collection that contains labeled training data. For example, a collection named `product_labels` holding documents with a `category` field. The collection must be accessible to the Spark cluster at runtime.",
      "minLength": 1
    },
    "fieldToVectorize": {
      "type": "string",
      "title": "Field to Vectorize",
      "description": "Specifies the Solr field or fields that the job reads text from for vectorization. Combine multiple fields with weights using the format `field1:weight1,field2:weight2`. The job converts this text into numeric vectors used to train the model.",
      "minLength": 1
    },
    "dataFormat": {
      "type": "string",
      "title": "Data format",
      "description": "Specifies the Spark-compatible format of the input training data. Common values include `solr`, `parquet`, and `orc`. Use `solr` when reading directly from a Solr collection.",
      "default": "solr",
      "minLength": 1
    },
    "trainingDataFrameConfigOptions": {
      "type": "object",
      "title": "Dataframe Config Options",
      "description": "Passes additional key-value configuration options to the Spark DataFrame reader at load time. For example, set `zkhost` to override ZooKeeper connection details for Solr. Leave empty to use defaults.",
      "properties": {},
      "additionalProperties": {
        "type": "string"
      },
      "hints": ["advanced"]
    },
    "trainingDataFilterQuery": {
      "type": "string",
      "title": "Training data filter query",
      "description": "Filters the training data loaded from Solr using a Solr query string. For example, use `status:active` to restrict training to active documents only. Applies only when `dataFormat` is `solr`.",
      "default": "*:*",
      "hints": ["advanced"]
    },
    "sparkSQL": {
      "type": "string",
      "title": "Spark SQL filter query",
      "description": "Filters the loaded input DataFrame using a Spark SQL statement before training begins. The input data is registered as a temporary table named `spark_input`. Use `SELECT * FROM spark_input WHERE ...` to apply row-level conditions.",
      "default": "SELECT * from spark_input",
      "hints": ["code/sql", "advanced"]
    },
    "trainingDataSamplingFraction": {
      "type": "number",
      "title": "Training data sampling fraction",
      "description": "Controls the proportion of training data randomly sampled before model training. A value of `1.0` uses all available data. Lower values such as `0.5` use half. Sampling reduces training time but may decrease model accuracy.",
      "default": 1,
      "hints": ["advanced"],
      "maximum": 1,
      "exclusiveMaximum": false
    },
    "randomSeed": {
      "type": "integer",
      "title": "Random seed",
      "description": "Sets the random seed for all pseudorandom operations in this job, including sampling and initialization. Using the same seed across runs produces identical results given the same input. Change this value to obtain different random outcomes.",
      "default": 1234,
      "hints": ["advanced"]
    },
    "outputCollection": {
      "type": "string",
      "title": "Output Collection",
      "description": "Specifies the Solr collection where the job writes model-labeled output documents. If left blank, no output documents are written. Ensure the collection exists before running the job."
    },
    "overwriteOutput": {
      "type": "boolean",
      "title": "Overwrite Output",
      "description": "Controls whether the job overwrites existing documents in the output collection on each run. When `true`, existing output is replaced. When `false`, the job appends to existing data. Set to `false` to preserve previous outputs.",
      "default": true,
      "hints": ["hidden", "advanced"]
    },
    "dataOutputFormat": {
      "type": "string",
      "title": "Data output format",
      "description": "Specifies the Spark-compatible format used when writing job output. Common values are `solr` and `parquet`. Must be compatible with the configured output destination.",
      "default": "solr",
      "hints": ["advanced"],
      "minLength": 1
    },
    "sourceFields": {
      "type": "string",
      "title": "Fields to Load",
      "description": "Restricts which document fields are loaded from the source collection into the Spark DataFrame. Specify field names as a comma-separated string such as `title,body`. If omitted, all fields are loaded.",
      "hints": ["advanced"]
    },
    "partitionCols": {
      "type": "string",
      "title": "Partition fields",
      "description": "Specifies a comma-delimited list of column names used to partition the output DataFrame before writing to non-Solr destinations. For example, `year,month` partitions output by those fields. Has no effect when writing to Solr.",
      "hints": ["advanced"]
    },
    "writeOptions": {
      "type": "array",
      "title": "Write Options",
      "description": "Passes additional key-value options to the Spark writer when writing output to Solr or other destinations. Options vary by format, for example, set `commit_within` for Solr soft commits. Leave empty to use defaults.",
      "hints": ["advanced"],
      "items": {
        "type": "object",
        "required": ["key"],
        "properties": {
          "key": {
            "type": "string",
            "title": "Parameter Name"
          },
          "value": {
            "type": "string",
            "title": "Parameter Value"
          }
        }
      }
    },
    "readOptions": {
      "type": "array",
      "title": "Read Options",
      "description": "Passes additional key-value options to the Spark reader when reading input from Solr or other sources. Options vary by format, for example, set `rows` to control Solr page size. Leave empty to use defaults.",
      "hints": ["advanced"],
      "items": {
        "type": "object",
        "required": ["key"],
        "properties": {
          "key": {
            "type": "string",
            "title": "Parameter Name"
          },
          "value": {
            "type": "string",
            "title": "Parameter Value"
          }
        }
      }
    },
    "modelId": {
      "type": "string",
      "title": "Model ID",
      "description": "Sets the identifier used to store and reference the trained model in the model store. Falls back to the Spark Job ID if not provided. Must be unique within the model store to avoid overwriting existing models.",
      "hints": ["advanced"],
      "minLength": 1
    },
    "analyzerConfig": {
      "type": "string",
      "title": "Lucene Analyzer Schema",
      "description": "Default is `'{ \"analyzers\": [{ \"name\": \"StdTokLowerStop\",\"charFilters\": [ { \"type\": \"htmlstrip\" } ],\"tokenizer\": { \"type\": \"standard\" },\"filters\": [{ \"type\": \"lowercase\" },{ \"type\": \"KStem\" },{ \"type\": \"length\", \"min\": \"2\", \"max\": \"32767\" },{ \"type\": \"fusionstop\", \"ignoreCase\": \"true\", \"format\": \"snowball\", \"words\": \"org/apache/lucene/analysis/snowball/english_stop.txt\" }] }],\"fields\": [{ \"regex\": \".+\", \"analyzer\": \"StdTokLowerStop\" } ]}'`.",
      "default": "{ \"analyzers\": [{ \"name\": \"StdTokLowerStop\",\"charFilters\": [ { \"type\": \"htmlstrip\" } ],\"tokenizer\": { \"type\": \"standard\" },\"filters\": [{ \"type\": \"lowercase\" },{ \"type\": \"KStem\" },{ \"type\": \"length\", \"min\": \"2\", \"max\": \"32767\" },{ \"type\": \"fusionstop\", \"ignoreCase\": \"true\", \"format\": \"snowball\", \"words\": \"org/apache/lucene/analysis/snowball/english_stop.txt\" }] }],\"fields\": [{ \"regex\": \".+\", \"analyzer\": \"StdTokLowerStop\" } ]}",
      "hints": ["advanced", "code/json", "lengthy"]
    },
    "withIdf": {
      "type": "boolean",
      "title": "IDF Weighting",
      "description": "Controls whether the job weights term vectors by inverse document frequency (IDF) during vectorization. When `true`, common terms across many documents receive lower weights. Disable to treat all terms equally regardless of document frequency.",
      "default": true,
      "hints": ["advanced"]
    },
    "w2vDimension": {
      "type": "integer",
      "title": "Word2Vec Dimension",
      "description": "Sets the dimensionality of Word2Vec embeddings used to represent text. Set to a positive integer such as `100` to enable Word2Vec. Set to `0` to disable it and use TF-IDF instead. Higher dimensions capture more semantic detail but require more memory.",
      "default": 0,
      "hints": ["advanced"],
      "minimum": 0,
      "exclusiveMinimum": false
    },
    "w2vWindowSize": {
      "type": "integer",
      "title": "Word2Vec Window Size",
      "description": "Sets the context window size for the Word2Vec model, defining how many surrounding words are considered during training. For example, a value of `5` considers up to 5 words on each side of the target word. Must be at least `3`.",
      "default": 5,
      "hints": ["advanced"],
      "minimum": 3,
      "exclusiveMinimum": false
    },
    "w2vMaxSentenceLength": {
      "type": "integer",
      "title": "Max Word2Vec Sentence Length",
      "description": "Sets the maximum number of words per sentence processed by Word2Vec. Sentences longer than this value are split into chunks of up to `maxSentenceLength` words each. Increase this value for documents with long paragraphs.",
      "default": 1000,
      "hints": ["advanced"],
      "minimum": 3,
      "exclusiveMinimum": false
    },
    "w2vMaxIter": {
      "type": "integer",
      "title": "Max Word2Vec Iterations",
      "description": "Sets the maximum number of training iterations for the Word2Vec model. More iterations may improve embedding quality but increase training time. Stop conditions may end training before this limit is reached.",
      "default": 1,
      "hints": ["advanced"]
    },
    "w2vStepSize": {
      "type": "number",
      "title": "Word2Vec Step Size",
      "description": "Sets the learning rate step size used during Word2Vec optimization. Smaller values such as `0.01` produce more stable but slower convergence. Larger values may cause instability. Change with caution as it affects convergence behavior.",
      "default": 0.025,
      "hints": ["advanced"],
      "minimum": 0.005,
      "exclusiveMinimum": false
    },
    "minDF": {
      "type": "number",
      "title": "Minimum Term Document Frequency",
      "description": "Filters terms that appear in fewer documents than this threshold before vectorization. Values greater than `1.0` specify an absolute document count. Values at or below `1.0` specify a fraction of total documents. Use to remove very rare terms that add noise.",
      "default": 0,
      "hints": ["advanced"]
    },
    "maxDF": {
      "type": "number",
      "title": "Max Term Document Frequency",
      "description": "Filters terms that appear in more documents than this threshold before vectorization. Values greater than `1.0` specify an absolute document count. Values at or below `1.0` specify a fraction. Use to remove near-ubiquitous terms that carry little signal.",
      "default": 1,
      "hints": ["advanced"]
    },
    "norm": {
      "type": "integer",
      "title": "Vector normalization",
      "description": "Applies p-norm normalization to feature vectors before training. Use `2` for standard Euclidean normalization, `1` for L1, or `-1` to disable normalization. Normalization ensures that document length does not skew similarity calculations.",
      "enum": [-1, 0, 1, 2],
      "default": 2,
      "hints": ["advanced"]
    },
    "predictedLabelField": {
      "type": "string",
      "title": "Predicted Label Field",
      "description": "Sets the name of the output field in which the model writes its predicted class label for each document. For example, set to `predicted_category` to store predictions in that field. Ensure no existing field with this name conflicts.",
      "default": "labelPredictedByFusionModel",
      "hints": ["advanced"]
    },
    "serializeAsMleap": {
      "type": "boolean",
      "title": "Serialize as Mleap Bundle",
      "description": "Controls whether the trained model is serialized as an MLeap bundle for use in online scoring pipelines. When `true`, the model is exported in MLeap format. When `false`, a standard Spark model is saved. MLeap bundles are required for real-time prediction stages.",
      "default": true,
      "hints": ["hidden"]
    },
    "minSparkPartitions": {
      "type": "integer",
      "title": "Minimum Number of Spark Partitions",
      "description": "Sets the minimum number of Spark partitions used during the training job. Higher values increase parallelism and can reduce wall-clock time on large datasets. Set at least as high as the number of available executor cores.",
      "default": 200,
      "hints": ["advanced"],
      "minimum": 1,
      "exclusiveMinimum": false
    },
    "stopwordsList": {
      "type": "array",
      "title": "List of stopwords",
      "description": "Lists blob resource references for stopword files used by the Lucene analyzer during tokenization. Each entry points to a `.txt` file in the Fusion blob store. These stopwords are applied before vectorization.",
      "hints": ["readonly", "hidden"],
      "items": {
        "type": "string",
        "minLength": 1,
        "reference": "blob",
        "blobType": "file:spark"
      }
    },
    "overwriteExistingModel": {
      "type": "boolean",
      "title": "Overwrite existing model",
      "description": "Controls whether the job replaces an existing model with the same ID in the model store. When `true`, the existing model is overwritten on each run. Set to `false` to skip training if a model already exists.",
      "default": true,
      "hints": ["advanced"]
    },
    "trainingLabelField": {
      "type": "string",
      "title": "Label Field",
      "description": "Specifies the Solr field that contains the class label for each training document. For example, use `category` if documents are labeled with a product category. This field is required. The job fails if it is absent or empty."
    },
    "gridSearch": {
      "type": "boolean",
      "title": "Grid Search with Cross Validation",
      "description": "Enables grid search with cross-validation to find the best hyperparameter combination. When `true`, the job evaluates multiple parameter configurations and selects the one with the best metric score. Significantly increases training time.",
      "default": false
    },
    "evaluationMetricType": {
      "type": "string",
      "title": "Evaluation Metric Type",
      "description": "Specifies the metric used to evaluate and select the best hyperparameters during grid search. Choose `binary` for two-class problems, `multiclass` for multi-class, `regression` for continuous outputs, or `none` to skip evaluation. Applies only when `gridSearch` is `true`.",
      "enum": ["binary", "multiclass", "regression", "none"],
      "default": "none",
      "hints": ["advanced"]
    },
    "autoBalanceClasses": {
      "type": "boolean",
      "title": "Auto-balance training classes",
      "description": "Controls whether the job balances class sizes by downsampling over-represented classes before training. When `true`, all classes are trimmed to the size of the smallest class. Set to `false` if class imbalance is intentional.",
      "default": true,
      "hints": ["advanced"]
    },
    "minTrainingSamplesPerClass": {
      "type": "integer",
      "title": "Minimum Labeled Class Size",
      "description": "Sets the minimum number of labeled examples required per class for that class to be included in training. Classes with fewer examples than this threshold are excluded or folded into the `Other` class. Increase to ensure meaningful per-class signal.",
      "default": 100,
      "hints": ["advanced"],
      "minimum": 1,
      "exclusiveMinimum": false
    },
    "makeOtherClass": {
      "type": "boolean",
      "title": "Make 'Other' Class",
      "description": "Controls whether documents from classes too small to train on are grouped into a catch-all `Other` class. When `true`, undersized classes contribute to the `Other` category. When `false`, they are excluded from training entirely. Useful when some labels have sparse coverage.",
      "default": true,
      "hints": ["advanced"]
    },
    "otherClassName": {
      "type": "string",
      "title": "'Other' class name",
      "description": "Sets the label assigned to the catch-all class created when `makeOtherClass` is `true`. For example, change to `Uncategorized` if that label is more meaningful in your taxonomy. Must be a non-empty string.",
      "default": "Other",
      "hints": ["advanced"],
      "minLength": 1
    },
    "regularizationWeight": {
      "type": "number",
      "title": "Regularization weight",
      "description": "Sets the L2 regularization lambda when `elasticNetWeight` is `0`, or a combined L1/L2 penalty otherwise. Higher values such as `0.1` reduce overfitting but may underfit on small datasets. Very small values such as `0.00001` apply minimal regularization.",
      "default": 0.01,
      "maximum": 1,
      "exclusiveMaximum": false,
      "minimum": 0.000001,
      "exclusiveMinimum": false
    },
    "elasticNetWeight": {
      "type": "number",
      "title": "Elastic net weight",
      "description": "Controls the mix of L1 and L2 regularization applied during training. A value of `0.0` applies pure L2 (ridge). `1.0` applies pure L1 (lasso). Intermediate values blend both. Use L1-leaning values to encourage sparse feature weights.",
      "default": 0,
      "maximum": 1,
      "exclusiveMaximum": false
    },
    "maxIters": {
      "type": "integer",
      "title": "Maximum number of iterations",
      "description": "Sets the maximum number of optimization iterations before training halts. Training may stop earlier if the convergence criterion is satisfied. Increase this value if the model has not converged after the default number of iterations.",
      "default": 10
    },
    "type": {
      "type": "string",
      "title": "Spark Job Type",
      "enum": ["logistic_regression_classifier_trainer"],
      "default": "logistic_regression_classifier_trainer",
      "hints": ["readonly"]
    }
  },
  "additionalProperties": true,
  "category": "Other",
  "categoryPriority": 1,
  "propertyGroups": [{
    "label": "Input/Output Parameters",
    "properties": ["trainingCollection", "outputCollection", "dataFormat", "trainingDataFilterQuery", "readOptions", "writeOptions", "trainingDataFrameConfigOptions", "trainingDataSamplingFraction", "randomSeed"]
  }, {
    "label": "Field Parameters",
    "properties": ["fieldToVectorize", "sourceFields", "predictedLabelField", "trainingLabelField"]
  }, {
    "label": "Model Tuning Parameters",
    "properties": ["w2vDimension", "w2vWindowSize", "w2vMaxIter", "w2vMaxSentenceLength", "w2vStepSize", "withIdf", "maxDF", "minDF", "norm", "autoBalanceClasses", "evaluationMetricType", "minTrainingSamplesPerClass", "otherClassName", "makeOtherClass", "gridSearch", "elasticNetWeight", "maxIters", "regularizationWeight"]
  }, {
    "label": "Featurization Parameters",
    "properties": ["analyzerConfig"]
  }, {
    "label": "Misc. Parameters",
    "properties": ["modelId"]
  }]
};

export const SchemaParamFields = ({schema}) => {
  const sanitize = str => {
    if (typeof str !== "string") return str;
    return str.replace(/^"(.*)"$/s, "$1").replace(/\\/g, "").replace(/"/g, "'");
  };
  const renderMd = str => {
    const s = sanitize(str);
    const text = (/[.!?]\)*$/).test(s) ? s : `${s}.`;
    return text.split(/(\*\*[^*]+\*\*|_[^_]+_|`[^`]+`)/g).map((part, i) => {
      if (part.startsWith("**")) return <strong key={i}>{part.slice(2, -2)}</strong>;
      if (part.startsWith("_")) return <em key={i}>{part.slice(1, -1)}</em>;
      if (part.startsWith("`")) return <code key={i}>{part.slice(1, -1)}</code>;
      return part;
    });
  };
  const {description, properties = {}, required: requiredProps = []} = schema;
  const visibleProps = useMemo(() => Object.entries(properties).filter(([, prop]) => !prop.hints?.includes("hidden")), [properties]);
  const renderProp = ([name, prop]) => {
    const isRequired = requiredProps.includes(name);
    const hasDefault = prop.default !== undefined;
    const rawDefault = prop.default;
    const hints = prop.hints || [];
    const isComplexDefault = hasDefault && (typeof rawDefault === "object" || typeof rawDefault === "string" && (rawDefault.length > 20 || rawDefault.includes('"')));
    const postBadges = [];
    if (prop.title) {
      postBadges.push(<><span className="text-stone-400 dark:text-stone-500">API property: </span>{name}</>);
    }
    const constraints = [];
    if (prop.minimum !== undefined && prop.maximum !== undefined) {
      constraints.push(`Range: ${prop.minimum} – ${prop.maximum}`);
    } else if (prop.minimum !== undefined) {
      constraints.push(`Min: ${prop.minimum}`);
    } else if (prop.maximum !== undefined) {
      constraints.push(`Max: ${prop.maximum}`);
    }
    if (prop.minLength !== undefined && prop.maxLength !== undefined) {
      constraints.push(`Length: ${prop.minLength} – ${prop.maxLength}`);
    } else if (prop.minLength !== undefined) {
      constraints.push(`Min length: ${prop.minLength}`);
    } else if (prop.maxLength !== undefined) {
      constraints.push(`Max length: ${prop.maxLength}`);
    }
    const fieldProps = {
      key: name,
      body: prop.title || name,
      type: prop.type,
      ...postBadges.length > 0 && ({
        post: postBadges
      }),
      ...isRequired && ({
        required: true
      }),
      ...!isComplexDefault && hasDefault ? {
        default: sanitize(String(rawDefault))
      } : {}
    };
    const isObject = prop.type === "object" && prop.properties;
    const isArrayOfObjects = prop.type === "array" && prop.items?.type === "object" && prop.items.properties;
    return <ParamField {...fieldProps}>
        {prop.description && <p>{renderMd(prop.description)}</p>}

        {prop.enum && <p>
            Allowed values: 
            {prop.enum.map((v, i) => <>{i > 0 && ", "}<code key={i}>{String(v)}</code></>)}
          </p>}

        {constraints.length > 0 && <p className="text-stone-500 dark:text-stone-400 text-sm">
            {constraints.join(" · ")}
          </p>}

        {isComplexDefault && <div className="flex">
            <p>
              <strong>Default:</strong>
            </p>
            <pre className="!my-0">
              <code>
                {JSON.stringify(rawDefault, null, 2)}
              </code>
            </pre>
          </div>}

        {isArrayOfObjects && <Expandable title="item properties">
            <SchemaParamFields schema={{
      properties: prop.items.properties,
      required: prop.items.required
    }} />
          </Expandable>}

        {isObject && <Expandable title="properties">
            <SchemaParamFields schema={{
      properties: prop.properties,
      required: prop.required
    }} />
          </Expandable>}
      </ParamField>;
  };
  return <div>
      {description && <p>{renderMd(description)}</p>}

      {visibleProps.map(renderProp)}
    </div>;
};

export const LwTemplate = ({title = "Key questions to get you started", icon = "sparkles", cta = "Powered by Agent Studio", linkHref = "https://lucidworks.com/demo/?utm_source=docs&utm_medium=referral&utm_campaign=docs_cta_ai"}) => {
  const [isLoaded, setIsLoaded] = useState(false);
  useEffect(() => {
    const timer = setTimeout(() => {
      setIsLoaded(true);
    }, 500);
    return () => clearTimeout(timer);
  }, []);
  return <div className="lw-template-container">
      <Card title={title} icon={icon}>
        {isLoaded && <span dangerouslySetInnerHTML={{
    __html: `<lw-template id="a029c1a9-28be-427e-b0e1-5d918920246a"></lw-template
            >`
  }} />}
        <Link href={linkHref} className="agent-studio-link text-left text-gray-600 gap-2 dark:text-gray-400 text-sm font-medium flex flex-row items-center hover:text-primary dark:hover:text-primary-light group-hover:text-primary group-hover:dark:text-primary-light">Powered by Lucidworks Agent Studio</Link>
      </Card>
    </div>;
};

[localhost link]: http://localhost:3000/docs/lucidworks-search/09-developer-documentation/config-specs/jobs/logistic-regression-classifier-training

[mintlify link]: https://doc.lucidworks.com/docs/lucidworks-search/09-developer-documentation/config-specs/jobs/logistic-regression-classifier-training

[old doc.lw link]: https://doc.lucidworks.com/managed-fusion/5.9/0yxzwn

Train a regularized logistic regression model for text classification.

<LwTemplate />

## Configuration properties

<SchemaParamFields schema={schema} />
