From e2939c5d672b7c5c7f8febdd024a17979eaa4b00 Mon Sep 17 00:00:00 2001 From: Jacqueline Date: Thu, 24 Oct 2024 14:20:43 -0400 Subject: [PATCH] Add endpoints for testing --- server/src/course/course.controller.ts | 32 +++++++++++++++++++++++++- server/src/course/course.recalgo.ts | 14 +++++++---- server/src/course/course.router.ts | 25 ++++++++++++++++++-- server/src/course/course.type.ts | 4 ++++ 4 files changed, 67 insertions(+), 8 deletions(-) diff --git a/server/src/course/course.controller.ts b/server/src/course/course.controller.ts index 8a9ed1cb2..601e5c3b6 100644 --- a/server/src/course/course.controller.ts +++ b/server/src/course/course.controller.ts @@ -1,5 +1,6 @@ import { findCourseById, findCourseByInfo } from './course.data-access'; -import { CourseIdRequestType, CourseInfoRequestType } from './course.type'; +import { CourseIdRequestType, CourseInfoRequestType, CourseDescriptionRequestType } from './course.type'; +import { preprocess, tfidf, cosineSimilarity, idf } from './course.recalgo'; import { findReviewCrossListOR } from '../utils'; @@ -78,3 +79,32 @@ export const getReviewsCrossListOR = async ({ return null; }; + +export const getProcessedDescription = (text) => { + const processed = preprocess(text); + return processed; +} + +export const getSimilarity = () => { + const descriptions = ["This course provides a detailed study on multiple financial markets including bonds, forwards, futures, swaps, and options and their role in addressing major issues facing humanity. In particular, we plan to study specific topics on the role of financial markets in addressing important issues like funding cancer cure, tackling climate change, and financing educational needs for the underserved. Relative to a traditional finance class, we take a broad approach and think of finance as a way to get things done and financial instruments as a way to solve problems. We explore topics related to diversification and purpose investing, including a highly innovative idea of a mega-fund developing cancer treatment. We examine how financial instruments can help solve or hedge some societal issues, particularly on climate change. As an example, we will be studying a financial solution to deal with California forest fire. We also examine the potential for social impact bonds for educating pre-school children and reducing prisoners' recidivism.", + "This course introduces and develops the leading modern theories of economies open to trade in financial assets and real goods. The goal is to understand how cross-country linkages in influence macroeconomic developments within individual countries; how financial markets distribute risk and wealth around the world; and how trade changes the effectiveness of national monetary and fiscal policies. In exploring these questions, we emphasize the role that exchange rates and exchange rate policy take in shaping the consequences of international linkages. We apply our theories to current and recent events, including growing geoeconomic conflict between Eastern and Western countries, hyperinflation in Argentina, Brexit, and recent Euro-area debt crises.", + "The Corporate Finance Immersion (CFI) Practicum is designed to provide students with a real world and practical perspective on the activities, processes and critical questions faced by corporate finance executives. It is oriented around the key principles of shareholder value creation and the skills and processes corporations use to drive value. The CFI Practicum will help develop skills and executive judgement for students seeking roles in corporate finance, corporate strategy, business development, financial planning, treasury, and financial management training programs. The course can also help students pursuing consulting to sharpen their financial skills and get an excellent view of a corporation's strategic and financial objectives. The practicum will be comprised of a mix of lectures, cases, guest speakers, and team projects. Additionally, there will be training workshops to build your financial modelling skills.", + "Environmental Finance & Impact Investing Practicum", + "Corporate Finance II" + ] + + const processedDescriptions = descriptions.map(desc => preprocess(desc).split(' ')); + const allTerms = [...new Set(processedDescriptions.flat())]; + const idfValues = idf(allTerms, processedDescriptions); + const tfidfVectors = processedDescriptions.map(terms => tfidf(terms, idfValues)); + + let similarity = []; + + for (let i = 0; i < descriptions.length; i++) { + for (let j = i + 1; j < descriptions.length; j++) { + const cos = cosineSimilarity(tfidfVectors[i], tfidfVectors[j]); + similarity.push({ courseA: i, courseB: j, similarity: cos }); + } + } + return similarity; +} \ No newline at end of file diff --git a/server/src/course/course.recalgo.ts b/server/src/course/course.recalgo.ts index 0b3249667..3e0b681d9 100644 --- a/server/src/course/course.recalgo.ts +++ b/server/src/course/course.recalgo.ts @@ -11,12 +11,12 @@ const stemWord = (word) => { return word; } -const preprocess = (text) => { +export const preprocess = (text: string) => { let sentences = text.match(/[^.!?]*[.!?]\s+[A-Z]/g) || [text]; let processedText = sentences.map(sentence => { let words = sentence.match(/\b\w+\b/g) || []; let cleanedWords = words.map(word => { - let singularWord = stemWord(word.toLowerCase()); + const singularWord = stemWord(word.toLowerCase()); return singularWord.replace(/[^\w\s]/g, ''); }); return cleanedWords.join(' '); @@ -24,16 +24,17 @@ const preprocess = (text) => { return processedText.join('. '); } -const idf = (terms, words) => { +export const idf = (terms, words) => { let df = {}; let idf = {}; for (const term of terms) { df[term] = words.reduce((count, wordsSet) => (count + (wordsSet.includes(term) ? 1 : 0)), 0); idf[term] = 1 / (df[term] + 1); } + return idf; } -const tfidf = (terms, idf) => { +export const tfidf = (terms, idf) => { let d = {}; for (const term of terms) { if (!d[term]) { @@ -42,6 +43,9 @@ const tfidf = (terms, idf) => { d[term]++; } for (const term in d) { + if (idf && idf[term] === undefined) { + idf[term] = 1; + } d[term] *= idf[term]; } return d; @@ -62,7 +66,7 @@ const norm = (vec) => { return Math.sqrt(sum); } -const cosineSimilarity = (vecA, vecB) => { +export const cosineSimilarity = (vecA, vecB) => { const dotProduct = dot(vecA, vecB); const magA = norm(vecA); const magB = norm(vecB); diff --git a/server/src/course/course.router.ts b/server/src/course/course.router.ts index 09eb9c650..aa7f5bcbe 100644 --- a/server/src/course/course.router.ts +++ b/server/src/course/course.router.ts @@ -1,7 +1,7 @@ import express from 'express'; -import { CourseIdRequestType, CourseInfoRequestType } from './course.type'; -import { getCourseByInfo, getReviewsCrossListOR } from './course.controller'; +import { CourseIdRequestType, CourseInfoRequestType, CourseDescriptionRequestType } from './course.type'; +import { getCourseByInfo, getReviewsCrossListOR, getProcessedDescription, getSimilarity } from './course.controller'; import { getCourseById } from '../utils'; @@ -69,3 +69,24 @@ courseRouter.post('/get-reviews', async (req, res) => { .json({ error: `Internal Server Error: ${err.message}` }); } }); + +/** Reachable at POST /api/courses/getPreDesc + * @body description: a course description + * Gets the processed description to use for the similarity algorithm + * Currently used for testing +*/ +courseRouter.post('/getPreDesc', async (req, res) => { + const { description }: CourseDescriptionRequestType = req.body; + const processed = getProcessedDescription(description); + return res.status(200).json({ result: processed }); +}); + +/** Reachable at POST /api/courses/getSimilarity + * @body courseId: a course's id field + * Gets the array of the top 5 similar courses for the course with id = courseId +*/ +courseRouter.post('/getSimilarity', async (req, res) => { + // const { courseId }: CourseIdRequestType = req.body; + const similarity = getSimilarity(); + return res.status(200).json({ result: similarity }); +}); diff --git a/server/src/course/course.type.ts b/server/src/course/course.type.ts index 2c7190dd7..3784d1719 100644 --- a/server/src/course/course.type.ts +++ b/server/src/course/course.type.ts @@ -6,3 +6,7 @@ export interface CourseInfoRequestType { export interface CourseIdRequestType { courseId: string; } + +export interface CourseDescriptionRequestType { + description: string; +}