StudBud​
​Study group matching algorithm
Jessica Shi
This summer, I worked with 3 other Columbia University students, Eitan Turok, Manasi Soman, and Kimberly Tsao, on a Columbia Summer Design Challenge about Improving Social Interactions in a World Shaped By COVID-19. We came up with a thorough design plan for a platform that helps match students to study groups based on their study habits and preferences. After completing the challenge, we decided to continue working on this project and implement it into classes at Columbia in the fall semester.
​
One goal that we had was to automate the process of matching students to groups, and I chose to tackle this challenge using the Wolfram Language. Students initially fill out a Google Form with questions on which class they are signing up for, time management, how collaborative they are, strength in the subject area, motivation, how often they want to meet... Then we will sort through the data and form the groups, using the algorithm I am about to describe.
*We chose to use Google Forms over a Wolfram Cloud Form for ease of use.
​
Visit our website:
Out[]=
http://studbud.org
For simplicity, I will omit the formatting of the survey data that is imported as a csv from the Google form. Within a class, the data that will be used to form the groups will be in the following form:
In[]:=
data=AssociationThreadAlphabet[],

Out[]=
a{2,3,2,4,1,5,5,4,1,1,1},b{2,3,2,4,1,5,5,4,1,1,1},c{2,3,2,4,1,5,5,4,1,1,1},d{2,3,2,4,5,5,5,4,1,1,1},e{2,3,1,5,3,5,5,3,3,3,3},f{1,3,3,4,2,5,5,3,2,2,2},g{2,3,2,3,4,5,4,4,1,1,1},h{2,4,1,3,2,5,5,3,1,1,1},i{1,3,2,4,3,5,4,3,1,1,1},j{1,4,1,3,3,5,5,3,1,1,1},k{1,3,1,3,4,5,4,3,1,1,1},l{1,3,1,3,3,5,5,2,1,1,1},m{1,4,3,4,5,5,4,4,1,1,1},n{2,4,1,3,5,5,4,5,1,1,1},o{9,3,1,3,3,4,4,2,2,2,2},p{1,3,1,2,4,4,4,4,1,1,1},q{1,3,2,3,4,5,5,4,1,1,1},r{1,3,2,4,3,5,5,4,1,1,1},s{1,3,2,3,4,5,5,4,1,1,1},t{2,4,2,3,3,5,4,2,1,1,1},u{1,3,2,4,3,4,3,3,4,4,4},v{1,3,1,4,3,5,5,3,4,4,4},w{1,3,1,3,3,5,4,3,4,4,4},x{5,3,1,3,4,3,3,3,4,4,4},y{1,3,2,3,4,5,4,4,4,4,4},z{1,3,2,3,4,5,3,2,1,1,1}
The keys indicate the unique identification for each student (in this case I used the alphabet as an example), and the values indicate the numerical representation of the student’s responses to the questions. The last three numbers for each student represent the time zone which has been weighted more heavily because we want the students’ scheduling to match with the group as best as possible.
​
Now, we use the k-Nearest Neighbors Graph algorithm and GraphPartition in order to group together similar individuals in groups of approximately 4 individuals. The algorithm
Main grouping function
In[]:=
groupstudents[data_]:=FindGraphPartition[NearestNeighborGraph[Values[data],2],​​Round@((Length@data)/4)]
In[]:=
groups=groupstudents[data]
Out[]=
{{{2,3,2,4,5,5,5,4,1,1,1},{2,3,2,3,4,5,4,4,1,1,1},{2,4,1,3,5,5,4,5,1,1,1},{1,3,2,3,4,5,5,4,1,1,1}},{{1,3,1,3,4,5,4,3,1,1,1},{1,4,3,4,5,5,4,4,1,1,1},{1,3,1,2,4,4,4,4,1,1,1},{1,3,2,3,4,5,3,2,1,1,1}},{{2,3,2,4,1,5,5,4,1,1,1},{1,3,3,4,2,5,5,3,2,2,2},{1,3,2,4,3,5,4,3,1,1,1},{1,3,2,4,3,5,5,4,1,1,1}},{{2,3,1,5,3,5,5,3,3,3,3},{9,3,1,3,3,4,4,2,2,2,2},{2,4,2,3,3,5,4,2,1,1,1},{1,3,1,4,3,5,5,3,4,4,4}},{{1,3,2,4,3,4,3,3,4,4,4},{1,3,1,3,3,5,4,3,4,4,4},{5,3,1,3,4,3,3,3,4,4,4},{1,3,2,3,4,5,4,4,4,4,4}},{{2,4,1,3,2,5,5,3,1,1,1},{1,4,1,3,3,5,5,3,1,1,1},{1,3,1,3,3,5,5,2,1,1,1}}}
As you can see, in most groups, the members have several similar traits. We then would match these groupings back to the unique identifiers.
Matches the responses to the corresponding identifier
In[]:=
matchname[data_,groups_]:=Flatten/@Map[(PositionIndex[<|data|>])[#]&,groups,{2}]
In[]:=
names=matchname[data,groups]
Out[]=
{{d,g,n,q,s},{k,m,p,z},{a,b,c,f,i,r},{e,o,t,v},{u,w,x,y},{h,j,l}}
Since some people may have the exact same answers, we put them in the same group automatically, which can cause the groups to be too big (we want study groups of 3-5 people), the following function fixes the groups if they are too big.
Splits groups with more than 6 people into smaller groups
In[]:=
fixgroup[group_]:=Module[{l,r,sublist},l=Length@group;​​r=Last@QuotientRemainder[l,4];If[l<6,sublist=group,​​Which[r 0, sublist=Partition[group,4],r1,​​sublist=Sequence@@TakeList[group,Append[ConstantArray[4,Floor[l/4]-1],5]],​​r2,sublist=Sequence@@TakeList[group,Append[Append[ConstantArray[4,Floor[l/4]-1],3],3]],​​r3,sublist=Sequence@@TakeList[group,Append[ConstantArray[4,Floor[l/4]],3]]]];sublist]
In[]:=
fixgroup/@names
Out[]=
{{d,g,n,q,s},{k,m,p,z},{a,b,c},{f,i,r},{e,o,t,v},{u,w,x,y},{h,j,l}}
Now we have 7 groups of 3-5 students ready to study with each other! From here we use the personal information and fun facts the students provided to send out emails to the students informing them of their study groups and introducing them to their new friends using the SendMail function. We also help them find an optimal time to meet based on their survey responses to encourage students to meet for the first time.
​
The email that is sent out:
We’ve been working hard getting Columbia students to sign up for our platform. As of now (9/10/2020), we have 538 students signed up! We’re really excited to match students up with their study groups next week. Thank you for checking our project out!
​
​