internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: mindsdb/lightwood

Issue:
:wrench: Colored terminal output
## Task

Modify the lightwood [logger class](https://github.com/mindsdb/lightwood/blob/stable/lightwood/helpers/log.py) so that its output is colored, depending on the log level. Color scheme is not set in stone, but should be something that makes sense, e.g.: red for `CRITICAL`, orange for `ERROR`, yellow for `WARNING`, green for `INFO`, uncolored for `DEBUG`.

## Steps :male_detective: :female_detective: 

- Fork the Lightwood repository, checkout the `staging` branch and from it create a new one.
- Implement the necessary changes. The package to achieve colored logging can be chosen as part of the PR, but we suggest using lightweight alternatives like [colored](https://pypi.org/project/colored/) or [termcolor](https://pypi.org/project/termcolor/).
- Check the logs are using the new color scheme. For this, you can run any of the integration tests, like [`test_boston_housing`](https://github.com/mindsdb/lightwood/blob/stable/tests/integration/basic/test_boston_housing.py), and analyze the output.
- Make the PR and address any comments that reviewers might make.

## Additional rewards :1st_place_medal: 

Each documentation PR brings :one:  point for entry into the draw for a :computer:  Deep Learning Laptop powered by the NVIDIA RTX 3080 Max-Q GPU or other swag :shirt: :bear: .  For more info check out https://mindsdb.com/hacktoberfest/


Discussion:
Hi @paxcema,
I would like to work on this issue


Resolving patch:
diff --git a/lightwood/helpers/log.py b/lightwood/helpers/log.py
--- a/lightwood/helpers/log.py
+++ b/lightwood/helpers/log.py
@@ -1,10 +1,15 @@
 import logging
 import os
+import colorlog
 
 
 def initialize_log():
     pid = os.getpid()
-    logging.basicConfig()
+
+    handler = colorlog.StreamHandler()
+    handler.setFormatter(colorlog.ColoredFormatter())
+
+    logging.basicConfig(handlers=[handler])
     log = logging.getLogger(f'lightwood-{pid}')
     log.setLevel(logging.DEBUG)
     return log


Test patch:
Repository: mindsdb/lightwood

Issue:
`Img2VecEncoder` calls `self.prepare` twice
## Your Environment
* Python version: Python 3.8.10
* Operating system: Ubuntu 20.04.3 LTS
* Lightwood version: 1.3.0

## Describe your issue
`Img2VecEncoder` crashes when `.encode(images)` is called.

Internally there seems to be some confusion on what the `.prepare` method actually does.
For some reason it is called to convert images to tensors, while in reality it should be used to initialize the model and (maybe) perform some initial training.

## Fixing the issue

Implement a method to convert images to torch tensors.



Discussion:

Resolving patch:
diff --git a/lightwood/encoder/image/img_2_vec.py b/lightwood/encoder/image/img_2_vec.py
--- a/lightwood/encoder/image/img_2_vec.py
+++ b/lightwood/encoder/image/img_2_vec.py
@@ -3,6 +3,7 @@
 import torchvision.transforms as transforms
 from lightwood.encoder.image.helpers.img_to_vec import Img2Vec
 from lightwood.encoder.base import BaseEncoder
+from PIL import Image
 
 
 class Img2VecEncoder(BaseEncoder):
@@ -10,13 +11,18 @@ class Img2VecEncoder(BaseEncoder):
     def __init__(self, is_target: bool = False):
         super().__init__(is_target)
         self.model = None
-        # I think we should make this an enum, something like: speed, balance, accuracy
-        self.aim = aim
+        # # I think we should make this an enum, something like: speed, balance, accuracy
+        # self.aim = aim
         self._prepared = False
 
-        self._scaler = transforms.Scale((224, 224))
+        self._scaler = transforms.Resize((224, 224))
         self._normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
         self._to_tensor = transforms.ToTensor()
+        self._img_to_tensor = transforms.Compose([
+            self._scaler,
+            self._to_tensor,
+            self._normalize
+        ])
 
         pil_logger = logging.getLogger('PIL')
         pil_logger.setLevel(logging.ERROR)
@@ -39,8 +45,11 @@ def encode(self, images):
         if not self._prepared:
             raise Exception('You need to call "prepare" before calling "encode" or "decode".')
 
-        img_tensors = self.prepare(images)
+        img_tensors = [self._img_to_tensor(
+            Image.open(img_path)
+        ) for img_path in images]
         vec_arr = []
+
         self.model.eval()
         with torch.no_grad():
             for img_tensor in img_tensors:


Test patch:
Repository: mindsdb/lightwood

Issue:
Implement a `predictor_from_json_ai` high level method
## Task

Lightwood aims at offering _declarative machine learning_ capabilities by enabling users to specify _what_ they want their models to learn, without necessarily having to look at the _how_.

A key ingredient for this feature is our intermediate representation called Json AI (a.k.a. _J{ai}son_). The objective behind Json AI is to build Lightwood predictors out of a JSON-like file.

We offer a variety of methods to cover the spectrum of `ProblemDefinition` <-> `Json AI` <-> `Lightwood Predictor`. However, we are currently missing a method to go _directly_ from `Json AI` to a lightwood predictor object. The current approach is:

```python
code = code_from_json_ai(json_ai)
predictor = predictor_from_code(code)
```

In this task, we ask for an implementation of a high level function so that the user is now able to do:

```python
predictor = predictor_from_json_ai(json_ai)
```

## Steps :male_detective: :female_detective: 

- Fork the Lightwood repository, checkout the `staging` branch and from it create a new one.
- Implement the function inside `lightwood/api/high_level.py`. Be sure to add type hints and a comprehensive docstring.
- Make the PR and address any comments that reviewers might make.

## Additional rewards :1st_place_medal: 

Each Lightwood API PR brings 3️⃣ points for entry into the draw for a :computer:  Deep Learning Laptop powered by the NVIDIA RTX 3080 Max-Q GPU or other swag :shirt: :bear: .  For more info check out https://mindsdb.com/hacktoberfest/


Discussion:

Resolving patch:
diff --git a/lightwood/api/high_level.py b/lightwood/api/high_level.py
--- a/lightwood/api/high_level.py
+++ b/lightwood/api/high_level.py
@@ -176,3 +176,16 @@ def _module_from_code(code: str, module_name: str) -> ModuleType:
         spec.loader.exec_module(temp_module)
 
     return temp_module
+
+
+def predictor_from_json_ai(json_ai: JsonAI) -> PredictorInterface:
+    """
+    Creates a ready-to-train ``Predictor`` object based on the details you specified inside your JsonAI.
+
+    :param json_ai: A ``JsonAI`` object
+
+    :returns: A lightwood ``Predictor`` object
+    """  # noqa
+    code = code_from_json_ai(json_ai)
+    predictor = predictor_from_code(code)
+    return predictor


Test patch:
Repository: mindsdb/lightwood

Issue:
Hardcoded `BestOf` ensemble assumption in `calibrate.py`
## What is broken

https://github.com/mindsdb/lightwood/pull/692 fails to run the test suite.

## Why it is broken

The test suite fails because of [this error](https://github.com/mindsdb/lightwood/runs/4015774197?check_suite_focus=true#step:8:19095):

```
Traceback (most recent call last):
  File "/home/andrea/lightwood/tests/integration/basic/test_ensembles.py", line 57, in test_1_mode_ensemble
    predictor.learn(df)
  File "/tmp/f04c77b5ca1ea065bfc13aecd2e23d77ae4c6bc8a26484aa1635322919366192.py", line 389, in learn
    self.analyze_ensemble(enc_train_test)
  File "/tmp/f04c77b5ca1ea065bfc13aecd2e23d77ae4c6bc8a26484aa1635322919366192.py", line 350, in analyze_ensemble
    self.model_analysis, self.runtime_analyzer = model_analyzer(
  File "/home/andrea/lightwood/lightwood/analysis/analyze.py", line 81, in model_analyzer
    runtime_analyzer = block.analyze(runtime_analyzer, **kwargs)
  File "/home/andrea/lightwood/lightwood/analysis/nc/calibrate.py", line 93, in analyze
    icp.nc_function.model.prediction_cache = ns.normal_predictions[all_cat_cols].values
UnboundLocalError: local variable 'all_cat_cols' referenced before assignment
```

After some digging, we se that we are running the following lines:

https://github.com/mindsdb/lightwood/blob/d0e41c846fada1f1bd13f044254ac9c32db7c53d/lightwood/analysis/nc/calibrate.py#L91-L93

But this should not happen with `ModeEnsembler`, since it does not support probabilities.

These lines are being run because instead of checking if the ensemble supports probabilities (`ModeEnsembler` does not), we are checking if `ns.predictor.mixers[ns.predictor.best_index]` does.

This would a valid assumption if we were always using `BestOf` (and if `BestOf` updated `self.best_index`), which up to this point was true.

Also check out this `TODO`:

https://github.com/mindsdb/lightwood/blob/d0e41c846fada1f1bd13f044254ac9c32db7c53d/lightwood/ensemble/base.py#L27

## How to fix it

I propose to change 

`if ns.predictor.mixers[ns.predictor.best_index].supports_proba:`
to
`if ns.predictor.supports_proba:`

and possibly remove `best_index` from the codebase since it currently has no use.


Discussion:

Resolving patch:
diff --git a/lightwood/analysis/nc/calibrate.py b/lightwood/analysis/nc/calibrate.py
--- a/lightwood/analysis/nc/calibrate.py
+++ b/lightwood/analysis/nc/calibrate.py
@@ -89,7 +89,7 @@ def analyze(self, info: Dict[str, object], **kwargs) -> Dict[str, object]:
 
             # setup prediction cache to avoid additional .predict() calls
             if ns.is_classification:
-                if ns.predictor.mixers[ns.predictor.best_index].supports_proba:
+                if ns.predictor.supports_proba:
                     icp.nc_function.model.prediction_cache = ns.normal_predictions[all_cat_cols].values
                 else:
                     predicted_classes = pd.get_dummies(


Test patch:
Repository: mindsdb/lightwood

Issue:
Make `column_importances` optional
If the column importance module gets automatically disabled (see #681) an issue may arise where the information required for a `ModelAnalysis` object is not available. Example stacktrace:

```python
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-10-b3f165881113> in <module>
     16 
     17 # Analyze the ensembles
---> 18 predictor.analyze_ensemble(enc_data)

/tmp/b380bd15a0ec89f57a82f719f514e67f0cae00fe7d0085d816353697296992059.py in analyze_ensemble(self, enc_data)
   1439         # --------------- #
   1440         log.info("Analyzing the ensemble of mixers")
-> 1441         self.model_analysis, self.runtime_analyzer = model_analyzer(
   1442             data=encoded_test_data,
   1443             train_data=encoded_train_data,

~/Documents/lightwood/lightwood/analysis/analyze.py in model_analyzer(predictor, data, train_data, stats_info, target, ts_cfg, dtype_dict, accuracy_functions, analysis_blocks)
     91         test_sample_size=len(encoded_val_data),
     92         confusion_matrix=runtime_analyzer['cm'],
---> 93         column_importances=runtime_analyzer['column_importances'],
     94         histograms=stats_info.histograms,
     95         dtypes=dtype_dict

KeyError: 'column_importances'
```



Discussion:

Resolving patch:
diff --git a/lightwood/analysis/analyze.py b/lightwood/analysis/analyze.py
--- a/lightwood/analysis/analyze.py
+++ b/lightwood/analysis/analyze.py
@@ -84,13 +84,13 @@ def model_analyzer(
     # Populate ModelAnalysis object
     # ------------------------- #
     model_analysis = ModelAnalysis(
-        accuracies=runtime_analyzer['score_dict'],
-        accuracy_histogram=runtime_analyzer['acc_histogram'],
-        accuracy_samples=runtime_analyzer['acc_samples'],
+        accuracies=runtime_analyzer.get('score_dict', {}),
+        accuracy_histogram=runtime_analyzer.get('acc_histogram', {}),
+        accuracy_samples=runtime_analyzer.get('acc_samples', {}),
         train_sample_size=len(encoded_train_data),
         test_sample_size=len(encoded_val_data),
         confusion_matrix=runtime_analyzer['cm'],
-        column_importances=runtime_analyzer['column_importances'],
+        column_importances=runtime_analyzer.get('column_importances', {}),
         histograms=stats_info.histograms,
         dtypes=dtype_dict
     )


Test patch:
Repository: mindsdb/lightwood

Issue:
Raise Exception for time series tasks that expect `previous_values` but do not receive them
See title. Currently, if this is the case, an error like this will pop up:

```
  File "/home/repos/MindsDB/mindsdb/mindsdb/interfaces/model/model_controller.py", line 207, in predict
    predictions = self.predictor_cache[name]['predictor'].predict(df)
  File "/tmp/79b4fcb309b6fb74da0cc527d239895a8424bd4695d872fe16364615234825585.py", line 463, in predict
    encoded_data = encoded_ds.get_encoded_data(include_target=False)
  File "/home/repos/MindsDB/lightwood/lightwood/data/encoded_ds.py", line 122, in get_encoded_data
    encoded_dfs.append(self.get_encoded_column_data(col))
  File "/home/repos/MindsDB/lightwood/lightwood/data/encoded_ds.py", line 105, in get_encoded_column_data
    encoded_data = self.encoders[column_name].encode(self.data_frame[column_name], **kwargs)
  File "/home/repos/MindsDB/lightwood/lightwood/encoder/time_series/rnn.py", line 407, in encode
    encoded = self._encode_one(val, previous=[values[i] for values in ptd])
  File "/home/repos/MindsDB/lightwood/lightwood/encoder/time_series/rnn.py", line 310, in _encode_one
    data_tensor = torch.cat((data, target_tensor), dim=-1)
```

Which is not very informative. We should aim to have a more descriptive message.


Discussion:

Resolving patch:
diff --git a/lightwood/data/timeseries_transform.py b/lightwood/data/timeseries_transform.py
--- a/lightwood/data/timeseries_transform.py
+++ b/lightwood/data/timeseries_transform.py
@@ -40,6 +40,9 @@ def transform_timeseries(
     ob_arr = tss.order_by
     window = tss.window
 
+    if tss.use_previous_target and target not in data.columns:
+        raise Exception(f"Cannot transform. Missing historical values for target column {target} (`use_previous_target` is set to True).")  # noqa
+
     if '__mdb_make_predictions' in original_df.columns:
         index = original_df[original_df['__mdb_make_predictions'].map(
             {'True': True, 'False': False, True: True, False: False}).isin([True])]
@@ -190,7 +193,6 @@ def transform_timeseries(
 
     del combined_df['original_index']
 
-    # return combined_df, secondary_type_dict, timeseries_row_mapping, df_gb_map
     return combined_df
 
 


Test patch:
Repository: mindsdb/lightwood

Issue:
Improve empty input handling when predicting
Currently, passing an empty dataframe to `PredictorInterface.predict()` will not raise an exception on grounds of empty input, and so will fail somewhere down the line. We should explicitly check for empty input and raise a descriptive exception for better UX.


Discussion:

Resolving patch:
diff --git a/lightwood/api/json_ai.py b/lightwood/api/json_ai.py
--- a/lightwood/api/json_ai.py
+++ b/lightwood/api/json_ai.py
@@ -1017,6 +1017,9 @@ def code_from_json_ai(json_ai: JsonAI) -> str:
     predict_body = f"""
 self.mode = 'predict'
 
+if len(data) == 0:
+    raise Exception("Empty input, aborting prediction. Please try again with some input data.")
+
 # Remove columns that user specifies to ignore
 log.info(f'Dropping features: {{self.problem_definition.ignore_features}}')
 data = data.drop(columns=self.problem_definition.ignore_features, errors='ignore')


Test patch:
diff --git a/tests/integration/basic/test_regression.py b/tests/integration/basic/test_regression.py
--- a/tests/integration/basic/test_regression.py
+++ b/tests/integration/basic/test_regression.py
@@ -53,3 +53,8 @@ def test_0_predict_file_flow(self):
         fixed_predictions = predictor.predict(df, {'fixed_confidence': fixed_conf})
 
         assert all([v == fixed_conf for v in fixed_predictions['confidence'].values])
+
+        # test empty dataframe handling
+        with self.assertRaises(Exception) as ctx:
+            predictor.predict(pd.DataFrame())
+        self.assertTrue('Empty input' in str(ctx.exception))
Repository: mindsdb/lightwood

Issue:
_norm_vec ignoring score sign
This means rescaled probabilities are incorrect, should fix ASAP.

[1](https://github.com/mindsdb/lightwood/blob/fee72018874076390c92dd5bd58c7cbe46715ac7/lightwood/encoder/categorical/binary.py#L158), and [2](https://github.com/mindsdb/lightwood/blob/fee72018874076390c92dd5bd58c7cbe46715ac7/lightwood/encoder/categorical/onehot.py#L174).


Discussion:

Resolving patch:
diff --git a/lightwood/encoder/categorical/binary.py b/lightwood/encoder/categorical/binary.py
--- a/lightwood/encoder/categorical/binary.py
+++ b/lightwood/encoder/categorical/binary.py
@@ -1,10 +1,12 @@
+from copy import deepcopy as dc
+from typing import Dict, List, Iterable, Tuple
+
 import torch
 import numpy as np
+from scipy.special import softmax
+
 from lightwood.encoder.base import BaseEncoder
 from lightwood.helpers.constants import _UNCOMMON_WORD
-from copy import deepcopy as dc
-
-from typing import Dict, List, Iterable, Tuple
 
 
 class BinaryEncoder(BaseEncoder):
@@ -157,11 +159,8 @@ def decode_probabilities(self, encoded_data: torch.Tensor) -> Tuple[List[str], L
     @staticmethod
     def _norm_vec(vec: List[float]):
         """
-        Given a vector, normalizes so that the sum of elements is 1.
+        Given a vector, normalizes so that the sum of elements is 1, using softmax.
 
         :param vec: Assigned weights for each category
         """  # noqa
-        total = sum(vec)
-        if total == 0:
-            return vec
-        return [i / total for i in vec]
+        return softmax(vec)
diff --git a/lightwood/encoder/categorical/onehot.py b/lightwood/encoder/categorical/onehot.py
--- a/lightwood/encoder/categorical/onehot.py
+++ b/lightwood/encoder/categorical/onehot.py
@@ -1,11 +1,13 @@
+from copy import deepcopy
+from typing import Dict, List, Iterable, Tuple
+
 import torch
 import numpy as np
+from scipy.special import softmax
+
 from lightwood.helpers.log import log
 from lightwood.encoder.base import BaseEncoder
 from lightwood.helpers.constants import _UNCOMMON_WORD
-from copy import deepcopy
-
-from typing import Dict, List, Iterable, Tuple
 
 
 class OneHotEncoder(BaseEncoder):
@@ -173,11 +175,8 @@ def decode_probabilities(self, encoded_data: torch.Tensor) -> Tuple[List[str], L
     @staticmethod
     def _norm_vec(vec: List[float]):
         """
-        Given a vector, normalizes so that the sum of elements is 1.
+        Given a vector, normalizes so that the sum of elements is 1, using softmax.
 
         :param vec: Assigned weights for each category
         """
-        total = sum(vec)
-        if total == 0:
-            return vec
-        return [i / total for i in vec]
+        return softmax(vec)


Test patch:
Repository: mindsdb/lightwood

Issue:
[TS] error if 'group by' column contains a single value
If 'group by' column has single value for all cells, then error appears. Can be replicated with any ts-dataset if add filter to data select query:
```
create predictor p_name from int_name (select * from test_data.ts_dataset where location='good') predict rental_price order by date group by location window 5 horizon 3;
```
error is
```
Traceback (most recent call last):
  File "./mindsdb/interfaces/model/learn_process.py", line 175, in run_learn
    run_fit(predictor_id, df)
  File "./mindsdb/utilities/functions.py", line 56, in wrapper
    return func(*args, **kwargs)
  File "./mindsdb/interfaces/model/learn_process.py", line 148, in run_fit
    raise e
  File "./mindsdb/interfaces/model/learn_process.py", line 119, in run_fit
    predictor.learn(df)
  File "/home/maxs/dev/mdb/venv38/sources/lightwood/lightwood/helpers/log.py", line 30, in wrap
    result = f(predictor, *args, **kw)
  File "/tmp/52931846b2322b65fafeb5782f9a3e9e76650c2aac7cecf516512142146485069.py", line 450, in learn
    self.analyze_data(data)
  File "/home/maxs/dev/mdb/venv38/sources/lightwood/lightwood/helpers/log.py", line 30, in wrap
    result = f(predictor, *args, **kw)
  File "/tmp/52931846b2322b65fafeb5782f9a3e9e76650c2aac7cecf516512142146485069.py", line 137, in analyze_data
    self.statistical_analysis = lightwood.data.statistical_analysis(
  File "/home/maxs/dev/mdb/venv38/sources/lightwood/lightwood/data/statistical_analysis.py", line 120, in statistical_analysis
    if dtypes[col] in (dtype.categorical, dtype.binary, dtype.tags):
KeyError: 'location'
```


Discussion:

Resolving patch:
diff --git a/lightwood/api/json_ai.py b/lightwood/api/json_ai.py
--- a/lightwood/api/json_ai.py
+++ b/lightwood/api/json_ai.py
@@ -193,7 +193,8 @@ def generate_json_ai(
     tss = problem_definition.timeseries_settings
     dtype_dict = type_information.dtypes
     for k in type_information.identifiers:
-        del dtype_dict[k]
+        if not (tss.is_timeseries and tss.group_by and k in tss.group_by):
+            del dtype_dict[k]
     dependency_dict = {}
 
     for col_name, col_dtype in dtype_dict.items():


Test patch:
Repository: mindsdb/lightwood

Issue:
Making a forecasts with a predictor that has a single group and horizon=1 results in an error 
## Your Environment
* Python version: 3.8.10
* Operating system: Linux Ubuntu 20.04.4 LTS (Focal Fossa)
* Lightwood version: Staging on 10/05/22

## Describe your issue
When making forecasts, I get this error: 
_ValueError: could not convert string to float: ''_

Tested, but error remains:
- Removing all text columns from the dataset
- Adding 'group_by' in tss

Tested, fixed error:
- Changing horizon to 2


## How can we replicate it?
* What dataset did you use (link to it please) - included in zip
* What was the code you ran - included in zip

[lightwood bug 110522.zip](https://github.com/mindsdb/lightwood/files/8670958/lightwood.bug.110522.zip)
Making a forecasts with a predictor that has a single group and horizon=1 results in an error 
## Your Environment
* Python version: 3.8.10
* Operating system: Linux Ubuntu 20.04.4 LTS (Focal Fossa)
* Lightwood version: Staging on 10/05/22

## Describe your issue
When making forecasts, I get this error: 
_ValueError: could not convert string to float: ''_

Tested, but error remains:
- Removing all text columns from the dataset
- Adding 'group_by' in tss

Tested, fixed error:
- Changing horizon to 2


## How can we replicate it?
* What dataset did you use (link to it please) - included in zip
* What was the code you ran - included in zip

[lightwood bug 110522.zip](https://github.com/mindsdb/lightwood/files/8670958/lightwood.bug.110522.zip)


Discussion:

Resolving patch:
diff --git a/lightwood/data/cleaner.py b/lightwood/data/cleaner.py
--- a/lightwood/data/cleaner.py
+++ b/lightwood/data/cleaner.py
@@ -264,7 +264,9 @@ def _clean_quantity(element: object) -> Optional[float]:
     """
     Given a quantity, clean and convert it into float numeric format. If element is NaN, or inf, then returns None.
     """
-    element = float(re.sub("[^0-9.,]", "", str(element)).replace(",", "."))
+    no_symbols = re.sub("[^0-9.,]", "", str(element)).replace(",", ".")
+    no_symbols = '0' if no_symbols == '' else no_symbols
+    element = float(no_symbols)
     return _clean_float(element)
 
 


Test patch: