Skip to content

Commit

Permalink
Merge pull request #342 from softeerbootcamp-2nd/feat/recommend
Browse files Browse the repository at this point in the history
추천 알고리즘 구현 및 flask 웹서버로 http통신 구현
  • Loading branch information
dydwo0740 authored Aug 20, 2023
2 parents 69ade4c + 9b78589 commit ee012c0
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 1 deletion.
12 changes: 12 additions & 0 deletions backend-recommend/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from flask import Flask, request
import recommend

app = Flask(__name__)

@app.route('/recommend/apriori', methods=['POST'])
def apriori():
data = request.get_json()
return recommend.recByApriori(data)

if __name__ == '__main__':
app.run(port=5001, debug=True)
63 changes: 63 additions & 0 deletions backend-recommend/recommend.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import pandas as pd
from mlxtend.preprocessing import TransactionEncoder
from mlxtend.frequent_patterns import apriori, fpgrowth
from mlxtend.frequent_patterns import association_rules
import pymysql
import time
import os
from dotenv import load_dotenv

load_dotenv(verbose=True)

conn = pymysql.connect(host=os.getenv('host'), user=os.getenv('user'), password=os.getenv('password'), db=os.getenv('db'))
cur = conn.cursor()

def recByApriori(body):
start = time.time()
carId = int(body['carId'])
powerTrainId = int(body['powerTrain'])
bodyTypeId = int(body['bodyType'])
operationId = int(body['operation'])

input = []

optionList = body['options']

for i in range(len(optionList)):
input.append(optionList[i]['subOptionId'])

input = set(input)
dataset = []
cur.execute('SELECT hm.history_id, sh.sold_count, sh.sold_options_id FROM SalesHistory sh INNER JOIN HistoryModelMapper hm ON sh.history_id = hm.history_id WHERE sh.car_id = %s AND hm.model_id IN (%s, %s, %s) GROUP BY hm.history_id HAVING COUNT(DISTINCT hm.model_id) = 3;', (carId, powerTrainId, bodyTypeId, operationId))
dbRow = cur.fetchall()
for j in range(len(dbRow)):
oneRow = dbRow[j][2]
if(oneRow == ''):
continue
options = oneRow.split(",")
for i in range(int(dbRow[j][1])):
dataset.append(options)

start = time.time()
te = TransactionEncoder()
te_ary = te.fit(dataset).transform(dataset)
df = pd.DataFrame(te_ary, columns=te.columns_)
frequent_itemsets = fpgrowth(df, min_support=0.05, use_colnames=True)

result_itemsets = association_rules(frequent_itemsets, metric="confidence", min_threshold=0.05)
matching_itemsets = {}

consequent_results = set()

for idx, row in result_itemsets.iterrows():
confidence = row.confidence

if set(row.antecedents).issubset(input) and len(row.consequents) <= 2 and not set(row.antecedents).union(set(row.consequents)).issubset(input):
key = tuple(row.consequents)
if key not in matching_itemsets or confidence > matching_itemsets[key]:
matching_itemsets[key] = confidence

sorted_items = sorted(matching_itemsets.items(), key=lambda x: x[1], reverse=True)
top_items = sorted_items[:4]
top_consequents = [consequent for consequent, _ in top_items]
return top_consequents
1 change: 1 addition & 0 deletions backend-recommend/templates/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Invalid Access
1 change: 1 addition & 0 deletions backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ dependencies {
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation group: 'com.h2database', name: 'h2', version: '2.2.220'
implementation 'org.springdoc:springdoc-openapi-ui:1.6.9'
implementation group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1'

}

Expand Down
2 changes: 1 addition & 1 deletion backend/src/main/java/autoever2/cartag/OpenApiConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class OpenApiConfig {
public OpenAPI openAPI() {
Info info = new Info()
.version("v1.0.0")
.title("API 타이틀")
.title("A2-CARTAG API 명세서")
.description("API Description");

return new OpenAPI()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package autoever2.cartag.controller;

import autoever2.cartag.service.RecommendService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/recommend")
@RequiredArgsConstructor
public class RecommendController {

private final RecommendService recommendService;

@PostMapping("/list")
public String getRecommendedList() {
return recommendService.getList();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package autoever2.cartag.service;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

@Service
public class RecommendService {

@Value("${python.url")
private String requestURL;

//TODO: 응답 존재 안할 시 예외처리
public String getList() {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(requestURL))
.POST(HttpRequest.BodyPublishers.ofString(getJsonFromEstimate())).build();

try {
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
String body = response.body();
return body;
} catch (Exception e) {
e.getMessage();
}

return null;
}

public String getJsonFromEstimate() {
JSONObject jsonObject = new JSONObject();
jsonObject.put("carId", 1);
jsonObject.put("powerTrain", 1);
jsonObject.put("bodyType", 3);
jsonObject.put("operation", 5);

JSONArray jsonArray = new JSONArray();
JSONObject subOption = new JSONObject();
subOption.put("subOptionId", 69);
jsonArray.add(subOption);
subOption.put("subOptionId", 70);
jsonArray.add(subOption);

jsonObject.put("options", jsonArray);


return jsonObject.toJSONString();
}
}

0 comments on commit ee012c0

Please sign in to comment.