James McCool
commited on
Commit
·
efb1867
1
Parent(s):
ff85862
Similarity Score > Diversity
Browse files- app.py +8 -8
- global_func/hedging_preset.py +2 -2
- global_func/large_field_preset.py +5 -5
- global_func/predict_dupes.py +1 -1
- global_func/small_field_preset.py +1 -1
- global_func/trim_portfolio.py +1 -1
- global_func/volatility_preset.py +4 -4
app.py
CHANGED
@@ -824,7 +824,7 @@ with tab2:
|
|
824 |
if submitted:
|
825 |
del st.session_state['working_frame']
|
826 |
|
827 |
-
excluded_cols = ['salary', 'median', 'Own', 'Finish_percentile', 'Dupes', 'Stack', 'Size', 'Win%', 'Lineup Edge', 'Weighted Own', 'Geomean', '
|
828 |
|
829 |
if 'working_frame' not in st.session_state:
|
830 |
st.session_state['working_frame'] = st.session_state['origin_portfolio'].copy()
|
@@ -954,7 +954,7 @@ with tab2:
|
|
954 |
'Lineup Edge': st.session_state['working_frame']['Lineup Edge'],
|
955 |
'Weighted Own': st.session_state['working_frame']['Weighted Own'],
|
956 |
'Geomean': st.session_state['working_frame']['Geomean'],
|
957 |
-
'
|
958 |
}
|
959 |
|
960 |
if 'trimming_dict_maxes' not in st.session_state:
|
@@ -964,7 +964,7 @@ with tab2:
|
|
964 |
'Weighted Own': st.session_state['working_frame']['Weighted Own'].max(),
|
965 |
'median': st.session_state['working_frame']['median'].max(),
|
966 |
'Finish_percentile': st.session_state['working_frame']['Finish_percentile'].max(),
|
967 |
-
'
|
968 |
}
|
969 |
|
970 |
with st.sidebar:
|
@@ -975,7 +975,7 @@ with tab2:
|
|
975 |
'Weighted Own': 500.0,
|
976 |
'median': 500.0,
|
977 |
'Finish_percentile': 1.0,
|
978 |
-
'
|
979 |
}
|
980 |
with st.expander('Macro Filter Options'):
|
981 |
with st.form(key='macro_filter_form'):
|
@@ -1083,7 +1083,7 @@ with tab2:
|
|
1083 |
with perf_var:
|
1084 |
performance_type = st.selectbox("Sorting variable", ['median', 'Own', 'Weighted Own'], key='sort_var')
|
1085 |
with own_var:
|
1086 |
-
own_type = st.selectbox("Trimming variable", ['Own', 'Geomean', 'Weighted Own', '
|
1087 |
|
1088 |
trim_slack_var = st.number_input("Trim slack (percentile addition to trimming variable ceiling)", value=0.0, min_value=0.0, max_value=1.0, step=0.1, key='trim_slack')
|
1089 |
|
@@ -1112,13 +1112,13 @@ with tab2:
|
|
1112 |
with st.expander('Presets'):
|
1113 |
st.info("Still heavily in testing here, I'll announce when they are ready for use.")
|
1114 |
with st.form(key='Small Field Preset'):
|
1115 |
-
preset_choice = st.selectbox("Preset", options=['Small Field (Heavy Own)', 'Large Field (Manage
|
1116 |
lineup_target = st.number_input("Lineups to produce", value=150, min_value=1, step=1)
|
1117 |
submitted = st.form_submit_button("Submit")
|
1118 |
if submitted:
|
1119 |
if preset_choice == 'Small Field (Heavy Own)':
|
1120 |
parsed_frame = small_field_preset(st.session_state['working_frame'], lineup_target, excluded_cols)
|
1121 |
-
elif preset_choice == 'Large Field (Manage
|
1122 |
parsed_frame = large_field_preset(st.session_state['working_frame'], lineup_target, excluded_cols)
|
1123 |
elif preset_choice == 'Volatility (Heavy Lineup Edge)':
|
1124 |
parsed_frame = volatility_preset(st.session_state['working_frame'], lineup_target, excluded_cols)
|
@@ -1221,7 +1221,7 @@ with tab2:
|
|
1221 |
min_value=-1.0,
|
1222 |
max_value=1.0
|
1223 |
),
|
1224 |
-
"
|
1225 |
"Diversity",
|
1226 |
help="Projected lineup diversity",
|
1227 |
width="small",
|
|
|
824 |
if submitted:
|
825 |
del st.session_state['working_frame']
|
826 |
|
827 |
+
excluded_cols = ['salary', 'median', 'Own', 'Finish_percentile', 'Dupes', 'Stack', 'Size', 'Win%', 'Lineup Edge', 'Weighted Own', 'Geomean', 'Diversity']
|
828 |
|
829 |
if 'working_frame' not in st.session_state:
|
830 |
st.session_state['working_frame'] = st.session_state['origin_portfolio'].copy()
|
|
|
954 |
'Lineup Edge': st.session_state['working_frame']['Lineup Edge'],
|
955 |
'Weighted Own': st.session_state['working_frame']['Weighted Own'],
|
956 |
'Geomean': st.session_state['working_frame']['Geomean'],
|
957 |
+
'Diversity': st.session_state['working_frame']['Diversity']
|
958 |
}
|
959 |
|
960 |
if 'trimming_dict_maxes' not in st.session_state:
|
|
|
964 |
'Weighted Own': st.session_state['working_frame']['Weighted Own'].max(),
|
965 |
'median': st.session_state['working_frame']['median'].max(),
|
966 |
'Finish_percentile': st.session_state['working_frame']['Finish_percentile'].max(),
|
967 |
+
'Diversity': st.session_state['working_frame']['Diversity'].max()
|
968 |
}
|
969 |
|
970 |
with st.sidebar:
|
|
|
975 |
'Weighted Own': 500.0,
|
976 |
'median': 500.0,
|
977 |
'Finish_percentile': 1.0,
|
978 |
+
'Diversity': 1.0
|
979 |
}
|
980 |
with st.expander('Macro Filter Options'):
|
981 |
with st.form(key='macro_filter_form'):
|
|
|
1083 |
with perf_var:
|
1084 |
performance_type = st.selectbox("Sorting variable", ['median', 'Own', 'Weighted Own'], key='sort_var')
|
1085 |
with own_var:
|
1086 |
+
own_type = st.selectbox("Trimming variable", ['Own', 'Geomean', 'Weighted Own', 'Diversity'], key='trim_var')
|
1087 |
|
1088 |
trim_slack_var = st.number_input("Trim slack (percentile addition to trimming variable ceiling)", value=0.0, min_value=0.0, max_value=1.0, step=0.1, key='trim_slack')
|
1089 |
|
|
|
1112 |
with st.expander('Presets'):
|
1113 |
st.info("Still heavily in testing here, I'll announce when they are ready for use.")
|
1114 |
with st.form(key='Small Field Preset'):
|
1115 |
+
preset_choice = st.selectbox("Preset", options=['Small Field (Heavy Own)', 'Large Field (Manage Diversity)', 'Hedge Chalk (Manage Leverage)', 'Volatility (Heavy Lineup Edge)'], index=0)
|
1116 |
lineup_target = st.number_input("Lineups to produce", value=150, min_value=1, step=1)
|
1117 |
submitted = st.form_submit_button("Submit")
|
1118 |
if submitted:
|
1119 |
if preset_choice == 'Small Field (Heavy Own)':
|
1120 |
parsed_frame = small_field_preset(st.session_state['working_frame'], lineup_target, excluded_cols)
|
1121 |
+
elif preset_choice == 'Large Field (Manage Diversity)':
|
1122 |
parsed_frame = large_field_preset(st.session_state['working_frame'], lineup_target, excluded_cols)
|
1123 |
elif preset_choice == 'Volatility (Heavy Lineup Edge)':
|
1124 |
parsed_frame = volatility_preset(st.session_state['working_frame'], lineup_target, excluded_cols)
|
|
|
1221 |
min_value=-1.0,
|
1222 |
max_value=1.0
|
1223 |
),
|
1224 |
+
"Diversity": st.column_config.NumberColumn(
|
1225 |
"Diversity",
|
1226 |
help="Projected lineup diversity",
|
1227 |
width="small",
|
global_func/hedging_preset.py
CHANGED
@@ -5,7 +5,7 @@ from global_func.large_field_preset import large_field_preset
|
|
5 |
|
6 |
def hedging_preset(portfolio: pd.DataFrame, lineup_target: int, projections_file: pd.DataFrame):
|
7 |
|
8 |
-
excluded_cols = ['salary', 'median', 'Own', 'Finish_percentile', 'Dupes', 'Stack', 'Size', 'Win%', 'Lineup Edge', 'Weighted Own', 'Geomean', '
|
9 |
list_size = 3
|
10 |
|
11 |
check_own_df = projections_file.copy()
|
@@ -81,7 +81,7 @@ def hedging_preset(portfolio: pd.DataFrame, lineup_target: int, projections_file
|
|
81 |
print(f"No lineups found with {team} stacked")
|
82 |
concat_portfolio = pd.concat([concat_portfolio, removed_lineups])
|
83 |
|
84 |
-
concat_portfolio = concat_portfolio.drop_duplicates(subset=['median', 'Own', 'Lineup Edge', '
|
85 |
|
86 |
if len(concat_portfolio) >= lineup_target:
|
87 |
return concat_portfolio.head(lineup_target)
|
|
|
5 |
|
6 |
def hedging_preset(portfolio: pd.DataFrame, lineup_target: int, projections_file: pd.DataFrame):
|
7 |
|
8 |
+
excluded_cols = ['salary', 'median', 'Own', 'Finish_percentile', 'Dupes', 'Stack', 'Size', 'Win%', 'Lineup Edge', 'Weighted Own', 'Geomean', 'Diversity']
|
9 |
list_size = 3
|
10 |
|
11 |
check_own_df = projections_file.copy()
|
|
|
81 |
print(f"No lineups found with {team} stacked")
|
82 |
concat_portfolio = pd.concat([concat_portfolio, removed_lineups])
|
83 |
|
84 |
+
concat_portfolio = concat_portfolio.drop_duplicates(subset=['median', 'Own', 'Lineup Edge', 'Diversity'])
|
85 |
|
86 |
if len(concat_portfolio) >= lineup_target:
|
87 |
return concat_portfolio.head(lineup_target)
|
global_func/large_field_preset.py
CHANGED
@@ -2,15 +2,15 @@ import pandas as pd
|
|
2 |
import numpy as np
|
3 |
|
4 |
def large_field_preset(portfolio: pd.DataFrame, lineup_target: int, exclude_cols: list):
|
5 |
-
excluded_cols = ['salary', 'median', 'Own', 'Finish_percentile', 'Dupes', 'Stack', 'Size', 'Win%', 'Lineup Edge', 'Weighted Own', 'Geomean', '
|
6 |
player_columns = [col for col in portfolio.columns if col not in excluded_cols]
|
7 |
|
8 |
concat_portfolio = portfolio.copy()
|
9 |
-
concat_portfolio = concat_portfolio.sort_values(by='
|
10 |
|
11 |
# Calculate target similarity scores for linear progression
|
12 |
-
similarity_floor = concat_portfolio['
|
13 |
-
similarity_ceiling = concat_portfolio['
|
14 |
|
15 |
# Create evenly spaced target similarity scores
|
16 |
target_similarities = np.linspace(similarity_floor, similarity_ceiling, lineup_target)
|
@@ -19,7 +19,7 @@ def large_field_preset(portfolio: pd.DataFrame, lineup_target: int, exclude_cols
|
|
19 |
selected_indices = []
|
20 |
for target_sim in target_similarities:
|
21 |
# Find the index of the closest similarity score
|
22 |
-
closest_idx = (concat_portfolio['
|
23 |
if closest_idx not in selected_indices: # Avoid duplicates
|
24 |
selected_indices.append(closest_idx)
|
25 |
|
|
|
2 |
import numpy as np
|
3 |
|
4 |
def large_field_preset(portfolio: pd.DataFrame, lineup_target: int, exclude_cols: list):
|
5 |
+
excluded_cols = ['salary', 'median', 'Own', 'Finish_percentile', 'Dupes', 'Stack', 'Size', 'Win%', 'Lineup Edge', 'Weighted Own', 'Geomean', 'Diversity']
|
6 |
player_columns = [col for col in portfolio.columns if col not in excluded_cols]
|
7 |
|
8 |
concat_portfolio = portfolio.copy()
|
9 |
+
concat_portfolio = concat_portfolio.sort_values(by='Diversity', ascending=True).reset_index(drop=True)
|
10 |
|
11 |
# Calculate target similarity scores for linear progression
|
12 |
+
similarity_floor = concat_portfolio['Diversity'].min()
|
13 |
+
similarity_ceiling = concat_portfolio['Diversity'].max()
|
14 |
|
15 |
# Create evenly spaced target similarity scores
|
16 |
target_similarities = np.linspace(similarity_floor, similarity_ceiling, lineup_target)
|
|
|
19 |
selected_indices = []
|
20 |
for target_sim in target_similarities:
|
21 |
# Find the index of the closest similarity score
|
22 |
+
closest_idx = (concat_portfolio['Diversity'] - target_sim).abs().idxmin()
|
23 |
if closest_idx not in selected_indices: # Avoid duplicates
|
24 |
selected_indices.append(closest_idx)
|
25 |
|
global_func/predict_dupes.py
CHANGED
@@ -353,7 +353,7 @@ def predict_dupes(portfolio, maps_dict, site_var, type_var, Contest_Size, streng
|
|
353 |
portfolio['Geomean'] = np.power((portfolio[own_columns] * 100).product(axis=1), 1 / len(own_columns))
|
354 |
|
355 |
# Calculate similarity score based on actual player selection
|
356 |
-
portfolio['
|
357 |
|
358 |
portfolio = portfolio.drop(columns=dup_count_columns)
|
359 |
portfolio = portfolio.drop(columns=own_columns)
|
|
|
353 |
portfolio['Geomean'] = np.power((portfolio[own_columns] * 100).product(axis=1), 1 / len(own_columns))
|
354 |
|
355 |
# Calculate similarity score based on actual player selection
|
356 |
+
portfolio['Diversity'] = calculate_player_similarity_score(portfolio, player_columns)
|
357 |
|
358 |
portfolio = portfolio.drop(columns=dup_count_columns)
|
359 |
portfolio = portfolio.drop(columns=own_columns)
|
global_func/small_field_preset.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
import pandas as pd
|
2 |
|
3 |
def small_field_preset(portfolio: pd.DataFrame, lineup_target: int, exclude_cols: list):
|
4 |
-
excluded_cols = ['salary', 'median', 'Own', 'Finish_percentile', 'Dupes', 'Stack', 'Size', 'Win%', 'Lineup Edge', 'Weighted Own', 'Geomean', '
|
5 |
player_columns = [col for col in portfolio.columns if col not in excluded_cols]
|
6 |
|
7 |
for slack_var in range(1, 20):
|
|
|
1 |
import pandas as pd
|
2 |
|
3 |
def small_field_preset(portfolio: pd.DataFrame, lineup_target: int, exclude_cols: list):
|
4 |
+
excluded_cols = ['salary', 'median', 'Own', 'Finish_percentile', 'Dupes', 'Stack', 'Size', 'Win%', 'Lineup Edge', 'Weighted Own', 'Geomean', 'Diversity']
|
5 |
player_columns = [col for col in portfolio.columns if col not in excluded_cols]
|
6 |
|
7 |
for slack_var in range(1, 20):
|
global_func/trim_portfolio.py
CHANGED
@@ -9,7 +9,7 @@ def trim_portfolio(portfolio: pd.DataFrame, trim_slack: float, performance_type:
|
|
9 |
curr_own_type_max = working_portfolio.loc[0, own_type] + (trim_slack * working_portfolio.loc[0, own_type])
|
10 |
|
11 |
for i in range(1, len(working_portfolio)):
|
12 |
-
if own_type == '
|
13 |
if working_portfolio.loc[i, own_type] < curr_own_type_max and \
|
14 |
working_portfolio.loc[i, performance_type] > performance_threshold_low and \
|
15 |
working_portfolio.loc[i, performance_type] <= performance_threshold_high and \
|
|
|
9 |
curr_own_type_max = working_portfolio.loc[0, own_type] + (trim_slack * working_portfolio.loc[0, own_type])
|
10 |
|
11 |
for i in range(1, len(working_portfolio)):
|
12 |
+
if own_type == 'Diversity':
|
13 |
if working_portfolio.loc[i, own_type] < curr_own_type_max and \
|
14 |
working_portfolio.loc[i, performance_type] > performance_threshold_low and \
|
15 |
working_portfolio.loc[i, performance_type] <= performance_threshold_high and \
|
global_func/volatility_preset.py
CHANGED
@@ -2,7 +2,7 @@ import pandas as pd
|
|
2 |
import numpy as np
|
3 |
|
4 |
def volatility_preset(portfolio: pd.DataFrame, lineup_target: int, exclude_cols: list):
|
5 |
-
excluded_cols = ['salary', 'median', 'Own', 'Finish_percentile', 'Dupes', 'Stack', 'Size', 'Win%', 'Lineup Edge', 'Weighted Own', 'Geomean', '
|
6 |
player_columns = [col for col in portfolio.columns if col not in excluded_cols]
|
7 |
|
8 |
for slack_var in range(1, 20):
|
@@ -13,13 +13,13 @@ def volatility_preset(portfolio: pd.DataFrame, lineup_target: int, exclude_cols:
|
|
13 |
working_portfolio = portfolio.copy()
|
14 |
working_portfolio = working_portfolio[working_portfolio['Stack'] == team].sort_values(by='Lineup Edge', ascending = False)
|
15 |
working_portfolio = working_portfolio.reset_index(drop=True)
|
16 |
-
curr_own_type_max = working_portfolio.loc[0, '
|
17 |
|
18 |
for i in range(1, len(working_portfolio)):
|
19 |
-
if working_portfolio.loc[i, '
|
20 |
rows_to_drop.append(i)
|
21 |
else:
|
22 |
-
curr_own_type_max = working_portfolio.loc[i, '
|
23 |
|
24 |
working_portfolio = working_portfolio.drop(rows_to_drop).reset_index(drop=True)
|
25 |
concat_portfolio = pd.concat([concat_portfolio, working_portfolio])
|
|
|
2 |
import numpy as np
|
3 |
|
4 |
def volatility_preset(portfolio: pd.DataFrame, lineup_target: int, exclude_cols: list):
|
5 |
+
excluded_cols = ['salary', 'median', 'Own', 'Finish_percentile', 'Dupes', 'Stack', 'Size', 'Win%', 'Lineup Edge', 'Weighted Own', 'Geomean', 'Diversity']
|
6 |
player_columns = [col for col in portfolio.columns if col not in excluded_cols]
|
7 |
|
8 |
for slack_var in range(1, 20):
|
|
|
13 |
working_portfolio = portfolio.copy()
|
14 |
working_portfolio = working_portfolio[working_portfolio['Stack'] == team].sort_values(by='Lineup Edge', ascending = False)
|
15 |
working_portfolio = working_portfolio.reset_index(drop=True)
|
16 |
+
curr_own_type_max = working_portfolio.loc[0, 'Diversity'] + (slack_var / 20 * working_portfolio.loc[0, 'Diversity'])
|
17 |
|
18 |
for i in range(1, len(working_portfolio)):
|
19 |
+
if working_portfolio.loc[i, 'Diversity'] < curr_own_type_max:
|
20 |
rows_to_drop.append(i)
|
21 |
else:
|
22 |
+
curr_own_type_max = working_portfolio.loc[i, 'Diversity'] + (slack_var / 20 * working_portfolio.loc[i, 'Diversity'])
|
23 |
|
24 |
working_portfolio = working_portfolio.drop(rows_to_drop).reset_index(drop=True)
|
25 |
concat_portfolio = pd.concat([concat_portfolio, working_portfolio])
|