Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

survey-generator.js 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. const similarity = require('compute-cosine-similarity')
  2. const magic = 1000 // Multiply cosine similary by this
  3. const not_important = '120'
  4. const somewhat_important = '140'
  5. const important = '160'
  6. const very_important = '180'
  7. const extremely_important = '200'
  8. const mandatory = '400'
  9. // -
  10. // 1440 - 2400 total range
  11. // 1440 - 1900 limited range
  12. // -
  13. // Reserved for REALLY important answers
  14. // like full-time vs part-time
  15. // and remote vs onsite only
  16. // 400 mandatory
  17. const importance = [
  18. not_important,
  19. somewhat_important,
  20. important,
  21. very_important,
  22. extremely_important,
  23. ]
  24. const langs = [
  25. 'javascript',
  26. 'python',
  27. 'ruby',
  28. 'erlang',
  29. 'haskall',
  30. 'php',
  31. 'swift',
  32. 'rust',
  33. 'objective-c',
  34. 'common lisp',
  35. 'java',
  36. 'perl',
  37. 'cobol',
  38. 'fortran',
  39. 'julia',
  40. 'c#',
  41. 'go',
  42. 'c++',
  43. ]
  44. const duration = ['full', 'part']
  45. const location = ['onsite', 'remote', 'flexible']
  46. const otherWeightLookup = {
  47. full: mandatory,
  48. part: mandatory,
  49. onsite: mandatory,
  50. remote: mandatory,
  51. flexible: mandatory,
  52. }
  53. const rand = max => {
  54. return Math.floor(Math.random() * max) < 1
  55. ? 1
  56. : Math.floor(Math.random() * max)
  57. }
  58. class DummyProfile {
  59. constructor() {
  60. this.id = null
  61. this.profileResponses = null
  62. this.langPref = null
  63. this.durationPref = null
  64. this.locationPref = null
  65. // profile is constructed of 12 answers, 2 for each dimension
  66. this.profileResponses = this.getRandomAnswers(12, importance)
  67. this.langPref = this.getRandomAnswers(rand(4), langs)
  68. this.durationPref = this.getRandomAnswers(1, duration)
  69. this.locationPref = this.getRandomAnswers(1, location)
  70. }
  71. getRandomAnswers(count, options) {
  72. const answers = []
  73. for (let i = 0; i < count; i++) {
  74. const random = rand(options.length)
  75. answers.push(options[random])
  76. }
  77. return answers
  78. }
  79. }
  80. const generateDummyProfiles = count => {
  81. const profiles = []
  82. for (let i = 0; i < count; i++) {
  83. const dummyProfile = new DummyProfile()
  84. dummyProfile.id = i + 1
  85. profiles.push(dummyProfile)
  86. }
  87. profiles.forEach(dummy => {
  88. dummy.profileResponses = dummy.profileResponses.map(
  89. (answer, response_key_id) => {
  90. const answerObj = {}
  91. // aka: id for the question we asked
  92. answerObj[response_key_id] = answer
  93. return answerObj
  94. },
  95. )
  96. })
  97. return profiles
  98. }
  99. const generatedSeekers = generateDummyProfiles(100)
  100. const generatedProviders = generateDummyProfiles(10)
  101. const scoreMatch = (seeker, potentialMatch) => {
  102. const seekerResponseValues = seeker.profileResponses.map(res =>
  103. parseInt(Object.values(res)),
  104. )
  105. const potentialMatchResponseValues = potentialMatch.profileResponses.map(
  106. res => parseInt(Object.values(res)),
  107. )
  108. return Math.floor(
  109. similarity(seekerResponseValues, potentialMatchResponseValues) * magic,
  110. )
  111. }
  112. const compareProfile = (seeker, unorderedPotentialMatches) => {
  113. const scored = unorderedPotentialMatches.map(potentialMatch => {
  114. // add the match to object keyed by score
  115. return {
  116. profileMatchScore: scoreMatch(seeker, potentialMatch),
  117. profile: potentialMatch,
  118. }
  119. })
  120. // return ordered by score
  121. return scored.sort((a, b) => a.profileMatchScore - b.profileMatchScore)
  122. }
  123. generatedSeekers.forEach(seeker => {
  124. const matchQueue = compareProfile(seeker, generatedProviders).map(
  125. provider => ({
  126. score: provider.profileMatchScore,
  127. profile_id: provider.profile.id,
  128. }),
  129. )
  130. console.log(`\n---| Results for job_seeker: ${seeker.id} |---`)
  131. console.log(matchQueue)
  132. })