Skip to content

Commit

Permalink
updated address evaluation
Browse files Browse the repository at this point in the history
  • Loading branch information
kristianeboe committed Apr 8, 2018
1 parent d2e032a commit c94bcbf
Show file tree
Hide file tree
Showing 17 changed files with 4,890 additions and 58 deletions.
4,619 changes: 4,619 additions & 0 deletions functions/cloud-functions-emulator.log

Large diffs are not rendered by default.

44 changes: 43 additions & 1 deletion functions/clusteringAlgorithms/clusteringPipeline.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,43 @@ function calculateFlatScore(flatmates) {
return Math.floor(flatScore)
}

function createGroupPropertyVector(flatmates) {
const groupVector = []
const propertyVectors = flatmates.map(mate => mate.propertyVector)
for (let i = 0; i < propertyVectors[0].length; i += 1) {
let sum = 0
for (let j = 0; j < flatmates.length; j += 1) {
sum += propertyVectors[j][i]
}
groupVector.push(sum / propertyVectors.length)
}
return groupVector
}

function mapPropScoreToPercentage(propScore) {
return Math.floor((1 - (propScore / 48)) * 100)
}

function calculatePropertyAlignment(flatmates) {
const propScores = []
for (let i = 0; i < flatmates.length; i += 1) {
const mate1 = flatmates[i]
for (let j = 0; j < flatmates.length; j += 1) {
const mate2 = flatmates[j]
if (i !== j) {
const propScore = euclidianDistanceSquared(mate1.propertyVector, mate2.propertyVector)
propScores.push(mapPropScoreToPercentage(propScore))
}
}
}

let propertyAlignment = 100
if (propScores.length > 1) {
propertyAlignment = propScores.reduce((a, b) => a + b, 0) / propScores.length
}
return Math.floor(propertyAlignment)
}

function chunckArray(array, cSize) {
const chunkArray = []
for (let index = 0; index < array.length; index += cSize) {
Expand Down Expand Up @@ -165,6 +202,8 @@ function matchAllAvailableUsers(userUid) {
const matchArray = []
return Promise.all(allFlatmates.map((flatmates) => {
const flatScore = calculateFlatScore(flatmates)
const propertyAlignment = calculatePropertyAlignment(flatmates)
const groupPropertyVector = createGroupPropertyVector(flatmates)

const matchUid = uuid.v4()
const match = {
Expand All @@ -173,6 +212,8 @@ function matchAllAvailableUsers(userUid) {
location: 'Oslo', // remember to change this in the future
bestOrigin: '',
flatScore,
propertyAlignment,
groupPropertyVector,
custom: false,
createdAt: admin.firestore.FieldValue.serverTimestamp()
}
Expand All @@ -188,7 +229,7 @@ function matchAllAvailableUsers(userUid) {
return matchRef
.set(match)
.then(() => {
initChatRoom(matchRef)
// initChatRoom(matchRef)
}).then(() => {
match.flatmates.forEach((mate) => {
let collectionName = 'testUsers'
Expand Down Expand Up @@ -224,3 +265,4 @@ module.exports.createFlatmatesFromClusters = createFlatmatesFromClusters
module.exports.matchAllAvailableUsers = matchAllAvailableUsers
module.exports.calculateFlatScore = calculateFlatScore
module.exports.calculateSimilarityScoreBetweenUsers = calculateSimilarityScoreBetweenUsers
module.exports.createGroupPropertyVector = createGroupPropertyVector
41 changes: 41 additions & 0 deletions functions/firebase-debug.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
[debug] [2018-04-08T12:18:57.017Z] ----------------------------------------------------------------------
[debug] [2018-04-08T12:18:57.020Z] Command: /usr/local/Cellar/node/9.11.1/bin/node /usr/local/bin/firebase functions:shell
[debug] [2018-04-08T12:18:57.020Z] CLI Version: 3.18.1
[debug] [2018-04-08T12:18:57.020Z] Platform: darwin
[debug] [2018-04-08T12:18:57.020Z] Node Version: v9.11.1
[debug] [2018-04-08T12:18:57.021Z] Time: Sun Apr 08 2018 14:18:57 GMT+0200 (CEST)
[debug] [2018-04-08T12:18:57.021Z] ----------------------------------------------------------------------
[debug]
[debug] [2018-04-08T12:18:57.048Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
[debug] [2018-04-08T12:18:57.048Z] > authorizing via signed-in user
[debug] [2018-04-08T12:18:57.051Z] >>> HTTP REQUEST GET https://admin.firebase.com/v1/projects/yaps-1496498804190

Sun Apr 08 2018 14:18:57 GMT+0200 (CEST)
[debug] [2018-04-08T12:18:57.789Z] <<< HTTP RESPONSE 200
[debug] [2018-04-08T12:18:57.790Z] >>> HTTP REQUEST GET https://admin.firebase.com/v1/database/yaps-1496498804190/tokens

Sun Apr 08 2018 14:18:57 GMT+0200 (CEST)
[debug] [2018-04-08T12:18:58.461Z] <<< HTTP RESPONSE 200
[info] i functions: Preparing to emulate functions.
[debug] [2018-04-08T12:18:59.064Z] Fetching environment
[debug] [2018-04-08T12:18:59.065Z] >>> HTTP REQUEST GET https://cloudresourcemanager.googleapis.com/v1/projects/yaps-1496498804190

Sun Apr 08 2018 14:18:59 GMT+0200 (CEST)
[debug] [2018-04-08T12:19:00.089Z] <<< HTTP RESPONSE 200
[debug] [2018-04-08T12:19:00.090Z] >>> HTTP REQUEST GET https://mobilesdk-pa.googleapis.com/v1/projects/569081698642:getServerAppConfig

Sun Apr 08 2018 14:19:00 GMT+0200 (CEST)
[debug] [2018-04-08T12:19:00.713Z] <<< HTTP RESPONSE 200
[debug] [2018-04-08T12:19:00.713Z] Starting @google-cloud/functions-emulator
[debug] [2018-04-08T12:19:02.283Z] Parsing function triggers
[info] ✔ functions: deleteTestUsers
[info] ✔ functions: populateDatabaseWithTestUsersHTTPS
[info] ✔ functions: updateUser
[info] ✔ functions: countTestUsers
[info] ✔ functions: setTestUsersReadyToMatch
[info] ✔ functions: resetDatabase
[info] ✔ functions: aggregateMatchInfo
[info] ✔ functions: getMatchedByCluster
[info] ✔ functions: getMatchedByClusterOnSave
[info] ✔ functions: getBestOriginHTTPforMatch
[info] ✔ functions: scoreApartment
12 changes: 6 additions & 6 deletions functions/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const functions = require('firebase-functions')
const admin = require('firebase-admin')
const cors = require('cors')({ origin: true })
const createUserData = require('./utils/createUserData')
const createTestData = require('./utils/createTestData')
const clusteringPipeline = require('./clusteringAlgorithms/clusteringPipeline')
const locationAlgorithms = require('./location/locationAlgorithms')
const { deleteMatchClusterCollection } = require('./utils/dbCleanupFunctions')
Expand All @@ -15,7 +15,7 @@ exports.populateDatabaseWithTestUsersHTTPS = functions.https.onRequest((req, res
if (!nrOfTestUsers) {
nrOfTestUsers = 50
}
const testUsers = createUserData.createTestUsers(nrOfTestUsers)
const testUsers = createTestData.createTestUsers(nrOfTestUsers)

Promise.all(testUsers.map(testUser =>
admin
Expand Down Expand Up @@ -177,7 +177,7 @@ exports.getMatchedByClusterOnSave = functions.https.onRequest((req, res) => {
}

cors(req, res, () => {
const testUsers = createUserData.createTestUsers(50)
const testUsers = createTestData.createTestUsers(50)
Promise.all(testUsers.map(testUser =>
admin
.firestore()
Expand All @@ -198,7 +198,7 @@ exports.getMatchedByClusterOnSave = functions.https.onRequest((req, res) => {
})


exports.onMatchCreate = functions.firestore
/* exports.onMatchCreate = functions.firestore
.document('matches/{matchId}')
// .onCreate((snap, context) => {
.onCreate((event) => {
Expand All @@ -215,7 +215,7 @@ exports.onMatchCreate = functions.firestore
}
return locationAlgorithms.getBestOriginForMatch(match)
})
}) */

exports.getBestOriginHTTPforMatch = functions.https.onRequest((req, res) => {
cors(req, res, () => {
Expand All @@ -242,7 +242,7 @@ exports.scoreApartment = functions.https.onRequest((req, res) => {
if (!address || !flatmates) {
res.status(400).end()
}
const origins = [address]
const origins = [encodeURI(address)]
locationAlgorithms.getOriginsToDestinationsObject(
origins,
flatmates
Expand Down
14 changes: 7 additions & 7 deletions functions/tests/clustering.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@
const uuid = require('uuid')
const knnClustering = require('../clusteringAlgorithms/knnClustering')
const kMeansClustering = require('../clusteringAlgorithms/kMeansClustering')
const createUserData = require('../utils/createUserData')
const createTestData = require('../utils/createTestData')
const { createFlatmatesFromClusters, calculateFlatScore, calculateSimilarityScoreBetweenUsers } = require('../clusteringAlgorithms/clusteringPipeline')
const { extractVectorsFromUsers } = require('../utils/vectorFunctions')

test('Create test users', () => {
const testUsers = createUserData.createTestUsers(200)
const testUsers = createTestData.createTestUsers(200)
expect(testUsers.length).toBe(200)
})


test('User similarity', () => {
const { me, antiKristianUser } = createUserData
const { me, antiKristianUser } = createTestData
const neg = { answerVector: Array(20).fill(-2) }
const pos = { answerVector: Array(20).fill(2) }
const almostPos = { answerVector: Array(20).fill(1) }
Expand Down Expand Up @@ -47,7 +47,7 @@ test('User similarity', () => {


/* test('Extract vector from user', () => {
const testUsers = createUserData.createTestUsers(1)
const testUsers = createTestData.createTestUsers(1)
const vectorsNormalized = extractVectorsFromUsers(testUsers, true)
expect(vectorsNormalized.length).toBe(1)
const vectorNormalized = vectorsNormalized[0]
Expand All @@ -68,7 +68,7 @@ test('User similarity', () => {

test('Clusters vectors with kNN', () => {
// Create test users
const testUsers = createUserData.createTestUsers(500)
const testUsers = createTestData.createTestUsers(500)
expect(testUsers.length).toBe(500)
// extract question vectors
const vectors = extractVectorsFromUsers(testUsers, false)
Expand Down Expand Up @@ -108,12 +108,12 @@ test('Clusters vectors with kNN', () => {
})
averageMatchScore /= matchArray.length
console.log(averageMatchScore)
expect(averageMatchScore).toBeGreaterThan(75)
expect(averageMatchScore).toBeGreaterThan(70)
})


test('Clusters with kMeans', () => {
const testUsers = createUserData.createTestUsers(500)
const testUsers = createTestData.createTestUsers(500)
const vectors = extractVectorsFromUsers(testUsers, false)
kMeansClustering(vectors, false).then((clusters) => {
expect(clusters.length).toBe(5)
Expand Down
13 changes: 13 additions & 0 deletions functions/tests/propertyRecommendations.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

/**
* @jest-environment node
*/


const { createGroupPropertyVector } = require('../clusteringAlgorithms/clusteringPipeline')

test('GroupPropertyVector', () => {
const flatmates = [{ propertyVector: [3, 3, 3] }, { propertyVector: [1, 3, 5] }, { propertyVector: [3, 5, 3] }, { propertyVector: [3, 3, 3] }]
const groupPropertyVector = createGroupPropertyVector(flatmates)
expect(groupPropertyVector).toEqual([10 / 4, 14 / 4, 14 / 4])
})
6 changes: 3 additions & 3 deletions functions/utils/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,9 @@ const STUDY_PROGRAMMES = {
}
const GENDERS = ['Gutt', 'Jente']

const BUDGETS = [1, 2, 3]
const PROPERTY_SIZES = [1, 2, 3]
const NEWNESS = [1, 2, 3]
const BUDGETS = [1, 3, 5]
const PROPERTY_SIZES = [1, 3, 5]
const NEWNESS = [1, 3, 5]

module.exports.BUDGETS = BUDGETS
module.exports.PROPERTY_SIZES = PROPERTY_SIZES
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,21 @@ function createTestUsers(n) {
const workplaceKey = Math.floor(Math.random() * Math.floor(Object.keys(WORKPLACES).length))
const workplace = Object.keys(WORKPLACES)[workplaceKey]
const workplaceLatLng = WORKPLACES[workplace]
const budget = BUDGETS[Math.floor(Math.random() * BUDGETS.length)]
const propertySize = PROPERTY_SIZES[Math.floor(Math.random() * PROPERTY_SIZES.length)]
const newness = NEWNESS[Math.floor(Math.random() * NEWNESS.length)]
const propertyVector = [budget, propertySize, newness]
const user = {
uid: uuid.v4(),
displayName: `testUser${index}`,
matchLocation: 'Oslo',
seeNewUsers: false,
workplace,
propertyVector,
workplaceLatLng,
photoURL: `https://placem.at/people?w=290&h=290&random=${getRandomInt(100)}`,
university,
budget: BUDGETS[Math.floor(Math.random() * BUDGETS.length)],
propertySize: PROPERTY_SIZES[Math.floor(Math.random() * PROPERTY_SIZES.length)],
newness: NEWNESS[Math.floor(Math.random() * NEWNESS.length)],

age: Math.floor(Math.random() * 10) + 20,
tos: true,
readyToMatch: true,
Expand All @@ -53,6 +56,30 @@ function createTestUsers(n) {
}
return users
}

function createTestProperties(n) {
const properties = []

for (let index = 0; index < n; index += 1) {
const budget = BUDGETS[Math.floor(Math.random() * BUDGETS.length)]
const propertySize = PROPERTY_SIZES[Math.floor(Math.random() * PROPERTY_SIZES.length)]
const newness = NEWNESS[Math.floor(Math.random() * NEWNESS.length)]
const propertyVector = [budget, propertySize, newness]
const property = {
uid: uuid.v4(),
location: 'Oslo',
address: '',
budget,
propertySize,
newness,
propertyVector
}
properties.push(property)
}
return properties
}


const me = {
age: '25',
currentMatchId: 'f9345ee3-58c2-4f91-a3c7-331554b7c88f',
Expand Down Expand Up @@ -86,3 +113,4 @@ module.exports.me = me
module.exports.antiKristianUser = antiKristianUser
module.exports.kristianVector = kristianVector
module.exports.antiKristianVector = antiKristianVector
module.exports.createTestProperties = createTestProperties
Empty file.
4 changes: 2 additions & 2 deletions functions/utils/vectorFunctions.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ function normalize(vector) {
}
function extractVectorsFromUsers(users, normalizeVectors) {
const userVectors = []

users.forEach((user) => {
userVectors.push(normalizeVectors ? normalize(user.answerVector) : user.answerVector)
const enhancedPropVector = user.propertyVector.map(el => el * 5)
userVectors.push(normalizeVectors ? normalize(user.answerVector) : user.answerVector.concat(enhancedPropVector))
})

return userVectors
Expand Down
Loading

0 comments on commit c94bcbf

Please sign in to comment.