abdullahmeda commited on
Commit
7fa3a99
1 Parent(s): fefd600
Files changed (3) hide show
  1. app.py +383 -0
  2. hugging_face_spaces.csv +0 -0
  3. requirements.txt +7 -0
app.py ADDED
@@ -0,0 +1,383 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pandas as pd
3
+ import numpy as np
4
+ import matplotlib.pyplot as plt
5
+ import seaborn as sns
6
+ from scipy import stats
7
+ from sklearn.manifold import TSNE
8
+
9
+ unfiltered_spaces_with_outliers = pd.read_csv('../data/hugging_face_spaces.csv')
10
+ spaces = unfiltered_spaces_with_outliers[unfiltered_spaces_with_outliers['likes'] >= 3]
11
+ # spaces = spaces_with_outliers[(np.abs(stats.zscore(spaces_with_outliers['likes'])) < 3)]
12
+ # print(spaces.describe())
13
+ # print(spaces.describe().columns)
14
+ # print(spaces.describe().astype(str).to_numpy().tolist())
15
+ # spaces = spaces[spaces[['total_commits', 'community_interactions']].notna()]
16
+ # spaces[['total_commits', 'community_interactions']] = spaces[['total_commits', 'community_interactions']].astype('Int64')
17
+
18
+ descriptions = [
19
+ 'Unique id of a space, comprised of username followed by the space name separated by a "/"',
20
+ 'SDK of space, one of gradio, streamlit or static',
21
+ 'Total number of likes associated with the space',
22
+ 'Username of the user',
23
+ 'Name of the space',
24
+ 'URL associated to the space',
25
+ 'Various forms of input the space takes in',
26
+ 'Various entities the space outputs',
27
+ 'Is True if the space repo has an app.py',
28
+ 'AI/ML related python packages that were used in the making of the model',
29
+ 'The date of the last known commit on the space\'s repository',
30
+ 'The total number of commits on the space\'s repository',
31
+ 'The current status of space',
32
+ 'The total number of contributions or interactions from the community on the space\'s repository',
33
+ ]
34
+
35
+
36
+ def info(df_in):
37
+ df_info = df_in.columns.to_frame(name='Column')
38
+ df_info['Non-Null Count'] = df_in.notna().sum()
39
+ df_info['Datatype'] = df_in.dtypes
40
+ df_info.reset_index(drop=True, inplace=True)
41
+ df_info['#'] = df_info.index
42
+ df_info['Description'] = descriptions
43
+ return df_info[['#', 'Column', 'Non-Null Count', 'Datatype', 'Description']].astype(str)
44
+
45
+
46
+ def get_nulls():
47
+ fig, ax = plt.subplots(figsize=(25, 5))
48
+ sns.barplot(x=spaces.columns, y=spaces.notnull().sum(), ax=ax, palette="tab20c_r")
49
+ ax.set_xticklabels(spaces.columns)
50
+ ax.set_title(f"Non-Null values in each column ( Total rows: {len(spaces.index)} )\n", fontsize="x-large")
51
+ for i, val in enumerate(spaces.notnull().sum()):
52
+ plt.text(i, val+9, val, horizontalalignment='center', verticalalignment='bottom', fontdict={'fontweight':500, 'size':12})
53
+ ax.set_yticklabels([])
54
+ ax.set_yticks([False])
55
+ sns.despine(top=True, right=True, left=True)
56
+ return fig
57
+
58
+
59
+ def get_corr():
60
+ fig = plt.figure(figsize=(10, 5))
61
+ sns.heatmap(spaces.corr(), annot=True, linewidths=.5, fmt='.1f')
62
+ plt.tight_layout()
63
+ return fig
64
+
65
+
66
+ def get_corr_df():
67
+ corr = spaces.corr()
68
+ corr = corr.reset_index()
69
+ return corr.astype(str)
70
+
71
+
72
+ def get_corr_scatter_total_commits():
73
+ fig = plt.figure(figsize=(15, 5))
74
+ plt.scatter(spaces['likes'], spaces['total_commits'])
75
+ plt.tight_layout()
76
+ return fig
77
+
78
+
79
+ def get_corr_scatter_community_interactions():
80
+ fig = plt.figure(figsize=(15, 5))
81
+ plt.scatter(spaces['likes'], spaces['community_interactions'])
82
+ plt.tight_layout()
83
+ return fig
84
+
85
+
86
+ def get_top_spaces(quantity, min_value, max_value, filter_by, sort_by):
87
+ top_spaces = spaces[(spaces[filter_by] >= min_value) & (spaces[filter_by] <= max_value)]
88
+ top_spaces = top_spaces.sort_values(filter_by, ascending=True if sort_by == 'ascending' else False)
89
+ top_spaces = top_spaces[['repo_id', filter_by]].iloc[:quantity]
90
+
91
+ fig = plt.figure(figsize=(10, 20))
92
+ plt.bar(top_spaces['repo_id'], top_spaces[filter_by])
93
+ plt.xticks(rotation=30)
94
+ plt.tight_layout()
95
+ return gr.Dataframe.update(value=top_spaces.astype(str).to_numpy().tolist()), gr.Plot.update(value=fig)
96
+
97
+
98
+ def change_limits(filter_by):
99
+ updated_slider = gr.Slider.update(minimum=spaces[filter_by].min(), maximum=spaces[filter_by].max(), value=3)
100
+ return updated_slider, updated_slider
101
+
102
+
103
+ def get_most_spaces():
104
+ most_spaces = spaces['user_name'].value_counts().sort_values(ascending=False).reset_index().iloc[:7]
105
+ fig = plt.figure(figsize=(20, 10))
106
+ plt.barh(most_spaces.iloc[:, 0], most_spaces.iloc[:, 1])
107
+ plt.xticks(rotation=30)
108
+ plt.tight_layout()
109
+ return most_spaces, fig
110
+
111
+
112
+ def get_most_liked_users():
113
+ y = pd.pivot_table(
114
+ spaces,
115
+ index=['user_name'],
116
+ aggfunc={'likes': np.sum, 'user_name': len}
117
+ ).sort_values('likes', ascending=False).rename(columns={'user_name': 'space_count'}).iloc[:10].reset_index()
118
+ y['likes'] = y['likes'].astype(int)
119
+ y['space_count'] = y['space_count'].astype(int)
120
+ fig = plt.figure(figsize=(20, 8))
121
+ sns.set_theme()
122
+ sns.relplot(data=y.iloc[:7], x='user_name', y='likes', col='space_count')
123
+ plt.show()
124
+ return y.iloc[:7].astype(str), fig
125
+
126
+
127
+ def get_sdk_proportions():
128
+ fig = plt.figure()
129
+ colors = ["#E13F29", "#D69A80", "#D63B59", "#AE5552", "#CB5C3B", "#EB8076", "#96624E"]
130
+ spaces['sdk'].value_counts().plot.pie(
131
+ shadow=False,
132
+ colors=colors,
133
+ startangle=90,
134
+ autopct='%1.1f%%')
135
+
136
+ plt.axis('equal')
137
+ plt.tight_layout()
138
+ return fig
139
+
140
+
141
+ def get_sdk_frequencies():
142
+ fig = plt.figure()
143
+ sns.stripplot(x='sdk', y='likes', data=spaces, jitter=True)
144
+ plt.tight_layout()
145
+ return fig
146
+
147
+
148
+ def get_io_proportions():
149
+ fig = plt.figure()
150
+ colors = ["#E13F29", "#D69A80", "#D63B59", "#AE5552", "#CB5C3B", "#EB8076", "#96624E"]
151
+ a = spaces[spaces['inputs'].notnull()]['inputs'].values
152
+ a = [y.split(',') for y in a]
153
+ flat_list = [x for xs in a for x in xs]
154
+ pd.Series(flat_list).value_counts().plot.pie(
155
+ shadow=False,
156
+ colors=colors,
157
+ # explode=(0.15, 0, 0),
158
+ startangle=90,
159
+ autopct='%1.1f%%')
160
+
161
+ plt.axis('equal')
162
+ plt.tight_layout()
163
+ return fig
164
+
165
+
166
+ def get_packages_proportions():
167
+ fig = plt.figure()
168
+ colors = ["#E13F29", "#D69A80", "#D63B59", "#AE5552", "#CB5C3B", "#EB8076", "#96624E"]
169
+ a = spaces[spaces['ai_ml_reqs'].notnull()]['ai_ml_reqs'].values
170
+ a = [y.split(',') for y in a]
171
+ flat_list = [x for xs in a for x in xs]
172
+ pd.Series(flat_list).value_counts().plot.pie(
173
+ shadow=False,
174
+ colors=colors,
175
+ # explode=(0.15, 0, 0),
176
+ startangle=90,
177
+ autopct='%1.1f%%')
178
+
179
+ plt.axis('equal')
180
+ plt.tight_layout()
181
+ return fig
182
+
183
+
184
+ def get_processable_spaces_proportions():
185
+ fig = plt.figure()
186
+ colors = ["#E13F29", "#D69A80", "#D63B59", "#AE5552", "#CB5C3B", "#EB8076", "#96624E"]
187
+ spaces['is_processed'].value_counts().plot.pie(
188
+ shadow=False,
189
+ colors=colors,
190
+ # explode=(0.15, 0, 0),
191
+ startangle=90,
192
+ autopct='%1.1f%%')
193
+
194
+ plt.axis('equal')
195
+ plt.tight_layout()
196
+ return fig
197
+
198
+
199
+ def get_tsne():
200
+ spaces_numeric = spaces[['likes', 'total_commits', 'community_interactions']]
201
+ spaces_numeric = spaces_numeric.dropna()
202
+ fig = plt.figure()
203
+ m = TSNE(learning_rate=50)
204
+ tsne_features = m.fit_transform(spaces_numeric)
205
+
206
+ spaces_numeric['x'] = tsne_features[:, 0]
207
+ spaces_numeric['y'] = tsne_features[:, 1]
208
+ spaces_numeric['sdk'] = spaces['sdk']
209
+ spaces_numeric['like_class'] = spaces_numeric['likes'].apply(get_likes_description)
210
+
211
+ sns.scatterplot(x='x', y='y', hue='sdk', style='like_class', data=spaces_numeric)
212
+ return fig
213
+
214
+
215
+ def get_likes_description(likes):
216
+ if likes < spaces['likes'].mean():
217
+ return "Below Average"
218
+ elif likes < (spaces['likes'].mean() + (spaces['likes'].std() * 1.5)):
219
+ return "Good"
220
+ else:
221
+ return "Awesome"
222
+
223
+
224
+ with gr.Blocks(css="""
225
+ #md {width: 60%; padding: 0px 10px 0px}
226
+ #plot {width: 40%; margin: auto;}
227
+ #spacer {padding: 15px 15px 15px 15px}
228
+ """) as demo:
229
+ gr.Markdown("""
230
+ # Exploring the statistics of 🤗 Spaces
231
+ Hugging Face Spaces offer a simple way to host ML demo apps directly on your profile or your organization’s profile. This allows you to create your ML portfolio, showcase your projects at conferences or to stakeholders, and work collaboratively with other people in the ML ecosystem.
232
+
233
+ This is an interactive blog that provides an overview of all the present spaces on 🤗
234
+
235
+ **Data Set**: The above and related information was collected by DeepKlarity using the HuggingFace Spaces API Endpoint and extracting data individually from each space's repository via scraping
236
+
237
+ The dataset can be accessed from the git repository here
238
+
239
+ ## Read the data
240
+ ```
241
+ spaces = pd.read_csv('hugging_face_spaces.csv')
242
+ ```
243
+ ### Data columns info and descriptions:
244
+ The following table gives insights into each of the columns in the aforementioned dataset and their respective descriptions
245
+ """)
246
+ gr.Dataframe(type="numpy",
247
+ headers=['#', 'Column', 'Non-Null Count', 'Datatype', 'Description'],
248
+ value=info(unfiltered_spaces_with_outliers).to_numpy().tolist(),
249
+ datatype=['number', 'str', 'number', 'str', 'str'],
250
+ row_count=14,
251
+ col_count=5,
252
+ )
253
+ gr.Markdown(f"""
254
+ ### Identifying valid spaces
255
+ For the sake of keeping things simple and logical, lets assume that a space is valid only if it has a minimum of 3 likes. Keeping this in mind, the size of the new filtered dataset falls from {len(unfiltered_spaces_with_outliers.index)} to {len(spaces.index)}.\n
256
+ """)
257
+ gr.Dataframe(type="numpy",
258
+ headers=list(spaces.columns),
259
+ value=spaces.astype(str).iloc[:5].to_numpy().tolist(),
260
+ row_count=5,
261
+ col_count=14,
262
+ )
263
+ gr.Markdown(f"""
264
+
265
+ The below plot summarizes the actual amount of non-null values present in each of the columns of the new filtered dataset.
266
+ """)
267
+ gr.Plot(value=get_nulls())
268
+ gr.Markdown("""
269
+ There seems to be lot of columns with empty/ null values. Perhaps familiarity with each of the columns and what exactly it captures will help in identifying which fields are useful for the analysis and which fields can be ignored. Here are the reasons for `NaN`s in each of these columns:
270
+ - **inputs, outputs**: An absence of any type of inputs/outputs represents a null. Moreover, the script corresponding to this dataset was able to only extract inputs/outputs for Gradio spaces. Therefore, any spaces that have Streamlit or Static as their sdk will also have a null in these columns
271
+ - **ai_ml_reqs**: Any spaces that do not use any of the AI/ML packages will have a null in this column
272
+ - **last_commit, total_commits, status, community_interactions**: These columns should have around the same number of nulls and represents the fact that an error occurred when scraping space's remote repository
273
+ ### Finding correlations between characteristics
274
+ """)
275
+ with gr.Row():
276
+ # with gr.Column():
277
+ gr.Markdown("""
278
+ Looking at the correlations and plot, we can see that all no 2 columns correlate quite well as they all have a Pearsons R-value of less than 0.4. However of all the columns, the `likes` column correlated the best with `total_commits` and `community_interactions`\r
279
+ Although not always true, this does make sense because wel-made HuggingFace Spaces are bound to get more likes and in turn mean that the authors had worked on it for quite a long time and therefore made a lot of commits. Secondly, a good space is also bound to get more attention, i.e. more interactions from the community
280
+ Below are the corresponding 2 Scatter plots
281
+ """, elem_id='md')
282
+ # with gr.Row():
283
+ # gr.Plot(value=get_corr_scatter_total_commits())
284
+ # gr.Plot(value=get_corr_scatter_community_interactions())
285
+ # with gr.Column():
286
+ gr.Plot(value=get_corr(), elem_id='plot')
287
+ gr.Markdown("""
288
+ ## Questions that we can try to answer?
289
+ One of the key reasons to writing this blog is to perform Exploratory Data Analysis (EDA) on the Huggingface Spaces datatset. We will be acomplishing this and gain insights by answering some high level questions as follows
290
+ ### What are the top n spaces on HuggingFace filtered by x?
291
+ """)
292
+ with gr.Row():
293
+ with gr.Column():
294
+ quantity = gr.Slider(minimum=1, maximum=10, value=10, step=1, label="Quantity:", show_label=True)
295
+ min_value = gr.Slider(minimum=spaces['likes'].min(), maximum=spaces['likes'].max(), value=3, step=1, label="Min Value of Quantity:", show_label=True)
296
+ max_value = gr.Slider(minimum=spaces['likes'].min(), maximum=spaces['likes'].max(), value=3, step=1, label="Max Value of Quantity:", show_label=True)
297
+ filter_by = gr.Radio(choices=['likes', 'total_commits', 'community_interactions'], value='likes', label="Filter by:", show_label=True)
298
+ sort_by = gr.Radio(choices=['ascending', 'descending'], value='descending', label="Sort by:", show_label=True)
299
+ submit = gr.Button(value='Submit')
300
+ with gr.Column():
301
+ data_points = gr.Dataframe(
302
+ type="numpy",
303
+ headers=["Repo ID", 'Value'],
304
+ datatype=["str", "number"],
305
+ value=spaces.sort_values('likes')[['repo_id', 'likes']].iloc[:10].astype(str).to_numpy().tolist(),
306
+ )
307
+ with gr.Column():
308
+ data_plot = gr.Plot()
309
+ filter_by.change(fn=change_limits, inputs=[filter_by], outputs=[min_value, max_value])
310
+ submit.click(fn=get_top_spaces, inputs=[quantity, min_value, max_value, filter_by, sort_by], outputs=[data_points, data_plot])
311
+ gr.Markdown("", elem_id='spacer')
312
+ with gr.Row():
313
+ gr.Markdown(f"""
314
+ ### What is the highest number of spaces created by any one user?
315
+
316
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec id rutrum diam, sed euismod lacus. Vivamus posuere, nibh sit amet dictum bibendum, tortor ligula faucibus odio, id mattis dolor erat eu ante. Quisque et velit nec libero viverra commodo in a augue. Quisque posuere leo arcu, in pretium ipsum dignissim non.
317
+
318
+ Curabitur in purus est. Proin vitae egestas orci, sit amet elementum urna. Sed condimentum rutrum erat, in vulputate purus consectetur sit amet. Cras rutrum mattis ante id malesuada. Duis luctus, erat vel imperdiet condimentum, elit lorem tincidunt sem, sit amet maximus arcu erat at ex.
319
+ """, elem_id='md')
320
+ gr.Plot(value=get_most_spaces()[1], elem_id='plot')
321
+ gr.Markdown("", elem_id='spacer')
322
+ with gr.Row():
323
+ gr.Plot(value=get_most_liked_users()[1], elem_id='plot')
324
+ gr.Markdown("""
325
+ ### Which users has achieved the most likes?
326
+
327
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec id rutrum diam, sed euismod lacus. Vivamus posuere, nibh sit amet dictum bibendum, tortor ligula faucibus odio, id mattis dolor erat eu ante. Quisque et velit nec libero viverra commodo in a augue. Quisque posuere leo arcu, in pretium ipsum dignissim non.
328
+
329
+ Curabitur in purus est. Proin vitae egestas orci, sit amet elementum urna. Sed condimentum rutrum erat, in vulputate purus consectetur sit amet. Cras rutrum mattis ante id malesuada. Duis luctus, erat vel imperdiet condimentum, elit lorem tincidunt sem, sit amet maximus arcu erat at ex.
330
+ """, elem_id='md')
331
+ gr.Markdown("", elem_id='spacer')
332
+ with gr.Row():
333
+ gr.Markdown("""
334
+ ### What are the proportions of the different SDKs used in creating spaces?
335
+
336
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec id rutrum diam, sed euismod lacus. Vivamus posuere, nibh sit amet dictum bibendum, tortor ligula faucibus odio, id mattis dolor erat eu ante. Quisque et velit nec libero viverra commodo in a augue. Quisque posuere leo arcu, in pretium ipsum dignissim non.
337
+
338
+ Curabitur in purus est. Proin vitae egestas orci, sit amet elementum urna. Sed condimentum rutrum erat, in vulputate purus consectetur sit amet. Cras rutrum mattis ante id malesuada. Duis luctus, erat vel imperdiet condimentum, elit lorem tincidunt sem, sit amet maximus arcu erat at ex.
339
+ """, elem_id='md')
340
+ gr.Plot(value=get_sdk_proportions(), elem_id='plot')
341
+ gr.Markdown("", elem_id='spacer')
342
+ with gr.Row():
343
+ gr.Plot(value=get_processable_spaces_proportions(), elem_id='plot')
344
+ gr.Markdown("""
345
+ ### How many spaces are processable?
346
+
347
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec id rutrum diam, sed euismod lacus. Vivamus posuere, nibh sit amet dictum bibendum, tortor ligula faucibus odio, id mattis dolor erat eu ante. Quisque et velit nec libero viverra commodo in a augue. Quisque posuere leo arcu, in pretium ipsum dignissim non.
348
+
349
+ Curabitur in purus est. Proin vitae egestas orci, sit amet elementum urna. Sed condimentum rutrum erat, in vulputate purus consectetur sit amet. Cras rutrum mattis ante id malesuada. Duis luctus, erat vel imperdiet condimentum, elit lorem tincidunt sem, sit amet maximus arcu erat at ex.
350
+ """, elem_id='md')
351
+ gr.Markdown("", elem_id='spacer')
352
+ with gr.Row():
353
+ gr.Markdown("""
354
+ ### What are the different types of input and output components used and which of them are used widely?
355
+
356
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec id rutrum diam, sed euismod lacus. Vivamus posuere, nibh sit amet dictum bibendum, tortor ligula faucibus odio, id mattis dolor erat eu ante. Quisque et velit nec libero viverra commodo in a augue. Quisque posuere leo arcu, in pretium ipsum dignissim non.
357
+
358
+ Curabitur in purus est. Proin vitae egestas orci, sit amet elementum urna. Sed condimentum rutrum erat, in vulputate purus consectetur sit amet. Cras rutrum mattis ante id malesuada. Duis luctus, erat vel imperdiet condimentum, elit lorem tincidunt sem, sit amet maximus arcu erat at ex.
359
+ """, elem_id='md')
360
+ gr.Plot(value=get_io_proportions(), elem_id='plot')
361
+ gr.Markdown("", elem_id='spacer')
362
+ with gr.Row():
363
+ gr.Plot(value=get_packages_proportions(), elem_id='plot')
364
+ gr.Markdown("""
365
+ ### Which AI/ML python packages are used the most?
366
+
367
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec id rutrum diam, sed euismod lacus. Vivamus posuere, nibh sit amet dictum bibendum, tortor ligula faucibus odio, id mattis dolor erat eu ante. Quisque et velit nec libero viverra commodo in a augue. Quisque posuere leo arcu, in pretium ipsum dignissim non.
368
+
369
+ Curabitur in purus est. Proin vitae egestas orci, sit amet elementum urna. Sed condimentum rutrum erat, in vulputate purus consectetur sit amet. Cras rutrum mattis ante id malesuada. Duis luctus, erat vel imperdiet condimentum, elit lorem tincidunt sem, sit amet maximus arcu erat at ex.
370
+ """, elem_id='md')
371
+ gr.Markdown("", elem_id='spacer')
372
+ gr.Markdown("""
373
+ ## Dataset in a nutshell
374
+ """)
375
+ # with gr.Row():
376
+ # with gr.Column():
377
+ # gr.Plot()
378
+ # with gr.Column():
379
+ # gr.Plot()
380
+ # with gr.Column():
381
+ # gr.Plot(value=get_tsne())
382
+
383
+ demo.launch()
hugging_face_spaces.csv ADDED
The diff for this file is too large to render. See raw diff
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ gradio==3.0.15
2
+ matplotlib==3.5.1
3
+ numpy==1.22.4
4
+ pandas==1.3.5
5
+ scikit_learn==1.1.1
6
+ scipy==1.7.3
7
+ seaborn==0.11.2