DimaKudosh / pydfs-lineup-optimizer

Daily Fantasy Sports lineup optimzer for all popular daily fantasy sports sites
MIT License
419 stars 157 forks source link

CORRELATION #229

Open Denwen12 opened 3 years ago

Denwen12 commented 3 years ago

i have a correlation file i build, ill give an example Anyway i can get this optimizer to use this. if a player has a minus correlation i don't want them in the same lineup. Is this a possiblity

Player MP.Ply Teammate MP.Tmm Team corMin corDK corFD
Trae Young 1981 De'Andre Hunter 1799 ATL 0.421 0.124 0.087
Trae Young 1854 Vince Carter 758 ATL -0.181 -0.149 -0.114
Trae Young 1829 Cam Reddish 1384 ATL 0.022 0.024 0.04
Trae Young 1813 Bruno Fernando 649 ATL -0.264 -0.031 -0.053
De'Andre Hunter 1799 Trae Young 1981 ATL 0.421 0.124 0.087
De'Andre Hunter 1795 Vince Carter 811 ATL -0.049 0.151 0.128
De'Andre Hunter 1746 Cam Reddish 1467 ATL -0.141 0.078 0.015
De'Andre Hunter 1745 Bruno Fernando 700 ATL -0.072 -0.029 -0.061
Trae Young 1733 Kevin Huerter 1529 ATL 0.296 0.191 0.189
cdbmgrdn commented 3 years ago

https://pydfs-lineup-optimizer.readthedocs.io/en/latest/rules.html#group-players

It looks possible to do it by this method. Get the players you can't have in the same lineup from your correlation sheet and then it should be possible to loop through that method with your list of 2 players.

Denwen12 commented 3 years ago

im not sure its possible cause my file is pretty big

cdbmgrdn commented 3 years ago

It should be fine but the optimizer might take longer. You'll just have to iterate through that list and create player groups before the optimizer generates the lineups. Should be pretty easy to do with Pandas. Maybe try adding this code:

import pandas as pd

csv_filepath = 'your correlation csv'

cdf = pd.read_csv(csv_filepath)

#set this to whatever you want the correlation cutoff to be
correlation_threshold = -0.15

for i in range(len(cdf)):
    if cdf['corDK'].iloc[i] <= correlation_threshold:
        negative_corr_players = (cdf['Player'].iloc[i],cdf['Teammate'].iloc[i])
        group = PlayersGroup([optimizer.get_player_by_name(name) for name in (negative_corr_players)])
        optimizer.add_players_group(group)
Denwen12 commented 3 years ago

thank you, ill try this out after work today

Denwen12 commented 3 years ago

I been working on this and i have to set the threshold like -.800 to get it to make a lineup so seems like its not working and i also deleted the duplicate lines , if i lower the threshold to where i want it i get

root@localhost:~/NBA/2Slate# python3 Fanduel2Finish.py Traceback (most recent call last): File "Fanduel2Finish.py", line 97, in lineups = list(optimizer.optimize(n=1,)) File "/usr/local/lib/python3.7/dist-packages/pydfs_lineup_optimizer/lineup_optimizer.py", line 395, in optimize constraint.apply(base_solver) File "/usr/local/lib/python3.7/dist-packages/pydfs_lineup_optimizer/rules.py", line 302, in apply self._create_constraints(solver) File "/usr/local/lib/python3.7/dist-packages/pydfs_lineup_optimizer/rules.py", line 336, in _create_constraints variables = [self.players_dict[p] for p in group_players] File "/usr/local/lib/python3.7/dist-packages/pydfs_lineup_optimizer/rules.py", line 336, in variables = [self.players_dict[p] for p in group_players] KeyError: None

cdbmgrdn commented 3 years ago

How big is the slate you're trying to create lineups for? There might not be possible combinations available on smaller slates which do not have negatively correlated players.

Denwen12 commented 3 years ago

it was todays slate with 7 games so it should be possible but its not i gotta set -.800 to get it to work

On Thu, Dec 17, 2020, 5:07 PM cdbmgrdn notifications@github.com wrote:

How big is the slate you're trying to create lineups for? There might not be possible combinations available on smaller slates which do not have negatively correlated players.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/DimaKudosh/pydfs-lineup-optimizer/issues/229#issuecomment-747731102, or unsubscribe https://github.com/notifications/unsubscribe-auth/ANBWO7XMKFJBTIKABM3AGA3SVJ6KRANCNFSM4UY5MIBQ .

Denwen12 commented 3 years ago

Possibly it can be the names not matching

On Thu, Dec 17, 2020, 6:47 PM joseph offen joffen12@gmail.com wrote:

it was todays slate with 7 games so it should be possible but its not i gotta set -.800 to get it to work

On Thu, Dec 17, 2020, 5:07 PM cdbmgrdn notifications@github.com wrote:

How big is the slate you're trying to create lineups for? There might not be possible combinations available on smaller slates which do not have negatively correlated players.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/DimaKudosh/pydfs-lineup-optimizer/issues/229#issuecomment-747731102, or unsubscribe https://github.com/notifications/unsubscribe-auth/ANBWO7XMKFJBTIKABM3AGA3SVJ6KRANCNFSM4UY5MIBQ .

cdbmgrdn commented 3 years ago

I'm working on something similar and I'm now thinking the issue could be with the types (I ran into a very similar problem).

Make sure that each list of uncorrelated players turns into a PlayersGroup. optimizer.add_players_group() needs a PlayersGroup input and not a list.

I'm thinking that setting your correlation cutoff to -.800 just shrunk your list to zero which made it work.

Try something like this if you have a list of lists fo uncorrelated players:

for i in range(len(uncorrelated_players_list)):
    uncorrelated_players_list[i] = PlayersGroup(uncorrelated_players_list[i])
Denwen12 commented 3 years ago

i can upload my list if you want

On Fri, Dec 18, 2020, 1:56 PM cdbmgrdn notifications@github.com wrote:

I'm working on something similar and I'm now thinking the issue could be with the types (I ran into a very similar problem).

Make sure that each list of uncorrelated players turns into a PlayersGroup. optimizer.add_players_group() needs a PlayersGroup input and not a list.

I'm thinking that setting your correlation cutoff to -.800 just shrunk your list to zero which made it work.

Try something like this if you have a list of lists fo uncorrelated players:

for i in range(len(uncorrelated_players_list)): uncorrelated_players_list[i] = PlayersGroup(uncorrelated_players_list[i])

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/DimaKudosh/pydfs-lineup-optimizer/issues/229#issuecomment-748261440, or unsubscribe https://github.com/notifications/unsubscribe-auth/ANBWO7SYHXNR7MQCPS5QKFTSVOQWFANCNFSM4UY5MIBQ .

Denwen12 commented 3 years ago

whats your email address? that's much better for me to communicate

On Fri, Dec 18, 2020, 3:00 PM joseph offen joffen12@gmail.com wrote:

i can upload my list if you want

On Fri, Dec 18, 2020, 1:56 PM cdbmgrdn notifications@github.com wrote:

I'm working on something similar and I'm now thinking the issue could be with the types (I ran into a very similar problem).

Make sure that each list of uncorrelated players turns into a PlayersGroup. optimizer.add_players_group() needs a PlayersGroup input and not a list.

I'm thinking that setting your correlation cutoff to -.800 just shrunk your list to zero which made it work.

Try something like this if you have a list of lists fo uncorrelated players:

for i in range(len(uncorrelated_players_list)): uncorrelated_players_list[i] = PlayersGroup(uncorrelated_players_list[i])

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/DimaKudosh/pydfs-lineup-optimizer/issues/229#issuecomment-748261440, or unsubscribe https://github.com/notifications/unsubscribe-auth/ANBWO7SYHXNR7MQCPS5QKFTSVOQWFANCNFSM4UY5MIBQ .

Denwen12 commented 3 years ago

i could also be looking at the numbers incorrectly. Is a negative better or the postive ?

On Fri, Dec 18, 2020, 4:56 PM joseph offen joffen12@gmail.com wrote:

whats your email address? that's much better for me to communicate

On Fri, Dec 18, 2020, 3:00 PM joseph offen joffen12@gmail.com wrote:

i can upload my list if you want

On Fri, Dec 18, 2020, 1:56 PM cdbmgrdn notifications@github.com wrote:

I'm working on something similar and I'm now thinking the issue could be with the types (I ran into a very similar problem).

Make sure that each list of uncorrelated players turns into a PlayersGroup. optimizer.add_players_group() needs a PlayersGroup input and not a list.

I'm thinking that setting your correlation cutoff to -.800 just shrunk your list to zero which made it work.

Try something like this if you have a list of lists fo uncorrelated players:

for i in range(len(uncorrelated_players_list)): uncorrelated_players_list[i] = PlayersGroup(uncorrelated_players_list[i])

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/DimaKudosh/pydfs-lineup-optimizer/issues/229#issuecomment-748261440, or unsubscribe https://github.com/notifications/unsubscribe-auth/ANBWO7SYHXNR7MQCPS5QKFTSVOQWFANCNFSM4UY5MIBQ .

Denwen12 commented 3 years ago

What is Teammate Correlation?

The Teammmate Correlation tool looks at the relationship between two teammates’ performances (minutes per game, DraftKings points per game and FanDuel points per game), measured by correlation.

Correlation measures how two values move relative to each other, and is expressed as the correlation coefficient, a number on a scale from -1 (perfectly negative correlation) to 1 (perfectly positive correlation).

The closer the correlation coefficient is to 0, the weaker the relationship, and the further it is from 0, the stronger the relationship.

For a positive correlation, the values move in the same direction. If Value A increases, Value B increases. If Value A decreases, Value B decreases.

For a negative correlation, the values move in opposite directions. If Value A increases, Value B decreases. If Value A decreases, Value B increases.

Finally, there are also cases of no correlation. In these cases, a change in Value A doesn’t impact Value B.

A final point on correlation: we are not dealing with any perfectly correlated relationships. For example, in the positive correlations we will look at below, when Value A moves one direction, Value B will typically move in the same direction, but not always.

The closer the correlation coefficient is to 1 (or -1), the more often the relationship will be true.

The general idea is: how does a change in Player A’s performance impact our expectation for Player B’s performance? If we expect Player A to have a big game tonight (which we do if we’re playing them in a large field tournament), how does that impact our prediction for Player B?

On Fri, Dec 18, 2020, 6:06 PM joseph offen joffen12@gmail.com wrote:

i could also be looking at the numbers incorrectly. Is a negative better or the postive ?

On Fri, Dec 18, 2020, 4:56 PM joseph offen joffen12@gmail.com wrote:

whats your email address? that's much better for me to communicate

On Fri, Dec 18, 2020, 3:00 PM joseph offen joffen12@gmail.com wrote:

i can upload my list if you want

On Fri, Dec 18, 2020, 1:56 PM cdbmgrdn notifications@github.com wrote:

I'm working on something similar and I'm now thinking the issue could be with the types (I ran into a very similar problem).

Make sure that each list of uncorrelated players turns into a PlayersGroup. optimizer.add_players_group() needs a PlayersGroup input and not a list.

I'm thinking that setting your correlation cutoff to -.800 just shrunk your list to zero which made it work.

Try something like this if you have a list of lists fo uncorrelated players:

for i in range(len(uncorrelated_players_list)): uncorrelated_players_list[i] = PlayersGroup(uncorrelated_players_list[i])

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/DimaKudosh/pydfs-lineup-optimizer/issues/229#issuecomment-748261440, or unsubscribe https://github.com/notifications/unsubscribe-auth/ANBWO7SYHXNR7MQCPS5QKFTSVOQWFANCNFSM4UY5MIBQ .

Denwen12 commented 3 years ago

what is the full code i should try

sansbacon commented 3 years ago

A couple of comments, one theoretical and one practical.

The theoretical comment is that the "no negatively correlated players" rule is likely a bad idea, especially as the slate size goes down. Most correlation coefficients for teammates are statistically weak, they do not measure the magnitude of the relationship, and do not take into account salary or the other players on the team. You may not want to play $8,000 players together if they have negative correlation, but it may be a mistake to pass on a $3,500 player on this basis.

The practical comment is that these types of relationships are better expressed in projections rather than optimizer rules. The optimizer rule "no negative correlations" can be approximated by generating projections that downgrade player B when player A has a favorable projection, while also allowing these players to be played together when justified by salary and the adjusted projections. This approach should also be superior from a performance standpoint, as creating more and more complicate optimizer rules can slow things down substantially.