-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtry_towear.py
166 lines (138 loc) · 6.89 KB
/
try_towear.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
"""Main backend for making the outfit suggestions"""
# needed for generating test data
from random import randint
# needed for predicting using training sets
from sklearn.linear_model import LinearRegression
def user_happy(
outfit_tried: list, temp_outfit: int, temp_global: int, *secrets: list
) -> bool:
"""simulates user's feeling in this outfit with this temperature
based on the user's desired temperature and coefficients
Arguments:
outfit_tried {list} -- outfit used
temp_outfit {int} -- warmth of the outfit
temp_global {int} -- temperature outside
*secrets {list} -- [temp_desired {int} -- a secret number,
temp_coefficients {[type]} -- a secret list of percentages
that affect the user's temperature]
Returns:
bool -- whether the user felt good in this outfit or not
"""
if secrets[0] is not None and secrets[1] is not None:
# the serets are known so, we can just take them
temp_desired = secrets[0]
temp_coefficients = secrets[1]
# deviation of what is an accepted outfit and what is not
temp_deviation = (temp_outfit + temp_global) - temp_desired
if temp_deviation > 1 or temp_deviation < -1:
# too much deviation from the desired temperature
# (remember, all temperatures are scaled from 0 to 40)
# user should be unhappy since the temperature does not match the desired temperature
return False
for index, element in enumerate(outfit_tried):
if temp_outfit == 0:
# this may seem redundant but it's necessary to avoid division by zero exception
element_significance = 0
else:
# the effect of any garment on the temperature of the outfit
# is equal to the temperature of the garment
# divided by the temperature of the outfit
element_significance = element / temp_outfit
if (
element_significance > 0.1 + temp_coefficients[index]
or element_significance < temp_coefficients[index] - 0.1
):
# user should be unhappy
# the coefficient does not match the desired temperature
return False
return True
# TODO: Allow users to modify desired temperature and coefficients with real inputs
raise ValueError("Expected known secrets")
def generate_data(*secrets: list) -> tuple:
"""create train set data for machine learning;
note that only the omniscient user knows the secret numbers
although the secrets are known, we'll let the AI figure them out on its own
Arguments:
data_amount {int} -- how much training data?
*secrets {list} -- [temp_desired {int} -- a secret number,
temp_coefficients {list} -- a secret list of percentages
that affect the user's temperature]
Returns:
tuple -- pairs of weathers and corresponding appropriate outfits
"""
# list for predicting the desired temperature of the user
estimated_desired_temp = list()
# list for predicting the warmth coefficients of the user
estimated_coefficients = []
# list of weather data
weather_input = list()
# list of outfits corresponding to the weather data
outfit_output = [[] for _ in range(0, 4)]
if secrets:
# the serets are known so, we can just take them
temp_desired = secrets[0]
temp_coefficients = secrets[1]
# scale the desired temperature to a number between 0 and 40
temp_desired_scaled = (40 / 134) * temp_desired
else:
# if we don't know the desired temperatures, we should estimate them later
temp_desired_scaled = temp_coefficients = None
# training amount (integer; 10 is usually enough. >100 is too high
training_amount = 10
# generate data_amount of items for the training sets of weather_input and outfit_output
while len(weather_input) != training_amount:
# random weather value between 0 and 40
temp_global_original = randint(0, 134)
# global temperature in the same terms as the temperature of the outfit
temp_global_scaled = (40 / 134) * temp_global_original
# generate a random tried outfit with garment warmths between 0 and 10 for all 4 parts
outfit_tried = [randint(0, 10) for _ in range(0, 4)]
# the temperature of the outfit generated
# between 0 and 40 for the temperature which is between 0 and 40
temp_outfit = sum(outfit_tried)
if user_happy(
outfit_tried,
temp_outfit,
temp_global_scaled,
temp_desired_scaled,
temp_coefficients,
):
# if the user, knowing their desired temperature
# and coefficients are happy with the result,
# we should include the weather_input and outfit_output pair
# in the training set
estimated_desired_temp.append(temp_outfit + temp_global_scaled)
estimated_coefficients.append(
[element / temp_outfit for element in outfit_tried]
)
weather_input.append([int(temp_global_original)])
for index, output in enumerate(outfit_output):
output.append(int(outfit_tried[index]))
return weather_input, outfit_output
def suggest_outfit(
weather_input: list, outfit_output: list, weather_given: int
) -> list:
"""suggest an outfit to the user using the training sets of weather and outfit pairs
Arguments:
weather_input {list} -- weather inputs to use as training sets
outfit_output {list} -- outfits appropriate for each weather input
weather_given {int} -- the given weather in this case
Returns:
list -- [int,int,int,int] of the perfect outfit for the weather for this user
"""
# create linear regression objects for the four clothing slots
predictors = [LinearRegression(n_jobs=-1) for _ in range(0, 4)]
# fit the linear model (approximate a target function)
for index, predictor in enumerate(predictors):
predictor.fit(X=weather_input, y=outfit_output[index])
# use the current weather as input
x_test = [[int(weather_given)]]
# Predict the ouput of the input X_Test using the linear model
outfit = [predictor.predict(X=x_test) for predictor in predictors]
# get rid of any below 0 inaccuracies
for i, suggested_garment_warmth in enumerate(outfit):
if suggested_garment_warmth < 0:
outfit[i] = 0
elif suggested_garment_warmth > 10:
outfit[i] = 10
return outfit