diff --git a/.gitignore b/.gitignore index d01469a36..f2ccde1d1 100644 --- a/.gitignore +++ b/.gitignore @@ -167,3 +167,4 @@ tmp output.wav metagpt/roles/idea_agent.py .aider* +/tests/metagpt/actions/check_data.py diff --git a/kaggle_team.py b/kaggle_team.py new file mode 100644 index 000000000..50a8f7288 --- /dev/null +++ b/kaggle_team.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +import asyncio + +import fire + +from metagpt.roles.kaggle_manager import KaggleManager +from metagpt.roles.ml_engineer import MLEngineer +from metagpt.team import Team + +async def main( + # competition: str, + # data_desc: str, + # requirement: str, + investment: float = 5.0, + n_round: int = 10, + auto_run: bool = False, +): + competition, data_desc, requirement = ( + "titanic", + "Training set is train.csv.\nTest set is test.csv. We also include gender_submission.csv, a set of predictions that assume all and only female passengers survive, as an example of what a submission file should look like.", + # "Run EDA on the train dataset, train a model to predict survival (20% as validation) and save it, predict the test set using saved model, save the test result according to format", + # "generate a random prediction, replace the Survived column of gender_submission.csv, and save the prediction to a new submission file", + "Score as high as possible for the provided dataset, save the test prediction to a csv with two columns PassengerId and Survived" + ) + + team = Team() + team.hire( + [ + KaggleManager(competition=competition, data_desc=data_desc), + MLEngineer(goal=requirement, auto_run=auto_run), + ] + ) + + team.invest(investment) + team.start_project(requirement) + await team.run(n_round=n_round) + +if __name__ == '__main__': + fire.Fire(main) diff --git a/metagpt/actions/debug_code.py b/metagpt/actions/debug_code.py index 53ca2f54d..3e1705d8e 100644 --- a/metagpt/actions/debug_code.py +++ b/metagpt/actions/debug_code.py @@ -1,57 +1,56 @@ from typing import Dict, List, Union, Tuple, Optional, Any -from metagpt.actions import Action from metagpt.logs import logger from metagpt.schema import Message, Plan from metagpt.utils.common import CodeParser, create_func_config from metagpt.actions.write_analysis_code import BaseWriteAnalysisCode -DEBUG_REFLECTION_EXAMPLE = '''Example 1: - [previous impl]: - ```python - def add(a: int, b: int) -> int: - """ - Given integers a and b, return the total value of a and b. - """ - return a - b - ``` +DEBUG_REFLECTION_EXAMPLE = ''' +Example 1: +[previous impl]: +```python +def add(a: int, b: int) -> int: + """ + Given integers a and b, return the total value of a and b. + """ + return a - b +``` - [runtime Error]: - Tested passed: +[runtime Error]: +Tested passed: - Tests failed: - assert add(1, 2) == 3 # output: -1 - assert add(1, 2) == 4 # output: -1 +Tests failed: +assert add(1, 2) == 3 # output: -1 +assert add(1, 2) == 4 # output: -1 - [reflection on previous impl]: - The implementation failed the test cases where the input integers are 1 and 2. The issue arises because the code does not add the two integers together, but instead subtracts the second integer from the first. To fix this issue, we should change the operator from `-` to `+` in the return statement. This will ensure that the function returns the correct output for the given input. +[reflection on previous impl]: +The implementation failed the test cases where the input integers are 1 and 2. The issue arises because the code does not add the two integers together, but instead subtracts the second integer from the first. To fix this issue, we should change the operator from `-` to `+` in the return statement. This will ensure that the function returns the correct output for the given input. - [improved impl]: - ```python - def add(a: int, b: int) -> int: - """ - Given integers a and b, return the total value of a and b. - """ - return a + b - ``` - ''' +[improved impl]: +```python +def add(a: int, b: int) -> int: + """ + Given integers a and b, return the total value of a and b. + """ + return a + b +``` +''' REFLECTION_PROMPT = """ - Here is an example for you. - {debug_example} - [context] - {context} - - [previous impl] - {code} - [runtime Error] - {runtime_result} +Here is an example for you. +{debug_example} +[context] +{context} - Analysis the error step by step, provide me improve method and code. Remember to follow [context] requirement. - [reflection on previous impl]: - xxx +[previous impl] +{code} +[runtime Error] +{runtime_result} - """ +Analysis the error step by step, provide me improve method and code. Remember to follow [context] rerquirement. Don't forget write code for steps behind the error step. +[reflection on previous impl]: +xxx +""" CODE_REFLECTION = { "name": "execute_reflection_code", @@ -85,10 +84,10 @@ class DebugCode(BaseWriteAnalysisCode): name: str = "debugcode" context: Optional[str] = None llm: None - + def __init__(self, **kwargs: Any): super().__init__(**kwargs) - + async def run_reflection( self, # goal, @@ -100,23 +99,26 @@ class DebugCode(BaseWriteAnalysisCode): ) -> dict: info = [] # finished_code_and_result = finished_code + "\n [finished results]\n\n" + finished_code_result - reflection_prompt = REFLECTION_PROMPT.format(debug_example=DEBUG_REFLECTION_EXAMPLE, - context=context, - # goal=goal, - # finished_code=finished_code_and_result, - code=code, - runtime_result=runtime_result - ) + reflection_prompt = REFLECTION_PROMPT.format( + debug_example=DEBUG_REFLECTION_EXAMPLE, + context=context, + # goal=goal, + # finished_code=finished_code_and_result, + code=code, + runtime_result=runtime_result, + ) system_prompt = "You are an AI Python assistant. You will be given your previous implementation code of a task, runtime error results, and a hint to change the implementation appropriately. Write your full implementation " info.append(Message(role="system", content=system_prompt)) info.append(Message(role="user", content=reflection_prompt)) - + # msg = messages_to_str(info) # resp = await self.llm.aask(msg=msg) - resp = await self.llm.aask_code(messages=info, **create_func_config(CODE_REFLECTION)) + resp = await self.llm.aask_code( + messages=info, **create_func_config(CODE_REFLECTION) + ) logger.info(f"reflection is {resp}") return resp - + # async def rewrite_code(self, reflection: str = "", context: List[Message] = None) -> str: # """ # 根据reflection重写代码 @@ -131,14 +133,16 @@ class DebugCode(BaseWriteAnalysisCode): # resp = await self.llm.aask(msg=msg) # improv_code = CodeParser.parse_code(block=None, text=resp) # return improv_code - - async def run(self, - context: List[Message] = None, - plan: str = "", - # finished_code: str = "", - # finished_code_result: str = "", - code: str = "", - runtime_result: str = "") -> str: + + async def run( + self, + context: List[Message] = None, + plan: str = "", + # finished_code: str = "", + # finished_code_result: str = "", + code: str = "", + runtime_result: str = "", + ) -> str: """ 根据当前运行代码和报错信息进行reflection和纠错 """ @@ -152,5 +156,5 @@ class DebugCode(BaseWriteAnalysisCode): ) # 根据reflection结果重写代码 # improv_code = await self.rewrite_code(reflection, context=context) - improv_code = reflection['improved_impl'] + improv_code = reflection["improved_impl"] return improv_code diff --git a/metagpt/actions/execute_code.py b/metagpt/actions/execute_code.py index 54d2cf348..e3557dcf2 100644 --- a/metagpt/actions/execute_code.py +++ b/metagpt/actions/execute_code.py @@ -8,6 +8,7 @@ from abc import ABC, abstractmethod from pathlib import Path from typing import Dict, List, Tuple, Union import traceback +import re import nbformat from nbclient import NotebookClient @@ -180,11 +181,31 @@ class ExecutePyCode(ExecuteCode, Action): # TODO: add max_tries for run code. cell_index = len(self.nb.cells) - 1 await self.nb_client.async_execute_cell(self.nb.cells[-1], cell_index) - return self.parse_outputs(self.nb.cells[-1].outputs), True + outputs = self.parse_outputs(self.nb.cells[-1].outputs) + success = True except Exception as e: - # FIXME: CellExecutionError is hard to read. for example `1\0` raise ZeroDivisionError: - # CellExecutionError('An error occurred while executing the following cell:\n------------------\nz=1/0\n------------------\n\n\n\x1b[0;31m---------------------------------------------------------------------------\x1b[0m\n\x1b[0;31mZeroDivisionError\x1b[0m Traceback (most recent call last)\nCell \x1b[0;32mIn[1], line 1\x1b[0m\n\x1b[0;32m----> 1\x1b[0m z\x1b[38;5;241m=\x1b[39m\x1b[38;5;241;43m1\x1b[39;49m\x1b[38;5;241;43m/\x1b[39;49m\x1b[38;5;241;43m0\x1b[39;49m\n\n\x1b[0;31mZeroDivisionError\x1b[0m: division by zero\n') - return traceback.format_exc(), False + outputs = traceback.format_exc() + success = False + return truncate(remove_escape_and_color_codes(outputs)), success else: # TODO: markdown raise NotImplementedError(f"Not support this code type : {language}, Only support code!") + + +def truncate(result: str, keep_len: int = 2000) -> str: + desc = f"Truncated to show only the last {keep_len} characters\n" + if result.startswith(desc): + result = result[len(desc) :] + + if len(result) > keep_len: + result = result[-keep_len:] + return desc + result + + return result + + +def remove_escape_and_color_codes(input_str): + # 使用正则表达式去除转义字符和颜色代码 + pattern = re.compile(r'\x1b\[[0-9;]*[mK]') + result = pattern.sub('', input_str) + return result diff --git a/metagpt/actions/ml_da_action.py b/metagpt/actions/ml_da_action.py new file mode 100644 index 000000000..5e4580b17 --- /dev/null +++ b/metagpt/actions/ml_da_action.py @@ -0,0 +1,116 @@ +import json +from typing import Dict, List, Union + +from metagpt.actions import Action +from metagpt.schema import Message, Plan +from metagpt.utils.common import CodeParser +from metagpt.logs import logger + + +class ReviewConst: + TASK_REVIEW_TRIGGER = "task" + CODE_REVIEW_TRIGGER = "code" + CONTINUE_WORD = ["confirm", "continue", "c", "yes", "y"] + CHANGE_WORD = ["change"] + EXIT_WORD = ["exit"] + TASK_REVIEW_INSTRUCTION = ( + f"If you want to change, add, delete a task or merge tasks in the plan, say '{CHANGE_WORD[0]} task task_id or current task, ... (things to change)' " + f"If you confirm the output from the current task and wish to continue, type: {CONTINUE_WORD[0]}" + ) + CODE_REVIEW_INSTRUCTION = ( + f"If you want the codes to be rewritten, say '{CHANGE_WORD[0]} ... (your change advice)' " + f"If you want to leave it as is, type: {CONTINUE_WORD[0]} or {CONTINUE_WORD[1]}" + ) + EXIT_INSTRUCTION = f"If you want to terminate the process, type: {EXIT_WORD[0]}" + + +class AskReview(Action): + async def run( + self, context: List[Message], plan: Plan = None, trigger: str = "task" + ): + logger.info("Current overall plan:") + logger.info( + "\n".join( + [ + f"{task.task_id}: {task.instruction}, is_finished: {task.is_finished}" + for task in plan.tasks + ] + ) + ) + + logger.info("most recent context:") + latest_action = context[-1].cause_by.__name__ if context[-1].cause_by else "" + review_instruction = ( + ReviewConst.TASK_REVIEW_INSTRUCTION + if trigger == ReviewConst.TASK_REVIEW_TRIGGER + else ReviewConst.CODE_REVIEW_INSTRUCTION + ) + prompt = ( + f"This is a <{trigger}> review. Please review output from {latest_action}\n" + f"{review_instruction}\n" + f"{ReviewConst.EXIT_INSTRUCTION}\n" + "Please type your review below:\n" + ) + + rsp = input(prompt) + + if rsp.lower() in ReviewConst.EXIT_WORD: + exit() + + # Confirmation can be one of "confirm", "continue", "c", "yes", "y" exactly, or sentences containing "confirm". + # One could say "confirm this task, but change the next task to ..." + confirmed = rsp.lower() in ReviewConst.CONTINUE_WORD or ReviewConst.CONTINUE_WORD[0] in rsp.lower() + + return rsp, confirmed + + +class SummarizeAnalysis(Action): + PROMPT_TEMPLATE = """ + # Context + {context} + # Summary + Output a 30-word summary on analysis tool and modeling algorithms you have used, and the corresponding result. Make sure to announce the complete path to your test prediction file. Your summary: + """ + + def __init__(self, name: str = "", context=None, llm=None) -> str: + super().__init__(name, context, llm) + + async def run(self, conmpleted_plan: Plan) -> str: + tasks = json.dumps( + [task.dict() for task in conmpleted_plan.tasks], + indent=4, + ensure_ascii=False, + ) # all tasks finished, return all task outputs + prompt = self.PROMPT_TEMPLATE.format(context=tasks) + summary = await self._aask(prompt) + return summary + + +class Reflect(Action): + PROMPT_TEMPLATE = """ + # Context + __context__ + # Latest User Requirement + __user_requirement__ + # Summary + Above is all your attempts to tackle the user requirement. You plan, act, submit your output, and get the result and feedback. + Output a json following the format: + ```json + { + "summary": str = "summarize each of your previous trial in a triple of (your methods, the corresponding result, potential improvement), list them out", + "takeaways": str = "carefully find key takeaways from your summarization", + "reflection": str = "give specific instruction to improve your next trial in a step-by-step thinking process", + } + ``` + """ + REWRITE_PLAN_INSTRUCTION = """Take this reflection for rewriting plan, modify the current plan in place, make reference to your specific instruction, think about you should + change which task, add or delete what tasks in the plan. Only make necessary changes, keep reusable tasks unchanged, output the COMPLETE new plan starting from the first task. Your plan should have no more than 5 tasks.""" + + async def run(self, context: str, user_requirement: str = "") -> str: + user_requirement = user_requirement or "Score as high as possible in a data modeling competition" + # prompt = self.PROMPT_TEMPLATE.format(context=context, user_requirement=user_requirement) + prompt = self.PROMPT_TEMPLATE.replace("__context__", context).replace("__user_requirement__", user_requirement) + rsp_json = await self._aask(prompt) + rsp = CodeParser.parse_code(block=None, text=rsp_json) + reflection = json.loads(rsp)["reflection"] + return reflection diff --git a/metagpt/actions/write_code_steps.py b/metagpt/actions/write_code_steps.py index 89bf8980f..79f3e5902 100644 --- a/metagpt/actions/write_code_steps.py +++ b/metagpt/actions/write_code_steps.py @@ -120,6 +120,5 @@ class WriteCodeSteps(Action): context = STRUCTURAL_CONTEXT.format( user_requirement=user_requirement, tasks=tasks, codes=codes, current_task=current_task ) - print(context) # print(context) return context diff --git a/metagpt/actions/write_plan.py b/metagpt/actions/write_plan.py index 5145ffd68..11a3f3e1e 100644 --- a/metagpt/actions/write_plan.py +++ b/metagpt/actions/write_plan.py @@ -4,13 +4,16 @@ @Author : orange-crow @File : plan.py """ -from typing import List, Dict +from typing import List, Dict, Tuple import json +from copy import deepcopy +import traceback from metagpt.actions import Action from metagpt.prompts.ml_engineer import ASSIGN_TASK_TYPE_PROMPT, ASSIGN_TASK_TYPE -from metagpt.schema import Message, Task +from metagpt.schema import Message, Task, Plan from metagpt.utils.common import CodeParser, create_func_config +from metagpt.logs import logger class WritePlan(Action): @@ -19,7 +22,8 @@ class WritePlan(Action): __context__ # Task: Based on the context, write a plan or modify an existing plan of what you should do to achieve the goal. A plan consists of one to __max_tasks__ tasks. - If you are modifying an existing plan, carefully follow the instruction, don't make unnecessary changes. + If you are modifying an existing plan, carefully follow the instruction, don't make unnecessary changes. Give the whole plan unless instructed to modify only one task of the plan. + If you encounter errors on the current task, revise and output the current single task only. Output a list of jsons following the format: ```json [ @@ -67,8 +71,36 @@ class WritePlan(Action): rsp = await self.assign_task_type(json.loads(rsp)) return rsp - @staticmethod - def rsp_to_tasks(rsp: str) -> List[Task]: - rsp = json.loads(rsp) - tasks = [Task(**task_config) for task_config in rsp] - return tasks +def rsp_to_tasks(rsp: str) -> List[Task]: + rsp = json.loads(rsp) + tasks = [Task(**task_config) for task_config in rsp] + return tasks + +def update_plan_from_rsp(rsp: str, current_plan: Plan): + tasks = rsp_to_tasks(rsp) + if len(tasks) == 1 or tasks[0].dependent_task_ids: + if tasks[0].dependent_task_ids and len(tasks) > 1: + # tasks[0].dependent_task_ids means the generated tasks are not a complete plan + # for they depend on tasks in the current plan, in this case, we only support updating one task each time + logger.warning( + "Current plan will take only the first generated task if the generated tasks are not a complete plan" + ) + # handle a single task + if current_plan.has_task_id(tasks[0].task_id): + # replace an existing task + current_plan.replace_task(tasks[0]) + else: + # append one task + current_plan.append_task(tasks[0]) + + else: + # add tasks in general + current_plan.add_tasks(tasks) + +def precheck_update_plan_from_rsp(rsp: str, current_plan: Plan) -> Tuple[bool, str]: + temp_plan = deepcopy(current_plan) + try: + update_plan_from_rsp(rsp, temp_plan) + return True, "" + except Exception as e: + return False, e diff --git a/metagpt/config.py b/metagpt/config.py index 3f9e742bd..5973adfc4 100644 --- a/metagpt/config.py +++ b/metagpt/config.py @@ -95,6 +95,9 @@ class Config(metaclass=Singleton): self.prompt_format = self._get("PROMPT_FORMAT", "markdown") + self.kaggle_username = self._get("KAGGLE_USERNAME", "") + self.kaggle_key = self._get("KAGGLE_KEY", "") + def _init_with_config_files_and_env(self, configs: dict, yaml_file): """Load from config/key.yaml, config/config.yaml, and env in decreasing order of priority""" configs.update(os.environ) diff --git a/metagpt/prompts/ml_engineer.py b/metagpt/prompts/ml_engineer.py index ae6938ee0..33eb9c40c 100644 --- a/metagpt/prompts/ml_engineer.py +++ b/metagpt/prompts/ml_engineer.py @@ -155,49 +155,72 @@ PRINT_DATA_COLUMNS = { GENERATE_CODE_PROMPT = """ # Background -Assist in completing [{user_requirement}] in a Jupyter notebook. +As a data scientist, you need to help user to achieve their goal [{user_requirement}] step-by-step in an continuous Jupyter notebook. -## Task Progress -### Done Tasks +## Done Tasks ```python {history_code} ```end -### Current Task +## Current Task {current_task} -## Latest Data Info +# Latest Data Info +Latest data info after previous tasks: {column_info} # Task -Fully implement 'Current Task', ensuring all necessary steps are covered without repeating code from 'Done Tasks'. Specifically, {special_prompt} +Write complete code for 'Current Task'. And avoid duplicating code from 'Done Tasks', such as repeated import of packages, reading data, etc. +Specifically, {special_prompt} # Code Steps: -Follow steps below when you writing code if it's convenient. +Strictly follow steps below when you writing code if it's convenient. {code_steps} + +# Output Example: +when current task is "train a lightgbm model on training data", and their are two steps in 'Code Steps', the code be like: +```python +# Step 1: check data type and convert to numeric +ojb_cols = train.select_dtypes(include='object').columns.tolist() + +for col in obj_cols: + encoder = LabelEncoder() + train[col] = encoder.fit_transform(train[col]) + test[col] = test[col].apply(lambda x: x if x in encoder.classes_ else 'unknown') + test[col] = encoder.transform(test[col]) + +# Step 2: train lightgbm model +model = LGBMClassifier() +model.fit(train, y_train) +```end + +# Constraints: +- Ensure the output new code is executable in the same Jupyter notebook with previous tasks code have been executed. +- The output code should contain all steps implemented in 'Code Steps'. """ TOOL_USAGE_PROMPT = """ # Background -Assist in completing [{user_requirement}] in a Jupyter notebook. +As a data scientist, you need to help user to achieve their goal [{user_requirement}] step-by-step in an continuous Jupyter notebook. -## Task Progress -### Done Tasks +## Done Tasks ```python {history_code} ```end -### Current Task +## Current Task {current_task} -## Latest Data Info +# Latest Data Info +Latest data info after previous tasks: {column_info} # Task -Fully implement 'Current Task', ensuring all necessary steps are covered without repeating code from 'Done Tasks'. Specifically, {special_prompt} +Write complete code for 'Current Task'. And avoid duplicating code from 'Done Tasks', such as repeated import of packages, reading data, etc. +Specifically, {special_prompt} # Code Steps: -Follow steps below when you writing code if it's convenient. +Strictly follow steps below when you writing code if it's convenient. {code_steps} # Capabilities @@ -205,14 +228,13 @@ Follow steps below when you writing code if it's convenient. - You can freely combine the use of any other public packages, like sklearn, numpy, pandas, etc.. # Available Tools: -Each Class tool is described in JSON format. When you call it, import the tool from `{module_name}` first. +Each Class tool is described in JSON format. When you call a tool, import the tool from `{module_name}` first. {tool_catalog} -# Step Example: -Here is a coding example for each code step: -[Step 1]: Handle missing values by imputing or dropping them. For numerical columns, use median or mean imputation -[Code] +# Output Example: +when current task is "do data preprocess, like fill missing value, handle outliers, etc.", and their are two steps in 'Code Steps', the code be like: ```python +# Step 1: fill missing value # Tools used: ['FillMissingValue'] from metagpt.tools.functions.libs.data_preprocess import FillMissingValue @@ -224,31 +246,20 @@ fill_missing_value.fit(train_processed) train_processed = fill_missing_value.transform(train_processed) test_processed = fill_missing_value.transform(test_processed) +# Step 2: handle outliers for col in num_cols: low, high = train_processed[col].quantile([0.01, 0.99]) train_processed[col] = train_processed[col].clip(low, high) test_processed[col] = test_processed[col].clip(low, high) ```end -[Step 2]: xxx -[Code]: -```python -# Tools used: [xxx] -from metagpt.tools.functions.libs.xxx import -```end -[Step 3]: xxx -[Code]: -```python -# Tools used: [xxx] -from metagpt.tools.functions.libs.xxx import -```end # Constraints: -- Prioritize using pre-defined tools for the same functionality. -- Copy DataFrame before processing if needed. -- Strictly follow the code steps to write code +- Ensure the output new code is executable in the same Jupyter notebook with previous tasks code have been executed. +- Always prioritize using pre-defined tools for the same functionality. +- Always copy the DataFrame before processing it and use the copy to process. +- The output code should contain all steps implemented correctly in 'Code Steps'. """ #- If 'Code Steps' contains step done in 'Done Tasks', such as reading data, don't repeat it. -#For "fill missing value and handle outliers", the output code be like when there are training data and test data: DATA_PREPROCESS_PROMPT = """ The current task is about data preprocessing, please note the following: @@ -276,7 +287,7 @@ The current task is about training a model, please ensure high performance: MODEL_EVALUATE_PROMPT = """ The current task is about evaluating a model, please note the following: -- Ensure that the evaluated data is same processed as the training data. +- Ensure that the evaluated data is same processed as the training data. If not, remember use object in 'Done Tasks' to transform the data. - Use trained model from previous task result directly, do not mock or reload model yourself. """ @@ -291,3 +302,14 @@ ML_MODULE_MAP = { "data_preprocess": "metagpt.tools.functions.libs.data_preprocess", "feature_engineering": "metagpt.tools.functions.libs.feature_engineering", } + +STRUCTURAL_CONTEXT = """ +## User Requirement +{user_requirement} +## Data Description +{data_desc} +## Current Plan +{tasks} +## Current Task +{current_task} +""" diff --git a/metagpt/roles/catboost_info/catboost_training.json b/metagpt/roles/catboost_info/catboost_training.json new file mode 100644 index 000000000..68f95dbe6 --- /dev/null +++ b/metagpt/roles/catboost_info/catboost_training.json @@ -0,0 +1,1004 @@ +{ +"meta":{"test_sets":[],"test_metrics":[],"learn_metrics":[{"best_value":"Min","name":"Logloss"}],"launch_mode":"Train","parameters":"","iteration_count":1000,"learn_sets":["learn"],"name":"experiment"}, +"iterations":[ +{"learn":[0.6882514366],"iteration":0,"passed_time":0.2209602877,"remaining_time":220.7393274}, +{"learn":[0.6847159377],"iteration":1,"passed_time":0.2329893569,"remaining_time":116.2616891}, +{"learn":[0.6795580406],"iteration":2,"passed_time":0.25602594,"remaining_time":85.08595405}, +{"learn":[0.6750537284],"iteration":3,"passed_time":0.2782187523,"remaining_time":69.27646932}, +{"learn":[0.6699312491],"iteration":4,"passed_time":0.2999463484,"remaining_time":59.68932333}, +{"learn":[0.6650724516],"iteration":5,"passed_time":0.3218397014,"remaining_time":53.31811054}, +{"learn":[0.6606555729],"iteration":6,"passed_time":0.3459084069,"remaining_time":49.06957829}, +{"learn":[0.6561724634],"iteration":7,"passed_time":0.3679667854,"remaining_time":45.62788139}, +{"learn":[0.6519794747],"iteration":8,"passed_time":0.3899457437,"remaining_time":42.93735911}, +{"learn":[0.6492472012],"iteration":9,"passed_time":0.4007993018,"remaining_time":39.67913088}, +{"learn":[0.6446640682],"iteration":10,"passed_time":0.4235608008,"remaining_time":38.08196655}, +{"learn":[0.6400603726],"iteration":11,"passed_time":0.4457455009,"remaining_time":36.69971291}, +{"learn":[0.637483839],"iteration":12,"passed_time":0.4554558546,"remaining_time":34.57960988}, +{"learn":[0.6334773178],"iteration":13,"passed_time":0.4733180286,"remaining_time":33.33511259}, +{"learn":[0.6286841787],"iteration":14,"passed_time":0.4951142595,"remaining_time":32.51250304}, +{"learn":[0.6262362324],"iteration":15,"passed_time":0.506736055,"remaining_time":31.16426738}, +{"learn":[0.6227706725],"iteration":16,"passed_time":0.5269891476,"remaining_time":30.47237247}, +{"learn":[0.618564194],"iteration":17,"passed_time":0.5488836139,"remaining_time":29.94465049}, +{"learn":[0.6154841122],"iteration":18,"passed_time":0.5635392104,"remaining_time":29.09641923}, +{"learn":[0.6112592312],"iteration":19,"passed_time":0.5852540048,"remaining_time":28.67744624}, +{"learn":[0.6077881571],"iteration":20,"passed_time":0.6073336225,"remaining_time":28.31331507}, +{"learn":[0.6037553183],"iteration":21,"passed_time":0.6292302093,"remaining_time":27.97214294}, +{"learn":[0.6006649251],"iteration":22,"passed_time":0.6456397926,"remaining_time":27.42565554}, +{"learn":[0.5975849834],"iteration":23,"passed_time":0.6645987882,"remaining_time":27.02701739}, +{"learn":[0.5940831045],"iteration":24,"passed_time":0.6864422193,"remaining_time":26.77124655}, +{"learn":[0.5916771489],"iteration":25,"passed_time":0.7039365724,"remaining_time":26.37054698}, +{"learn":[0.5894338237],"iteration":26,"passed_time":0.7168747032,"remaining_time":25.83404023}, +{"learn":[0.5875190394],"iteration":27,"passed_time":0.7261948992,"remaining_time":25.20933721}, +{"learn":[0.5844895773],"iteration":28,"passed_time":0.7450785696,"remaining_time":24.9472859}, +{"learn":[0.5810267327],"iteration":29,"passed_time":0.7672816003,"remaining_time":24.80877174}, +{"learn":[0.5778936903],"iteration":30,"passed_time":0.7890965402,"remaining_time":24.66563056}, +{"learn":[0.576124503],"iteration":31,"passed_time":0.7996305702,"remaining_time":24.18882475}, +{"learn":[0.5735057785],"iteration":32,"passed_time":0.8142960813,"remaining_time":23.86134275}, +{"learn":[0.570293767],"iteration":33,"passed_time":0.8360974032,"remaining_time":23.75500269}, +{"learn":[0.5672457801],"iteration":34,"passed_time":0.8581203558,"remaining_time":23.6596041}, +{"learn":[0.5649423522],"iteration":35,"passed_time":0.8765849625,"remaining_time":23.47299733}, +{"learn":[0.5615275613],"iteration":36,"passed_time":0.9024578152,"remaining_time":23.48829395}, +{"learn":[0.5581402135],"iteration":37,"passed_time":0.9273196032,"remaining_time":23.47582785}, +{"learn":[0.555577741],"iteration":38,"passed_time":0.9458885498,"remaining_time":23.30766401}, +{"learn":[0.5523266666],"iteration":39,"passed_time":0.9682634562,"remaining_time":23.23832295}, +{"learn":[0.5508561568],"iteration":40,"passed_time":0.9762371787,"remaining_time":22.83442572}, +{"learn":[0.5487373589],"iteration":41,"passed_time":0.9944226088,"remaining_time":22.68230617}, +{"learn":[0.5460358061],"iteration":42,"passed_time":1.017613209,"remaining_time":22.64781026}, +{"learn":[0.5429618153],"iteration":43,"passed_time":1.039705016,"remaining_time":22.58995444}, +{"learn":[0.5411169242],"iteration":44,"passed_time":1.058342618,"remaining_time":22.46038223}, +{"learn":[0.5389150372],"iteration":45,"passed_time":1.080413363,"remaining_time":22.40683365}, +{"learn":[0.5364783846],"iteration":46,"passed_time":1.102740504,"remaining_time":22.3598234}, +{"learn":[0.534124059],"iteration":47,"passed_time":1.117903644,"remaining_time":22.17175561}, +{"learn":[0.5307002414],"iteration":48,"passed_time":1.140720347,"remaining_time":22.13928674}, +{"learn":[0.5289874066],"iteration":49,"passed_time":1.176629736,"remaining_time":22.35596498}, +{"learn":[0.5263977673],"iteration":50,"passed_time":1.206713737,"remaining_time":22.45433992}, +{"learn":[0.5243808354],"iteration":51,"passed_time":1.229893513,"remaining_time":22.42190481}, +{"learn":[0.5226468558],"iteration":52,"passed_time":1.251654021,"remaining_time":22.36445959}, +{"learn":[0.5205374561],"iteration":53,"passed_time":1.277702019,"remaining_time":22.38344648}, +{"learn":[0.5184600522],"iteration":54,"passed_time":1.300474793,"remaining_time":22.34452145}, +{"learn":[0.5161120982],"iteration":55,"passed_time":1.32256994,"remaining_time":22.29475042}, +{"learn":[0.5135670428],"iteration":56,"passed_time":1.345110102,"remaining_time":22.25331274}, +{"learn":[0.5117345666],"iteration":57,"passed_time":1.367616671,"remaining_time":22.21198111}, +{"learn":[0.5103042276],"iteration":58,"passed_time":1.379228529,"remaining_time":21.99752619}, +{"learn":[0.5088685224],"iteration":59,"passed_time":1.393836981,"remaining_time":21.83677937}, +{"learn":[0.5069392613],"iteration":60,"passed_time":1.420003792,"remaining_time":21.85874689}, +{"learn":[0.5058379484],"iteration":61,"passed_time":1.434821217,"remaining_time":21.70745648}, +{"learn":[0.504071849],"iteration":62,"passed_time":1.450886544,"remaining_time":21.57905859}, +{"learn":[0.5026509319],"iteration":63,"passed_time":1.470451497,"remaining_time":21.50535314}, +{"learn":[0.5013652681],"iteration":64,"passed_time":1.485685519,"remaining_time":21.37101477}, +{"learn":[0.4990494982],"iteration":65,"passed_time":1.507402942,"remaining_time":21.33203558}, +{"learn":[0.4975801239],"iteration":66,"passed_time":1.529043474,"remaining_time":21.29250091}, +{"learn":[0.4954073892],"iteration":67,"passed_time":1.55148063,"remaining_time":21.26441099}, +{"learn":[0.4937794274],"iteration":68,"passed_time":1.573374258,"remaining_time":21.22915121}, +{"learn":[0.4917253363],"iteration":69,"passed_time":1.595265697,"remaining_time":21.19424426}, +{"learn":[0.4897655824],"iteration":70,"passed_time":1.617828232,"remaining_time":21.16848489}, +{"learn":[0.4881025387],"iteration":71,"passed_time":1.63997141,"remaining_time":21.13740929}, +{"learn":[0.4855490154],"iteration":72,"passed_time":1.668328528,"remaining_time":21.18548693}, +{"learn":[0.4839406321],"iteration":73,"passed_time":1.694200638,"remaining_time":21.20040257}, +{"learn":[0.4825486397],"iteration":74,"passed_time":1.714501822,"remaining_time":21.14552248}, +{"learn":[0.4806147512],"iteration":75,"passed_time":1.74069548,"remaining_time":21.16319241}, +{"learn":[0.4790772126],"iteration":76,"passed_time":1.76355628,"remaining_time":21.13977203}, +{"learn":[0.4783791778],"iteration":77,"passed_time":1.771777779,"remaining_time":20.94332195}, +{"learn":[0.476922228],"iteration":78,"passed_time":1.789701952,"remaining_time":20.86475313}, +{"learn":[0.4757319459],"iteration":79,"passed_time":1.811825511,"remaining_time":20.83599338}, +{"learn":[0.4742068644],"iteration":80,"passed_time":1.833878171,"remaining_time":20.80659308}, +{"learn":[0.4726812191],"iteration":81,"passed_time":1.855740771,"remaining_time":20.77524424}, +{"learn":[0.4710468444],"iteration":82,"passed_time":1.877655908,"remaining_time":20.74470443}, +{"learn":[0.4693673381],"iteration":83,"passed_time":1.899915651,"remaining_time":20.71812782}, +{"learn":[0.4676818392],"iteration":84,"passed_time":1.929145481,"remaining_time":20.76668371}, +{"learn":[0.4657056761],"iteration":85,"passed_time":1.951233566,"remaining_time":20.73752883}, +{"learn":[0.4642140634],"iteration":86,"passed_time":1.969771174,"remaining_time":20.6712768}, +{"learn":[0.4632998746],"iteration":87,"passed_time":1.991742157,"remaining_time":20.64169144}, +{"learn":[0.4622314595],"iteration":88,"passed_time":2.014152311,"remaining_time":20.61677254}, +{"learn":[0.460592481],"iteration":89,"passed_time":2.036215085,"remaining_time":20.58839697}, +{"learn":[0.4593241639],"iteration":90,"passed_time":2.058798714,"remaining_time":20.56536298}, +{"learn":[0.4584569869],"iteration":91,"passed_time":2.073992457,"remaining_time":20.46940381}, +{"learn":[0.4577605438],"iteration":92,"passed_time":2.085384355,"remaining_time":20.33810334}, +{"learn":[0.4561556633],"iteration":93,"passed_time":2.107586742,"remaining_time":20.31354881}, +{"learn":[0.4554982999],"iteration":94,"passed_time":2.119182321,"remaining_time":20.188}, +{"learn":[0.4545744958],"iteration":95,"passed_time":2.137405105,"remaining_time":20.1272314}, +{"learn":[0.4540947284],"iteration":96,"passed_time":2.145521477,"remaining_time":19.97325664}, +{"learn":[0.4540085087],"iteration":97,"passed_time":2.150456003,"remaining_time":19.7929726}, +{"learn":[0.4531926189],"iteration":98,"passed_time":2.164042187,"remaining_time":19.6949698}, +{"learn":[0.4527317281],"iteration":99,"passed_time":2.176278456,"remaining_time":19.5865061}, +{"learn":[0.4519466344],"iteration":100,"passed_time":2.196543022,"remaining_time":19.55140769}, +{"learn":[0.450688372],"iteration":101,"passed_time":2.226552191,"remaining_time":19.60239085}, +{"learn":[0.4488322057],"iteration":102,"passed_time":2.2501016,"remaining_time":19.595545}, +{"learn":[0.4478782417],"iteration":103,"passed_time":2.272366787,"remaining_time":19.57731386}, +{"learn":[0.4468232543],"iteration":104,"passed_time":2.294253479,"remaining_time":19.55577965}, +{"learn":[0.4457592303],"iteration":105,"passed_time":2.316373853,"remaining_time":19.53620967}, +{"learn":[0.4447781675],"iteration":106,"passed_time":2.334811885,"remaining_time":19.48585994}, +{"learn":[0.4438522903],"iteration":107,"passed_time":2.36016004,"remaining_time":19.49317366}, +{"learn":[0.4430406598],"iteration":108,"passed_time":2.375441273,"remaining_time":19.41759793}, +{"learn":[0.4420804721],"iteration":109,"passed_time":2.397764964,"remaining_time":19.40009835}, +{"learn":[0.4413288303],"iteration":110,"passed_time":2.431630964,"remaining_time":19.47495429}, +{"learn":[0.4406769097],"iteration":111,"passed_time":2.448104093,"remaining_time":19.40996816}, +{"learn":[0.439927404],"iteration":112,"passed_time":2.471054306,"remaining_time":19.39668291}, +{"learn":[0.4387131738],"iteration":113,"passed_time":2.493169175,"remaining_time":19.37673587}, +{"learn":[0.4379161685],"iteration":114,"passed_time":2.515201611,"remaining_time":19.35611674}, +{"learn":[0.4368122477],"iteration":115,"passed_time":2.536876581,"remaining_time":19.33274912}, +{"learn":[0.4363066446],"iteration":116,"passed_time":2.558814198,"remaining_time":19.31139262}, +{"learn":[0.4352350106],"iteration":117,"passed_time":2.580710273,"remaining_time":19.28971577}, +{"learn":[0.4340016567],"iteration":118,"passed_time":2.602677388,"remaining_time":19.26856117}, +{"learn":[0.4332395033],"iteration":119,"passed_time":2.625437408,"remaining_time":19.25320766}, +{"learn":[0.4323511556],"iteration":120,"passed_time":2.650764059,"remaining_time":19.25637692}, +{"learn":[0.4316166781],"iteration":121,"passed_time":2.686256274,"remaining_time":19.33223778}, +{"learn":[0.4304510199],"iteration":122,"passed_time":2.712823213,"remaining_time":19.34265007}, +{"learn":[0.4297836948],"iteration":123,"passed_time":2.744805133,"remaining_time":19.39072014}, +{"learn":[0.4286476712],"iteration":124,"passed_time":2.819134566,"remaining_time":19.73394196}, +{"learn":[0.4281044323],"iteration":125,"passed_time":2.83375925,"remaining_time":19.65639353}, +{"learn":[0.4277452421],"iteration":126,"passed_time":2.851695114,"remaining_time":19.60259712}, +{"learn":[0.4268564678],"iteration":127,"passed_time":2.873147663,"remaining_time":19.57331846}, +{"learn":[0.4262834378],"iteration":128,"passed_time":2.894895865,"remaining_time":19.54615735}, +{"learn":[0.4255606014],"iteration":129,"passed_time":2.917059119,"remaining_time":19.52185718}, +{"learn":[0.4252233113],"iteration":130,"passed_time":2.937915636,"remaining_time":19.48892128}, +{"learn":[0.424750709],"iteration":131,"passed_time":2.956196683,"remaining_time":19.43923273}, +{"learn":[0.4237267015],"iteration":132,"passed_time":2.978141095,"remaining_time":19.41389721}, +{"learn":[0.4229110275],"iteration":133,"passed_time":3.000071725,"remaining_time":19.38852324}, +{"learn":[0.4226882753],"iteration":134,"passed_time":3.011578793,"remaining_time":19.29641227}, +{"learn":[0.4220238002],"iteration":135,"passed_time":3.029874756,"remaining_time":19.24861609}, +{"learn":[0.4216236205],"iteration":136,"passed_time":3.044691237,"remaining_time":19.17933239}, +{"learn":[0.4213023831],"iteration":137,"passed_time":3.059441462,"remaining_time":19.1104242}, +{"learn":[0.4205216151],"iteration":138,"passed_time":3.081243821,"remaining_time":19.08597792}, +{"learn":[0.4202240166],"iteration":139,"passed_time":3.099524481,"remaining_time":19.0399361}, +{"learn":[0.4192685081],"iteration":140,"passed_time":3.121315434,"remaining_time":19.01567346}, +{"learn":[0.4183050279],"iteration":141,"passed_time":3.143410659,"remaining_time":18.99328412}, +{"learn":[0.4173978005],"iteration":142,"passed_time":3.165354005,"remaining_time":18.96998868}, +{"learn":[0.4162954182],"iteration":143,"passed_time":3.195654275,"remaining_time":18.9963893}, +{"learn":[0.415992639],"iteration":144,"passed_time":3.220638215,"remaining_time":18.99065982}, +{"learn":[0.4157126501],"iteration":145,"passed_time":3.240805289,"remaining_time":18.95649121}, +{"learn":[0.4155852885],"iteration":146,"passed_time":3.249262286,"remaining_time":18.85456279}, +{"learn":[0.4148007449],"iteration":147,"passed_time":3.271747229,"remaining_time":18.83465297}, +{"learn":[0.4145476092],"iteration":148,"passed_time":3.289985958,"remaining_time":18.79045671}, +{"learn":[0.4139132529],"iteration":149,"passed_time":3.312792785,"remaining_time":18.77249245}, +{"learn":[0.4134843771],"iteration":150,"passed_time":3.32803032,"remaining_time":18.71190558}, +{"learn":[0.4124055164],"iteration":151,"passed_time":3.350009767,"remaining_time":18.68952817}, +{"learn":[0.412222917],"iteration":152,"passed_time":3.358421193,"remaining_time":18.59204412}, +{"learn":[0.4115787549],"iteration":153,"passed_time":3.380687937,"remaining_time":18.57183113}, +{"learn":[0.411081548],"iteration":154,"passed_time":3.402466212,"remaining_time":18.5489287}, +{"learn":[0.4110031407],"iteration":155,"passed_time":3.411424026,"remaining_time":18.45667871}, +{"learn":[0.4105687169],"iteration":156,"passed_time":3.439257058,"remaining_time":18.46683885}, +{"learn":[0.4095109133],"iteration":157,"passed_time":3.463613233,"remaining_time":18.45798951}, +{"learn":[0.4089787829],"iteration":158,"passed_time":3.485545103,"remaining_time":18.43612221}, +{"learn":[0.4084130488],"iteration":159,"passed_time":3.507325669,"remaining_time":18.41345976}, +{"learn":[0.4077252474],"iteration":160,"passed_time":3.529486341,"remaining_time":18.39278907}, +{"learn":[0.4072843557],"iteration":161,"passed_time":3.548156286,"remaining_time":18.35404301}, +{"learn":[0.4066351535],"iteration":162,"passed_time":3.569884188,"remaining_time":18.3312458}, +{"learn":[0.4063103387],"iteration":163,"passed_time":3.584669678,"remaining_time":18.27307226}, +{"learn":[0.4059185096],"iteration":164,"passed_time":3.599569148,"remaining_time":18.21600144}, +{"learn":[0.4052304697],"iteration":165,"passed_time":3.621153956,"remaining_time":18.1930265}, +{"learn":[0.4050859305],"iteration":166,"passed_time":3.629460067,"remaining_time":18.10383375}, +{"learn":[0.4044742571],"iteration":167,"passed_time":3.65097424,"remaining_time":18.08101529}, +{"learn":[0.4041975026],"iteration":168,"passed_time":3.679528258,"remaining_time":18.0928283}, +{"learn":[0.4035590426],"iteration":169,"passed_time":3.703328795,"remaining_time":18.08095824}, +{"learn":[0.4030297385],"iteration":170,"passed_time":3.728541368,"remaining_time":18.07579412}, +{"learn":[0.4025456368],"iteration":171,"passed_time":3.762066103,"remaining_time":18.11041124}, +{"learn":[0.402334931],"iteration":172,"passed_time":3.773807336,"remaining_time":18.0401079}, +{"learn":[0.401831618],"iteration":173,"passed_time":3.795813183,"remaining_time":18.01920511}, +{"learn":[0.4017743873],"iteration":174,"passed_time":3.807120561,"remaining_time":17.94785407}, +{"learn":[0.4011280658],"iteration":175,"passed_time":3.829251163,"remaining_time":17.92785772}, +{"learn":[0.4005475562],"iteration":176,"passed_time":3.851096112,"remaining_time":17.90650904}, +{"learn":[0.4000603326],"iteration":177,"passed_time":3.883514366,"remaining_time":17.93398207}, +{"learn":[0.3990424765],"iteration":178,"passed_time":3.954211249,"remaining_time":18.13635439}, +{"learn":[0.3987132685],"iteration":179,"passed_time":4.006291434,"remaining_time":18.2508832}, +{"learn":[0.3980735307],"iteration":180,"passed_time":4.04072907,"remaining_time":18.28374093}, +{"learn":[0.3976839336],"iteration":181,"passed_time":4.066100873,"remaining_time":18.27511272}, +{"learn":[0.3970583957],"iteration":182,"passed_time":4.088135325,"remaining_time":18.25140197}, +{"learn":[0.3968093954],"iteration":183,"passed_time":4.109985916,"remaining_time":18.22689406}, +{"learn":[0.3965549511],"iteration":184,"passed_time":4.121652408,"remaining_time":18.1575498}, +{"learn":[0.3961498711],"iteration":185,"passed_time":4.13684245,"remaining_time":18.10424599}, +{"learn":[0.3958574586],"iteration":186,"passed_time":4.158257951,"remaining_time":18.07841558}, +{"learn":[0.3958036693],"iteration":187,"passed_time":4.166355942,"remaining_time":17.99511183}, +{"learn":[0.3954652307],"iteration":188,"passed_time":4.184386925,"remaining_time":17.95522644}, +{"learn":[0.3949970516],"iteration":189,"passed_time":4.215870756,"remaining_time":17.9729227}, +{"learn":[0.3946423615],"iteration":190,"passed_time":4.243567046,"remaining_time":17.97406147}, +{"learn":[0.3937733218],"iteration":191,"passed_time":4.267948498,"remaining_time":17.96094993}, +{"learn":[0.3931025335],"iteration":192,"passed_time":4.290856304,"remaining_time":17.94155978}, +{"learn":[0.3925366206],"iteration":193,"passed_time":4.31302246,"remaining_time":17.91905208}, +{"learn":[0.391865258],"iteration":194,"passed_time":4.33481009,"remaining_time":17.89498524}, +{"learn":[0.3914533348],"iteration":195,"passed_time":4.356400319,"remaining_time":17.87013192}, +{"learn":[0.3912476553],"iteration":196,"passed_time":4.37834033,"remaining_time":17.84673749}, +{"learn":[0.3905329154],"iteration":197,"passed_time":4.400898981,"remaining_time":17.82586355}, +{"learn":[0.3898798389],"iteration":198,"passed_time":4.423174721,"remaining_time":17.80383393}, +{"learn":[0.3891654603],"iteration":199,"passed_time":4.455398968,"remaining_time":17.82159587}, +{"learn":[0.3887747769],"iteration":200,"passed_time":4.477551848,"remaining_time":17.7988255}, +{"learn":[0.3884753081],"iteration":201,"passed_time":4.499497174,"remaining_time":17.77524131}, +{"learn":[0.3877793274],"iteration":202,"passed_time":4.521143304,"remaining_time":17.75049859}, +{"learn":[0.3874664375],"iteration":203,"passed_time":4.543454079,"remaining_time":17.72837964}, +{"learn":[0.3871008215],"iteration":204,"passed_time":4.565293203,"remaining_time":17.70442974}, +{"learn":[0.3865209415],"iteration":205,"passed_time":4.587377641,"remaining_time":17.68144586}, +{"learn":[0.3859273739],"iteration":206,"passed_time":4.609581413,"remaining_time":17.65892783}, +{"learn":[0.3855620818],"iteration":207,"passed_time":4.631576096,"remaining_time":17.63561667}, +{"learn":[0.3851648115],"iteration":208,"passed_time":4.653493816,"remaining_time":17.61202684}, +{"learn":[0.3843406643],"iteration":209,"passed_time":4.675584403,"remaining_time":17.58910323}, +{"learn":[0.3842506785],"iteration":210,"passed_time":4.702482855,"remaining_time":17.58416575}, +{"learn":[0.3840729725],"iteration":211,"passed_time":4.725032901,"remaining_time":17.56285814}, +{"learn":[0.3836865443],"iteration":212,"passed_time":4.759392503,"remaining_time":17.58517324}, +{"learn":[0.3834504777],"iteration":213,"passed_time":4.787775158,"remaining_time":17.58500595}, +{"learn":[0.383221126],"iteration":214,"passed_time":4.810450824,"remaining_time":17.56373906}, +{"learn":[0.382875332],"iteration":215,"passed_time":4.833018275,"remaining_time":17.54206633}, +{"learn":[0.3827132502],"iteration":216,"passed_time":4.854566753,"remaining_time":17.51670861}, +{"learn":[0.3825534206],"iteration":217,"passed_time":4.872745824,"remaining_time":17.47929924}, +{"learn":[0.3821802218],"iteration":218,"passed_time":4.894785533,"remaining_time":17.45583334}, +{"learn":[0.3818052054],"iteration":219,"passed_time":4.916556405,"remaining_time":17.43142725}, +{"learn":[0.3816117561],"iteration":220,"passed_time":4.938252004,"remaining_time":17.40677969}, +{"learn":[0.3812172842],"iteration":221,"passed_time":4.960909917,"remaining_time":17.38553115}, +{"learn":[0.3810255507],"iteration":222,"passed_time":4.988823751,"remaining_time":17.3825832}, +{"learn":[0.3809283758],"iteration":223,"passed_time":5.010867096,"remaining_time":17.3590753}, +{"learn":[0.3808446585],"iteration":224,"passed_time":5.03372608,"remaining_time":17.33838983}, +{"learn":[0.3801708307],"iteration":225,"passed_time":5.055982895,"remaining_time":17.31562284}, +{"learn":[0.3798560036],"iteration":226,"passed_time":5.078222381,"remaining_time":17.29280132}, +{"learn":[0.3794923916],"iteration":227,"passed_time":5.100240524,"remaining_time":17.26923546}, +{"learn":[0.3793373475],"iteration":228,"passed_time":5.121943623,"remaining_time":17.24462242}, +{"learn":[0.3791100641],"iteration":229,"passed_time":5.144086578,"remaining_time":17.22150724}, +{"learn":[0.3786186348],"iteration":230,"passed_time":5.16685425,"remaining_time":17.20048017}, +{"learn":[0.3783799747],"iteration":231,"passed_time":5.20100571,"remaining_time":17.21712235}, +{"learn":[0.3779793355],"iteration":232,"passed_time":5.262317101,"remaining_time":17.32273483}, +{"learn":[0.3777902426],"iteration":233,"passed_time":5.311745138,"remaining_time":17.38802041}, +{"learn":[0.377759024],"iteration":234,"passed_time":5.326918408,"remaining_time":17.3408195}, +{"learn":[0.3775407801],"iteration":235,"passed_time":5.366940659,"remaining_time":17.37433332}, +{"learn":[0.3772180796],"iteration":236,"passed_time":5.410539935,"remaining_time":17.41874249}, +{"learn":[0.3770122934],"iteration":237,"passed_time":5.434735311,"remaining_time":17.40028701}, +{"learn":[0.3765490897],"iteration":238,"passed_time":5.464453118,"remaining_time":17.39936746}, +{"learn":[0.3764835925],"iteration":239,"passed_time":5.490098561,"remaining_time":17.38531211}, +{"learn":[0.3759776808],"iteration":240,"passed_time":5.513007919,"remaining_time":17.36254361}, +{"learn":[0.3757142158],"iteration":241,"passed_time":5.534974237,"remaining_time":17.33682013}, +{"learn":[0.3752871326],"iteration":242,"passed_time":5.556902667,"remaining_time":17.31100954}, +{"learn":[0.3748925461],"iteration":243,"passed_time":5.578824076,"remaining_time":17.28520902}, +{"learn":[0.3746214472],"iteration":244,"passed_time":5.600775557,"remaining_time":17.25953284}, +{"learn":[0.3740866821],"iteration":245,"passed_time":5.622820585,"remaining_time":17.23417366}, +{"learn":[0.3735711811],"iteration":246,"passed_time":5.645061274,"remaining_time":17.20943781}, +{"learn":[0.3732294839],"iteration":247,"passed_time":5.666748819,"remaining_time":17.1830448}, +{"learn":[0.3729683346],"iteration":248,"passed_time":5.678427534,"remaining_time":17.12650232}, +{"learn":[0.3727413457],"iteration":249,"passed_time":5.709521815,"remaining_time":17.12856544}, +{"learn":[0.3723892856],"iteration":250,"passed_time":5.732680933,"remaining_time":17.10668534}, +{"learn":[0.3719863363],"iteration":251,"passed_time":5.758476679,"remaining_time":17.09262125}, +{"learn":[0.3716739793],"iteration":252,"passed_time":5.793914284,"remaining_time":17.10693269}, +{"learn":[0.3716103601],"iteration":253,"passed_time":5.808977588,"remaining_time":17.06101292}, +{"learn":[0.3715319129],"iteration":254,"passed_time":5.827444128,"remaining_time":17.02527794}, +{"learn":[0.371508316],"iteration":255,"passed_time":5.835459561,"remaining_time":16.95930435}, +{"learn":[0.3713832526],"iteration":256,"passed_time":5.847111057,"remaining_time":16.90429383}, +{"learn":[0.3710349299],"iteration":257,"passed_time":5.86851783,"remaining_time":16.87767531}, +{"learn":[0.371030348],"iteration":258,"passed_time":5.873415663,"remaining_time":16.80386489}, +{"learn":[0.3708892154],"iteration":259,"passed_time":5.894554845,"remaining_time":16.77680994}, +{"learn":[0.3705921581],"iteration":260,"passed_time":5.916265404,"remaining_time":16.75141814}, +{"learn":[0.3702244894],"iteration":261,"passed_time":5.938204167,"remaining_time":16.72669723}, +{"learn":[0.3702202347],"iteration":262,"passed_time":5.943096693,"remaining_time":16.65422914}, +{"learn":[0.3698349185],"iteration":263,"passed_time":5.965210221,"remaining_time":16.63028304}, +{"learn":[0.3696711654],"iteration":264,"passed_time":5.983506973,"remaining_time":16.59576462}, +{"learn":[0.3692863237],"iteration":265,"passed_time":6.008756231,"remaining_time":16.58055291}, +{"learn":[0.3690671729],"iteration":266,"passed_time":6.030910934,"remaining_time":16.55677047}, +{"learn":[0.3687581564],"iteration":267,"passed_time":6.053029386,"remaining_time":16.53290116}, +{"learn":[0.3683941859],"iteration":268,"passed_time":6.074786966,"remaining_time":16.50806421}, +{"learn":[0.368050992],"iteration":269,"passed_time":6.096955104,"remaining_time":16.4843601}, +{"learn":[0.3677324616],"iteration":270,"passed_time":6.118732429,"remaining_time":16.45961602}, +{"learn":[0.3674997199],"iteration":271,"passed_time":6.133897356,"remaining_time":16.41719586}, +{"learn":[0.3672484703],"iteration":272,"passed_time":6.155501408,"remaining_time":16.3921228}, +{"learn":[0.3670583272],"iteration":273,"passed_time":6.177355776,"remaining_time":16.3677383}, +{"learn":[0.366936125],"iteration":274,"passed_time":6.196658037,"remaining_time":16.33664392}, +{"learn":[0.3665623609],"iteration":275,"passed_time":6.223489438,"remaining_time":16.32538534}, +{"learn":[0.3663926512],"iteration":276,"passed_time":6.249200888,"remaining_time":16.31109113}, +{"learn":[0.3659325492],"iteration":277,"passed_time":6.275677092,"remaining_time":16.29870094}, +{"learn":[0.3656171802],"iteration":278,"passed_time":6.300903365,"remaining_time":16.28297966}, +{"learn":[0.3654984176],"iteration":279,"passed_time":6.322813287,"remaining_time":16.25866274}, +{"learn":[0.3653075674],"iteration":280,"passed_time":6.344882826,"remaining_time":16.23477136}, +{"learn":[0.3652175898],"iteration":281,"passed_time":6.366618787,"remaining_time":16.21004358}, +{"learn":[0.365164193],"iteration":282,"passed_time":6.374755754,"remaining_time":16.15088295}, +{"learn":[0.3648739127],"iteration":283,"passed_time":6.397192914,"remaining_time":16.12813425}, +{"learn":[0.3648461699],"iteration":284,"passed_time":6.408952603,"remaining_time":16.07860039}, +{"learn":[0.3646301237],"iteration":285,"passed_time":6.430803359,"remaining_time":16.05452307}, +{"learn":[0.3646030346],"iteration":286,"passed_time":6.444636163,"remaining_time":16.01054211}, +{"learn":[0.3644969437],"iteration":287,"passed_time":6.469654901,"remaining_time":15.99442462}, +{"learn":[0.3643646754],"iteration":288,"passed_time":6.495103933,"remaining_time":15.97930414}, +{"learn":[0.3639816129],"iteration":289,"passed_time":6.516903674,"remaining_time":15.95517796}, +{"learn":[0.3636656294],"iteration":290,"passed_time":6.538871352,"remaining_time":15.93147694}, +{"learn":[0.363430258],"iteration":291,"passed_time":6.575359293,"remaining_time":15.94299445}, +{"learn":[0.3632201443],"iteration":292,"passed_time":6.615051101,"remaining_time":15.96191511}, +{"learn":[0.3628359855],"iteration":293,"passed_time":6.65904192,"remaining_time":15.99076053}, +{"learn":[0.3627236518],"iteration":294,"passed_time":6.696672672,"remaining_time":16.00391266}, +{"learn":[0.3622184354],"iteration":295,"passed_time":6.758116653,"remaining_time":16.07335853}, +{"learn":[0.3621264294],"iteration":296,"passed_time":6.787336902,"remaining_time":16.0656493}, +{"learn":[0.3620089934],"iteration":297,"passed_time":6.824504579,"remaining_time":16.0765175}, +{"learn":[0.3618790034],"iteration":298,"passed_time":6.853537324,"remaining_time":16.06799219}, +{"learn":[0.3617399454],"iteration":299,"passed_time":6.877452265,"remaining_time":16.04738862}, +{"learn":[0.3616850281],"iteration":300,"passed_time":6.889464347,"remaining_time":15.99912152}, +{"learn":[0.3613225424],"iteration":301,"passed_time":6.911690035,"remaining_time":15.97470081}, +{"learn":[0.3613077955],"iteration":302,"passed_time":6.919765154,"remaining_time":15.9177436}, +{"learn":[0.3611613922],"iteration":303,"passed_time":6.941101626,"remaining_time":15.89146951}, +{"learn":[0.3606681647],"iteration":304,"passed_time":6.963247586,"remaining_time":15.86707237}, +{"learn":[0.3606662726],"iteration":305,"passed_time":6.971583113,"remaining_time":15.81136824}, +{"learn":[0.3606644378],"iteration":306,"passed_time":6.977915177,"remaining_time":15.75145022}, +{"learn":[0.3601634319],"iteration":307,"passed_time":7.004917362,"remaining_time":15.73832083}, +{"learn":[0.3599344409],"iteration":308,"passed_time":7.027043523,"remaining_time":15.71419765}, +{"learn":[0.3596092344],"iteration":309,"passed_time":7.049369762,"remaining_time":15.6905327}, +{"learn":[0.3595229983],"iteration":310,"passed_time":7.071081586,"remaining_time":15.66551515}, +{"learn":[0.3591048131],"iteration":311,"passed_time":7.093007056,"remaining_time":15.64098992}, +{"learn":[0.3589464226],"iteration":312,"passed_time":7.114835418,"remaining_time":15.61626815}, +{"learn":[0.3588198429],"iteration":313,"passed_time":7.136272187,"remaining_time":15.5907093}, +{"learn":[0.3585066029],"iteration":314,"passed_time":7.1580098,"remaining_time":15.56583083}, +{"learn":[0.3584892118],"iteration":315,"passed_time":7.172922678,"remaining_time":15.52619972}, +{"learn":[0.3580264626],"iteration":316,"passed_time":7.195573733,"remaining_time":15.50339703}, +{"learn":[0.3580001595],"iteration":317,"passed_time":7.207669718,"remaining_time":15.45795833}, +{"learn":[0.3578136454],"iteration":318,"passed_time":7.228151813,"remaining_time":15.4306313}, +{"learn":[0.3576122347],"iteration":319,"passed_time":7.255577239,"remaining_time":15.41810163}, +{"learn":[0.3573283521],"iteration":320,"passed_time":7.28056961,"remaining_time":15.4003326}, +{"learn":[0.3569801921],"iteration":321,"passed_time":7.307082032,"remaining_time":15.38571931}, +{"learn":[0.3568810457],"iteration":322,"passed_time":7.329394107,"remaining_time":15.36222851}, +{"learn":[0.35676928],"iteration":323,"passed_time":7.355222467,"remaining_time":15.34608144}, +{"learn":[0.3566134286],"iteration":324,"passed_time":7.377839391,"remaining_time":15.32320489}, +{"learn":[0.3565307492],"iteration":325,"passed_time":7.393089132,"remaining_time":15.28509839}, +{"learn":[0.3562459001],"iteration":326,"passed_time":7.415445478,"remaining_time":15.26175782}, +{"learn":[0.3559648846],"iteration":327,"passed_time":7.43874903,"remaining_time":15.24036387}, +{"learn":[0.3558310934],"iteration":328,"passed_time":7.461531161,"remaining_time":15.21789486}, +{"learn":[0.355525639],"iteration":329,"passed_time":7.488692372,"remaining_time":15.20431482}, +{"learn":[0.3553348141],"iteration":330,"passed_time":7.512358605,"remaining_time":15.18358884}, +{"learn":[0.3552290203],"iteration":331,"passed_time":7.534131988,"remaining_time":15.15903665}, +{"learn":[0.3545412457],"iteration":332,"passed_time":7.556277348,"remaining_time":15.13524622}, +{"learn":[0.3543498177],"iteration":333,"passed_time":7.578229608,"remaining_time":15.1110806}, +{"learn":[0.354267269],"iteration":334,"passed_time":7.600212936,"remaining_time":15.08698986}, +{"learn":[0.3541845198],"iteration":335,"passed_time":7.62304827,"remaining_time":15.06459539}, +{"learn":[0.3538121961],"iteration":336,"passed_time":7.644785675,"remaining_time":15.04003829}, +{"learn":[0.3535608169],"iteration":337,"passed_time":7.667040919,"remaining_time":15.0165121}, +{"learn":[0.3531983941],"iteration":338,"passed_time":7.689794841,"remaining_time":14.99396575}, +{"learn":[0.3530182856],"iteration":339,"passed_time":7.706120291,"remaining_time":14.95893939}, +{"learn":[0.3527164122],"iteration":340,"passed_time":7.737325144,"remaining_time":14.95277792}, +{"learn":[0.352633574],"iteration":341,"passed_time":7.779216311,"remaining_time":14.96703021}, +{"learn":[0.3525075494],"iteration":342,"passed_time":7.905813197,"remaining_time":15.14320487}, +{"learn":[0.3524961056],"iteration":343,"passed_time":7.927378105,"remaining_time":15.11732569}, +{"learn":[0.35245364],"iteration":344,"passed_time":7.959635347,"remaining_time":15.11177146}, +{"learn":[0.3521993518],"iteration":345,"passed_time":7.982424347,"remaining_time":15.08816625}, +{"learn":[0.3520077509],"iteration":346,"passed_time":8.011559383,"remaining_time":15.076508}, +{"learn":[0.3519447224],"iteration":347,"passed_time":8.041947635,"remaining_time":15.06709729}, +{"learn":[0.3518945368],"iteration":348,"passed_time":8.053708214,"remaining_time":15.02281962}, +{"learn":[0.3516107656],"iteration":349,"passed_time":8.075229556,"remaining_time":14.99685489}, +{"learn":[0.3515159018],"iteration":350,"passed_time":8.09696984,"remaining_time":14.9713203}, +{"learn":[0.3515000807],"iteration":351,"passed_time":8.105153638,"remaining_time":14.92085101}, +{"learn":[0.3512670327],"iteration":352,"passed_time":8.127032488,"remaining_time":14.89572244}, +{"learn":[0.3508513767],"iteration":353,"passed_time":8.148752566,"remaining_time":14.87032248}, +{"learn":[0.3504572704],"iteration":354,"passed_time":8.174282947,"remaining_time":14.8518662}, +{"learn":[0.35017651],"iteration":355,"passed_time":8.214266086,"remaining_time":14.85951505}, +{"learn":[0.3501286962],"iteration":356,"passed_time":8.260065356,"remaining_time":14.87737262}, +{"learn":[0.3498837488],"iteration":357,"passed_time":8.323683533,"remaining_time":14.92682913}, +{"learn":[0.3495626772],"iteration":358,"passed_time":8.36389557,"remaining_time":14.93386368}, +{"learn":[0.3493757992],"iteration":359,"passed_time":8.399382759,"remaining_time":14.93223602}, +{"learn":[0.3490827511],"iteration":360,"passed_time":8.424002237,"remaining_time":14.91118401}, +{"learn":[0.3488646977],"iteration":361,"passed_time":8.448150513,"remaining_time":14.88928184}, +{"learn":[0.3484613426],"iteration":362,"passed_time":8.471364531,"remaining_time":14.86572784}, +{"learn":[0.3483259359],"iteration":363,"passed_time":8.496857622,"remaining_time":14.84615782}, +{"learn":[0.3480209179],"iteration":364,"passed_time":8.522528902,"remaining_time":14.82686535}, +{"learn":[0.3476817077],"iteration":365,"passed_time":8.54443234,"remaining_time":14.80101121}, +{"learn":[0.3474725024],"iteration":366,"passed_time":8.566187938,"remaining_time":14.77492361}, +{"learn":[0.3474285581],"iteration":367,"passed_time":8.577474249,"remaining_time":14.73087969}, +{"learn":[0.3470858003],"iteration":368,"passed_time":8.599341907,"remaining_time":14.70510771}, +{"learn":[0.3469015363],"iteration":369,"passed_time":8.621413585,"remaining_time":14.67970421}, +{"learn":[0.3463432335],"iteration":370,"passed_time":8.643379322,"remaining_time":14.65413907}, +{"learn":[0.3461185251],"iteration":371,"passed_time":8.665799542,"remaining_time":14.62936052}, +{"learn":[0.3458407874],"iteration":372,"passed_time":8.701760975,"remaining_time":14.62735692}, +{"learn":[0.3457031815],"iteration":373,"passed_time":8.756442967,"remaining_time":14.65650614}, +{"learn":[0.3455128742],"iteration":374,"passed_time":8.807534181,"remaining_time":14.67922364}, +{"learn":[0.3452742962],"iteration":375,"passed_time":8.872117774,"remaining_time":14.72394014}, +{"learn":[0.3452251263],"iteration":376,"passed_time":8.899250902,"remaining_time":14.70618916}, +{"learn":[0.3450881669],"iteration":377,"passed_time":8.928085048,"remaining_time":14.69118757}, +{"learn":[0.3449793371],"iteration":378,"passed_time":8.947728076,"remaining_time":14.66105313}, +{"learn":[0.344691491],"iteration":379,"passed_time":8.969934723,"remaining_time":14.63515665}, +{"learn":[0.3443639578],"iteration":380,"passed_time":8.99241215,"remaining_time":14.60971948}, +{"learn":[0.3442136782],"iteration":381,"passed_time":9.02144383,"remaining_time":14.59490127}, +{"learn":[0.3440594348],"iteration":382,"passed_time":9.03745504,"remaining_time":14.55903332}, +{"learn":[0.3439143606],"iteration":383,"passed_time":9.059658661,"remaining_time":14.53320244}, +{"learn":[0.3437593269],"iteration":384,"passed_time":9.081463941,"remaining_time":14.50675409}, +{"learn":[0.3433892597],"iteration":385,"passed_time":9.103490585,"remaining_time":14.48068192}, +{"learn":[0.3430005665],"iteration":386,"passed_time":9.125031046,"remaining_time":14.45386055}, +{"learn":[0.3426363435],"iteration":387,"passed_time":9.147229098,"remaining_time":14.42810363}, +{"learn":[0.3425431519],"iteration":388,"passed_time":9.169451319,"remaining_time":14.40240297}, +{"learn":[0.3422194687],"iteration":389,"passed_time":9.192135544,"remaining_time":14.37744277}, +{"learn":[0.3420983186],"iteration":390,"passed_time":9.21482497,"remaining_time":14.35250232}, +{"learn":[0.3419547464],"iteration":391,"passed_time":9.240174122,"remaining_time":14.33169864}, +{"learn":[0.3418564406],"iteration":392,"passed_time":9.266114196,"remaining_time":14.31178452}, +{"learn":[0.3416273848],"iteration":393,"passed_time":9.291484275,"remaining_time":14.29096312}, +{"learn":[0.3413111854],"iteration":394,"passed_time":9.321332214,"remaining_time":14.27697719}, +{"learn":[0.3411554684],"iteration":395,"passed_time":9.340067818,"remaining_time":14.24596203}, +{"learn":[0.3410876043],"iteration":396,"passed_time":9.370184518,"remaining_time":14.23229538}, +{"learn":[0.3410429673],"iteration":397,"passed_time":9.39162494,"remaining_time":14.20542265}, +{"learn":[0.341042403],"iteration":398,"passed_time":9.406694781,"remaining_time":14.16898136}, +{"learn":[0.3409573532],"iteration":399,"passed_time":9.451310091,"remaining_time":14.17696514}, +{"learn":[0.3408655821],"iteration":400,"passed_time":9.4923409,"remaining_time":14.17933217}, +{"learn":[0.3406567823],"iteration":401,"passed_time":9.547103264,"remaining_time":14.20190983}, +{"learn":[0.3404763525],"iteration":402,"passed_time":9.579503053,"remaining_time":14.19097599}, +{"learn":[0.3403717595],"iteration":403,"passed_time":9.60199694,"remaining_time":14.16532222}, +{"learn":[0.3400880712],"iteration":404,"passed_time":9.62408225,"remaining_time":14.1390838}, +{"learn":[0.3399640397],"iteration":405,"passed_time":9.646009648,"remaining_time":14.1126348}, +{"learn":[0.3399010234],"iteration":406,"passed_time":9.667975784,"remaining_time":14.08626447}, +{"learn":[0.339826297],"iteration":407,"passed_time":9.690275059,"remaining_time":14.06039911}, +{"learn":[0.3397102041],"iteration":408,"passed_time":9.709651563,"remaining_time":14.03032781}, +{"learn":[0.3395576906],"iteration":409,"passed_time":9.732244916,"remaining_time":14.00493781}, +{"learn":[0.3392198413],"iteration":410,"passed_time":9.757549483,"remaining_time":13.98344683}, +{"learn":[0.3391475536],"iteration":411,"passed_time":9.785746366,"remaining_time":13.9660652}, +{"learn":[0.3389268153],"iteration":412,"passed_time":9.814648628,"remaining_time":13.94963376}, +{"learn":[0.3389266721],"iteration":413,"passed_time":9.823336433,"remaining_time":13.90452935}, +{"learn":[0.3388830216],"iteration":414,"passed_time":9.838841117,"remaining_time":13.86920977}, +{"learn":[0.3388260339],"iteration":415,"passed_time":9.861509022,"remaining_time":13.84404151}, +{"learn":[0.3385376482],"iteration":416,"passed_time":9.884074666,"remaining_time":13.81874228}, +{"learn":[0.3384459997],"iteration":417,"passed_time":9.906639396,"remaining_time":13.79345485}, +{"learn":[0.3384035804],"iteration":418,"passed_time":9.928521171,"remaining_time":13.76723341}, +{"learn":[0.338206978],"iteration":419,"passed_time":9.950592651,"remaining_time":13.74129461}, +{"learn":[0.3381563107],"iteration":420,"passed_time":9.972312358,"remaining_time":13.71489039}, +{"learn":[0.3380916237],"iteration":421,"passed_time":9.994182293,"remaining_time":13.68871414}, +{"learn":[0.3379155117],"iteration":422,"passed_time":10.01716742,"remaining_time":13.66407943}, +{"learn":[0.3377370109],"iteration":423,"passed_time":10.0451664,"remaining_time":13.64626379}, +{"learn":[0.3376685347],"iteration":424,"passed_time":10.06750274,"remaining_time":13.620739}, +{"learn":[0.3375387678],"iteration":425,"passed_time":10.08578742,"remaining_time":13.58976991}, +{"learn":[0.3375264339],"iteration":426,"passed_time":10.10044959,"remaining_time":13.5539991}, +{"learn":[0.3375078804],"iteration":427,"passed_time":10.10840815,"remaining_time":13.5093679}, +{"learn":[0.337340127],"iteration":428,"passed_time":10.13027685,"remaining_time":13.4834221}, +{"learn":[0.3372056844],"iteration":429,"passed_time":10.15208,"remaining_time":13.45740837}, +{"learn":[0.336977263],"iteration":430,"passed_time":10.18504522,"remaining_time":13.44615019}, +{"learn":[0.3367988208],"iteration":431,"passed_time":10.2187855,"remaining_time":13.43581056}, +{"learn":[0.3367285927],"iteration":432,"passed_time":10.23098873,"remaining_time":13.39716076}, +{"learn":[0.3366052887],"iteration":433,"passed_time":10.2766679,"remaining_time":13.40229039}, +{"learn":[0.3363612465],"iteration":434,"passed_time":10.32772274,"remaining_time":13.41416862}, +{"learn":[0.3362435567],"iteration":435,"passed_time":10.37212705,"remaining_time":13.41715518}, +{"learn":[0.3361462199],"iteration":436,"passed_time":10.40813808,"remaining_time":13.40911154}, +{"learn":[0.3361461347],"iteration":437,"passed_time":10.41298218,"remaining_time":13.36094973}, +{"learn":[0.3360079098],"iteration":438,"passed_time":10.43960066,"remaining_time":13.34081086}, +{"learn":[0.3358086626],"iteration":439,"passed_time":10.46151863,"remaining_time":13.31466007}, +{"learn":[0.3356011997],"iteration":440,"passed_time":10.48387624,"remaining_time":13.28908576}, +{"learn":[0.3354146851],"iteration":441,"passed_time":10.50689004,"remaining_time":13.26435439}, +{"learn":[0.3352191524],"iteration":442,"passed_time":10.53608105,"remaining_time":13.24739762}, +{"learn":[0.3348674793],"iteration":443,"passed_time":10.55831293,"remaining_time":13.22167115}, +{"learn":[0.3348375647],"iteration":444,"passed_time":10.56995489,"remaining_time":13.18275273}, +{"learn":[0.3346763511],"iteration":445,"passed_time":10.59183961,"remaining_time":13.15667969}, +{"learn":[0.3344469846],"iteration":446,"passed_time":10.61412676,"remaining_time":13.13112326}, +{"learn":[0.3341331513],"iteration":447,"passed_time":10.63614375,"remaining_time":13.10524854}, +{"learn":[0.3338919982],"iteration":448,"passed_time":10.65810123,"remaining_time":13.07931798}, +{"learn":[0.3336666898],"iteration":449,"passed_time":10.67988947,"remaining_time":13.05319824}, +{"learn":[0.3336666289],"iteration":450,"passed_time":10.68502464,"remaining_time":13.00682601}, +{"learn":[0.3336154028],"iteration":451,"passed_time":10.70821328,"remaining_time":12.98252407}, +{"learn":[0.3333581167],"iteration":452,"passed_time":10.73100265,"remaining_time":12.95774492}, +{"learn":[0.333290786],"iteration":453,"passed_time":10.74255886,"remaining_time":12.91946506}, +{"learn":[0.3332008443],"iteration":454,"passed_time":10.76369789,"remaining_time":12.89278099}, +{"learn":[0.3331038516],"iteration":455,"passed_time":10.79258158,"remaining_time":12.87536048}, +{"learn":[0.3329428533],"iteration":456,"passed_time":10.81736692,"remaining_time":12.85302021}, +{"learn":[0.3329254389],"iteration":457,"passed_time":10.83350231,"remaining_time":12.82043286}, +{"learn":[0.3326182973],"iteration":458,"passed_time":10.85619419,"remaining_time":12.795645}, +{"learn":[0.3321795229],"iteration":459,"passed_time":10.87927788,"remaining_time":12.77132621}, +{"learn":[0.3320965842],"iteration":460,"passed_time":10.90369744,"remaining_time":12.74857466}, +{"learn":[0.3320919904],"iteration":461,"passed_time":10.9128379,"remaining_time":12.70802336}, +{"learn":[0.3317616467],"iteration":462,"passed_time":10.94039362,"remaining_time":12.68896625}, +{"learn":[0.3314515976],"iteration":463,"passed_time":10.96485849,"remaining_time":12.66630204}, +{"learn":[0.3314302988],"iteration":464,"passed_time":10.97934712,"remaining_time":12.63215206}, +{"learn":[0.331326468],"iteration":465,"passed_time":11.02336518,"remaining_time":12.63192491}, +{"learn":[0.3312172495],"iteration":466,"passed_time":11.06920655,"remaining_time":12.6335912}, +{"learn":[0.3311362468],"iteration":467,"passed_time":11.11033467,"remaining_time":12.62969667}, +{"learn":[0.3308259578],"iteration":468,"passed_time":11.15241621,"remaining_time":12.62672283}, +{"learn":[0.3306543113],"iteration":469,"passed_time":11.19050052,"remaining_time":12.61907506}, +{"learn":[0.3304472924],"iteration":470,"passed_time":11.22114388,"remaining_time":12.60294079}, +{"learn":[0.3302050118],"iteration":471,"passed_time":11.24489435,"remaining_time":12.57903435}, +{"learn":[0.3302042287],"iteration":472,"passed_time":11.25318644,"remaining_time":12.5379054}, +{"learn":[0.3302042278],"iteration":473,"passed_time":11.2585324,"remaining_time":12.49364566}, +{"learn":[0.330077596],"iteration":474,"passed_time":11.28675622,"remaining_time":12.47483582}, +{"learn":[0.3299967493],"iteration":475,"passed_time":11.30915867,"remaining_time":12.44957803}, +{"learn":[0.3298204689],"iteration":476,"passed_time":11.33547981,"remaining_time":12.42862881}, +{"learn":[0.3296573275],"iteration":477,"passed_time":11.36870769,"remaining_time":12.41519961}, +{"learn":[0.3295569924],"iteration":478,"passed_time":11.39100902,"remaining_time":12.38980313}, +{"learn":[0.329329664],"iteration":479,"passed_time":11.41344547,"remaining_time":12.36456593}, +{"learn":[0.329131173],"iteration":480,"passed_time":11.43771739,"remaining_time":12.34132084}, +{"learn":[0.3289868495],"iteration":481,"passed_time":11.45959838,"remaining_time":12.31550199}, +{"learn":[0.3288599313],"iteration":482,"passed_time":11.481945,"remaining_time":12.29019786}, +{"learn":[0.3285822513],"iteration":483,"passed_time":11.50452789,"remaining_time":12.26515783}, +{"learn":[0.3282988587],"iteration":484,"passed_time":11.52631836,"remaining_time":12.23928651}, +{"learn":[0.3282849959],"iteration":485,"passed_time":11.54937837,"remaining_time":12.21477465}, +{"learn":[0.3281045884],"iteration":486,"passed_time":11.57297806,"remaining_time":12.19083726}, +{"learn":[0.3279303325],"iteration":487,"passed_time":11.59488577,"remaining_time":12.16512606}, +{"learn":[0.3277856921],"iteration":488,"passed_time":11.61756328,"remaining_time":12.14023484}, +{"learn":[0.3277359886],"iteration":489,"passed_time":11.63917325,"remaining_time":12.11424154}, +{"learn":[0.3275212786],"iteration":490,"passed_time":11.66039364,"remaining_time":12.08786225}, +{"learn":[0.3273286251],"iteration":491,"passed_time":11.68281481,"remaining_time":12.06274374}, +{"learn":[0.3271903876],"iteration":492,"passed_time":11.70660697,"remaining_time":12.03904611}, +{"learn":[0.3270655317],"iteration":493,"passed_time":11.73027173,"remaining_time":12.0152176}, +{"learn":[0.3270389056],"iteration":494,"passed_time":11.73848459,"remaining_time":11.97562569}, +{"learn":[0.326813723],"iteration":495,"passed_time":11.76041241,"remaining_time":11.95009648}, +{"learn":[0.3265823051],"iteration":496,"passed_time":11.7841956,"remaining_time":11.92645954}, +{"learn":[0.326481471],"iteration":497,"passed_time":11.80409698,"remaining_time":11.898909}, +{"learn":[0.3263322725],"iteration":498,"passed_time":11.82616979,"remaining_time":11.87356926}, +{"learn":[0.3261136043],"iteration":499,"passed_time":11.86466859,"remaining_time":11.86466859}, +{"learn":[0.3259491378],"iteration":500,"passed_time":11.88944591,"remaining_time":11.84198305}, +{"learn":[0.3255755285],"iteration":501,"passed_time":11.91145079,"remaining_time":11.81653883}, +{"learn":[0.325431063],"iteration":502,"passed_time":11.9334484,"remaining_time":11.79110111}, +{"learn":[0.3251221632],"iteration":503,"passed_time":11.9553648,"remaining_time":11.7655971}, +{"learn":[0.3249533874],"iteration":504,"passed_time":11.97708778,"remaining_time":11.73991773}, +{"learn":[0.3245557056],"iteration":505,"passed_time":11.99903462,"remaining_time":11.71447253}, +{"learn":[0.3244819748],"iteration":506,"passed_time":12.02060642,"remaining_time":11.68867646}, +{"learn":[0.3244571553],"iteration":507,"passed_time":12.0398824,"remaining_time":11.66067351}, +{"learn":[0.3243944087],"iteration":508,"passed_time":12.06431851,"remaining_time":11.63768249}, +{"learn":[0.3243932505],"iteration":509,"passed_time":12.07556097,"remaining_time":11.60200956}, +{"learn":[0.3243735511],"iteration":510,"passed_time":12.08694504,"remaining_time":11.56656776}, +{"learn":[0.3242641705],"iteration":511,"passed_time":12.10916608,"remaining_time":11.54154892}, +{"learn":[0.3238891977],"iteration":512,"passed_time":12.13107379,"remaining_time":11.51624354}, +{"learn":[0.3237673065],"iteration":513,"passed_time":12.15282633,"remaining_time":11.49080466}, +{"learn":[0.3236015493],"iteration":514,"passed_time":12.17484746,"remaining_time":11.46563305}, +{"learn":[0.3233656351],"iteration":515,"passed_time":12.19863579,"remaining_time":11.44213125}, +{"learn":[0.3232732615],"iteration":516,"passed_time":12.22211573,"remaining_time":11.41834023}, +{"learn":[0.3231361121],"iteration":517,"passed_time":12.24498624,"remaining_time":11.39398333}, +{"learn":[0.32299658],"iteration":518,"passed_time":12.2674654,"remaining_time":11.36926947}, +{"learn":[0.3229860023],"iteration":519,"passed_time":12.27596326,"remaining_time":11.3316584}, +{"learn":[0.322752282],"iteration":520,"passed_time":12.30415749,"remaining_time":11.31226764}, +{"learn":[0.3227072424],"iteration":521,"passed_time":12.32641801,"remaining_time":11.2874096}, +{"learn":[0.3226090551],"iteration":522,"passed_time":12.35471927,"remaining_time":11.26807092}, +{"learn":[0.3224092365],"iteration":523,"passed_time":12.39195665,"remaining_time":11.25681558}, +{"learn":[0.3224092358],"iteration":524,"passed_time":12.39737271,"remaining_time":11.21667054}, +{"learn":[0.322391538],"iteration":525,"passed_time":12.40533802,"remaining_time":11.1789548}, +{"learn":[0.3222006912],"iteration":526,"passed_time":12.42948673,"remaining_time":11.15587708}, +{"learn":[0.3221324811],"iteration":527,"passed_time":12.4519036,"remaining_time":11.13124716}, +{"learn":[0.3221061996],"iteration":528,"passed_time":12.46338891,"remaining_time":11.09689258}, +{"learn":[0.3220694662],"iteration":529,"passed_time":12.48500417,"remaining_time":11.07160747}, +{"learn":[0.3219756017],"iteration":530,"passed_time":12.5070657,"remaining_time":11.04673035}, +{"learn":[0.3219724232],"iteration":531,"passed_time":12.51552779,"remaining_time":11.00990039}, +{"learn":[0.3215889876],"iteration":532,"passed_time":12.53731651,"remaining_time":10.98485331}, +{"learn":[0.3214944521],"iteration":533,"passed_time":12.56633158,"remaining_time":10.96612456}, +{"learn":[0.3214735687],"iteration":534,"passed_time":12.57450905,"remaining_time":10.92924618}, +{"learn":[0.3211667307],"iteration":535,"passed_time":12.59607083,"remaining_time":10.90406132}, +{"learn":[0.3210361058],"iteration":536,"passed_time":12.6184051,"remaining_time":10.87955598}, +{"learn":[0.3209803394],"iteration":537,"passed_time":12.63658166,"remaining_time":10.85148834}, +{"learn":[0.3209803394],"iteration":538,"passed_time":12.64103614,"remaining_time":10.81172108}, +{"learn":[0.3209335447],"iteration":539,"passed_time":12.65243667,"remaining_time":10.77800161}, +{"learn":[0.3208255558],"iteration":540,"passed_time":12.67388975,"remaining_time":10.75289352}, +{"learn":[0.3204879029],"iteration":541,"passed_time":12.69799169,"remaining_time":10.73003726}, +{"learn":[0.3203255553],"iteration":542,"passed_time":12.72041289,"remaining_time":10.70576186}, +{"learn":[0.3203078373],"iteration":543,"passed_time":12.7392844,"remaining_time":10.67851781}, +{"learn":[0.3201807045],"iteration":544,"passed_time":12.76135281,"remaining_time":10.65397345}, +{"learn":[0.3200168479],"iteration":545,"passed_time":12.78311559,"remaining_time":10.62918403}, +{"learn":[0.3199792981],"iteration":546,"passed_time":12.80212903,"remaining_time":10.6021288}, +{"learn":[0.3198294345],"iteration":547,"passed_time":12.82745361,"remaining_time":10.58030845}, +{"learn":[0.3198294344],"iteration":548,"passed_time":12.83217461,"remaining_time":10.54154964}, +{"learn":[0.319647278],"iteration":549,"passed_time":12.88575667,"remaining_time":10.54289182}, +{"learn":[0.3196091956],"iteration":550,"passed_time":12.91083071,"remaining_time":10.52080397}, +{"learn":[0.3194977614],"iteration":551,"passed_time":12.95694549,"remaining_time":10.51578184}, +{"learn":[0.3194412347],"iteration":552,"passed_time":12.97875463,"remaining_time":10.49096442}, +{"learn":[0.319377863],"iteration":553,"passed_time":13.00016171,"remaining_time":10.46583416}, +{"learn":[0.319212072],"iteration":554,"passed_time":13.02191225,"remaining_time":10.44099271}, +{"learn":[0.3192120719],"iteration":555,"passed_time":13.02651986,"remaining_time":10.40247269}, +{"learn":[0.3191064217],"iteration":556,"passed_time":13.05525834,"remaining_time":10.38326651}, +{"learn":[0.3190443835],"iteration":557,"passed_time":13.07782907,"remaining_time":10.35914059}, +{"learn":[0.3189403324],"iteration":558,"passed_time":13.09956572,"remaining_time":10.33436222}, +{"learn":[0.3187465621],"iteration":559,"passed_time":13.12216052,"remaining_time":10.31026898}, +{"learn":[0.3185833798],"iteration":560,"passed_time":13.14414249,"remaining_time":10.28570152}, +{"learn":[0.3184379867],"iteration":561,"passed_time":13.16591073,"remaining_time":10.26097669}, +{"learn":[0.3182631548],"iteration":562,"passed_time":13.18804655,"remaining_time":10.23654768}, +{"learn":[0.3181986719],"iteration":563,"passed_time":13.2078342,"remaining_time":10.21031155}, +{"learn":[0.3180519592],"iteration":564,"passed_time":13.23026202,"remaining_time":10.18613094}, +{"learn":[0.3180225705],"iteration":565,"passed_time":13.24844462,"remaining_time":10.15870135}, +{"learn":[0.3178969873],"iteration":566,"passed_time":13.27035077,"remaining_time":10.13414794}, +{"learn":[0.3176445672],"iteration":567,"passed_time":13.29577878,"remaining_time":10.11228245}, +{"learn":[0.317322944],"iteration":568,"passed_time":13.32134689,"remaining_time":10.09051056}, +{"learn":[0.317228846],"iteration":569,"passed_time":13.34365403,"remaining_time":10.06626532}, +{"learn":[0.3170580473],"iteration":570,"passed_time":13.37570572,"remaining_time":10.04934808}, +{"learn":[0.3167691984],"iteration":571,"passed_time":13.40324414,"remaining_time":10.02900086}, +{"learn":[0.316670053],"iteration":572,"passed_time":13.42788682,"remaining_time":10.00647063}, +{"learn":[0.3164501718],"iteration":573,"passed_time":13.45331304,"remaining_time":9.984514557}, +{"learn":[0.3163287563],"iteration":574,"passed_time":13.49501302,"remaining_time":9.974574844}, +{"learn":[0.3162894601],"iteration":575,"passed_time":13.53471092,"remaining_time":9.963051095}, +{"learn":[0.3162494869],"iteration":576,"passed_time":13.58837703,"remaining_time":9.961669818}, +{"learn":[0.3159951385],"iteration":577,"passed_time":13.63095028,"remaining_time":9.952008685}, +{"learn":[0.3157978717],"iteration":578,"passed_time":13.67218492,"remaining_time":9.941260534}, +{"learn":[0.3155850358],"iteration":579,"passed_time":13.70123406,"remaining_time":9.921583284}, +{"learn":[0.315355402],"iteration":580,"passed_time":13.72422975,"remaining_time":9.897508201}, +{"learn":[0.3150989936],"iteration":581,"passed_time":13.74689945,"remaining_time":9.873202701}, +{"learn":[0.3148114702],"iteration":582,"passed_time":13.76882133,"remaining_time":9.848367913}, +{"learn":[0.3144519215],"iteration":583,"passed_time":13.79434107,"remaining_time":9.826105965}, +{"learn":[0.3143229251],"iteration":584,"passed_time":13.84787179,"remaining_time":9.823703919}, +{"learn":[0.3141904066],"iteration":585,"passed_time":13.90335501,"remaining_time":9.82250678}, +{"learn":[0.3140027965],"iteration":586,"passed_time":13.9489919,"remaining_time":9.814197027}, +{"learn":[0.3138685082],"iteration":587,"passed_time":13.99129849,"remaining_time":9.80342683}, +{"learn":[0.3138181058],"iteration":588,"passed_time":14.03659042,"remaining_time":9.794632705}, +{"learn":[0.313574669],"iteration":589,"passed_time":14.06815424,"remaining_time":9.776174981}, +{"learn":[0.3134898049],"iteration":590,"passed_time":14.09487967,"remaining_time":9.754324512}, +{"learn":[0.313320396],"iteration":591,"passed_time":14.11692573,"remaining_time":9.729232599}, +{"learn":[0.3131676802],"iteration":592,"passed_time":14.13857285,"remaining_time":9.70387715}, +{"learn":[0.3129757867],"iteration":593,"passed_time":14.16077145,"remaining_time":9.678911124}, +{"learn":[0.3127907517],"iteration":594,"passed_time":14.18313665,"remaining_time":9.654067803}, +{"learn":[0.3125289035],"iteration":595,"passed_time":14.20720097,"remaining_time":9.630384553}, +{"learn":[0.3123599621],"iteration":596,"passed_time":14.23064686,"remaining_time":9.606282555}, +{"learn":[0.3121137456],"iteration":597,"passed_time":14.25288883,"remaining_time":9.581373427}, +{"learn":[0.3119284015],"iteration":598,"passed_time":14.27492804,"remaining_time":9.55633747}, +{"learn":[0.3119267487],"iteration":599,"passed_time":14.28632892,"remaining_time":9.52421928}, +{"learn":[0.3119112192],"iteration":600,"passed_time":14.30279762,"remaining_time":9.495534525}, +{"learn":[0.3118470126],"iteration":601,"passed_time":14.32951711,"remaining_time":9.473667455}, +{"learn":[0.3117666572],"iteration":602,"passed_time":14.35212255,"remaining_time":9.449075711}, +{"learn":[0.3116060866],"iteration":603,"passed_time":14.37601067,"remaining_time":9.425331499}, +{"learn":[0.311604484],"iteration":604,"passed_time":14.38875212,"remaining_time":9.394309237}, +{"learn":[0.3113084243],"iteration":605,"passed_time":14.43525,"remaining_time":9.385294556}, +{"learn":[0.3112684311],"iteration":606,"passed_time":14.48716047,"remaining_time":9.379660734}, +{"learn":[0.3111182078],"iteration":607,"passed_time":14.55474728,"remaining_time":9.383981801}, +{"learn":[0.3109941013],"iteration":608,"passed_time":14.60355513,"remaining_time":9.376009941}, +{"learn":[0.3108986608],"iteration":609,"passed_time":14.65277384,"remaining_time":9.368166881}, +{"learn":[0.3107318621],"iteration":610,"passed_time":14.67810413,"remaining_time":9.344979556}, +{"learn":[0.3106806721],"iteration":611,"passed_time":14.70494523,"remaining_time":9.322743053}, +{"learn":[0.3105565129],"iteration":612,"passed_time":14.73133964,"remaining_time":9.300209526}, +{"learn":[0.3103924843],"iteration":613,"passed_time":14.7562304,"remaining_time":9.276718134}, +{"learn":[0.3102082538],"iteration":614,"passed_time":14.78098881,"remaining_time":9.253139335}, +{"learn":[0.3100890351],"iteration":615,"passed_time":14.805187,"remaining_time":9.229207479}, +{"learn":[0.3099299428],"iteration":616,"passed_time":14.83016501,"remaining_time":9.205758831}, +{"learn":[0.3099148853],"iteration":617,"passed_time":14.85097273,"remaining_time":9.179727481}, +{"learn":[0.3098292521],"iteration":618,"passed_time":14.87482513,"remaining_time":9.155587033}, +{"learn":[0.3097022539],"iteration":619,"passed_time":14.89875155,"remaining_time":9.131492883}, +{"learn":[0.3095586079],"iteration":620,"passed_time":14.92966579,"remaining_time":9.111663983}, +{"learn":[0.3095365057],"iteration":621,"passed_time":14.96288268,"remaining_time":9.093198797}, +{"learn":[0.3093867074],"iteration":622,"passed_time":14.98789146,"remaining_time":9.069719231}, +{"learn":[0.3090971237],"iteration":623,"passed_time":15.01706544,"remaining_time":9.048744563}, +{"learn":[0.3090567117],"iteration":624,"passed_time":15.03814037,"remaining_time":9.022884225}, +{"learn":[0.3090514438],"iteration":625,"passed_time":15.05096904,"remaining_time":8.992112496}, +{"learn":[0.3089121979],"iteration":626,"passed_time":15.1048228,"remaining_time":8.985803678}, +{"learn":[0.3088734529],"iteration":627,"passed_time":15.13101518,"remaining_time":8.962958036}, +{"learn":[0.3087798566],"iteration":628,"passed_time":15.15559681,"remaining_time":8.939151693}, +{"learn":[0.3085569569],"iteration":629,"passed_time":15.18628248,"remaining_time":8.918927806}, +{"learn":[0.3083945767],"iteration":630,"passed_time":15.21558256,"remaining_time":8.89786048}, +{"learn":[0.3082636175],"iteration":631,"passed_time":15.24035069,"remaining_time":8.874128248}, +{"learn":[0.308097633],"iteration":632,"passed_time":15.26563185,"remaining_time":8.850690187}, +{"learn":[0.3080161232],"iteration":633,"passed_time":15.2904056,"remaining_time":8.826953388}, +{"learn":[0.3079940498],"iteration":634,"passed_time":15.31462655,"remaining_time":8.802895579}, +{"learn":[0.3077049522],"iteration":635,"passed_time":15.33624358,"remaining_time":8.777346955}, +{"learn":[0.3074875181],"iteration":636,"passed_time":15.35822191,"remaining_time":8.752016568}, +{"learn":[0.3073941113],"iteration":637,"passed_time":15.38096155,"remaining_time":8.727128651}, +{"learn":[0.3070378662],"iteration":638,"passed_time":15.4242628,"remaining_time":8.713863648}, +{"learn":[0.3069235694],"iteration":639,"passed_time":15.45524212,"remaining_time":8.693573694}, +{"learn":[0.3068787888],"iteration":640,"passed_time":15.47926165,"remaining_time":8.669352466}, +{"learn":[0.3067815049],"iteration":641,"passed_time":15.51473893,"remaining_time":8.651521084}, +{"learn":[0.3067274077],"iteration":642,"passed_time":15.5591241,"remaining_time":8.638580567}, +{"learn":[0.3067273505],"iteration":643,"passed_time":15.57439764,"remaining_time":8.609449626}, +{"learn":[0.30654485],"iteration":644,"passed_time":15.60990177,"remaining_time":8.591496323}, +{"learn":[0.306542431],"iteration":645,"passed_time":15.62539633,"remaining_time":8.562523686}, +{"learn":[0.3063441894],"iteration":646,"passed_time":15.66716512,"remaining_time":8.547927802}, +{"learn":[0.3061944627],"iteration":647,"passed_time":15.71421395,"remaining_time":8.536116217}, +{"learn":[0.3061943966],"iteration":648,"passed_time":15.72971142,"remaining_time":8.507132062}, +{"learn":[0.3059553625],"iteration":649,"passed_time":15.75314641,"remaining_time":8.48246345}, +{"learn":[0.3057317972],"iteration":650,"passed_time":15.77560955,"remaining_time":8.457277621}, +{"learn":[0.305636842],"iteration":651,"passed_time":15.79864888,"remaining_time":8.432407685}, +{"learn":[0.3056207008],"iteration":652,"passed_time":15.807586,"remaining_time":8.400049528}, +{"learn":[0.3054612738],"iteration":653,"passed_time":15.82717303,"remaining_time":8.373397353}, +{"learn":[0.3053219515],"iteration":654,"passed_time":15.85644191,"remaining_time":8.35186635}, +{"learn":[0.3053042191],"iteration":655,"passed_time":15.87826828,"remaining_time":8.326408976}, +{"learn":[0.3051397112],"iteration":656,"passed_time":15.9139373,"remaining_time":8.308189489}, +{"learn":[0.3049434285],"iteration":657,"passed_time":15.96952775,"remaining_time":8.300271261}, +{"learn":[0.3048304658],"iteration":658,"passed_time":16.04229694,"remaining_time":8.301097507}, +{"learn":[0.3047096301],"iteration":659,"passed_time":16.09940802,"remaining_time":8.293634435}, +{"learn":[0.3042903415],"iteration":660,"passed_time":16.17347815,"remaining_time":8.29471875}, +{"learn":[0.3042772412],"iteration":661,"passed_time":16.1971499,"remaining_time":8.269843906}, +{"learn":[0.3040841367],"iteration":662,"passed_time":16.23556689,"remaining_time":8.252467636}, +{"learn":[0.3039029953],"iteration":663,"passed_time":16.26662238,"remaining_time":8.231302891}, +{"learn":[0.3036718031],"iteration":664,"passed_time":16.29784551,"remaining_time":8.210192852}, +{"learn":[0.303650484],"iteration":665,"passed_time":16.32503138,"remaining_time":8.18702775}, +{"learn":[0.3035074481],"iteration":666,"passed_time":16.38176119,"remaining_time":8.178600412}, +{"learn":[0.3033167887],"iteration":667,"passed_time":16.45371574,"remaining_time":8.17759525}, +{"learn":[0.3032946087],"iteration":668,"passed_time":16.4777861,"remaining_time":8.152686399}, +{"learn":[0.3032089215],"iteration":669,"passed_time":16.54239358,"remaining_time":8.147746092}, +{"learn":[0.3030821849],"iteration":670,"passed_time":16.56585054,"remaining_time":8.122451308}, +{"learn":[0.3029894163],"iteration":671,"passed_time":16.58837822,"remaining_time":8.096708416}, +{"learn":[0.302865477],"iteration":672,"passed_time":16.6172538,"remaining_time":8.074059426}, +{"learn":[0.3028067159],"iteration":673,"passed_time":16.63609293,"remaining_time":8.046537528}, +{"learn":[0.3027061901],"iteration":674,"passed_time":16.65820596,"remaining_time":8.020617682}, +{"learn":[0.3025646938],"iteration":675,"passed_time":16.68103442,"remaining_time":7.995051998}, +{"learn":[0.3025250377],"iteration":676,"passed_time":16.69379449,"remaining_time":7.964690722}, +{"learn":[0.3020655554],"iteration":677,"passed_time":16.7164889,"remaining_time":7.93909945}, +{"learn":[0.3020534847],"iteration":678,"passed_time":16.72869792,"remaining_time":7.908559695}, +{"learn":[0.3020343145],"iteration":679,"passed_time":16.76349825,"remaining_time":7.888705057}, +{"learn":[0.3018419602],"iteration":680,"passed_time":16.8072208,"remaining_time":7.872985954}, +{"learn":[0.3016898998],"iteration":681,"passed_time":16.85202658,"remaining_time":7.857689812}, +{"learn":[0.3015708555],"iteration":682,"passed_time":16.88419123,"remaining_time":7.836440148}, +{"learn":[0.3014896934],"iteration":683,"passed_time":16.92755692,"remaining_time":7.820333312}, +{"learn":[0.301382652],"iteration":684,"passed_time":16.95983849,"remaining_time":7.799049817}, +{"learn":[0.3010326679],"iteration":685,"passed_time":16.9823736,"remaining_time":7.773273046}, +{"learn":[0.3009148994],"iteration":686,"passed_time":17.00382974,"remaining_time":7.74701413}, +{"learn":[0.30091463],"iteration":687,"passed_time":17.01200093,"remaining_time":7.714744607}, +{"learn":[0.3007108906],"iteration":688,"passed_time":17.03396364,"remaining_time":7.688770234}, +{"learn":[0.3006049621],"iteration":689,"passed_time":17.05610975,"remaining_time":7.662889886}, +{"learn":[0.3004424014],"iteration":690,"passed_time":17.07874149,"remaining_time":7.63723751}, +{"learn":[0.3002521525],"iteration":691,"passed_time":17.10159712,"remaining_time":7.611693515}, +{"learn":[0.3001677248],"iteration":692,"passed_time":17.13033905,"remaining_time":7.588764918}, +{"learn":[0.3000495606],"iteration":693,"passed_time":17.15264985,"remaining_time":7.562983939}, +{"learn":[0.2999076935],"iteration":694,"passed_time":17.17487661,"remaining_time":7.537176065}, +{"learn":[0.2997878011],"iteration":695,"passed_time":17.1986168,"remaining_time":7.512039522}, +{"learn":[0.2997774515],"iteration":696,"passed_time":17.21042258,"remaining_time":7.481718853}, +{"learn":[0.2997265735],"iteration":697,"passed_time":17.23318916,"remaining_time":7.456193591}, +{"learn":[0.2996999851],"iteration":698,"passed_time":17.25516902,"remaining_time":7.430337448}, +{"learn":[0.2995208066],"iteration":699,"passed_time":17.27751275,"remaining_time":7.40464832}, +{"learn":[0.2995205559],"iteration":700,"passed_time":17.28640479,"remaining_time":7.373231143}, +{"learn":[0.2993846391],"iteration":701,"passed_time":17.31035892,"remaining_time":7.348272021}, +{"learn":[0.2991289729],"iteration":702,"passed_time":17.33681112,"remaining_time":7.324371129}, +{"learn":[0.2990709937],"iteration":703,"passed_time":17.36675989,"remaining_time":7.301933138}, +{"learn":[0.2990700247],"iteration":704,"passed_time":17.37528246,"remaining_time":7.270508264}, +{"learn":[0.2989463307],"iteration":705,"passed_time":17.39860223,"remaining_time":7.245310278}, +{"learn":[0.2989462517],"iteration":706,"passed_time":17.4147936,"remaining_time":7.217163403}, +{"learn":[0.2987724441],"iteration":707,"passed_time":17.44933557,"remaining_time":7.196618625}, +{"learn":[0.2987179044],"iteration":708,"passed_time":17.47148817,"remaining_time":7.170949307}, +{"learn":[0.2985139439],"iteration":709,"passed_time":17.49374124,"remaining_time":7.14533093}, +{"learn":[0.2982107603],"iteration":710,"passed_time":17.51577211,"remaining_time":7.119631702}, +{"learn":[0.2981313323],"iteration":711,"passed_time":17.53812766,"remaining_time":7.094074111}, +{"learn":[0.2980878246],"iteration":712,"passed_time":17.56294973,"remaining_time":7.069518333}, +{"learn":[0.297945571],"iteration":713,"passed_time":17.58499817,"remaining_time":7.043850809}, +{"learn":[0.2977036341],"iteration":714,"passed_time":17.60727451,"remaining_time":7.018284247}, +{"learn":[0.2976532538],"iteration":715,"passed_time":17.63636028,"remaining_time":6.99542782}, +{"learn":[0.2972948225],"iteration":716,"passed_time":17.65843273,"remaining_time":6.96978586}, +{"learn":[0.2972072898],"iteration":717,"passed_time":17.68058855,"remaining_time":6.94418659}, +{"learn":[0.2970205352],"iteration":718,"passed_time":17.70485614,"remaining_time":6.919422218}, +{"learn":[0.2968625698],"iteration":719,"passed_time":17.72750556,"remaining_time":6.89402994}, +{"learn":[0.296778922],"iteration":720,"passed_time":17.75015606,"remaining_time":6.868645689}, +{"learn":[0.2965144868],"iteration":721,"passed_time":17.77211874,"remaining_time":6.843004167}, +{"learn":[0.2964393382],"iteration":722,"passed_time":17.79405049,"remaining_time":6.817360975}, +{"learn":[0.2963119084],"iteration":723,"passed_time":17.81623397,"remaining_time":6.791824}, +{"learn":[0.2960547659],"iteration":724,"passed_time":17.83883814,"remaining_time":6.766455845}, +{"learn":[0.2959726674],"iteration":725,"passed_time":17.86237455,"remaining_time":6.741447144}, +{"learn":[0.2959442898],"iteration":726,"passed_time":17.92023066,"remaining_time":6.729330081}, +{"learn":[0.2958761466],"iteration":727,"passed_time":17.93996576,"remaining_time":6.702844349}, +{"learn":[0.2955882368],"iteration":728,"passed_time":17.96248951,"remaining_time":6.677413797}, +{"learn":[0.2955462923],"iteration":729,"passed_time":18.01029763,"remaining_time":6.661342958}, +{"learn":[0.2953304881],"iteration":730,"passed_time":18.03427959,"remaining_time":6.636417524}, +{"learn":[0.2951897941],"iteration":731,"passed_time":18.05763098,"remaining_time":6.6112638}, +{"learn":[0.2950068022],"iteration":732,"passed_time":18.08062816,"remaining_time":6.585985974}, +{"learn":[0.2949951299],"iteration":733,"passed_time":18.10420309,"remaining_time":6.560923737}, +{"learn":[0.2948810476],"iteration":734,"passed_time":18.13520748,"remaining_time":6.538544192}, +{"learn":[0.2948013604],"iteration":735,"passed_time":18.15856612,"remaining_time":6.513398716}, +{"learn":[0.2947457831],"iteration":736,"passed_time":18.17803723,"remaining_time":6.486870815}, +{"learn":[0.2945614394],"iteration":737,"passed_time":18.20246632,"remaining_time":6.462122191}, +{"learn":[0.2942434298],"iteration":738,"passed_time":18.22474259,"remaining_time":6.436614093}, +{"learn":[0.2939751704],"iteration":739,"passed_time":18.24767836,"remaining_time":6.411346451}, +{"learn":[0.2938581582],"iteration":740,"passed_time":18.2701075,"remaining_time":6.38590802}, +{"learn":[0.29382581],"iteration":741,"passed_time":18.27862017,"remaining_time":6.355638818}, +{"learn":[0.2935313901],"iteration":742,"passed_time":18.30044636,"remaining_time":6.330033264}, +{"learn":[0.293385087],"iteration":743,"passed_time":18.32305332,"remaining_time":6.304706517}, +{"learn":[0.2931688515],"iteration":744,"passed_time":18.345594,"remaining_time":6.27936439}, +{"learn":[0.2929784993],"iteration":745,"passed_time":18.37302216,"remaining_time":6.255693871}, +{"learn":[0.2927616087],"iteration":746,"passed_time":18.40180032,"remaining_time":6.232470523}, +{"learn":[0.2927348935],"iteration":747,"passed_time":18.43168092,"remaining_time":6.209603732}, +{"learn":[0.2926524614],"iteration":748,"passed_time":18.45196518,"remaining_time":6.183502349}, +{"learn":[0.292532443],"iteration":749,"passed_time":18.4744705,"remaining_time":6.158156832}, +{"learn":[0.2923772006],"iteration":750,"passed_time":18.4974505,"remaining_time":6.132976263}, +{"learn":[0.292133322],"iteration":751,"passed_time":18.52078053,"remaining_time":6.107916982}, +{"learn":[0.291968671],"iteration":752,"passed_time":18.54324045,"remaining_time":6.082576881}, +{"learn":[0.2918869516],"iteration":753,"passed_time":18.56544318,"remaining_time":6.057160508}, +{"learn":[0.2917246816],"iteration":754,"passed_time":18.58865144,"remaining_time":6.032078943}, +{"learn":[0.2916077821],"iteration":755,"passed_time":18.61393085,"remaining_time":6.007670802}, +{"learn":[0.2914285282],"iteration":756,"passed_time":18.64160854,"remaining_time":5.984030217}, +{"learn":[0.2913445284],"iteration":757,"passed_time":18.66491,"remaining_time":5.958981822}, +{"learn":[0.2913443551],"iteration":758,"passed_time":18.67365163,"remaining_time":5.929314943}, +{"learn":[0.291344066],"iteration":759,"passed_time":18.68183598,"remaining_time":5.899527152}, +{"learn":[0.2911691075],"iteration":760,"passed_time":18.70671,"remaining_time":5.8750377}, +{"learn":[0.2908231947],"iteration":761,"passed_time":18.73052052,"remaining_time":5.85021507}, +{"learn":[0.2907754775],"iteration":762,"passed_time":18.75434069,"remaining_time":5.825398092}, +{"learn":[0.2906135806],"iteration":763,"passed_time":18.77785035,"remaining_time":5.800487806}, +{"learn":[0.2905947266],"iteration":764,"passed_time":18.79727277,"remaining_time":5.774325622}, +{"learn":[0.2905295128],"iteration":765,"passed_time":18.81722706,"remaining_time":5.748343516}, +{"learn":[0.2902453894],"iteration":766,"passed_time":18.8405561,"remaining_time":5.723402309}, +{"learn":[0.2900319175],"iteration":767,"passed_time":18.86818989,"remaining_time":5.699765697}, +{"learn":[0.2899129422],"iteration":768,"passed_time":18.89480903,"remaining_time":5.675813895}, +{"learn":[0.289784147],"iteration":769,"passed_time":18.92259459,"remaining_time":5.65220358}, +{"learn":[0.2896433582],"iteration":770,"passed_time":18.95342224,"remaining_time":5.629485984}, +{"learn":[0.2893137629],"iteration":771,"passed_time":18.98132175,"remaining_time":5.605882591}, +{"learn":[0.2892767962],"iteration":772,"passed_time":19.00473325,"remaining_time":5.580950126}, +{"learn":[0.2890654442],"iteration":773,"passed_time":19.02796904,"remaining_time":5.55597029}, +{"learn":[0.2889086488],"iteration":774,"passed_time":19.05106703,"remaining_time":5.530954945}, +{"learn":[0.2887625489],"iteration":775,"passed_time":19.07288043,"remaining_time":5.505573731}, +{"learn":[0.2886341007],"iteration":776,"passed_time":19.09188604,"remaining_time":5.479395864}, +{"learn":[0.2886019791],"iteration":777,"passed_time":19.11521274,"remaining_time":5.454469444}, +{"learn":[0.2883053437],"iteration":778,"passed_time":19.14616913,"remaining_time":5.431711654}, +{"learn":[0.2881800888],"iteration":779,"passed_time":19.17758908,"remaining_time":5.409063588}, +{"learn":[0.2881493372],"iteration":780,"passed_time":19.2048689,"remaining_time":5.385232125}, +{"learn":[0.2879469616],"iteration":781,"passed_time":19.22949891,"remaining_time":5.360653148}, +{"learn":[0.2878030143],"iteration":782,"passed_time":19.2543558,"remaining_time":5.336136921}, +{"learn":[0.2876184323],"iteration":783,"passed_time":19.27809709,"remaining_time":5.311312464}, +{"learn":[0.2873371785],"iteration":784,"passed_time":19.30222025,"remaining_time":5.286595354}, +{"learn":[0.287291682],"iteration":785,"passed_time":19.32579239,"remaining_time":5.261729735}, +{"learn":[0.2870997336],"iteration":786,"passed_time":19.34894999,"remaining_time":5.236755206}, +{"learn":[0.2869277017],"iteration":787,"passed_time":19.37326393,"remaining_time":5.212096386}, +{"learn":[0.2868849395],"iteration":788,"passed_time":19.40280941,"remaining_time":5.188837498}, +{"learn":[0.2866008202],"iteration":789,"passed_time":19.43469769,"remaining_time":5.166185462}, +{"learn":[0.286433075],"iteration":790,"passed_time":19.46118519,"remaining_time":5.142083065}, +{"learn":[0.2863247094],"iteration":791,"passed_time":19.48432218,"remaining_time":5.117094713}, +{"learn":[0.2861530229],"iteration":792,"passed_time":19.50804413,"remaining_time":5.092263727}, +{"learn":[0.2860601397],"iteration":793,"passed_time":19.53011588,"remaining_time":5.067007394}, +{"learn":[0.285782435],"iteration":794,"passed_time":19.55303951,"remaining_time":5.041978741}, +{"learn":[0.2857395573],"iteration":795,"passed_time":19.57553156,"remaining_time":5.016844771}, +{"learn":[0.2855575819],"iteration":796,"passed_time":19.59854296,"remaining_time":4.991849714}, +{"learn":[0.2855155269],"iteration":797,"passed_time":19.62208312,"remaining_time":4.966993471}, +{"learn":[0.2853027357],"iteration":798,"passed_time":19.65210334,"remaining_time":4.943770678}, +{"learn":[0.2852479317],"iteration":799,"passed_time":19.67522216,"remaining_time":4.918805541}, +{"learn":[0.2851592302],"iteration":800,"passed_time":19.69927286,"remaining_time":4.894076529}, +{"learn":[0.2851054653],"iteration":801,"passed_time":19.72196036,"remaining_time":4.869012657}, +{"learn":[0.2850244642],"iteration":802,"passed_time":19.74401728,"remaining_time":4.843800004}, +{"learn":[0.2847988254],"iteration":803,"passed_time":19.76599931,"remaining_time":4.818576947}, +{"learn":[0.2847954492],"iteration":804,"passed_time":19.77443812,"remaining_time":4.790081285}, +{"learn":[0.2847668538],"iteration":805,"passed_time":19.79611254,"remaining_time":4.764821133}, +{"learn":[0.2846572393],"iteration":806,"passed_time":19.81859879,"remaining_time":4.739764022}, +{"learn":[0.2843730264],"iteration":807,"passed_time":19.84128682,"remaining_time":4.714761224}, +{"learn":[0.284141588],"iteration":808,"passed_time":19.86445555,"remaining_time":4.689877639}, +{"learn":[0.284041018],"iteration":809,"passed_time":19.89360124,"remaining_time":4.66640029}, +{"learn":[0.2839261452],"iteration":810,"passed_time":19.91740236,"remaining_time":4.641663434}, +{"learn":[0.2837666765],"iteration":811,"passed_time":19.94034852,"remaining_time":4.616730937}, +{"learn":[0.2836468321],"iteration":812,"passed_time":19.97762223,"remaining_time":4.595098841}, +{"learn":[0.2835959553],"iteration":813,"passed_time":20.00746692,"remaining_time":4.571730771}, +{"learn":[0.2834490287],"iteration":814,"passed_time":20.0425443,"remaining_time":4.549534595}, +{"learn":[0.2833510414],"iteration":815,"passed_time":20.08029393,"remaining_time":4.527909416}, +{"learn":[0.2833281488],"iteration":816,"passed_time":20.13046868,"remaining_time":4.509027868}, +{"learn":[0.2832314365],"iteration":817,"passed_time":20.18125584,"remaining_time":4.490206068}, +{"learn":[0.2831363442],"iteration":818,"passed_time":20.21374897,"remaining_time":4.467263204}, +{"learn":[0.2830386545],"iteration":819,"passed_time":20.24440593,"remaining_time":4.443893986}, +{"learn":[0.2829967032],"iteration":820,"passed_time":20.26934245,"remaining_time":4.419259804}, +{"learn":[0.2828641845],"iteration":821,"passed_time":20.29211314,"remaining_time":4.394155886}, +{"learn":[0.2825780004],"iteration":822,"passed_time":20.31456744,"remaining_time":4.368989596}, +{"learn":[0.2823101112],"iteration":823,"passed_time":20.33763218,"remaining_time":4.343960272}, +{"learn":[0.2821905518],"iteration":824,"passed_time":20.3598163,"remaining_time":4.318748912}, +{"learn":[0.2819471832],"iteration":825,"passed_time":20.38282979,"remaining_time":4.293719593}, +{"learn":[0.2819286265],"iteration":826,"passed_time":20.41034151,"remaining_time":4.269636131}, +{"learn":[0.2818280875],"iteration":827,"passed_time":20.45157014,"remaining_time":4.248393797}, +{"learn":[0.2817546833],"iteration":828,"passed_time":20.48226,"remaining_time":4.224929385}, +{"learn":[0.281587275],"iteration":829,"passed_time":20.50552826,"remaining_time":4.199927474}, +{"learn":[0.2814154303],"iteration":830,"passed_time":20.52883315,"remaining_time":4.174937188}, +{"learn":[0.2813141668],"iteration":831,"passed_time":20.55206209,"remaining_time":4.149935615}, +{"learn":[0.2812636016],"iteration":832,"passed_time":20.57503672,"remaining_time":4.124887314}, +{"learn":[0.2812172885],"iteration":833,"passed_time":20.59771147,"remaining_time":4.099784297}, +{"learn":[0.281044403],"iteration":834,"passed_time":20.62116367,"remaining_time":4.074840726}, +{"learn":[0.2809039898],"iteration":835,"passed_time":20.6444309,"remaining_time":4.049864436}, +{"learn":[0.2807492094],"iteration":836,"passed_time":20.67501646,"remaining_time":4.026317424}, +{"learn":[0.2807239878],"iteration":837,"passed_time":20.70039035,"remaining_time":4.001746106}, +{"learn":[0.2804031359],"iteration":838,"passed_time":20.7230494,"remaining_time":3.976651911}, +{"learn":[0.2803187933],"iteration":839,"passed_time":20.74560852,"remaining_time":3.951544481}, +{"learn":[0.280178431],"iteration":840,"passed_time":20.7676303,"remaining_time":3.92634152}, +{"learn":[0.2800356414],"iteration":841,"passed_time":20.78986737,"remaining_time":3.901186513}, +{"learn":[0.2798041757],"iteration":842,"passed_time":20.82095241,"remaining_time":3.877686274}, +{"learn":[0.2796980093],"iteration":843,"passed_time":20.86209174,"remaining_time":3.856026435}, +{"learn":[0.2795734447],"iteration":844,"passed_time":20.91418815,"remaining_time":3.83633037}, +{"learn":[0.2794519833],"iteration":845,"passed_time":20.9700609,"remaining_time":3.817245129}, +{"learn":[0.2793843487],"iteration":846,"passed_time":21.03050779,"remaining_time":3.798899282}, +{"learn":[0.2792873292],"iteration":847,"passed_time":21.07558948,"remaining_time":3.7777}, +{"learn":[0.2790298494],"iteration":848,"passed_time":21.12625627,"remaining_time":3.757437806}, +{"learn":[0.2788323685],"iteration":849,"passed_time":21.16095811,"remaining_time":3.734286725}, +{"learn":[0.2786864684],"iteration":850,"passed_time":21.19017393,"remaining_time":3.710147963}, +{"learn":[0.2785577462],"iteration":851,"passed_time":21.21701221,"remaining_time":3.685584281}, +{"learn":[0.2783806677],"iteration":852,"passed_time":21.25896675,"remaining_time":3.663620296}, +{"learn":[0.2783359299],"iteration":853,"passed_time":21.30383455,"remaining_time":3.642107547}, +{"learn":[0.2779284052],"iteration":854,"passed_time":21.35587999,"remaining_time":3.621757424}, +{"learn":[0.2778033989],"iteration":855,"passed_time":21.40426189,"remaining_time":3.600716954}, +{"learn":[0.2776226122],"iteration":856,"passed_time":21.46367464,"remaining_time":3.581453294}, +{"learn":[0.2775176091],"iteration":857,"passed_time":21.52034093,"remaining_time":3.561641505}, +{"learn":[0.277464614],"iteration":858,"passed_time":21.56305994,"remaining_time":3.539454542}, +{"learn":[0.2773883128],"iteration":859,"passed_time":21.60634761,"remaining_time":3.517312402}, +{"learn":[0.2772957947],"iteration":860,"passed_time":21.65155055,"remaining_time":3.495430344}, +{"learn":[0.27707483],"iteration":861,"passed_time":21.70220186,"remaining_time":3.474366423}, +{"learn":[0.2770458448],"iteration":862,"passed_time":21.7451042,"remaining_time":3.452003796}, +{"learn":[0.2770211473],"iteration":863,"passed_time":21.81058221,"remaining_time":3.4331472}, +{"learn":[0.2769134335],"iteration":864,"passed_time":21.86328773,"remaining_time":3.412189415}, +{"learn":[0.2767272068],"iteration":865,"passed_time":21.91124204,"remaining_time":3.390423133}, +{"learn":[0.2766651275],"iteration":866,"passed_time":21.95803491,"remaining_time":3.368418273}, +{"learn":[0.2766236015],"iteration":867,"passed_time":21.98865411,"remaining_time":3.343896707}, +{"learn":[0.2764190352],"iteration":868,"passed_time":22.01628927,"remaining_time":3.318911271}, +{"learn":[0.2763464641],"iteration":869,"passed_time":22.03879351,"remaining_time":3.293153053}, +{"learn":[0.2762459842],"iteration":870,"passed_time":22.06084269,"remaining_time":3.267334911}, +{"learn":[0.2761180515],"iteration":871,"passed_time":22.08344645,"remaining_time":3.241606818}, +{"learn":[0.275946872],"iteration":872,"passed_time":22.10540595,"remaining_time":3.21579216}, +{"learn":[0.2757959937],"iteration":873,"passed_time":22.1273718,"remaining_time":3.189987238}, +{"learn":[0.2757647864],"iteration":874,"passed_time":22.14955984,"remaining_time":3.164222834}, +{"learn":[0.2756470463],"iteration":875,"passed_time":22.17206941,"remaining_time":3.138512109}, +{"learn":[0.2755577091],"iteration":876,"passed_time":22.20870126,"remaining_time":3.114789344}, +{"learn":[0.2754184544],"iteration":877,"passed_time":22.25209122,"remaining_time":3.091976229}, +{"learn":[0.2753339669],"iteration":878,"passed_time":22.29594659,"remaining_time":3.069180361}, +{"learn":[0.2752650527],"iteration":879,"passed_time":22.34520085,"remaining_time":3.047072843}, +{"learn":[0.2751829758],"iteration":880,"passed_time":22.39111612,"remaining_time":3.024452688}, +{"learn":[0.2749553951],"iteration":881,"passed_time":22.45076853,"remaining_time":3.003617558}, +{"learn":[0.2746921572],"iteration":882,"passed_time":22.50653576,"remaining_time":2.98217971}, +{"learn":[0.274531533],"iteration":883,"passed_time":22.549468,"remaining_time":2.958979963}, +{"learn":[0.2744750271],"iteration":884,"passed_time":22.57161604,"remaining_time":2.933034853}, +{"learn":[0.2744017506],"iteration":885,"passed_time":22.59489076,"remaining_time":2.907243281}, +{"learn":[0.2742392046],"iteration":886,"passed_time":22.61704765,"remaining_time":2.881314976}, +{"learn":[0.2740790607],"iteration":887,"passed_time":22.64893968,"remaining_time":2.856623022}, +{"learn":[0.2740407752],"iteration":888,"passed_time":22.70215534,"remaining_time":2.834577326}, +{"learn":[0.2738901483],"iteration":889,"passed_time":22.7535678,"remaining_time":2.812238717}, +{"learn":[0.2737557],"iteration":890,"passed_time":22.7960782,"remaining_time":2.788745818}, +{"learn":[0.2734666852],"iteration":891,"passed_time":22.83855164,"remaining_time":2.765205804}, +{"learn":[0.2732677571],"iteration":892,"passed_time":22.88274713,"remaining_time":2.741829724}, +{"learn":[0.2731920043],"iteration":893,"passed_time":22.97414922,"remaining_time":2.72400427}, +{"learn":[0.2729943916],"iteration":894,"passed_time":23.02020561,"remaining_time":2.700694513}, +{"learn":[0.2728667147],"iteration":895,"passed_time":23.06679197,"remaining_time":2.677395496}, +{"learn":[0.2728023199],"iteration":896,"passed_time":23.08897489,"remaining_time":2.651242378}, +{"learn":[0.2726450733],"iteration":897,"passed_time":23.11081782,"remaining_time":2.625059485}, +{"learn":[0.2724540231],"iteration":898,"passed_time":23.13305855,"remaining_time":2.598930939}, +{"learn":[0.2722533675],"iteration":899,"passed_time":23.15498608,"remaining_time":2.572776231}, +{"learn":[0.2719798723],"iteration":900,"passed_time":23.17690447,"remaining_time":2.546629903}, +{"learn":[0.271838961],"iteration":901,"passed_time":23.20607422,"remaining_time":2.521280791}, +{"learn":[0.2716784004],"iteration":902,"passed_time":23.23319485,"remaining_time":2.495703102}, +{"learn":[0.2715997004],"iteration":903,"passed_time":23.26018112,"remaining_time":2.47010773}, +{"learn":[0.2715553961],"iteration":904,"passed_time":23.28532586,"remaining_time":2.444315975}, +{"learn":[0.2715040967],"iteration":905,"passed_time":23.30905326,"remaining_time":2.418378594}, +{"learn":[0.2714110852],"iteration":906,"passed_time":23.33292333,"remaining_time":2.392460717}, +{"learn":[0.2711783584],"iteration":907,"passed_time":23.35614585,"remaining_time":2.366481738}, +{"learn":[0.2709994568],"iteration":908,"passed_time":23.3780827,"remaining_time":2.340380117}, +{"learn":[0.2709026458],"iteration":909,"passed_time":23.40132538,"remaining_time":2.314416795}, +{"learn":[0.2707555722],"iteration":910,"passed_time":23.42400284,"remaining_time":2.288404229}, +{"learn":[0.2704601695],"iteration":911,"passed_time":23.44978174,"remaining_time":2.262698238}, +{"learn":[0.2702425665],"iteration":912,"passed_time":23.47564167,"remaining_time":2.236999808}, +{"learn":[0.2701770836],"iteration":913,"passed_time":23.50186451,"remaining_time":2.211335172}, +{"learn":[0.2699971732],"iteration":914,"passed_time":23.52737442,"remaining_time":2.185603088}, +{"learn":[0.269885267],"iteration":915,"passed_time":23.5500863,"remaining_time":2.159614901}, +{"learn":[0.2697787171],"iteration":916,"passed_time":23.57260904,"remaining_time":2.133616739}, +{"learn":[0.2697367678],"iteration":917,"passed_time":23.59423385,"remaining_time":2.107545943}, +{"learn":[0.2697244921],"iteration":918,"passed_time":23.61617665,"remaining_time":2.08151285}, +{"learn":[0.2695088772],"iteration":919,"passed_time":23.63857522,"remaining_time":2.05552828}, +{"learn":[0.2692360607],"iteration":920,"passed_time":23.66064219,"remaining_time":2.029523055}, +{"learn":[0.2691868859],"iteration":921,"passed_time":23.70105795,"remaining_time":2.005078655}, +{"learn":[0.2689761885],"iteration":922,"passed_time":23.74595053,"remaining_time":1.980973121}, +{"learn":[0.2687792851],"iteration":923,"passed_time":23.78731312,"remaining_time":1.956532248}, +{"learn":[0.2683329367],"iteration":924,"passed_time":23.82670762,"remaining_time":1.931895212}, +{"learn":[0.2682383468],"iteration":925,"passed_time":23.8676536,"remaining_time":1.907350288}, +{"learn":[0.2681411189],"iteration":926,"passed_time":23.90665807,"remaining_time":1.882617086}, +{"learn":[0.2680166243],"iteration":927,"passed_time":23.95383044,"remaining_time":1.858486844}, +{"learn":[0.2680097861],"iteration":928,"passed_time":24.00201139,"remaining_time":1.834384078}, +{"learn":[0.2678649617],"iteration":929,"passed_time":24.03147583,"remaining_time":1.808820762}, +{"learn":[0.2677926982],"iteration":930,"passed_time":24.05396793,"remaining_time":1.782732317}, +{"learn":[0.2676177519],"iteration":931,"passed_time":24.07625836,"remaining_time":1.756636876}, +{"learn":[0.2675419733],"iteration":932,"passed_time":24.09823464,"remaining_time":1.730527032}, +{"learn":[0.2674892708],"iteration":933,"passed_time":24.12017091,"remaining_time":1.704423212}, +{"learn":[0.2673888832],"iteration":934,"passed_time":24.14221881,"remaining_time":1.678336067}, +{"learn":[0.2673408241],"iteration":935,"passed_time":24.16428228,"remaining_time":1.652258618}, +{"learn":[0.267061597],"iteration":936,"passed_time":24.18717108,"remaining_time":1.626245228}, +{"learn":[0.2670483357],"iteration":937,"passed_time":24.21444774,"remaining_time":1.600528529}, +{"learn":[0.2669986935],"iteration":938,"passed_time":24.23981304,"remaining_time":1.574684341}, +{"learn":[0.2667914988],"iteration":939,"passed_time":24.2623561,"remaining_time":1.548661028}, +{"learn":[0.2666629717],"iteration":940,"passed_time":24.28508323,"remaining_time":1.522656653}, +{"learn":[0.2663673411],"iteration":941,"passed_time":24.30729083,"remaining_time":1.496627249}, +{"learn":[0.2662679127],"iteration":942,"passed_time":24.32898627,"remaining_time":1.470574992}, +{"learn":[0.2661806153],"iteration":943,"passed_time":24.35133577,"remaining_time":1.444570766}, +{"learn":[0.2660864679],"iteration":944,"passed_time":24.37363009,"remaining_time":1.418571063}, +{"learn":[0.2660772833],"iteration":945,"passed_time":24.39239275,"remaining_time":1.392377599}, +{"learn":[0.2659919549],"iteration":946,"passed_time":24.4160891,"remaining_time":1.366475948}, +{"learn":[0.2659294851],"iteration":947,"passed_time":24.43827206,"remaining_time":1.340495936}, +{"learn":[0.2658864129],"iteration":948,"passed_time":24.46472254,"remaining_time":1.314753266}, +{"learn":[0.2656973273],"iteration":949,"passed_time":24.49066288,"remaining_time":1.288982257}, +{"learn":[0.2654822842],"iteration":950,"passed_time":24.51928759,"remaining_time":1.263349203}, +{"learn":[0.2654357361],"iteration":951,"passed_time":24.54243954,"remaining_time":1.237433926}, +{"learn":[0.2652483245],"iteration":952,"passed_time":24.56490013,"remaining_time":1.211490353}, +{"learn":[0.2650786501],"iteration":953,"passed_time":24.58736673,"remaining_time":1.185554371}, +{"learn":[0.2650437914],"iteration":954,"passed_time":24.60931258,"remaining_time":1.159601116}, +{"learn":[0.2647589672],"iteration":955,"passed_time":24.63138292,"remaining_time":1.133661975}, +{"learn":[0.2645760187],"iteration":956,"passed_time":24.65376702,"remaining_time":1.107745018}, +{"learn":[0.2644273667],"iteration":957,"passed_time":24.67566451,"remaining_time":1.081814102}, +{"learn":[0.2642487937],"iteration":958,"passed_time":24.69985831,"remaining_time":1.055989771}, +{"learn":[0.2641295931],"iteration":959,"passed_time":24.72576284,"remaining_time":1.030240118}, +{"learn":[0.2639643656],"iteration":960,"passed_time":24.75146344,"remaining_time":1.004481867}, +{"learn":[0.2638271273],"iteration":961,"passed_time":24.77349924,"remaining_time":0.9785789721}, +{"learn":[0.26378499],"iteration":962,"passed_time":24.79605048,"remaining_time":0.9527039126}, +{"learn":[0.263585605],"iteration":963,"passed_time":24.81817395,"remaining_time":0.926819774}, +{"learn":[0.2635169052],"iteration":964,"passed_time":24.84010583,"remaining_time":0.9009364807}, +{"learn":[0.2634345598],"iteration":965,"passed_time":24.8624533,"remaining_time":0.8750759961}, +{"learn":[0.2634097593],"iteration":966,"passed_time":24.88446723,"remaining_time":0.8492113947}, +{"learn":[0.2633306114],"iteration":967,"passed_time":24.90657225,"remaining_time":0.8233577603}, +{"learn":[0.2631360168],"iteration":968,"passed_time":24.92874625,"remaining_time":0.79751407}, +{"learn":[0.2629773219],"iteration":969,"passed_time":24.95092926,"remaining_time":0.7716782246}, +{"learn":[0.262887109],"iteration":970,"passed_time":24.9825894,"remaining_time":0.7461329482}, +{"learn":[0.2627283493],"iteration":971,"passed_time":25.00857418,"remaining_time":0.720411602}, +{"learn":[0.2626493335],"iteration":972,"passed_time":25.03449893,"remaining_time":0.6946880484}, +{"learn":[0.2625417584],"iteration":973,"passed_time":25.0570851,"remaining_time":0.6688749616}, +{"learn":[0.2623745457],"iteration":974,"passed_time":25.08006808,"remaining_time":0.6430786686}, +{"learn":[0.2622252779],"iteration":975,"passed_time":25.10275279,"remaining_time":0.6172808064}, +{"learn":[0.2620765279],"iteration":976,"passed_time":25.12650391,"remaining_time":0.5915144215}, +{"learn":[0.2619056227],"iteration":977,"passed_time":25.14859496,"remaining_time":0.565714815}, +{"learn":[0.2616868552],"iteration":978,"passed_time":25.17038647,"remaining_time":0.5399163594}, +{"learn":[0.2614966561],"iteration":979,"passed_time":25.19430345,"remaining_time":0.5141694582}, +{"learn":[0.2614164281],"iteration":980,"passed_time":25.21690348,"remaining_time":0.488400781}, +{"learn":[0.2613355646],"iteration":981,"passed_time":25.24687944,"remaining_time":0.4627737576}, +{"learn":[0.2611604482],"iteration":982,"passed_time":25.26973736,"remaining_time":0.4370147865}, +{"learn":[0.2609467509],"iteration":983,"passed_time":25.29197863,"remaining_time":0.4112516851}, +{"learn":[0.2608803914],"iteration":984,"passed_time":25.31431985,"remaining_time":0.3854972567}, +{"learn":[0.2608064874],"iteration":985,"passed_time":25.33675271,"remaining_time":0.3597510527}, +{"learn":[0.2607424461],"iteration":986,"passed_time":25.35896906,"remaining_time":0.334008711}, +{"learn":[0.2604634089],"iteration":987,"passed_time":25.38110387,"remaining_time":0.3082725167}, +{"learn":[0.2603511649],"iteration":988,"passed_time":25.40489471,"remaining_time":0.282562024}, +{"learn":[0.2603052916],"iteration":989,"passed_time":25.42704056,"remaining_time":0.2568387935}, +{"learn":[0.2601502245],"iteration":990,"passed_time":25.45103872,"remaining_time":0.231139605}, +{"learn":[0.259927874],"iteration":991,"passed_time":25.47547957,"remaining_time":0.2054474159}, +{"learn":[0.2597611063],"iteration":992,"passed_time":25.50295153,"remaining_time":0.1797791145}, +{"learn":[0.2597041835],"iteration":993,"passed_time":25.52553775,"remaining_time":0.1540776926}, +{"learn":[0.2594450403],"iteration":994,"passed_time":25.55414859,"remaining_time":0.128412807}, +{"learn":[0.2593932196],"iteration":995,"passed_time":25.57650936,"remaining_time":0.1027169051}, +{"learn":[0.2592866892],"iteration":996,"passed_time":25.59858627,"remaining_time":0.07702683932}, +{"learn":[0.2591544901],"iteration":997,"passed_time":25.62038117,"remaining_time":0.05134344924}, +{"learn":[0.2591143866],"iteration":998,"passed_time":25.64281049,"remaining_time":0.02566847897}, +{"learn":[0.2589307024],"iteration":999,"passed_time":25.66502601,"remaining_time":0} +]} \ No newline at end of file diff --git a/metagpt/roles/catboost_info/learn/events.out.tfevents b/metagpt/roles/catboost_info/learn/events.out.tfevents new file mode 100644 index 000000000..47650f04f Binary files /dev/null and b/metagpt/roles/catboost_info/learn/events.out.tfevents differ diff --git a/metagpt/roles/catboost_info/learn_error.tsv b/metagpt/roles/catboost_info/learn_error.tsv new file mode 100644 index 000000000..1b878d300 --- /dev/null +++ b/metagpt/roles/catboost_info/learn_error.tsv @@ -0,0 +1,1001 @@ +iter Logloss +0 0.6882514366 +1 0.6847159377 +2 0.6795580406 +3 0.6750537284 +4 0.6699312491 +5 0.6650724516 +6 0.6606555729 +7 0.6561724634 +8 0.6519794747 +9 0.6492472012 +10 0.6446640682 +11 0.6400603726 +12 0.637483839 +13 0.6334773178 +14 0.6286841787 +15 0.6262362324 +16 0.6227706725 +17 0.618564194 +18 0.6154841122 +19 0.6112592312 +20 0.6077881571 +21 0.6037553183 +22 0.6006649251 +23 0.5975849834 +24 0.5940831045 +25 0.5916771489 +26 0.5894338237 +27 0.5875190394 +28 0.5844895773 +29 0.5810267327 +30 0.5778936903 +31 0.576124503 +32 0.5735057785 +33 0.570293767 +34 0.5672457801 +35 0.5649423522 +36 0.5615275613 +37 0.5581402135 +38 0.555577741 +39 0.5523266666 +40 0.5508561568 +41 0.5487373589 +42 0.5460358061 +43 0.5429618153 +44 0.5411169242 +45 0.5389150372 +46 0.5364783846 +47 0.534124059 +48 0.5307002414 +49 0.5289874066 +50 0.5263977673 +51 0.5243808354 +52 0.5226468558 +53 0.5205374561 +54 0.5184600522 +55 0.5161120982 +56 0.5135670428 +57 0.5117345666 +58 0.5103042276 +59 0.5088685224 +60 0.5069392613 +61 0.5058379484 +62 0.504071849 +63 0.5026509319 +64 0.5013652681 +65 0.4990494982 +66 0.4975801239 +67 0.4954073892 +68 0.4937794274 +69 0.4917253363 +70 0.4897655824 +71 0.4881025387 +72 0.4855490154 +73 0.4839406321 +74 0.4825486397 +75 0.4806147512 +76 0.4790772126 +77 0.4783791778 +78 0.476922228 +79 0.4757319459 +80 0.4742068644 +81 0.4726812191 +82 0.4710468444 +83 0.4693673381 +84 0.4676818392 +85 0.4657056761 +86 0.4642140634 +87 0.4632998746 +88 0.4622314595 +89 0.460592481 +90 0.4593241639 +91 0.4584569869 +92 0.4577605438 +93 0.4561556633 +94 0.4554982999 +95 0.4545744958 +96 0.4540947284 +97 0.4540085087 +98 0.4531926189 +99 0.4527317281 +100 0.4519466344 +101 0.450688372 +102 0.4488322057 +103 0.4478782417 +104 0.4468232543 +105 0.4457592303 +106 0.4447781675 +107 0.4438522903 +108 0.4430406598 +109 0.4420804721 +110 0.4413288303 +111 0.4406769097 +112 0.439927404 +113 0.4387131738 +114 0.4379161685 +115 0.4368122477 +116 0.4363066446 +117 0.4352350106 +118 0.4340016567 +119 0.4332395033 +120 0.4323511556 +121 0.4316166781 +122 0.4304510199 +123 0.4297836948 +124 0.4286476712 +125 0.4281044323 +126 0.4277452421 +127 0.4268564678 +128 0.4262834378 +129 0.4255606014 +130 0.4252233113 +131 0.424750709 +132 0.4237267015 +133 0.4229110275 +134 0.4226882753 +135 0.4220238002 +136 0.4216236205 +137 0.4213023831 +138 0.4205216151 +139 0.4202240166 +140 0.4192685081 +141 0.4183050279 +142 0.4173978005 +143 0.4162954182 +144 0.415992639 +145 0.4157126501 +146 0.4155852885 +147 0.4148007449 +148 0.4145476092 +149 0.4139132529 +150 0.4134843771 +151 0.4124055164 +152 0.412222917 +153 0.4115787549 +154 0.411081548 +155 0.4110031407 +156 0.4105687169 +157 0.4095109133 +158 0.4089787829 +159 0.4084130488 +160 0.4077252474 +161 0.4072843557 +162 0.4066351535 +163 0.4063103387 +164 0.4059185096 +165 0.4052304697 +166 0.4050859305 +167 0.4044742571 +168 0.4041975026 +169 0.4035590426 +170 0.4030297385 +171 0.4025456368 +172 0.402334931 +173 0.401831618 +174 0.4017743873 +175 0.4011280658 +176 0.4005475562 +177 0.4000603326 +178 0.3990424765 +179 0.3987132685 +180 0.3980735307 +181 0.3976839336 +182 0.3970583957 +183 0.3968093954 +184 0.3965549511 +185 0.3961498711 +186 0.3958574586 +187 0.3958036693 +188 0.3954652307 +189 0.3949970516 +190 0.3946423615 +191 0.3937733218 +192 0.3931025335 +193 0.3925366206 +194 0.391865258 +195 0.3914533348 +196 0.3912476553 +197 0.3905329154 +198 0.3898798389 +199 0.3891654603 +200 0.3887747769 +201 0.3884753081 +202 0.3877793274 +203 0.3874664375 +204 0.3871008215 +205 0.3865209415 +206 0.3859273739 +207 0.3855620818 +208 0.3851648115 +209 0.3843406643 +210 0.3842506785 +211 0.3840729725 +212 0.3836865443 +213 0.3834504777 +214 0.383221126 +215 0.382875332 +216 0.3827132502 +217 0.3825534206 +218 0.3821802218 +219 0.3818052054 +220 0.3816117561 +221 0.3812172842 +222 0.3810255507 +223 0.3809283758 +224 0.3808446585 +225 0.3801708307 +226 0.3798560036 +227 0.3794923916 +228 0.3793373475 +229 0.3791100641 +230 0.3786186348 +231 0.3783799747 +232 0.3779793355 +233 0.3777902426 +234 0.377759024 +235 0.3775407801 +236 0.3772180796 +237 0.3770122934 +238 0.3765490897 +239 0.3764835925 +240 0.3759776808 +241 0.3757142158 +242 0.3752871326 +243 0.3748925461 +244 0.3746214472 +245 0.3740866821 +246 0.3735711811 +247 0.3732294839 +248 0.3729683346 +249 0.3727413457 +250 0.3723892856 +251 0.3719863363 +252 0.3716739793 +253 0.3716103601 +254 0.3715319129 +255 0.371508316 +256 0.3713832526 +257 0.3710349299 +258 0.371030348 +259 0.3708892154 +260 0.3705921581 +261 0.3702244894 +262 0.3702202347 +263 0.3698349185 +264 0.3696711654 +265 0.3692863237 +266 0.3690671729 +267 0.3687581564 +268 0.3683941859 +269 0.368050992 +270 0.3677324616 +271 0.3674997199 +272 0.3672484703 +273 0.3670583272 +274 0.366936125 +275 0.3665623609 +276 0.3663926512 +277 0.3659325492 +278 0.3656171802 +279 0.3654984176 +280 0.3653075674 +281 0.3652175898 +282 0.365164193 +283 0.3648739127 +284 0.3648461699 +285 0.3646301237 +286 0.3646030346 +287 0.3644969437 +288 0.3643646754 +289 0.3639816129 +290 0.3636656294 +291 0.363430258 +292 0.3632201443 +293 0.3628359855 +294 0.3627236518 +295 0.3622184354 +296 0.3621264294 +297 0.3620089934 +298 0.3618790034 +299 0.3617399454 +300 0.3616850281 +301 0.3613225424 +302 0.3613077955 +303 0.3611613922 +304 0.3606681647 +305 0.3606662726 +306 0.3606644378 +307 0.3601634319 +308 0.3599344409 +309 0.3596092344 +310 0.3595229983 +311 0.3591048131 +312 0.3589464226 +313 0.3588198429 +314 0.3585066029 +315 0.3584892118 +316 0.3580264626 +317 0.3580001595 +318 0.3578136454 +319 0.3576122347 +320 0.3573283521 +321 0.3569801921 +322 0.3568810457 +323 0.35676928 +324 0.3566134286 +325 0.3565307492 +326 0.3562459001 +327 0.3559648846 +328 0.3558310934 +329 0.355525639 +330 0.3553348141 +331 0.3552290203 +332 0.3545412457 +333 0.3543498177 +334 0.354267269 +335 0.3541845198 +336 0.3538121961 +337 0.3535608169 +338 0.3531983941 +339 0.3530182856 +340 0.3527164122 +341 0.352633574 +342 0.3525075494 +343 0.3524961056 +344 0.35245364 +345 0.3521993518 +346 0.3520077509 +347 0.3519447224 +348 0.3518945368 +349 0.3516107656 +350 0.3515159018 +351 0.3515000807 +352 0.3512670327 +353 0.3508513767 +354 0.3504572704 +355 0.35017651 +356 0.3501286962 +357 0.3498837488 +358 0.3495626772 +359 0.3493757992 +360 0.3490827511 +361 0.3488646977 +362 0.3484613426 +363 0.3483259359 +364 0.3480209179 +365 0.3476817077 +366 0.3474725024 +367 0.3474285581 +368 0.3470858003 +369 0.3469015363 +370 0.3463432335 +371 0.3461185251 +372 0.3458407874 +373 0.3457031815 +374 0.3455128742 +375 0.3452742962 +376 0.3452251263 +377 0.3450881669 +378 0.3449793371 +379 0.344691491 +380 0.3443639578 +381 0.3442136782 +382 0.3440594348 +383 0.3439143606 +384 0.3437593269 +385 0.3433892597 +386 0.3430005665 +387 0.3426363435 +388 0.3425431519 +389 0.3422194687 +390 0.3420983186 +391 0.3419547464 +392 0.3418564406 +393 0.3416273848 +394 0.3413111854 +395 0.3411554684 +396 0.3410876043 +397 0.3410429673 +398 0.341042403 +399 0.3409573532 +400 0.3408655821 +401 0.3406567823 +402 0.3404763525 +403 0.3403717595 +404 0.3400880712 +405 0.3399640397 +406 0.3399010234 +407 0.339826297 +408 0.3397102041 +409 0.3395576906 +410 0.3392198413 +411 0.3391475536 +412 0.3389268153 +413 0.3389266721 +414 0.3388830216 +415 0.3388260339 +416 0.3385376482 +417 0.3384459997 +418 0.3384035804 +419 0.338206978 +420 0.3381563107 +421 0.3380916237 +422 0.3379155117 +423 0.3377370109 +424 0.3376685347 +425 0.3375387678 +426 0.3375264339 +427 0.3375078804 +428 0.337340127 +429 0.3372056844 +430 0.336977263 +431 0.3367988208 +432 0.3367285927 +433 0.3366052887 +434 0.3363612465 +435 0.3362435567 +436 0.3361462199 +437 0.3361461347 +438 0.3360079098 +439 0.3358086626 +440 0.3356011997 +441 0.3354146851 +442 0.3352191524 +443 0.3348674793 +444 0.3348375647 +445 0.3346763511 +446 0.3344469846 +447 0.3341331513 +448 0.3338919982 +449 0.3336666898 +450 0.3336666289 +451 0.3336154028 +452 0.3333581167 +453 0.333290786 +454 0.3332008443 +455 0.3331038516 +456 0.3329428533 +457 0.3329254389 +458 0.3326182973 +459 0.3321795229 +460 0.3320965842 +461 0.3320919904 +462 0.3317616467 +463 0.3314515976 +464 0.3314302988 +465 0.331326468 +466 0.3312172495 +467 0.3311362468 +468 0.3308259578 +469 0.3306543113 +470 0.3304472924 +471 0.3302050118 +472 0.3302042287 +473 0.3302042278 +474 0.330077596 +475 0.3299967493 +476 0.3298204689 +477 0.3296573275 +478 0.3295569924 +479 0.329329664 +480 0.329131173 +481 0.3289868495 +482 0.3288599313 +483 0.3285822513 +484 0.3282988587 +485 0.3282849959 +486 0.3281045884 +487 0.3279303325 +488 0.3277856921 +489 0.3277359886 +490 0.3275212786 +491 0.3273286251 +492 0.3271903876 +493 0.3270655317 +494 0.3270389056 +495 0.326813723 +496 0.3265823051 +497 0.326481471 +498 0.3263322725 +499 0.3261136043 +500 0.3259491378 +501 0.3255755285 +502 0.325431063 +503 0.3251221632 +504 0.3249533874 +505 0.3245557056 +506 0.3244819748 +507 0.3244571553 +508 0.3243944087 +509 0.3243932505 +510 0.3243735511 +511 0.3242641705 +512 0.3238891977 +513 0.3237673065 +514 0.3236015493 +515 0.3233656351 +516 0.3232732615 +517 0.3231361121 +518 0.32299658 +519 0.3229860023 +520 0.322752282 +521 0.3227072424 +522 0.3226090551 +523 0.3224092365 +524 0.3224092358 +525 0.322391538 +526 0.3222006912 +527 0.3221324811 +528 0.3221061996 +529 0.3220694662 +530 0.3219756017 +531 0.3219724232 +532 0.3215889876 +533 0.3214944521 +534 0.3214735687 +535 0.3211667307 +536 0.3210361058 +537 0.3209803394 +538 0.3209803394 +539 0.3209335447 +540 0.3208255558 +541 0.3204879029 +542 0.3203255553 +543 0.3203078373 +544 0.3201807045 +545 0.3200168479 +546 0.3199792981 +547 0.3198294345 +548 0.3198294344 +549 0.319647278 +550 0.3196091956 +551 0.3194977614 +552 0.3194412347 +553 0.319377863 +554 0.319212072 +555 0.3192120719 +556 0.3191064217 +557 0.3190443835 +558 0.3189403324 +559 0.3187465621 +560 0.3185833798 +561 0.3184379867 +562 0.3182631548 +563 0.3181986719 +564 0.3180519592 +565 0.3180225705 +566 0.3178969873 +567 0.3176445672 +568 0.317322944 +569 0.317228846 +570 0.3170580473 +571 0.3167691984 +572 0.316670053 +573 0.3164501718 +574 0.3163287563 +575 0.3162894601 +576 0.3162494869 +577 0.3159951385 +578 0.3157978717 +579 0.3155850358 +580 0.315355402 +581 0.3150989936 +582 0.3148114702 +583 0.3144519215 +584 0.3143229251 +585 0.3141904066 +586 0.3140027965 +587 0.3138685082 +588 0.3138181058 +589 0.313574669 +590 0.3134898049 +591 0.313320396 +592 0.3131676802 +593 0.3129757867 +594 0.3127907517 +595 0.3125289035 +596 0.3123599621 +597 0.3121137456 +598 0.3119284015 +599 0.3119267487 +600 0.3119112192 +601 0.3118470126 +602 0.3117666572 +603 0.3116060866 +604 0.311604484 +605 0.3113084243 +606 0.3112684311 +607 0.3111182078 +608 0.3109941013 +609 0.3108986608 +610 0.3107318621 +611 0.3106806721 +612 0.3105565129 +613 0.3103924843 +614 0.3102082538 +615 0.3100890351 +616 0.3099299428 +617 0.3099148853 +618 0.3098292521 +619 0.3097022539 +620 0.3095586079 +621 0.3095365057 +622 0.3093867074 +623 0.3090971237 +624 0.3090567117 +625 0.3090514438 +626 0.3089121979 +627 0.3088734529 +628 0.3087798566 +629 0.3085569569 +630 0.3083945767 +631 0.3082636175 +632 0.308097633 +633 0.3080161232 +634 0.3079940498 +635 0.3077049522 +636 0.3074875181 +637 0.3073941113 +638 0.3070378662 +639 0.3069235694 +640 0.3068787888 +641 0.3067815049 +642 0.3067274077 +643 0.3067273505 +644 0.30654485 +645 0.306542431 +646 0.3063441894 +647 0.3061944627 +648 0.3061943966 +649 0.3059553625 +650 0.3057317972 +651 0.305636842 +652 0.3056207008 +653 0.3054612738 +654 0.3053219515 +655 0.3053042191 +656 0.3051397112 +657 0.3049434285 +658 0.3048304658 +659 0.3047096301 +660 0.3042903415 +661 0.3042772412 +662 0.3040841367 +663 0.3039029953 +664 0.3036718031 +665 0.303650484 +666 0.3035074481 +667 0.3033167887 +668 0.3032946087 +669 0.3032089215 +670 0.3030821849 +671 0.3029894163 +672 0.302865477 +673 0.3028067159 +674 0.3027061901 +675 0.3025646938 +676 0.3025250377 +677 0.3020655554 +678 0.3020534847 +679 0.3020343145 +680 0.3018419602 +681 0.3016898998 +682 0.3015708555 +683 0.3014896934 +684 0.301382652 +685 0.3010326679 +686 0.3009148994 +687 0.30091463 +688 0.3007108906 +689 0.3006049621 +690 0.3004424014 +691 0.3002521525 +692 0.3001677248 +693 0.3000495606 +694 0.2999076935 +695 0.2997878011 +696 0.2997774515 +697 0.2997265735 +698 0.2996999851 +699 0.2995208066 +700 0.2995205559 +701 0.2993846391 +702 0.2991289729 +703 0.2990709937 +704 0.2990700247 +705 0.2989463307 +706 0.2989462517 +707 0.2987724441 +708 0.2987179044 +709 0.2985139439 +710 0.2982107603 +711 0.2981313323 +712 0.2980878246 +713 0.297945571 +714 0.2977036341 +715 0.2976532538 +716 0.2972948225 +717 0.2972072898 +718 0.2970205352 +719 0.2968625698 +720 0.296778922 +721 0.2965144868 +722 0.2964393382 +723 0.2963119084 +724 0.2960547659 +725 0.2959726674 +726 0.2959442898 +727 0.2958761466 +728 0.2955882368 +729 0.2955462923 +730 0.2953304881 +731 0.2951897941 +732 0.2950068022 +733 0.2949951299 +734 0.2948810476 +735 0.2948013604 +736 0.2947457831 +737 0.2945614394 +738 0.2942434298 +739 0.2939751704 +740 0.2938581582 +741 0.29382581 +742 0.2935313901 +743 0.293385087 +744 0.2931688515 +745 0.2929784993 +746 0.2927616087 +747 0.2927348935 +748 0.2926524614 +749 0.292532443 +750 0.2923772006 +751 0.292133322 +752 0.291968671 +753 0.2918869516 +754 0.2917246816 +755 0.2916077821 +756 0.2914285282 +757 0.2913445284 +758 0.2913443551 +759 0.291344066 +760 0.2911691075 +761 0.2908231947 +762 0.2907754775 +763 0.2906135806 +764 0.2905947266 +765 0.2905295128 +766 0.2902453894 +767 0.2900319175 +768 0.2899129422 +769 0.289784147 +770 0.2896433582 +771 0.2893137629 +772 0.2892767962 +773 0.2890654442 +774 0.2889086488 +775 0.2887625489 +776 0.2886341007 +777 0.2886019791 +778 0.2883053437 +779 0.2881800888 +780 0.2881493372 +781 0.2879469616 +782 0.2878030143 +783 0.2876184323 +784 0.2873371785 +785 0.287291682 +786 0.2870997336 +787 0.2869277017 +788 0.2868849395 +789 0.2866008202 +790 0.286433075 +791 0.2863247094 +792 0.2861530229 +793 0.2860601397 +794 0.285782435 +795 0.2857395573 +796 0.2855575819 +797 0.2855155269 +798 0.2853027357 +799 0.2852479317 +800 0.2851592302 +801 0.2851054653 +802 0.2850244642 +803 0.2847988254 +804 0.2847954492 +805 0.2847668538 +806 0.2846572393 +807 0.2843730264 +808 0.284141588 +809 0.284041018 +810 0.2839261452 +811 0.2837666765 +812 0.2836468321 +813 0.2835959553 +814 0.2834490287 +815 0.2833510414 +816 0.2833281488 +817 0.2832314365 +818 0.2831363442 +819 0.2830386545 +820 0.2829967032 +821 0.2828641845 +822 0.2825780004 +823 0.2823101112 +824 0.2821905518 +825 0.2819471832 +826 0.2819286265 +827 0.2818280875 +828 0.2817546833 +829 0.281587275 +830 0.2814154303 +831 0.2813141668 +832 0.2812636016 +833 0.2812172885 +834 0.281044403 +835 0.2809039898 +836 0.2807492094 +837 0.2807239878 +838 0.2804031359 +839 0.2803187933 +840 0.280178431 +841 0.2800356414 +842 0.2798041757 +843 0.2796980093 +844 0.2795734447 +845 0.2794519833 +846 0.2793843487 +847 0.2792873292 +848 0.2790298494 +849 0.2788323685 +850 0.2786864684 +851 0.2785577462 +852 0.2783806677 +853 0.2783359299 +854 0.2779284052 +855 0.2778033989 +856 0.2776226122 +857 0.2775176091 +858 0.277464614 +859 0.2773883128 +860 0.2772957947 +861 0.27707483 +862 0.2770458448 +863 0.2770211473 +864 0.2769134335 +865 0.2767272068 +866 0.2766651275 +867 0.2766236015 +868 0.2764190352 +869 0.2763464641 +870 0.2762459842 +871 0.2761180515 +872 0.275946872 +873 0.2757959937 +874 0.2757647864 +875 0.2756470463 +876 0.2755577091 +877 0.2754184544 +878 0.2753339669 +879 0.2752650527 +880 0.2751829758 +881 0.2749553951 +882 0.2746921572 +883 0.274531533 +884 0.2744750271 +885 0.2744017506 +886 0.2742392046 +887 0.2740790607 +888 0.2740407752 +889 0.2738901483 +890 0.2737557 +891 0.2734666852 +892 0.2732677571 +893 0.2731920043 +894 0.2729943916 +895 0.2728667147 +896 0.2728023199 +897 0.2726450733 +898 0.2724540231 +899 0.2722533675 +900 0.2719798723 +901 0.271838961 +902 0.2716784004 +903 0.2715997004 +904 0.2715553961 +905 0.2715040967 +906 0.2714110852 +907 0.2711783584 +908 0.2709994568 +909 0.2709026458 +910 0.2707555722 +911 0.2704601695 +912 0.2702425665 +913 0.2701770836 +914 0.2699971732 +915 0.269885267 +916 0.2697787171 +917 0.2697367678 +918 0.2697244921 +919 0.2695088772 +920 0.2692360607 +921 0.2691868859 +922 0.2689761885 +923 0.2687792851 +924 0.2683329367 +925 0.2682383468 +926 0.2681411189 +927 0.2680166243 +928 0.2680097861 +929 0.2678649617 +930 0.2677926982 +931 0.2676177519 +932 0.2675419733 +933 0.2674892708 +934 0.2673888832 +935 0.2673408241 +936 0.267061597 +937 0.2670483357 +938 0.2669986935 +939 0.2667914988 +940 0.2666629717 +941 0.2663673411 +942 0.2662679127 +943 0.2661806153 +944 0.2660864679 +945 0.2660772833 +946 0.2659919549 +947 0.2659294851 +948 0.2658864129 +949 0.2656973273 +950 0.2654822842 +951 0.2654357361 +952 0.2652483245 +953 0.2650786501 +954 0.2650437914 +955 0.2647589672 +956 0.2645760187 +957 0.2644273667 +958 0.2642487937 +959 0.2641295931 +960 0.2639643656 +961 0.2638271273 +962 0.26378499 +963 0.263585605 +964 0.2635169052 +965 0.2634345598 +966 0.2634097593 +967 0.2633306114 +968 0.2631360168 +969 0.2629773219 +970 0.262887109 +971 0.2627283493 +972 0.2626493335 +973 0.2625417584 +974 0.2623745457 +975 0.2622252779 +976 0.2620765279 +977 0.2619056227 +978 0.2616868552 +979 0.2614966561 +980 0.2614164281 +981 0.2613355646 +982 0.2611604482 +983 0.2609467509 +984 0.2608803914 +985 0.2608064874 +986 0.2607424461 +987 0.2604634089 +988 0.2603511649 +989 0.2603052916 +990 0.2601502245 +991 0.259927874 +992 0.2597611063 +993 0.2597041835 +994 0.2594450403 +995 0.2593932196 +996 0.2592866892 +997 0.2591544901 +998 0.2591143866 +999 0.2589307024 diff --git a/metagpt/roles/catboost_info/time_left.tsv b/metagpt/roles/catboost_info/time_left.tsv new file mode 100644 index 000000000..9dad8374b --- /dev/null +++ b/metagpt/roles/catboost_info/time_left.tsv @@ -0,0 +1,1001 @@ +iter Passed Remaining +0 220 220739 +1 232 116261 +2 256 85085 +3 278 69276 +4 299 59689 +5 321 53318 +6 345 49069 +7 367 45627 +8 389 42937 +9 400 39679 +10 423 38081 +11 445 36699 +12 455 34579 +13 473 33335 +14 495 32512 +15 506 31164 +16 526 30472 +17 548 29944 +18 563 29096 +19 585 28677 +20 607 28313 +21 629 27972 +22 645 27425 +23 664 27027 +24 686 26771 +25 703 26370 +26 716 25834 +27 726 25209 +28 745 24947 +29 767 24808 +30 789 24665 +31 799 24188 +32 814 23861 +33 836 23755 +34 858 23659 +35 876 23472 +36 902 23488 +37 927 23475 +38 945 23307 +39 968 23238 +40 976 22834 +41 994 22682 +42 1017 22647 +43 1039 22589 +44 1058 22460 +45 1080 22406 +46 1102 22359 +47 1117 22171 +48 1140 22139 +49 1176 22355 +50 1206 22454 +51 1229 22421 +52 1251 22364 +53 1277 22383 +54 1300 22344 +55 1322 22294 +56 1345 22253 +57 1367 22211 +58 1379 21997 +59 1393 21836 +60 1420 21858 +61 1434 21707 +62 1450 21579 +63 1470 21505 +64 1485 21371 +65 1507 21332 +66 1529 21292 +67 1551 21264 +68 1573 21229 +69 1595 21194 +70 1617 21168 +71 1639 21137 +72 1668 21185 +73 1694 21200 +74 1714 21145 +75 1740 21163 +76 1763 21139 +77 1771 20943 +78 1789 20864 +79 1811 20835 +80 1833 20806 +81 1855 20775 +82 1877 20744 +83 1899 20718 +84 1929 20766 +85 1951 20737 +86 1969 20671 +87 1991 20641 +88 2014 20616 +89 2036 20588 +90 2058 20565 +91 2073 20469 +92 2085 20338 +93 2107 20313 +94 2119 20188 +95 2137 20127 +96 2145 19973 +97 2150 19792 +98 2164 19694 +99 2176 19586 +100 2196 19551 +101 2226 19602 +102 2250 19595 +103 2272 19577 +104 2294 19555 +105 2316 19536 +106 2334 19485 +107 2360 19493 +108 2375 19417 +109 2397 19400 +110 2431 19474 +111 2448 19409 +112 2471 19396 +113 2493 19376 +114 2515 19356 +115 2536 19332 +116 2558 19311 +117 2580 19289 +118 2602 19268 +119 2625 19253 +120 2650 19256 +121 2686 19332 +122 2712 19342 +123 2744 19390 +124 2819 19733 +125 2833 19656 +126 2851 19602 +127 2873 19573 +128 2894 19546 +129 2917 19521 +130 2937 19488 +131 2956 19439 +132 2978 19413 +133 3000 19388 +134 3011 19296 +135 3029 19248 +136 3044 19179 +137 3059 19110 +138 3081 19085 +139 3099 19039 +140 3121 19015 +141 3143 18993 +142 3165 18969 +143 3195 18996 +144 3220 18990 +145 3240 18956 +146 3249 18854 +147 3271 18834 +148 3289 18790 +149 3312 18772 +150 3328 18711 +151 3350 18689 +152 3358 18592 +153 3380 18571 +154 3402 18548 +155 3411 18456 +156 3439 18466 +157 3463 18457 +158 3485 18436 +159 3507 18413 +160 3529 18392 +161 3548 18354 +162 3569 18331 +163 3584 18273 +164 3599 18216 +165 3621 18193 +166 3629 18103 +167 3650 18081 +168 3679 18092 +169 3703 18080 +170 3728 18075 +171 3762 18110 +172 3773 18040 +173 3795 18019 +174 3807 17947 +175 3829 17927 +176 3851 17906 +177 3883 17933 +178 3954 18136 +179 4006 18250 +180 4040 18283 +181 4066 18275 +182 4088 18251 +183 4109 18226 +184 4121 18157 +185 4136 18104 +186 4158 18078 +187 4166 17995 +188 4184 17955 +189 4215 17972 +190 4243 17974 +191 4267 17960 +192 4290 17941 +193 4313 17919 +194 4334 17894 +195 4356 17870 +196 4378 17846 +197 4400 17825 +198 4423 17803 +199 4455 17821 +200 4477 17798 +201 4499 17775 +202 4521 17750 +203 4543 17728 +204 4565 17704 +205 4587 17681 +206 4609 17658 +207 4631 17635 +208 4653 17612 +209 4675 17589 +210 4702 17584 +211 4725 17562 +212 4759 17585 +213 4787 17585 +214 4810 17563 +215 4833 17542 +216 4854 17516 +217 4872 17479 +218 4894 17455 +219 4916 17431 +220 4938 17406 +221 4960 17385 +222 4988 17382 +223 5010 17359 +224 5033 17338 +225 5055 17315 +226 5078 17292 +227 5100 17269 +228 5121 17244 +229 5144 17221 +230 5166 17200 +231 5201 17217 +232 5262 17322 +233 5311 17388 +234 5326 17340 +235 5366 17374 +236 5410 17418 +237 5434 17400 +238 5464 17399 +239 5490 17385 +240 5513 17362 +241 5534 17336 +242 5556 17311 +243 5578 17285 +244 5600 17259 +245 5622 17234 +246 5645 17209 +247 5666 17183 +248 5678 17126 +249 5709 17128 +250 5732 17106 +251 5758 17092 +252 5793 17106 +253 5808 17061 +254 5827 17025 +255 5835 16959 +256 5847 16904 +257 5868 16877 +258 5873 16803 +259 5894 16776 +260 5916 16751 +261 5938 16726 +262 5943 16654 +263 5965 16630 +264 5983 16595 +265 6008 16580 +266 6030 16556 +267 6053 16532 +268 6074 16508 +269 6096 16484 +270 6118 16459 +271 6133 16417 +272 6155 16392 +273 6177 16367 +274 6196 16336 +275 6223 16325 +276 6249 16311 +277 6275 16298 +278 6300 16282 +279 6322 16258 +280 6344 16234 +281 6366 16210 +282 6374 16150 +283 6397 16128 +284 6408 16078 +285 6430 16054 +286 6444 16010 +287 6469 15994 +288 6495 15979 +289 6516 15955 +290 6538 15931 +291 6575 15942 +292 6615 15961 +293 6659 15990 +294 6696 16003 +295 6758 16073 +296 6787 16065 +297 6824 16076 +298 6853 16067 +299 6877 16047 +300 6889 15999 +301 6911 15974 +302 6919 15917 +303 6941 15891 +304 6963 15867 +305 6971 15811 +306 6977 15751 +307 7004 15738 +308 7027 15714 +309 7049 15690 +310 7071 15665 +311 7093 15640 +312 7114 15616 +313 7136 15590 +314 7158 15565 +315 7172 15526 +316 7195 15503 +317 7207 15457 +318 7228 15430 +319 7255 15418 +320 7280 15400 +321 7307 15385 +322 7329 15362 +323 7355 15346 +324 7377 15323 +325 7393 15285 +326 7415 15261 +327 7438 15240 +328 7461 15217 +329 7488 15204 +330 7512 15183 +331 7534 15159 +332 7556 15135 +333 7578 15111 +334 7600 15086 +335 7623 15064 +336 7644 15040 +337 7667 15016 +338 7689 14993 +339 7706 14958 +340 7737 14952 +341 7779 14967 +342 7905 15143 +343 7927 15117 +344 7959 15111 +345 7982 15088 +346 8011 15076 +347 8041 15067 +348 8053 15022 +349 8075 14996 +350 8096 14971 +351 8105 14920 +352 8127 14895 +353 8148 14870 +354 8174 14851 +355 8214 14859 +356 8260 14877 +357 8323 14926 +358 8363 14933 +359 8399 14932 +360 8424 14911 +361 8448 14889 +362 8471 14865 +363 8496 14846 +364 8522 14826 +365 8544 14801 +366 8566 14774 +367 8577 14730 +368 8599 14705 +369 8621 14679 +370 8643 14654 +371 8665 14629 +372 8701 14627 +373 8756 14656 +374 8807 14679 +375 8872 14723 +376 8899 14706 +377 8928 14691 +378 8947 14661 +379 8969 14635 +380 8992 14609 +381 9021 14594 +382 9037 14559 +383 9059 14533 +384 9081 14506 +385 9103 14480 +386 9125 14453 +387 9147 14428 +388 9169 14402 +389 9192 14377 +390 9214 14352 +391 9240 14331 +392 9266 14311 +393 9291 14290 +394 9321 14276 +395 9340 14245 +396 9370 14232 +397 9391 14205 +398 9406 14168 +399 9451 14176 +400 9492 14179 +401 9547 14201 +402 9579 14190 +403 9601 14165 +404 9624 14139 +405 9646 14112 +406 9667 14086 +407 9690 14060 +408 9709 14030 +409 9732 14004 +410 9757 13983 +411 9785 13966 +412 9814 13949 +413 9823 13904 +414 9838 13869 +415 9861 13844 +416 9884 13818 +417 9906 13793 +418 9928 13767 +419 9950 13741 +420 9972 13714 +421 9994 13688 +422 10017 13664 +423 10045 13646 +424 10067 13620 +425 10085 13589 +426 10100 13553 +427 10108 13509 +428 10130 13483 +429 10152 13457 +430 10185 13446 +431 10218 13435 +432 10230 13397 +433 10276 13402 +434 10327 13414 +435 10372 13417 +436 10408 13409 +437 10412 13360 +438 10439 13340 +439 10461 13314 +440 10483 13289 +441 10506 13264 +442 10536 13247 +443 10558 13221 +444 10569 13182 +445 10591 13156 +446 10614 13131 +447 10636 13105 +448 10658 13079 +449 10679 13053 +450 10685 13006 +451 10708 12982 +452 10731 12957 +453 10742 12919 +454 10763 12892 +455 10792 12875 +456 10817 12853 +457 10833 12820 +458 10856 12795 +459 10879 12771 +460 10903 12748 +461 10912 12708 +462 10940 12688 +463 10964 12666 +464 10979 12632 +465 11023 12631 +466 11069 12633 +467 11110 12629 +468 11152 12626 +469 11190 12619 +470 11221 12602 +471 11244 12579 +472 11253 12537 +473 11258 12493 +474 11286 12474 +475 11309 12449 +476 11335 12428 +477 11368 12415 +478 11391 12389 +479 11413 12364 +480 11437 12341 +481 11459 12315 +482 11481 12290 +483 11504 12265 +484 11526 12239 +485 11549 12214 +486 11572 12190 +487 11594 12165 +488 11617 12140 +489 11639 12114 +490 11660 12087 +491 11682 12062 +492 11706 12039 +493 11730 12015 +494 11738 11975 +495 11760 11950 +496 11784 11926 +497 11804 11898 +498 11826 11873 +499 11864 11864 +500 11889 11841 +501 11911 11816 +502 11933 11791 +503 11955 11765 +504 11977 11739 +505 11999 11714 +506 12020 11688 +507 12039 11660 +508 12064 11637 +509 12075 11602 +510 12086 11566 +511 12109 11541 +512 12131 11516 +513 12152 11490 +514 12174 11465 +515 12198 11442 +516 12222 11418 +517 12244 11393 +518 12267 11369 +519 12275 11331 +520 12304 11312 +521 12326 11287 +522 12354 11268 +523 12391 11256 +524 12397 11216 +525 12405 11178 +526 12429 11155 +527 12451 11131 +528 12463 11096 +529 12485 11071 +530 12507 11046 +531 12515 11009 +532 12537 10984 +533 12566 10966 +534 12574 10929 +535 12596 10904 +536 12618 10879 +537 12636 10851 +538 12641 10811 +539 12652 10778 +540 12673 10752 +541 12697 10730 +542 12720 10705 +543 12739 10678 +544 12761 10653 +545 12783 10629 +546 12802 10602 +547 12827 10580 +548 12832 10541 +549 12885 10542 +550 12910 10520 +551 12956 10515 +552 12978 10490 +553 13000 10465 +554 13021 10440 +555 13026 10402 +556 13055 10383 +557 13077 10359 +558 13099 10334 +559 13122 10310 +560 13144 10285 +561 13165 10260 +562 13188 10236 +563 13207 10210 +564 13230 10186 +565 13248 10158 +566 13270 10134 +567 13295 10112 +568 13321 10090 +569 13343 10066 +570 13375 10049 +571 13403 10029 +572 13427 10006 +573 13453 9984 +574 13495 9974 +575 13534 9963 +576 13588 9961 +577 13630 9952 +578 13672 9941 +579 13701 9921 +580 13724 9897 +581 13746 9873 +582 13768 9848 +583 13794 9826 +584 13847 9823 +585 13903 9822 +586 13948 9814 +587 13991 9803 +588 14036 9794 +589 14068 9776 +590 14094 9754 +591 14116 9729 +592 14138 9703 +593 14160 9678 +594 14183 9654 +595 14207 9630 +596 14230 9606 +597 14252 9581 +598 14274 9556 +599 14286 9524 +600 14302 9495 +601 14329 9473 +602 14352 9449 +603 14376 9425 +604 14388 9394 +605 14435 9385 +606 14487 9379 +607 14554 9383 +608 14603 9376 +609 14652 9368 +610 14678 9344 +611 14704 9322 +612 14731 9300 +613 14756 9276 +614 14780 9253 +615 14805 9229 +616 14830 9205 +617 14850 9179 +618 14874 9155 +619 14898 9131 +620 14929 9111 +621 14962 9093 +622 14987 9069 +623 15017 9048 +624 15038 9022 +625 15050 8992 +626 15104 8985 +627 15131 8962 +628 15155 8939 +629 15186 8918 +630 15215 8897 +631 15240 8874 +632 15265 8850 +633 15290 8826 +634 15314 8802 +635 15336 8777 +636 15358 8752 +637 15380 8727 +638 15424 8713 +639 15455 8693 +640 15479 8669 +641 15514 8651 +642 15559 8638 +643 15574 8609 +644 15609 8591 +645 15625 8562 +646 15667 8547 +647 15714 8536 +648 15729 8507 +649 15753 8482 +650 15775 8457 +651 15798 8432 +652 15807 8400 +653 15827 8373 +654 15856 8351 +655 15878 8326 +656 15913 8308 +657 15969 8300 +658 16042 8301 +659 16099 8293 +660 16173 8294 +661 16197 8269 +662 16235 8252 +663 16266 8231 +664 16297 8210 +665 16325 8187 +666 16381 8178 +667 16453 8177 +668 16477 8152 +669 16542 8147 +670 16565 8122 +671 16588 8096 +672 16617 8074 +673 16636 8046 +674 16658 8020 +675 16681 7995 +676 16693 7964 +677 16716 7939 +678 16728 7908 +679 16763 7888 +680 16807 7872 +681 16852 7857 +682 16884 7836 +683 16927 7820 +684 16959 7799 +685 16982 7773 +686 17003 7747 +687 17012 7714 +688 17033 7688 +689 17056 7662 +690 17078 7637 +691 17101 7611 +692 17130 7588 +693 17152 7562 +694 17174 7537 +695 17198 7512 +696 17210 7481 +697 17233 7456 +698 17255 7430 +699 17277 7404 +700 17286 7373 +701 17310 7348 +702 17336 7324 +703 17366 7301 +704 17375 7270 +705 17398 7245 +706 17414 7217 +707 17449 7196 +708 17471 7170 +709 17493 7145 +710 17515 7119 +711 17538 7094 +712 17562 7069 +713 17584 7043 +714 17607 7018 +715 17636 6995 +716 17658 6969 +717 17680 6944 +718 17704 6919 +719 17727 6894 +720 17750 6868 +721 17772 6843 +722 17794 6817 +723 17816 6791 +724 17838 6766 +725 17862 6741 +726 17920 6729 +727 17939 6702 +728 17962 6677 +729 18010 6661 +730 18034 6636 +731 18057 6611 +732 18080 6585 +733 18104 6560 +734 18135 6538 +735 18158 6513 +736 18178 6486 +737 18202 6462 +738 18224 6436 +739 18247 6411 +740 18270 6385 +741 18278 6355 +742 18300 6330 +743 18323 6304 +744 18345 6279 +745 18373 6255 +746 18401 6232 +747 18431 6209 +748 18451 6183 +749 18474 6158 +750 18497 6132 +751 18520 6107 +752 18543 6082 +753 18565 6057 +754 18588 6032 +755 18613 6007 +756 18641 5984 +757 18664 5958 +758 18673 5929 +759 18681 5899 +760 18706 5875 +761 18730 5850 +762 18754 5825 +763 18777 5800 +764 18797 5774 +765 18817 5748 +766 18840 5723 +767 18868 5699 +768 18894 5675 +769 18922 5652 +770 18953 5629 +771 18981 5605 +772 19004 5580 +773 19027 5555 +774 19051 5530 +775 19072 5505 +776 19091 5479 +777 19115 5454 +778 19146 5431 +779 19177 5409 +780 19204 5385 +781 19229 5360 +782 19254 5336 +783 19278 5311 +784 19302 5286 +785 19325 5261 +786 19348 5236 +787 19373 5212 +788 19402 5188 +789 19434 5166 +790 19461 5142 +791 19484 5117 +792 19508 5092 +793 19530 5067 +794 19553 5041 +795 19575 5016 +796 19598 4991 +797 19622 4966 +798 19652 4943 +799 19675 4918 +800 19699 4894 +801 19721 4869 +802 19744 4843 +803 19765 4818 +804 19774 4790 +805 19796 4764 +806 19818 4739 +807 19841 4714 +808 19864 4689 +809 19893 4666 +810 19917 4641 +811 19940 4616 +812 19977 4595 +813 20007 4571 +814 20042 4549 +815 20080 4527 +816 20130 4509 +817 20181 4490 +818 20213 4467 +819 20244 4443 +820 20269 4419 +821 20292 4394 +822 20314 4368 +823 20337 4343 +824 20359 4318 +825 20382 4293 +826 20410 4269 +827 20451 4248 +828 20482 4224 +829 20505 4199 +830 20528 4174 +831 20552 4149 +832 20575 4124 +833 20597 4099 +834 20621 4074 +835 20644 4049 +836 20675 4026 +837 20700 4001 +838 20723 3976 +839 20745 3951 +840 20767 3926 +841 20789 3901 +842 20820 3877 +843 20862 3856 +844 20914 3836 +845 20970 3817 +846 21030 3798 +847 21075 3777 +848 21126 3757 +849 21160 3734 +850 21190 3710 +851 21217 3685 +852 21258 3663 +853 21303 3642 +854 21355 3621 +855 21404 3600 +856 21463 3581 +857 21520 3561 +858 21563 3539 +859 21606 3517 +860 21651 3495 +861 21702 3474 +862 21745 3452 +863 21810 3433 +864 21863 3412 +865 21911 3390 +866 21958 3368 +867 21988 3343 +868 22016 3318 +869 22038 3293 +870 22060 3267 +871 22083 3241 +872 22105 3215 +873 22127 3189 +874 22149 3164 +875 22172 3138 +876 22208 3114 +877 22252 3091 +878 22295 3069 +879 22345 3047 +880 22391 3024 +881 22450 3003 +882 22506 2982 +883 22549 2958 +884 22571 2933 +885 22594 2907 +886 22617 2881 +887 22648 2856 +888 22702 2834 +889 22753 2812 +890 22796 2788 +891 22838 2765 +892 22882 2741 +893 22974 2724 +894 23020 2700 +895 23066 2677 +896 23088 2651 +897 23110 2625 +898 23133 2598 +899 23154 2572 +900 23176 2546 +901 23206 2521 +902 23233 2495 +903 23260 2470 +904 23285 2444 +905 23309 2418 +906 23332 2392 +907 23356 2366 +908 23378 2340 +909 23401 2314 +910 23424 2288 +911 23449 2262 +912 23475 2236 +913 23501 2211 +914 23527 2185 +915 23550 2159 +916 23572 2133 +917 23594 2107 +918 23616 2081 +919 23638 2055 +920 23660 2029 +921 23701 2005 +922 23745 1980 +923 23787 1956 +924 23826 1931 +925 23867 1907 +926 23906 1882 +927 23953 1858 +928 24002 1834 +929 24031 1808 +930 24053 1782 +931 24076 1756 +932 24098 1730 +933 24120 1704 +934 24142 1678 +935 24164 1652 +936 24187 1626 +937 24214 1600 +938 24239 1574 +939 24262 1548 +940 24285 1522 +941 24307 1496 +942 24328 1470 +943 24351 1444 +944 24373 1418 +945 24392 1392 +946 24416 1366 +947 24438 1340 +948 24464 1314 +949 24490 1288 +950 24519 1263 +951 24542 1237 +952 24564 1211 +953 24587 1185 +954 24609 1159 +955 24631 1133 +956 24653 1107 +957 24675 1081 +958 24699 1055 +959 24725 1030 +960 24751 1004 +961 24773 978 +962 24796 952 +963 24818 926 +964 24840 900 +965 24862 875 +966 24884 849 +967 24906 823 +968 24928 797 +969 24950 771 +970 24982 746 +971 25008 720 +972 25034 694 +973 25057 668 +974 25080 643 +975 25102 617 +976 25126 591 +977 25148 565 +978 25170 539 +979 25194 514 +980 25216 488 +981 25246 462 +982 25269 437 +983 25291 411 +984 25314 385 +985 25336 359 +986 25358 334 +987 25381 308 +988 25404 282 +989 25427 256 +990 25451 231 +991 25475 205 +992 25502 179 +993 25525 154 +994 25554 128 +995 25576 102 +996 25598 77 +997 25620 51 +998 25642 25 +999 25665 0 diff --git a/metagpt/roles/kaggle_manager.py b/metagpt/roles/kaggle_manager.py new file mode 100644 index 000000000..18ac6733a --- /dev/null +++ b/metagpt/roles/kaggle_manager.py @@ -0,0 +1,153 @@ +from typing import Dict, List, Union, Tuple +import json +import subprocess +import os + +import fire +import pandas as pd + +from metagpt.config import CONFIG +from metagpt.const import WORKSPACE_ROOT +from metagpt.roles import Role +from metagpt.actions import Action, BossRequirement +from metagpt.actions.ml_da_action import AskReview, SummarizeAnalysis +from metagpt.schema import Message, Task, Plan +from metagpt.logs import logger +from metagpt.utils.common import CodeParser + + +os.environ["KAGGLE_USERNAME"] = CONFIG.kaggle_username +os.environ["KAGGLE_KEY"] = CONFIG.kaggle_key + +def run_command(cmd): + print(cmd) + output = subprocess.run(cmd, shell=True, capture_output=True, text=True) + if output.returncode != 0: + print("Error output:", output.stderr) + exit() + else: + print(output.stdout) + return output.stdout + +class DownloadData(Action): + + async def run(self, competition, data_desc="") -> str: + data_path = WORKSPACE_ROOT / competition + + output = run_command(f"kaggle competitions list --search {competition}") + assert output != "No competitions found", "You must provide the correct competition name" + + run_command(f"kaggle competitions download {competition} --path {WORKSPACE_ROOT}") + + if not os.path.exists(data_path): + # if True: + # run_command(f"rm -r {data_path / '*'}") + run_command(f"unzip -o {WORKSPACE_ROOT / '*.zip'} -d {data_path}") # FIXME: not safe + + file_list = run_command(f"ls {data_path}") + + rsp = f""" + Location: + Data downloaded at {data_path} folder, including {file_list} + Data Description: + {data_desc} + """ + return rsp + +class SubmitResult(Action): + PROMPT_TEMPLATE = """ + # Summary + __summary__ + # Your task + Extract the file path for test set prediction from the summary above, output a json following the format: + ```json + {"file_path": str = "the file path, for example, /path/to/the/prediction/file/xxx.csv, /path/to/the/prediction/file/xxx.xlsx"} + ``` + """ + + def __init__(self, name: str = "", context=None, llm=None) -> str: + super().__init__(name, context, llm) + + async def _parse_submit_file_path(self, context) -> str: + prompt = self.PROMPT_TEMPLATE.replace("__summary__", context) + rsp = await self._aask(prompt) + rsp = CodeParser.parse_code(block=None, text=rsp) + file_path = json.loads(rsp)["file_path"] + return file_path + + async def run(self, competition, submit_message="") -> str: + submit_file_path = await self._parse_submit_file_path(submit_message) + + data_path = WORKSPACE_ROOT / competition + submit_message = submit_message.replace("'", "") + + run_command(f"kaggle competitions submit {competition} -f {submit_file_path} -m '{submit_message}'") + run_command(f"kaggle competitions leaderboard --show --csv {competition} > {data_path / 'leaderboard.csv'}") + run_command(f"kaggle competitions submissions --csv {competition} > {data_path / 'submission.csv'}") + + leaderboard = pd.read_csv(data_path / 'leaderboard.csv') + submission = pd.read_csv(data_path / 'submission.csv') + print(submission) # submission.to_json(orient="records") + + submission_score = submission.loc[0, "publicScore"] + best_score = max(submission["publicScore"]) # might be min + rank = leaderboard.loc[leaderboard["score"] == best_score].index[0] + rank_pct = round(rank / len(leaderboard), 4) * 100 + + submission_summary = f""" + # All histories: + {submission.head(5).to_string()} + # Current + Current submission score: {submission_score}, best score: {best_score}, best rank: {rank} (top {rank_pct}%) + """ + logger.info(submission_summary) + return submission_summary + + +class KaggleManager(Role): + def __init__( + self, name="ABC", profile="KaggleManager", goal="", competition="titanic", data_desc="" + ): + super().__init__(name=name, profile=profile, goal=goal) + self._init_actions([DownloadData, SubmitResult]) + self._watch([BossRequirement, SummarizeAnalysis]) + self.competition = competition + self.data_desc = data_desc # currently passed in, later can be scrapped down from web by another Role + + async def _think(self): + observed = self.get_memories()[-1].cause_by + if observed == BossRequirement: + self._set_state(0) # DownloadData, get competition of interest from human, download datasets + elif observed == SummarizeAnalysis: + self._set_state(1) # SubmitResult, get prediction from MLEngineer and submit it to Kaggle + + async def _act(self): + todo = self._rc.todo + logger.info(f"{self._setting}: ready to {self._rc.todo}") + + if isinstance(todo, DownloadData): + rsp = await todo.run(self.competition, self.data_desc) + + elif isinstance(todo, SubmitResult): + submit_message = self.get_memories()[-1].content # use analysis summary from MLEngineer as submission message + rsp = await todo.run(competition=self.competition, submit_message=submit_message) + + msg = Message(content=rsp, role="user", cause_by=type(todo)) + + return msg + +if __name__ == "__main__": + competition, data_desc, requirement = ( + "titanic", + "Training set is train.csv.\nTest set is test.csv. We also include gender_submission.csv, a set of predictions that assume all and only female passengers survive, as an example of what a submission file should look like.", + "Run EDA on the train dataset, train a model to predict survival (20% as validation) and save it, predict the test set using saved model, save the test result according to format", + ) + + summary = "I used Python with pandas for data preprocessing, sklearn's RandomForestClassifier for modeling, and achieved 82.12% accuracy on validation. Predictions saved at '/Users/gary/Desktop/data_agents_opt/workspace/titanic/gender_submission.csv'." + + async def main(requirement: str = requirement): + role = KaggleManager(competition=competition, data_desc=data_desc) + # await role.run(Message(content="", cause_by=BossRequirement)) + await role.run(Message(content=summary, cause_by=SummarizeAnalysis)) + + fire.Fire(main) \ No newline at end of file diff --git a/metagpt/roles/ml_engineer.py b/metagpt/roles/ml_engineer.py index e8b0bda16..fa006b061 100644 --- a/metagpt/roles/ml_engineer.py +++ b/metagpt/roles/ml_engineer.py @@ -1,90 +1,32 @@ +from typing import List import json -import re from datetime import datetime -from typing import List import fire import nbformat from pathlib import Path from metagpt.actions import Action +from metagpt.actions.debug_code import DebugCode from metagpt.actions.execute_code import ExecutePyCode +from metagpt.actions.ml_da_action import AskReview, SummarizeAnalysis, Reflect, ReviewConst from metagpt.actions.write_analysis_code import WriteCodeByGenerate, WriteCodeWithTools from metagpt.actions.write_code_steps import WriteCodeSteps from metagpt.actions.write_plan import WritePlan +from metagpt.actions.write_plan import update_plan_from_rsp, precheck_update_plan_from_rsp from metagpt.const import DATA_PATH, PROJECT_ROOT from metagpt.logs import logger +from metagpt.memory import Memory +from metagpt.prompts.ml_engineer import STRUCTURAL_CONTEXT from metagpt.prompts.ml_engineer import ( - GEN_DATA_DESC_PROMPT, UPDATE_DATA_COLUMNS, PRINT_DATA_COLUMNS ) from metagpt.roles import Role +from metagpt.roles.kaggle_manager import DownloadData, SubmitResult from metagpt.schema import Message, Plan -from metagpt.utils.common import CodeParser, remove_comments, create_func_config -from metagpt.actions.debug_code import DebugCode - -STRUCTURAL_CONTEXT = """ -## User Requirement -{user_requirement} -## Dataset Description -{data_desc} -## Current Plan -{tasks} -## Current Task -{current_task} -## Packages Installed -pandas -numpy -""" - - -# scikit-learn -# lightgbm -# xgboost -# catboost - -def truncate(result: str, keep_len: int = 1000) -> str: - desc = "Truncated to show only the last 1000 characters\n" - if result.startswith(desc): - result = result[-len(desc):] - - if len(result) > keep_len: - result = result[-keep_len:] - - if not result.startswith(desc): - return desc + result - return desc - - -def remove_escape_and_color_codes(input_str): - # 使用正则表达式去除转义字符和颜色代码 - pattern = re.compile(r'\x1b\[[0-9;]*[mK]') - result = pattern.sub('', input_str) - return result - - -class AskReview(Action): - async def run(self, context: List[Message], plan: Plan = None): - logger.info("Current overall plan:") - logger.info( - "\n".join([f"{task.task_id}: {task.instruction}, is_finished: {task.is_finished}" for task in plan.tasks]) - ) - - logger.info("most recent context:") - latest_action = context[-1].cause_by.__name__ if context[-1].cause_by else "" - prompt = f"\nPlease review output from {latest_action}:\n" \ - "If you want to change a task in the plan, say 'change task task_id, ... (things to change)'\n" \ - "If you confirm the output and wish to continue with the current process, type CONFIRM\n" \ - "If you want to terminate the process, type exit:\n" - rsp = input(prompt) - - if rsp.lower() in ("exit"): - exit() - - confirmed = rsp.lower() in ("confirm", "yes", "y") - - return rsp, confirmed +from metagpt.utils.common import remove_comments, create_func_config +from metagpt.utils.save_code import save_code_file class UpdateDataColumns(Action): @@ -100,50 +42,95 @@ class UpdateDataColumns(Action): class MLEngineer(Role): def __init__( - self, name="ABC", profile="MLEngineer", goal="", auto_run: bool = False, + self, name="ABC", profile="MLEngineer", goal="", auto_run: bool = False ): super().__init__(name=name, profile=profile, goal=goal) self._set_react_mode(react_mode="plan_and_act") + self._watch([DownloadData, SubmitResult]) + self.plan = Plan(goal=goal) - self.use_tools = True - self.use_code_steps = True + self.use_tools = False + self.use_code_steps = False self.execute_code = ExecutePyCode() self.auto_run = auto_run self.data_desc = {} - + + # memory for working on each task, discarded each time a task is done + self.working_memory = Memory() + async def _plan_and_act(self): + + ### Actions in a multi-agent multi-turn setting ### + memories = self.get_memories() + if memories: + latest_event = memories[-1].cause_by + if latest_event == DownloadData: + self.plan.context = memories[-1].content + elif latest_event == SubmitResult: + # self reflect on previous plan outcomes and think about how to improve the plan, add to working memory + await self._reflect() + + # get feedback for improvement from human, add to working memory + await self._ask_review(trigger=ReviewConst.TASK_REVIEW_TRIGGER) + + ### Common Procedure in both single- and multi-agent setting ### # create initial plan and update until confirmation await self._update_plan() - + while self.plan.current_task: task = self.plan.current_task logger.info(f"ready to take on task {task}") - + # take on current task - code, result, success, code_steps = await self._write_and_exec_code() - + code, result, success = await self._write_and_exec_code() + # ask for acceptance, users can other refuse and change tasks in the plan - task_result_confirmed = await self._ask_review() - - if success and task_result_confirmed: + review, task_result_confirmed = await self._ask_review(trigger=ReviewConst.TASK_REVIEW_TRIGGER) + + if self.auto_run: + # if human confirms the task result, then we deem the task completed, regardless of whether the code run succeeds; + # if auto mode, then the code run has to succeed for the task to be considered completed + task_result_confirmed = success + + if task_result_confirmed: # tick off this task and record progress task.code = code task.result = result - task.code_steps = code_steps self.plan.finish_current_task() self.working_memory.clear() + if self.use_tools: success, new_code = await self._update_data_columns() if success: task.code = task.code + "\n\n" + new_code + + confirmed_and_more = (ReviewConst.CONTINUE_WORD[0] in review.lower() + and review.lower() not in ReviewConst.CONTINUE_WORD[0]) # "confirm, ... (more content, such as changing downstream tasks)" + if confirmed_and_more: + self.working_memory.add(Message(content=review, role="user", cause_by=AskReview)) + await self._update_plan(review) + elif "redo" in review: + # Ask the Role to redo this task with help of review feedback, + # useful when the code run is successful but the procedure or result is not what we want + continue + else: # update plan according to user's feedback and to take on changed tasks - await self._update_plan() + await self._update_plan(review) - time = datetime.now().strftime('%Y-%m-%d_%H-%M-%S') - self.execute_code.save_notebook(f"{DATA_PATH}/notebooks/ml_{time}.ipynb") + completed_plan_memory = self.get_useful_memories() # completed plan as a outcome + self._rc.memory.add(completed_plan_memory[0]) # add to persistent memory + summary = await SummarizeAnalysis().run(self.plan) + rsp = Message(content=summary, cause_by=SummarizeAnalysis) + self._rc.memory.add(rsp) + + # save code using datetime.now or keywords related to the goal of your project (plan.goal). + project_record = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") + save_code_file(name=project_record, code_context=self.execute_code.nb, file_format="ipynb") + return rsp + async def _update_data_columns(self): rsp = await UpdateDataColumns().run(self.plan) is_update, code = rsp["is_update"], rsp["code"] @@ -155,34 +142,36 @@ class MLEngineer(Role): return success, code async def _write_and_exec_code(self, max_retry: int = 3): - code_steps = ( + self.plan.current_task.code_steps = ( await WriteCodeSteps().run(self.plan) if self.use_code_steps else "" ) - + counter = 0 - improve_code = "" success = False debug_context = [] - + while not success and counter < max_retry: context = self.get_useful_memories() - if counter > 0: - improve_code = await DebugCode().run(plan=self.plan.current_task.instruction, + # print("*" * 10) + # print(context) + # print("*" * 10) + # breakpoint() + if counter > 0 and self.use_tools: + code = await DebugCode().run( + plan=self.plan.current_task.instruction, code=code, runtime_result=self.working_memory.get(), - context=debug_context) - - if improve_code != "": - code = improve_code - logger.info(f"new code \n{improve_code}") + context=debug_context + ) + logger.info(f"new code \n{code}") cause_by = DebugCode elif not self.use_tools or self.plan.current_task.task_type == "other": logger.info("Write code with pure generation") code = await WriteCodeByGenerate().run( - context=context, plan=self.plan, code_steps=code_steps, temperature=0.0 + context=context, plan=self.plan, temperature=0.0 ) debug_context = [self.get_useful_memories(task_exclude_field={'result', 'code_steps'})[0]] cause_by = WriteCodeByGenerate @@ -192,47 +181,46 @@ class MLEngineer(Role): tool_context, code = await WriteCodeWithTools(schema_path=schema_path).run( context=context, plan=self.plan, - code_steps=code_steps, column_info=self.data_desc.get("column_info", ""), ) debug_context = tool_context cause_by = WriteCodeWithTools - + self.working_memory.add( Message(content=code, role="assistant", cause_by=cause_by) ) - - # debug on code, run on runcode with finished code and new_df - # runcode = code_context + "\n\n" + code + result, success = await self.execute_code.run(code) - # truncated the result - print(truncate(result)) - + print(result) self.working_memory.add( - Message(content=truncate(remove_escape_and_color_codes(result)), role="user", cause_by=ExecutePyCode) + Message(content=result, role="user", cause_by=ExecutePyCode) ) - + if "!pip" in code: success = False - # if not success: - # await self._ask_review() - + counter += 1 - - return code, result, success, code_steps - - async def _ask_review(self): - if not self.auto_run: + + if not success and counter >= max_retry: + logger.info("coding failed!") + review, _ = await self._ask_review(auto_run=False, trigger=ReviewConst.CODE_REVIEW_TRIGGER) + if ReviewConst.CHANGE_WORD[0] in review: + counter = 0 # redo the task again with help of human suggestions + + return code, result, success + + async def _ask_review(self, auto_run: bool = None, trigger: str = ReviewConst.TASK_REVIEW_TRIGGER): + auto_run = auto_run or self.auto_run + if not auto_run: context = self.get_useful_memories() - review, confirmed = await AskReview().run(context=context[-5:], plan=self.plan) + review, confirmed = await AskReview().run(context=context[-5:], plan=self.plan, trigger=trigger) if not confirmed: self.working_memory.add(Message(content=review, role="user", cause_by=AskReview)) - return confirmed - return True - - async def _update_plan(self, max_tasks: int = 3): + return review, confirmed + return "", True + + async def _update_plan(self, review: str = "", max_tasks: int = 3, max_retries: int = 3): plan_confirmed = False - while not plan_confirmed: context = self.get_useful_memories() rsp = await WritePlan().run( @@ -241,43 +229,57 @@ class MLEngineer(Role): self.working_memory.add( Message(content=rsp, role="assistant", cause_by=WritePlan) ) - plan_confirmed = await self._ask_review() - - new_tasks = WritePlan.rsp_to_tasks(rsp) - logger.debug(len(self.plan.tasks)) - logger.debug(len(new_tasks)) - ## fixme: 能重复执行多轮重新plan,但应该有更优处理逻辑 - ## fixme: do not overwrite original tasks - tasks = self.plan.tasks + new_tasks - - self.plan.add_tasks(tasks) + + # precheck plan before asking reviews + is_plan_valid, error = precheck_update_plan_from_rsp(rsp, self.plan) + if not is_plan_valid and max_retries > 0: + error_msg = f"The generated plan is not valid with error: {error}, try regenerating, remember to generate either the whole plan or the single changed task only" + logger.warning(error_msg) + self.working_memory.add(Message(content=error_msg, role="assistant", cause_by=WritePlan)) + max_retries -= 1 + continue + + _, plan_confirmed = await self._ask_review(trigger=ReviewConst.TASK_REVIEW_TRIGGER) + + update_plan_from_rsp(rsp, self.plan) + self.working_memory.clear() - def get_useful_memories(self, task_exclude_field: set = None) -> List[Message]: + async def _reflect(self): + context = self.get_memories() + context = "\n".join([str(msg) for msg in context]) + # print("*" * 10) + # print(context) + # print("*" * 10) + reflection = await Reflect().run(context=context) + self.working_memory.add(Message(content=reflection, role="assistant")) + self.working_memory.add(Message(content=Reflect.REWRITE_PLAN_INSTRUCTION, role="user")) + + def get_useful_memories(self, task_exclude_field=None) -> List[Message]: """find useful memories only to reduce context length and improve performance""" # TODO dataset description , code steps + if task_exclude_field is None: + # Shorten the context as we don't need code steps after we get the codes. + # This doesn't affect current_task below, which should hold the code steps + task_exclude_field = {'code_steps'} user_requirement = self.plan.goal - tasks = json.dumps( - [task.dict(exclude=task_exclude_field) for task in self.plan.tasks], indent=4, ensure_ascii=False - ) + data_desc = self.plan.context + tasks = [task.dict(exclude=task_exclude_field) for task in self.plan.tasks] + tasks = json.dumps(tasks, indent=4, ensure_ascii=False) current_task = self.plan.current_task.json() if self.plan.current_task else {} context = STRUCTURAL_CONTEXT.format( - user_requirement=user_requirement, - data_desc=self.data_desc, - tasks=tasks, - current_task=current_task + user_requirement=user_requirement, data_desc=data_desc, tasks=tasks, current_task=current_task ) context_msg = [Message(content=context, role="user")] + + return context_msg + self.get_working_memories() - return context_msg + self.working_memory.get() - - @property - def working_memory(self): - return self._rc.memory + def get_working_memories(self) -> List[Message]: + return self.working_memory.get() if __name__ == "__main__": - # requirement = "Run data analysis on sklearn Iris dataset, include a plot" + requirement = "Run data analysis on sklearn Iris dataset, include a plot" # requirement = "Run data analysis on sklearn Diabetes dataset, include a plot" # requirement = "Run data analysis on sklearn Wine recognition dataset, include a plot, and train a model to predict wine class (20% as validation), and show validation accuracy" # requirement = "Run data analysis on sklearn Wisconsin Breast Cancer dataset, include a plot, train a model to predict targets (20% as validation), and show validation accuracy" diff --git a/metagpt/schema.py b/metagpt/schema.py index 2e4260096..8eb7e31ca 100644 --- a/metagpt/schema.py +++ b/metagpt/schema.py @@ -78,14 +78,15 @@ class Task(BaseModel): dependent_task_ids: list[str] = [] # Tasks prerequisite to this Task instruction: str = "" task_type: str = "" + code_steps: str = "" code: str = "" result: str = "" is_finished: bool = False - code_steps: str = "" class Plan(BaseModel): goal: str + context: str = "" tasks: list[Task] = [] task_map: dict[str, Task] = {} current_task_id = "" @@ -149,14 +150,81 @@ class Plan(BaseModel): self.tasks = final_tasks # Update current_task_id to the first unfinished task in the merged list - for task in self.tasks: - if not task.is_finished: - self.current_task_id = task.task_id - break + self._update_current_task() # Update the task map for quick access to tasks by ID self.task_map = {task.task_id: task for task in self.tasks} + + def reset_task(self, task_id: str): + """ + Clear code and result of the task based on task_id, and set the task as unfinished. + Args: + task_id (str): The ID of the task to be reset. + + Returns: + None + """ + if task_id in self.task_map: + task = self.task_map[task_id] + task.code = "" + task.result = "" + task.is_finished = False + + def replace_task(self, new_task: Task): + """ + Replace an existing task with the new input task based on task_id, and reset all tasks depending on it. + + Args: + new_task (Task): The new task that will replace an existing one. + + Returns: + None + """ + if new_task.task_id in self.task_map: + # Replace the task in the task map and the task list + self.task_map[new_task.task_id] = new_task + for i, task in enumerate(self.tasks): + if task.task_id == new_task.task_id: + self.tasks[i] = new_task + break + + # Reset dependent tasks + for task in self.tasks: + if new_task.task_id in task.dependent_task_ids: + self.reset_task(task.task_id) + + def append_task(self, new_task: Task): + """ + Append a new task to the end of existing task sequences + + Args: + new_task (Task): The new task to be appended to the existing task sequence + + Returns: + None + """ + assert not self.has_task_id(new_task.task_id), "Task already in current plan, use replace_task instead" + + assert all([self.has_task_id(dep_id) for dep_id in new_task.dependent_task_ids]), \ + "New task has unknown dependencies" + + # Existing tasks do not depend on the new task, it's fine to put it to the end of the sorted task sequence + self.tasks.append(new_task) + self.task_map[new_task.task_id] = new_task + self._update_current_task() + + def has_task_id(self, task_id: str) -> bool: + return task_id in self.task_map + + def _update_current_task(self): + current_task_id = "" + for task in self.tasks: + if not task.is_finished: + current_task_id = task.task_id + break + self.current_task_id = current_task_id # all tasks finished + @property def current_task(self) -> Task: """Find current task to execute @@ -170,10 +238,8 @@ class Plan(BaseModel): """Finish current task, set Task.is_finished=True, set current task to next task """ if self.current_task_id: - current_task = self.current_task - current_task.is_finished = True - next_task_index = self.tasks.index(current_task) + 1 - self.current_task_id = self.tasks[next_task_index].task_id if next_task_index < len(self.tasks) else None + self.current_task.is_finished = True + self._update_current_task() # set to next task def get_finished_tasks(self) -> list[Task]: """return all finished tasks in correct linearized order diff --git a/metagpt/tools/functions/__init__.py b/metagpt/tools/functions/__init__.py index 30ee10827..a0a43f507 100644 --- a/metagpt/tools/functions/__init__.py +++ b/metagpt/tools/functions/__init__.py @@ -4,6 +4,3 @@ # @Author : lidanyang # @File : __init__.py # @Desc : -from metagpt.tools.functions.register.register import registry -import metagpt.tools.functions.libs.feature_engineering -import metagpt.tools.functions.libs.data_preprocess diff --git a/metagpt/tools/functions/libs/data_preprocess.py b/metagpt/tools/functions/libs/data_preprocess.py index fa70bf8fc..ec3580889 100644 --- a/metagpt/tools/functions/libs/data_preprocess.py +++ b/metagpt/tools/functions/libs/data_preprocess.py @@ -1,4 +1,5 @@ import numpy as np +import pandas as pd from sklearn.impute import SimpleImputer from sklearn.preprocessing import LabelEncoder from sklearn.preprocessing import MaxAbsScaler @@ -9,7 +10,6 @@ from sklearn.preprocessing import RobustScaler from sklearn.preprocessing import StandardScaler from metagpt.tools.functions.libs.base import MLProcess -from metagpt.tools.functions.schemas.data_preprocess import * class FillMissingValue(MLProcess): @@ -141,7 +141,10 @@ def get_column_info(df: pd.DataFrame) -> dict: for i in df.columns: nan_freq = float("%.2g" % (df[i].isna().mean() * 100)) n_unique = df[i].nunique() - data.append([i, df[i].dtype, nan_freq, n_unique]) + data_type = str(df[i].dtype).replace("dtype('", "").replace("')", "") + if data_type == "O": + data_type = "object" + data.append([i, data_type, nan_freq, n_unique]) samples = pd.DataFrame( data, diff --git a/metagpt/tools/functions/libs/feature_engineering.py b/metagpt/tools/functions/libs/feature_engineering.py index de54e4db0..1ec2b9675 100644 --- a/metagpt/tools/functions/libs/feature_engineering.py +++ b/metagpt/tools/functions/libs/feature_engineering.py @@ -7,6 +7,7 @@ import itertools import numpy as np +import pandas as pd from dateutil.relativedelta import relativedelta from joblib import Parallel, delayed from pandas.api.types import is_numeric_dtype @@ -15,7 +16,6 @@ from sklearn.model_selection import KFold from sklearn.preprocessing import PolynomialFeatures, KBinsDiscretizer from metagpt.tools.functions.libs.base import MLProcess -from metagpt.tools.functions.schemas.feature_engineering import * class PolynomialExpansion(MLProcess): diff --git a/metagpt/tools/functions/libs/ml_model.py b/metagpt/tools/functions/libs/ml_model.py deleted file mode 100644 index b669de2c1..000000000 --- a/metagpt/tools/functions/libs/ml_model.py +++ /dev/null @@ -1,196 +0,0 @@ -from sklearn.model_selection import train_test_split -from sklearn.preprocessing import LabelEncoder - -from sklearn.linear_model import LogisticRegression -from sklearn.ensemble import RandomForestClassifier -from sklearn.ensemble import GradientBoostingClassifier - - -from sklearn.linear_model import LinearRegression -from sklearn.ensemble import RandomForestRegressor -from sklearn.ensemble import GradientBoostingRegressor - -from metagpt.tools.functions import registry -from metagpt.tools.functions.schemas.ml_model import * - - -######### -## 分类 ## -######### - - -@registry.register("classification_model", LogisticRegressionClassification) -def logistic_regression_classification(df, label, test_size=0.2, penalty='l2', dual=False): - nonnumeric_columns = [col for col in df if df[col].dtype == 'object'] - for col in nonnumeric_columns: - df[col] = LabelEncoder().fit_transform(df[col]) - df = df.fillna(0) - - features = [col for col in df if col != label] - x, y = df[features], df[label] - tr_x, te_x, tr_y, te_y = train_test_split(x, y, test_size=test_size, random_state=1) - - model = LogisticRegression(penalty=penalty, dual=dual) - model.fit(tr_x, tr_y, ) - te_pred_prob = model.predict_proba(te_x) - - res = { - 'te_pred_prob': te_pred_prob - } - return res - - -@registry.register("classification_model", RandomForestClassification) -def random_forest_classification(df, label, test_size=0.2, n_estimators=100, criterion='gini'): - nonnumeric_columns = [col for col in df if df[col].dtype == 'object'] - for col in nonnumeric_columns: - df[col] = LabelEncoder().fit_transform(df[col]) - df = df.fillna(0) - - features = [col for col in df if col != label] - x, y = df[features], df[label] - tr_x, te_x, tr_y, te_y = train_test_split(x, y, test_size=test_size, random_state=1) - model = RandomForestClassifier(n_estimators=n_estimators, criterion=criterion) - model.fit(tr_x, tr_y, ) - te_pred_prob = model.predict_proba(te_x) - - res = { - 'te_pred_prob': te_pred_prob - } - return res - - -@registry.register("classification_model", GradientBoostingClassification) -def gradient_boosting_classification(df, label, test_size=0.2, n_estimators=100, learning_rate=0.1): - nonnumeric_columns = [col for col in df if df[col].dtype == 'object'] - for col in nonnumeric_columns: - df[col] = LabelEncoder().fit_transform(df[col]) - df = df.fillna(0) - - features = [col for col in df if col != label] - x, y = df[features], df[label] - tr_x, te_x, tr_y, te_y = train_test_split(x, y, test_size=test_size, random_state=1) - model = GradientBoostingClassifier(n_estimators=n_estimators, learning_rate=learning_rate) - model.fit(tr_x, tr_y, ) - te_pred_prob = model.predict_proba(te_x) - - res = { - 'te_pred_prob': te_pred_prob - } - return res - - - -######### -## 回归 ## -######### - - -@registry.register("regression_model", LinearRegressionRegression) -def linear_regression(df, label, test_size=0.2, ): - nonnumeric_columns = [col for col in df if df[col].dtype == 'object'] - for col in nonnumeric_columns: - df[col] = LabelEncoder().fit_transform(df[col]) - df = df.fillna(0) - - features = [col for col in df if col != label] - x, y = df[features], df[label] - tr_x, te_x, tr_y, te_y = train_test_split(x, y, test_size=test_size, random_state=1) - - model = LinearRegression() - model.fit(tr_x, tr_y, ) - te_pred_prob = model.predict(te_x) - - res = { - 'te_pred_prob': te_pred_prob - } - return res - - -@registry.register("regression_model", RandomForestRegression) -def random_forest_regression(df, label, test_size=0.2, n_estimators=100, criterion='squared_error'): - nonnumeric_columns = [col for col in df if df[col].dtype == 'object'] - for col in nonnumeric_columns: - df[col] = LabelEncoder().fit_transform(df[col]) - df = df.fillna(0) - - features = [col for col in df if col != label] - x, y = df[features], df[label] - tr_x, te_x, tr_y, te_y = train_test_split(x, y, test_size=test_size, random_state=1) - model = RandomForestRegressor(n_estimators=n_estimators, criterion=criterion) - model.fit(tr_x, tr_y, ) - te_pred_prob = model.predict(te_x) - - res = { - 'te_pred_prob': te_pred_prob - } - return res - - -@registry.register("regression_model", GradientBoostingRegression) -def gradient_boosting_regression(df, label, test_size=0.2, n_estimators=100, learning_rate=0.1): - nonnumeric_columns = [col for col in df if df[col].dtype == 'object'] - for col in nonnumeric_columns: - df[col] = LabelEncoder().fit_transform(df[col]) - df = df.fillna(0) - - features = [col for col in df if col != label] - x, y = df[features], df[label] - tr_x, te_x, tr_y, te_y = train_test_split(x, y, test_size=test_size, random_state=1) - model = GradientBoostingRegressor(n_estimators=n_estimators, learning_rate=learning_rate) - model.fit(tr_x, tr_y, ) - te_pred_prob = model.predict(te_x) - - res = { - 'te_pred_prob': te_pred_prob - } - return res - - -if __name__ == '__main__': - def run(): - from sklearn.datasets import load_iris - loader = load_iris(as_frame=True) - df = loader['data'] - df['target'] = loader['target'] - - df[df.columns[0]] = df[df.columns[0]].astype(str) - df[df.columns[1]] = df[df.columns[1]].astype(int) - df['target'] = df['target'].astype(str) - - print(df) - print('####'*5) - res = logistic_regression_classification(df, 'target', test_size=0.25, penalty='l2', dual=False) - print(res['te_pred_prob']) - - print('####'*5) - res = random_forest_classification(df, 'target', test_size=0.25, n_estimators=100, criterion='gini') - print(res['te_pred_prob']) - - print('####'*5) - res = gradient_boosting_classification(df, 'target', test_size=0.25, n_estimators=100, learning_rate=0.1) - print(res['te_pred_prob']) - - from sklearn.datasets import make_regression - import pandas as pd - loader = make_regression() - df = pd.DataFrame(loader[0]) - df['target'] = loader[1] - - df[df.columns[0]] = df[df.columns[0]].astype(str) - df[df.columns[1]] = df[df.columns[1]].astype(int) - # df['target'] = df['target'].astype(str) - - print(df) - print('####' * 5) - res = linear_regression(df, 'target', test_size=0.25, ) - print(res['te_pred_prob']) - - print('####' * 5) - res = random_forest_regression(df, 'target', test_size=0.25, n_estimators=100, criterion='squared_error') - print(res['te_pred_prob']) - - print('####' * 5) - res = gradient_boosting_regression(df, 'target', test_size=0.25, n_estimators=100, learning_rate=0.1) - print(res['te_pred_prob']) - run() \ No newline at end of file diff --git a/metagpt/tools/functions/register/__init__.py b/metagpt/tools/functions/register/__init__.py deleted file mode 100644 index c80872750..000000000 --- a/metagpt/tools/functions/register/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# @Time : 2023/11/16 16:37 -# @Author : lidanyang -# @File : __init__.py -# @Desc : diff --git a/metagpt/tools/functions/register/register.py b/metagpt/tools/functions/register/register.py deleted file mode 100644 index 0731e31c0..000000000 --- a/metagpt/tools/functions/register/register.py +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# @Time : 2023/11/16 16:38 -# @Author : lidanyang -# @File : register.py -# @Desc : -import inspect -from typing import Type, Optional, Callable, Dict, Union, List - -from metagpt.tools.functions.schemas.base import ToolSchema - - -class FunctionRegistry: - def __init__(self): - self.functions: Dict[str, Dict[str, Dict]] = {} - - @staticmethod - def _check_param_consistency(func_params, schema): - param_names = set(func_params.keys()) - schema_names = set(schema["parameters"]["properties"].keys()) - - if param_names != schema_names: - raise ValueError("Function parameters do not match schema properties") - - def register(self, module: str, tool_schema: Type[ToolSchema]) -> Callable: - def wrapper(func: Callable) -> Callable: - module_registry = self.functions.setdefault(module, {}) - - if func.__name__ in module_registry: - raise ValueError(f"Function {func.__name__} is already registered in {module}") - - func_params = inspect.signature(func).parameters - - schema = tool_schema.schema() - schema["name"] = func.__name__ - - self._check_param_consistency(func_params, schema) - - module_registry[func.__name__] = { - "func": func, - "schema": schema, - } - return func - - return wrapper - - def get(self, module: str, name: str) -> Optional[Union[Callable, Dict]]: - """Get function by module and name""" - module_registry = self.functions.get(module, {}) - return module_registry.get(name) - - def get_by_name(self, name: str) -> Optional[Dict]: - """Get function by name""" - for module_registry in self.functions.values(): - if name in module_registry: - return module_registry.get(name, {}) - - def get_all_by_module(self, module: str) -> Optional[Dict]: - """Get all functions by module""" - return self.functions.get(module, {}) - - def get_schema(self, module: str, name: str) -> Optional[Dict]: - """Get schema by module and name""" - module_registry = self.functions.get(module, {}) - return module_registry.get(name, {}).get("schema") - - def get_schemas(self, module: str, names: List[str]) -> List[Dict]: - """Get schemas by module and names""" - module_registry = self.functions.get(module, {}) - return [module_registry.get(name, {}).get("schema") for name in names] - - def get_all_schema_by_module(self, module: str) -> List[Dict]: - """Get all schemas by module""" - module_registry = self.functions.get(module, {}) - return [v.get("schema") for v in module_registry.values()] - - -registry = FunctionRegistry() diff --git a/metagpt/tools/functions/schemas/base.py b/metagpt/tools/functions/schemas/base.py deleted file mode 100644 index aef604c8d..000000000 --- a/metagpt/tools/functions/schemas/base.py +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# @Time : 2023/11/16 16:34 -# @Author : lidanyang -# @File : base.py -# @Desc : Build base class to generate schema for tool -from typing import Any, List, Optional, get_type_hints - - -class NoDefault: - """ - A class to represent a missing default value. - - This is used to distinguish between a default value of None and a missing default value. - """ - pass - - -def tool_field( - description: str, default: Any = NoDefault(), enum: Optional[List[Any]] = None, **kwargs -): - """ - Create a field for a tool parameter. - - Args: - description (str): A description of the field. - default (Any, optional): The default value for the field. Defaults to None. - enum (Optional[List[Any]], optional): A list of possible values for the field. Defaults to None. - **kwargs: Additional keyword arguments. - - Returns: - dict: A dictionary representing the field with provided attributes. - """ - field_info = { - "description": description, - "default": default, - "enum": enum, - } - field_info.update(kwargs) - return field_info - - -class ToolSchema: - @staticmethod - def format_type(type_hint): - """ - Format a type hint into a string representation. - - Args: - type_hint (type): The type hint to format. - - Returns: - str: A string representation of the type hint. - """ - if isinstance(type_hint, type): - # Handle built-in types separately - if type_hint.__module__ == "builtins": - return type_hint.__name__ - else: - return f"{type_hint.__module__}.{type_hint.__name__}" - elif hasattr(type_hint, "__origin__") and hasattr(type_hint, "__args__"): - # Handle generic types (like List[int]) - origin_type = ToolSchema.format_type(type_hint.__origin__) - args_type = ", ".join( - [ToolSchema.format_type(t) for t in type_hint.__args__] - ) - return f"{origin_type}[{args_type}]" - else: - return str(type_hint) - - @classmethod - def schema(cls): - """ - Generate a schema dictionary for the class. - - The schema includes the class name, description, and information about - each class parameter based on type hints and field definitions. - - Returns: - dict: A dictionary representing the schema of the class. - """ - schema = { - "name": cls.__name__, - "description": cls.__doc__, - "parameters": {"type": "object", "properties": {}, "required": []}, - } - type_hints = get_type_hints(cls) - for attr, type_hint in type_hints.items(): - value = getattr(cls, attr, None) - if isinstance(value, dict): - # Process each attribute that is defined using the field function - prop_info = {k: v for k, v in value.items() if v is not None or k == "default"} - if isinstance(prop_info["default"], NoDefault): - del prop_info["default"] - prop_info["type"] = ToolSchema.format_type(type_hint) - schema["parameters"]["properties"][attr] = prop_info - # Check for required fields - if "default" not in prop_info: - schema["parameters"]["required"].append(attr) - return schema diff --git a/metagpt/tools/functions/schemas/data_preprocess.py b/metagpt/tools/functions/schemas/data_preprocess.py deleted file mode 100644 index 16b97aeac..000000000 --- a/metagpt/tools/functions/schemas/data_preprocess.py +++ /dev/null @@ -1,67 +0,0 @@ - -import pandas as pd - -from metagpt.tools.functions.schemas.base import tool_field, ToolSchema - - -class FillMissingValue(ToolSchema): - """Completing missing values with simple strategies""" - df: pd.DataFrame = tool_field(description="input dataframe") - features: list = tool_field(description="columns to be processed") - strategy: str = tool_field( - description="the imputation strategy", - default='mean', - enum=['mean', 'median', 'most_frequent', 'constant'] - ) - fill_value: int = tool_field( - description="fill_value is used to replace all occurrences of missing_values", default=None) - - -class SplitBins(ToolSchema): - """Bin continuous data into intervals and return the bin identifier encoded as an integer value""" - df: pd.DataFrame = tool_field(description="input dataframe") - features: list = tool_field(description="columns to be processed") - strategy: str = tool_field(description="Strategy used to define the widths of the bins", default='quantile') - - -class MinMaxScale(ToolSchema): - """Transform features by scaling each feature to a range, witch is (0, 1)""" - df: pd.DataFrame = tool_field(description="input dataframe") - features: list = tool_field(description="columns to be processed") - - -class StandardScale(ToolSchema): - """Standardize features by removing the mean and scaling to unit variance""" - df: pd.DataFrame = tool_field(description="input dataframe") - features: list = tool_field(description="columns to be processed") - - -class LogTransform(ToolSchema): - """Performs a logarithmic transformation on the specified columns""" - df: pd.DataFrame = tool_field(description="input dataframe") - features: list = tool_field(description="columns to be processed") - - -class MaxAbsScale(ToolSchema): - """Scale each feature by its maximum absolute value""" - df: pd.DataFrame = tool_field(description="input dataframe") - features: list = tool_field(description="columns to be processed") - - -class RobustScale(ToolSchema): - """Scale features using statistics that are robust to outliers, the quantile_range is (25.0, 75.0)""" - df: pd.DataFrame = tool_field(description="input dataframe") - features: list = tool_field(description="columns to be processed") - - -class OrdinalEncode(ToolSchema): - """Encode categorical features as an integer array""" - df: pd.DataFrame = tool_field(description="input dataframe") - features: list = tool_field(description="columns to be processed") - - -class OneHotEncoding(ToolSchema): - """Apply one-hot encoding to specified categorical columns, the original columns will be dropped.""" - - df: pd.DataFrame = tool_field(description="DataFrame to process.") - cols: list = tool_field(description="Categorical columns to be one-hot encoded and dropped.") diff --git a/metagpt/tools/functions/schemas/feature_engineering.py b/metagpt/tools/functions/schemas/feature_engineering.py deleted file mode 100644 index 5c89d9b16..000000000 --- a/metagpt/tools/functions/schemas/feature_engineering.py +++ /dev/null @@ -1,110 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# @Time : 2023/11/17 10:34 -# @Author : lidanyang -# @File : feature_engineering.py -# @Desc : Schema for feature engineering functions -from typing import List - -import pandas as pd - -from metagpt.tools.functions.schemas.base import ToolSchema, tool_field - - -class PolynomialExpansion(ToolSchema): - """Add polynomial and interaction features from selected numeric columns, excluding the bias column.""" - - df: pd.DataFrame = tool_field(description="DataFrame to process.") - cols: list = tool_field(description="Columns for polynomial expansion.") - degree: int = tool_field(description="Degree of polynomial features.", default=2) - - -class FrequencyEncoding(ToolSchema): - """Add value counts of categorical columns as new features.""" - - df: pd.DataFrame = tool_field(description="DataFrame to process.") - cols: list = tool_field(description="Categorical columns to be frequency encoded.") - - -class TargetMeanEncoder(ToolSchema): - """Encodes a categorical column by the mean of the label column, and adds the result as a new feature.""" - - df: pd.DataFrame = tool_field(description="DataFrame to process.") - col: str = tool_field(description="Column to be mean encoded.") - label: str = tool_field(description="Predicted label column.") - - -class KFoldTargetMeanEncoder(ToolSchema): - """Adds a new feature to the DataFrame by k-fold mean encoding of a categorical column using the label column.""" - df: pd.DataFrame = tool_field(description="DataFrame to process.") - col: str = tool_field(description="Column to be k-fold mean encoded.") - label: str = tool_field(description="Predicted label column.") - n_splits: int = tool_field(description="Number of splits for K-fold.", default=5) - random_state: int = tool_field(description="Random seed.", default=2021) - - -class CatCross(ToolSchema): - """Add pairwise crossed features and convert them to numerical features.""" - - df: pd.DataFrame = tool_field(description="DataFrame to process.") - cols: list = tool_field(description="Columns to be pairwise crossed.") - max_cat_num: int = tool_field( - description="Maximum unique categories per crossed feature.", default=100 - ) - - -class GroupStat(ToolSchema): - """Aggregate specified column in a DataFrame grouped by another column, adding new features named '__by_'.""" - - df: pd.DataFrame = tool_field(description="DataFrame to process.") - group_col: str = tool_field(description="Column used for grouping.") - agg_col: str = tool_field(description="Column on which aggregation is performed.") - agg_funcs: list = tool_field( - description="""List of aggregation functions to apply, such as ['mean', 'std']. - Each function must be supported by pandas.""" - ) - - -class ExtractTimeComps(ToolSchema): - """Extract and add specific time components as new features from a designated time column.""" - - df: pd.DataFrame = tool_field(description="DataFrame to process.") - time_col: str = tool_field( - description="The name of the column containing time data." - ) - time_comps: List[str] = tool_field( - description="""List of time components to extract. - Each component must be in ['year', 'month', 'day', 'hour', 'dayofweek', 'is_weekend'].""" - ) - - -class FeShiftByTime(ToolSchema): - """Shift column values based on specified time intervals and add the resulting new features to the DataFrame. New features are named in the format of '__lag__'.""" - - df: pd.DataFrame = tool_field(description="DataFrame to process.") - time_col: str = tool_field(description="Column for time-based shifting.") - group_col: str = tool_field(description="Column for grouping before shifting.") - shift_col: str = tool_field(description="Column to shift.") - periods: list = tool_field(description="Time intervals for shifting.") - freq: str = tool_field( - description="Frequency unit for time intervals (e.g., 'D', 'M').", - enum=["D", "M", "Y", "W", "H"], - ) - - -class FeRollingByTime(ToolSchema): - """Calculate rolling statistics for a DataFrame column over time intervals.""" - - df: pd.DataFrame = tool_field(description="DataFrame to process.") - time_col: str = tool_field(description="Column for time-based rolling.") - group_col: str = tool_field(description="Column for grouping before rolling.") - rolling_col: str = tool_field(description="Column for rolling calculations.") - periods: list = tool_field(description="Window sizes for rolling.") - freq: str = tool_field( - description="Frequency unit for time windows (e.g., 'D', 'M').", - enum=["D", "M", "Y", "W", "H"], - ) - agg_funcs: list = tool_field( - description="""List of aggregation functions for rolling, like ['mean', 'std']. - Each function must be in ['mean', 'std', 'min', 'max', 'median', 'sum', 'count'].""" - ) diff --git a/metagpt/tools/functions/schemas/feature_engineering.yml b/metagpt/tools/functions/schemas/feature_engineering.yml index 4f2a7100d..3ba9e863b 100644 --- a/metagpt/tools/functions/schemas/feature_engineering.yml +++ b/metagpt/tools/functions/schemas/feature_engineering.yml @@ -53,17 +53,17 @@ PolynomialExpansion: CatCount: type: class - description: "Add value counts of categorical columns as new features." + description: "Add value counts of a categorical column as new feature." methods: __init__: description: "Initialize self." parameters: properties: - cols: - type: list - description: "Columns for value counts." + col: + type: str + description: "Column for value counts." required: - - cols + - col fit: description: "Fit the CatCount model." parameters: diff --git a/metagpt/tools/functions/schemas/ml_model.py b/metagpt/tools/functions/schemas/ml_model.py deleted file mode 100644 index 9268156af..000000000 --- a/metagpt/tools/functions/schemas/ml_model.py +++ /dev/null @@ -1,55 +0,0 @@ -import pandas as pd - -from metagpt.tools.functions.schemas.base import tool_field, ToolSchema - - -class LogisticRegressionClassification(ToolSchema): - """Logistic Regression (aka logit, MaxEnt) classifier""" - df: pd.DataFrame = tool_field(description="input dataframe") - label: str = tool_field(description="target name") - test_size: float = tool_field(description="The proportion of the test set to all the data", default=0.2) - penalty: str = tool_field(description="Specify the norm of the penalty", default="l2") - dual: bool = tool_field(description="Dual (constrained) or primal (regularized) formulation", default="l2") - - -class RandomForestClassification(ToolSchema): - """random forest is a meta estimator that fits a number of decision tree classifiers on various sub-samples of the dataset and uses averaging to improve the predictive accuracy and control over-fitting""" - df: pd.DataFrame = tool_field(description="input dataframe") - label: str = tool_field(description="target name") - test_size: float = tool_field(description="The proportion of the test set to all the data", default=0.2) - n_estimators: int = tool_field(description="The number of trees in the forest", default=100) - criterion: str = tool_field(description="The function to measure the quality of a split", default="gini") - - -class GradientBoostingClassification(ToolSchema): - """Gradient Boosting for classification.This algorithm builds an additive model in a forward stage-wise fashion""" - df: pd.DataFrame = tool_field(description="input dataframe") - label: str = tool_field(description="target name") - test_size: float = tool_field(description="The proportion of the test set to all the data", default=0.2) - n_estimators: int = tool_field(description="The number of boosting stages to perform", default=100) - learning_rate: float = tool_field(description="Learning rate shrinks the contribution of each tree by learning_rate", default=0.1) - - -class LinearRegressionRegression(ToolSchema): - """Ordinary least squares Linear Regression.""" - df: pd.DataFrame = tool_field(description="input dataframe") - label: str = tool_field(description="target name") - test_size: float = tool_field(description="The proportion of the test set to all the data", default=0.2) - - -class RandomForestRegression(ToolSchema): - """random forest is a meta estimator that fits a number of decision tree on various sub-samples of the dataset and uses averaging to improve the predictive accuracy and control over-fitting""" - df: pd.DataFrame = tool_field(description="input dataframe") - label: str = tool_field(description="target name") - test_size: float = tool_field(description="The proportion of the test set to all the data", default=0.2) - n_estimators: int = tool_field(description="The number of trees in the forest", default=100) - criterion: str = tool_field(description="The function to measure the quality of a split", default="squared_error") - - -class GradientBoostingRegression(ToolSchema): - """Gradient Boosting for regression.This estimator builds an additive model in a forward stage-wise fashion""" - df: pd.DataFrame = tool_field(description="input dataframe") - label: str = tool_field(description="target name") - test_size: float = tool_field(description="The proportion of the test set to all the data", default=0.2) - n_estimators: int = tool_field(description="The number of boosting stages to perform", default=100) - learning_rate: float = tool_field(description="Learning rate shrinks the contribution of each tree by learning_rate", default=0.1) diff --git a/metagpt/tools/web_browser_engine.py b/metagpt/tools/web_browser_engine.py index 7228ae9cf..453d87f31 100644 --- a/metagpt/tools/web_browser_engine.py +++ b/metagpt/tools/web_browser_engine.py @@ -7,7 +7,7 @@ from typing import Any, Callable, Coroutine, Literal, overload from metagpt.config import CONFIG from metagpt.tools import WebBrowserEngineType -# from metagpt.utils.parse_html import WebPage +from metagpt.utils.parse_html import WebPage class WebBrowserEngine: diff --git a/metagpt/utils/__init__.py b/metagpt/utils/__init__.py index 86cac50db..f13175cf8 100644 --- a/metagpt/utils/__init__.py +++ b/metagpt/utils/__init__.py @@ -6,7 +6,7 @@ @File : __init__.py """ -# from metagpt.utils.read_document import read_docx +from metagpt.utils.read_document import read_docx from metagpt.utils.singleton import Singleton from metagpt.utils.token_counter import ( TOKEN_COSTS, @@ -16,7 +16,7 @@ from metagpt.utils.token_counter import ( __all__ = [ - # "read_docx", + "read_docx", "Singleton", "TOKEN_COSTS", "count_message_tokens", diff --git a/metagpt/utils/save_code.py b/metagpt/utils/save_code.py new file mode 100644 index 000000000..96c310336 --- /dev/null +++ b/metagpt/utils/save_code.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# @Date : 12/12/2023 4:14 PM +# @Author : stellahong (stellahong@fuzhi.ai) +# @Desc : +import os +import json + +import nbformat + +from metagpt.const import DATA_PATH + +def save_code_file(name: str, code_context: str, file_format: str = "py") -> None: + """ + Save code files to a specified path. + + Args: + - name (str): The name of the folder to save the files. + - code_context (str): The code content. + - file_format (str, optional): The file format. Supports 'py' (Python file), 'json' (JSON file), and 'ipynb' (Jupyter Notebook file). Default is 'py'. + + + Returns: + - None + """ + # Create the folder path if it doesn't exist + os.makedirs(name=DATA_PATH / "output" / f"{name}", exist_ok=True) + + # Choose to save as a Python file or a JSON file based on the file format + file_path = DATA_PATH / "output" / f"{name}/code.{file_format}" + if file_format == "py": + with open(file_path, "w", encoding="utf-8") as fp: + fp.write(code_context + "\n\n") + elif file_format == "json": + # Parse the code content as JSON and save + data = {"code": code_context} + with open(file_path, "w", encoding="utf-8") as fp: + json.dump(data, fp, indent=2) + elif file_format == "ipynb": + nbformat.write(code_context, file_path) + else: + raise ValueError("Unsupported file format. Please choose 'py', 'json', or 'ipynb'.") + + + + diff --git a/requirements.txt b/requirements.txt index 9b75fd200..2328de2a1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -45,6 +45,7 @@ wrapt==1.15.0 websocket-client==0.58.0 zhipuai==1.0.7 rich==13.6.0 +nbclient==0.9.0 nbformat==5.9.2 ipython==8.17.2 ipykernel==6.27.0 diff --git a/tests/metagpt/actions/test_execute_code.py b/tests/metagpt/actions/test_execute_code.py index 73b5886dc..95f883e12 100644 --- a/tests/metagpt/actions/test_execute_code.py +++ b/tests/metagpt/actions/test_execute_code.py @@ -1,6 +1,6 @@ import pytest -from metagpt.actions.execute_code import ExecutePyCode +from metagpt.actions.execute_code import ExecutePyCode, truncate from metagpt.schema import Message @@ -81,3 +81,10 @@ async def test_plotting_bug(): pi = ExecutePyCode() output = await pi.run(code) assert output[1] is True + + +def test_truncate(): + output = "hello world" + assert truncate(output) == output + output = "hello world" + assert truncate(output, 5) == "Truncated to show only the last 5 characters\nworld" diff --git a/tests/metagpt/actions/test_write_analysis_code.py b/tests/metagpt/actions/test_write_analysis_code.py index 661202115..1a568cdcd 100644 --- a/tests/metagpt/actions/test_write_analysis_code.py +++ b/tests/metagpt/actions/test_write_analysis_code.py @@ -31,22 +31,15 @@ async def test_tool_recommendation(): step 1: 对数据集进行去重 step 2: 对数据集进行缺失值处理 """ - available_tools = [ - { - "name": "fill_missing_value", - "description": "Completing missing values with simple strategies", - }, - { - "name": "split_bins", - "description": "Bin continuous data into intervals and return the bin identifier encoded as an integer value", - }, - ] + available_tools = { + "fill_missing_value": "Completing missing values with simple strategies", + "split_bins": "Bin continuous data into intervals and return the bin identifier encoded as an integer value", + } write_code = WriteCodeWithTools() tools = await write_code._tool_recommendation(task, code_steps, available_tools) - assert len(tools) == 2 - assert tools[0] == [] - assert tools[1] == ["fill_missing_value"] + assert len(tools) == 1 + assert tools[0] == ["fill_missing_value"] @pytest.mark.asyncio @@ -57,7 +50,7 @@ async def test_write_code_with_tools(): "1": Task( task_id="1", instruction="随机生成一个pandas DataFrame数据集", - task_type="unknown", + task_type="other", dependent_task_ids=[], code=""" import pandas as pd @@ -75,6 +68,10 @@ async def test_write_code_with_tools(): instruction="对数据集进行数据清洗", task_type="data_preprocess", dependent_task_ids=["1"], + code_steps=""" + {"Step 1": "对数据集进行去重", + "Step 2": "对数据集进行缺失值处理"} + """ ), } plan = Plan( @@ -83,13 +80,9 @@ async def test_write_code_with_tools(): task_map=task_map, current_task_id="2", ) - task_guide = """ - step 1: 对数据集进行去重 - step 2: 对数据集进行缺失值处理 - """ - data_desc = "None" + column_info = "" - code = await write_code.run(messages, plan, task_guide, data_desc) + code = await write_code.run(messages, plan, column_info) assert len(code) > 0 print(code) diff --git a/tests/metagpt/actions/test_write_plan.py b/tests/metagpt/actions/test_write_plan.py index 2bf200ab3..7766e0d51 100644 --- a/tests/metagpt/actions/test_write_plan.py +++ b/tests/metagpt/actions/test_write_plan.py @@ -1,13 +1,15 @@ import pytest -from metagpt.actions.write_plan import WritePlan +from metagpt.actions.write_plan import WritePlan, precheck_update_plan_from_rsp, Plan, Task +def test_precheck_update_plan_from_rsp(): + plan = Plan(goal="") + plan.add_tasks([Task(task_id="1")]) + rsp = '[{"task_id": "2"}]' + success, _ = precheck_update_plan_from_rsp(rsp, plan) + assert success + assert len(plan.tasks) == 1 and plan.tasks[0].task_id == "1" # precheck should not change the original one -@pytest.mark.asyncio -async def test_plan(): - p = WritePlan() - task_desc = """Here’s some background information on Cyclistic, a bike-sharing company designing a marketing strategy aimed at converting casual riders into annual members: So far, Cyclistic’s marketing strategy has relied on building general awareness and engaging a wide range of consumers. group. One way to help achieve these goals is the flexibility of its pricing plans: one-way passes, full-day passes, and annual memberships. Customers who purchase a one-way or full-day pass are known as recreational riders. Customers purchasing an annual membership are Cyclistic members. I will provide you with a data sheet that records user behavior: '/Users/vicis/Downloads/202103-divvy-tripdata.csv""" - rsp = await p.run(task_desc, role="data analyst") - assert len(rsp.content) > 0 - assert rsp.sent_from == "WritePlan" - print(rsp) + invalid_rsp = 'wrong' + success, _ = precheck_update_plan_from_rsp(invalid_rsp, plan) + assert not success diff --git a/tests/metagpt/test_schema.py b/tests/metagpt/test_schema.py index 8f65d3785..b5d49b7a1 100644 --- a/tests/metagpt/test_schema.py +++ b/tests/metagpt/test_schema.py @@ -5,6 +5,7 @@ @Author : alexanderwu @File : test_schema.py """ +import pytest from metagpt.schema import AIMessage, Message, SystemMessage, UserMessage from metagpt.schema import Task, Plan @@ -104,3 +105,82 @@ class TestPlan: finished_tasks = plan.get_finished_tasks() assert len(finished_tasks) == 1 assert finished_tasks[0].task_id == "1" + + def test_reset_task_existing(self): + plan = Plan(goal="") + task = Task(task_id="1", instruction="Do something", code="print('Hello')", result="Hello", finished=True) + plan.add_tasks([task]) + plan.reset_task("1") + reset_task = plan.task_map["1"] + assert reset_task.code == "" + assert reset_task.result == "" + assert not reset_task.is_finished + + def test_reset_task_non_existing(self): + plan = Plan(goal="") + task = Task(task_id="1", instruction="Do something", code="print('Hello')", result="Hello", finished=True) + plan.add_tasks([task]) + plan.reset_task("2") # Task with ID 2 does not exist + assert "1" in plan.task_map + assert "2" not in plan.task_map + + def test_replace_task_with_dependents(self): + plan = Plan(goal="") + tasks = [Task(task_id="1", instruction="First Task", finished=True), + Task(task_id="2", instruction="Second Task", dependent_task_ids=["1"], finished=True)] + plan.add_tasks(tasks) + new_task = Task(task_id="1", instruction="Updated First Task") + plan.replace_task(new_task) + assert plan.task_map["1"].instruction == "Updated First Task" + assert not plan.task_map["2"].is_finished # Dependent task should be reset + assert plan.task_map["2"].code == "" + assert plan.task_map["2"].result == "" + + def test_replace_task_non_existing(self): + plan = Plan(goal="") + task = Task(task_id="1", instruction="First Task") + plan.add_tasks([task]) + new_task = Task(task_id="2", instruction="New Task") + plan.replace_task(new_task) # Task with ID 2 does not exist in plan + assert "1" in plan.task_map + assert "2" not in plan.task_map + + def test_append_task_with_valid_dependencies(self): + plan = Plan(goal="Test") + existing_task = [Task(task_id="1")] + plan.add_tasks(existing_task) + new_task = Task(task_id="2", dependent_task_ids=["1"]) + plan.append_task(new_task) + assert plan.tasks[-1].task_id == "2" + assert plan.task_map["2"] == new_task + + def test_append_task_with_invalid_dependencies(self): + new_task = Task(task_id="2", dependent_task_ids=["3"]) + plan = Plan(goal="Test") + with pytest.raises(AssertionError): + plan.append_task(new_task) + + def test_append_task_without_dependencies(self): + plan = Plan(goal="Test") + existing_task = [Task(task_id="1")] + plan.add_tasks(existing_task) + + new_task = Task(task_id="2") + plan.append_task(new_task) + + assert len(plan.tasks) == 2 + assert plan.current_task_id == "1" + + def test_append_task_updates_current_task(self): + finished_task = Task(task_id="1", is_finished=True) + new_task = Task(task_id="2") + plan = Plan(goal="Test", tasks=[finished_task]) + plan.append_task(new_task) + assert plan.current_task_id == "2" + + def test_update_current_task(self): + task1 = Task(task_id="1", is_finished=True) + task2 = Task(task_id="2") + plan = Plan(goal="Test", tasks=[task1, task2]) + plan._update_current_task() + assert plan.current_task_id == "2" diff --git a/tests/metagpt/utils/test_save_code.py b/tests/metagpt/utils/test_save_code.py new file mode 100644 index 000000000..60a9e1ff4 --- /dev/null +++ b/tests/metagpt/utils/test_save_code.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +# @Date : 12/12/2023 4:17 PM +# @Author : stellahong (stellahong@fuzhi.ai) +# @Desc : +import pytest +import os +import json +import nbformat + +from metagpt.actions.write_analysis_code import WriteCodeByGenerate +from metagpt.actions.execute_code import ExecutePyCode + +from metagpt.utils.save_code import save_code_file, DATA_PATH + + +def test_save_code_file_python(): + save_code_file("example", "print('Hello, World!')") + file_path = DATA_PATH / "output" / "example" / "code.py" + assert os.path.exists(file_path), f"File does not exist: {file_path}" + + +def test_save_code_file_python(): + save_code_file("example", "print('Hello, World!')") + file_path = DATA_PATH / "output" / "example" / "code.py" + with open(file_path, "r", encoding="utf-8") as fp: + content = fp.read() + assert "print('Hello, World!')" in content, "File content does not match" + + +def test_save_code_file_json(): + save_code_file("example_json", "print('Hello, JSON!')", file_format="json") + file_path = DATA_PATH / "output" / "example_json" / "code.json" + with open(file_path, "r", encoding="utf-8") as fp: + data = json.load(fp) + assert "code" in data, "JSON key 'code' is missing" + assert data["code"] == "print('Hello, JSON!')", "JSON content does not match" + + + +@pytest.mark.asyncio +async def test_save_code_file_notebook(): + code = await WriteCodeByGenerate().run( + context="basic python, hello world", plan="", code_steps="", temperature=0.0 + ) + executor = ExecutePyCode() + await executor.run(code) + # Save as a Notebook file + save_code_file("example_nb", executor.nb, file_format="ipynb") + file_path = DATA_PATH / "output" / "example_nb" / "code.ipynb" + assert os.path.exists(file_path), f"Notebook file does not exist: {file_path}" + + # Additional checks specific to notebook format + notebook = nbformat.read(file_path, as_version=4) + assert len(notebook.cells) > 0, "Notebook should have at least one cell" + first_cell_source = notebook.cells[0].source + assert "print('Hello, World!')" in first_cell_source, "Notebook cell content does not match"