├── images ├── Capture.png ├── Process.png ├── Topology.png ├── DTO-Diagram.png ├── GitHub-Mark.png ├── ML-Diagram.png ├── Twitter_Icon.png ├── Vaadin-Diagram.png └── Service-Diagram.png ├── income-predictor-dto ├── src │ └── main │ │ └── java │ │ └── oscuroweb │ │ └── ia │ │ ├── type │ │ ├── IncomeType.java │ │ ├── SexType.java │ │ ├── RaceType.java │ │ ├── RelationshipType.java │ │ ├── WorkClassType.java │ │ ├── MaritalStatusType.java │ │ ├── OccupationType.java │ │ ├── EducationType.java │ │ └── NativeCountryType.java │ │ └── dto │ │ ├── ComboDto.java │ │ ├── ComboEducationDto.java │ │ ├── OutputResultDto.java │ │ ├── OutputDto.java │ │ ├── Column.java │ │ ├── IncomeDto.java │ │ └── IncomeResultDto.java ├── .settings │ ├── org.eclipse.m2e.core.prefs │ └── org.eclipse.jdt.core.prefs ├── target │ ├── classes │ │ ├── META-INF │ │ │ ├── MANIFEST.MF │ │ │ └── maven │ │ │ │ └── oscuroweb.ia │ │ │ │ └── income-predictor-dto │ │ │ │ ├── pom.properties │ │ │ │ └── pom.xml │ │ └── oscuroweb │ │ │ └── ia │ │ │ └── dto │ │ │ ├── Column.class │ │ │ ├── ComboDto.class │ │ │ ├── OutputDto.class │ │ │ ├── OutputResultDto.class │ │ │ ├── ComboEducationDto.class │ │ │ ├── ComboDto$ComboDtoBuilder.class │ │ │ ├── OutputDto$OutputDtoBuilder.class │ │ │ ├── OutputResultDto$OutputResultDtoBuilder.class │ │ │ └── ComboEducationDto$ComboEducationDtoBuilder.class │ ├── income-predictor-dto-0.0.1-SNAPSHOT.jar │ ├── maven-archiver │ │ └── pom.properties │ └── maven-status │ │ └── maven-compiler-plugin │ │ └── compile │ │ └── default-compile │ │ ├── createdFiles.lst │ │ └── inputFiles.lst ├── .project ├── pom.xml └── .classpath ├── income-predictor-vaadin ├── src │ ├── main │ │ ├── resources │ │ │ └── application.properties │ │ ├── webapp │ │ │ └── VAADIN │ │ │ │ └── themes │ │ │ │ └── income │ │ │ │ ├── styles.scss │ │ │ │ ├── favicon.ico │ │ │ │ ├── images │ │ │ │ ├── UMA_logo.png │ │ │ │ ├── logoA2BD.png │ │ │ │ ├── logo_osc.png │ │ │ │ ├── siuss_logo.png │ │ │ │ ├── master_banner.png │ │ │ │ └── logo-white.svg │ │ │ │ ├── addons.scss │ │ │ │ └── income.scss │ │ └── java │ │ │ └── oscuroweb │ │ │ └── ia │ │ │ ├── config │ │ │ └── AppConfiguration.java │ │ │ ├── IncomePredictorVaadinApplication.java │ │ │ ├── screen │ │ │ ├── IndexScreen.java │ │ │ ├── AbstractIncomeView.java │ │ │ └── IncomeInputScreen.java │ │ │ ├── converter │ │ │ ├── SexTypeConverter.java │ │ │ ├── RaceTypeConverter.java │ │ │ ├── EducationTypeConverter.java │ │ │ ├── WorkClassTypeConverter.java │ │ │ ├── OccupationTypeConverter.java │ │ │ ├── RelationshipTypeConverter.java │ │ │ ├── MaritalStatusTypeConverter.java │ │ │ └── NativeCountryTypeConverter.java │ │ │ ├── rest │ │ │ └── RestClient.java │ │ │ ├── component │ │ │ ├── Header.java │ │ │ └── Footer.java │ │ │ └── ui │ │ │ └── MainUI.java │ └── test │ │ └── java │ │ └── oscuroweb │ │ └── ia │ │ └── IncomePredictorVaadinApplicationTests.java ├── pom.xml ├── mvnw.cmd └── mvnw ├── income-predictor-ml ├── src │ ├── main │ │ ├── java │ │ │ └── oscuroweb │ │ │ │ └── ia │ │ │ │ ├── service │ │ │ │ ├── SparkService.java │ │ │ │ └── impl │ │ │ │ │ └── SparkServiceImpl.java │ │ │ │ ├── IncomePredictorMLServiceApplication.java │ │ │ │ ├── controller │ │ │ │ └── MLController.java │ │ │ │ └── config │ │ │ │ └── ApplicationConfig.java │ │ └── resources │ │ │ └── application.properties │ └── test │ │ └── java │ │ └── oscuroweb │ │ └── ia │ │ └── IncomePredictorServiceApplicationTests.java └── pom.xml ├── income-predictor-service ├── src │ ├── main │ │ ├── java │ │ │ └── oscuroweb │ │ │ │ └── ia │ │ │ │ ├── service │ │ │ │ ├── SparkService.java │ │ │ │ └── impl │ │ │ │ │ └── SparkServiceImpl.java │ │ │ │ ├── IncomePredictorServiceApplication.java │ │ │ │ ├── controller │ │ │ │ └── ServicesController.java │ │ │ │ └── config │ │ │ │ └── ApplicationConfig.java │ │ └── resources │ │ │ └── application.properties │ └── test │ │ └── java │ │ └── oscuroweb │ │ └── ia │ │ └── IncomePredictorServiceApplicationTests.java ├── pom.xml ├── mvnw.cmd └── mvnw ├── .gitignore └── README.md /images/Capture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscuroweb/microservices-ml/HEAD/images/Capture.png -------------------------------------------------------------------------------- /images/Process.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscuroweb/microservices-ml/HEAD/images/Process.png -------------------------------------------------------------------------------- /images/Topology.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscuroweb/microservices-ml/HEAD/images/Topology.png -------------------------------------------------------------------------------- /images/DTO-Diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscuroweb/microservices-ml/HEAD/images/DTO-Diagram.png -------------------------------------------------------------------------------- /images/GitHub-Mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscuroweb/microservices-ml/HEAD/images/GitHub-Mark.png -------------------------------------------------------------------------------- /images/ML-Diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscuroweb/microservices-ml/HEAD/images/ML-Diagram.png -------------------------------------------------------------------------------- /images/Twitter_Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscuroweb/microservices-ml/HEAD/images/Twitter_Icon.png -------------------------------------------------------------------------------- /images/Vaadin-Diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscuroweb/microservices-ml/HEAD/images/Vaadin-Diagram.png -------------------------------------------------------------------------------- /images/Service-Diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscuroweb/microservices-ml/HEAD/images/Service-Diagram.png -------------------------------------------------------------------------------- /income-predictor-dto/src/main/java/oscuroweb/ia/type/IncomeType.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.type; 2 | 3 | public interface IncomeType { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /income-predictor-dto/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /income-predictor-dto/target/classes/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Built-By: oscuro 3 | Build-Jdk: 1.8.0_25 4 | Created-By: Maven Integration for Eclipse 5 | 6 | -------------------------------------------------------------------------------- /income-predictor-dto/target/classes/oscuroweb/ia/dto/Column.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscuroweb/microservices-ml/HEAD/income-predictor-dto/target/classes/oscuroweb/ia/dto/Column.class -------------------------------------------------------------------------------- /income-predictor-vaadin/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=8080 2 | endpoint.evaluate=http://localhost:8082/evaluate 3 | endpoint.addResult=http://localhost:8082/addResult -------------------------------------------------------------------------------- /income-predictor-dto/target/classes/oscuroweb/ia/dto/ComboDto.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscuroweb/microservices-ml/HEAD/income-predictor-dto/target/classes/oscuroweb/ia/dto/ComboDto.class -------------------------------------------------------------------------------- /income-predictor-dto/target/classes/oscuroweb/ia/dto/OutputDto.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscuroweb/microservices-ml/HEAD/income-predictor-dto/target/classes/oscuroweb/ia/dto/OutputDto.class -------------------------------------------------------------------------------- /income-predictor-dto/target/income-predictor-dto-0.0.1-SNAPSHOT.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscuroweb/microservices-ml/HEAD/income-predictor-dto/target/income-predictor-dto-0.0.1-SNAPSHOT.jar -------------------------------------------------------------------------------- /income-predictor-vaadin/src/main/webapp/VAADIN/themes/income/styles.scss: -------------------------------------------------------------------------------- 1 | @import "addons.scss"; 2 | @import "income.scss"; 3 | 4 | .income { 5 | @include addons; 6 | @include income; 7 | } 8 | 9 | -------------------------------------------------------------------------------- /income-predictor-dto/target/maven-archiver/pom.properties: -------------------------------------------------------------------------------- 1 | #Generated by Maven 2 | #Sat Jan 20 13:22:13 CET 2018 3 | version=0.0.1-SNAPSHOT 4 | groupId=com.accenture.ia 5 | artifactId=income-predictor-dto 6 | -------------------------------------------------------------------------------- /income-predictor-vaadin/src/main/webapp/VAADIN/themes/income/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscuroweb/microservices-ml/HEAD/income-predictor-vaadin/src/main/webapp/VAADIN/themes/income/favicon.ico -------------------------------------------------------------------------------- /income-predictor-dto/target/classes/oscuroweb/ia/dto/OutputResultDto.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscuroweb/microservices-ml/HEAD/income-predictor-dto/target/classes/oscuroweb/ia/dto/OutputResultDto.class -------------------------------------------------------------------------------- /income-predictor-dto/target/classes/oscuroweb/ia/dto/ComboEducationDto.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscuroweb/microservices-ml/HEAD/income-predictor-dto/target/classes/oscuroweb/ia/dto/ComboEducationDto.class -------------------------------------------------------------------------------- /income-predictor-vaadin/src/main/webapp/VAADIN/themes/income/images/UMA_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscuroweb/microservices-ml/HEAD/income-predictor-vaadin/src/main/webapp/VAADIN/themes/income/images/UMA_logo.png -------------------------------------------------------------------------------- /income-predictor-vaadin/src/main/webapp/VAADIN/themes/income/images/logoA2BD.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscuroweb/microservices-ml/HEAD/income-predictor-vaadin/src/main/webapp/VAADIN/themes/income/images/logoA2BD.png -------------------------------------------------------------------------------- /income-predictor-vaadin/src/main/webapp/VAADIN/themes/income/images/logo_osc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscuroweb/microservices-ml/HEAD/income-predictor-vaadin/src/main/webapp/VAADIN/themes/income/images/logo_osc.png -------------------------------------------------------------------------------- /income-predictor-dto/target/classes/oscuroweb/ia/dto/ComboDto$ComboDtoBuilder.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscuroweb/microservices-ml/HEAD/income-predictor-dto/target/classes/oscuroweb/ia/dto/ComboDto$ComboDtoBuilder.class -------------------------------------------------------------------------------- /income-predictor-vaadin/src/main/webapp/VAADIN/themes/income/images/siuss_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscuroweb/microservices-ml/HEAD/income-predictor-vaadin/src/main/webapp/VAADIN/themes/income/images/siuss_logo.png -------------------------------------------------------------------------------- /income-predictor-dto/target/classes/oscuroweb/ia/dto/OutputDto$OutputDtoBuilder.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscuroweb/microservices-ml/HEAD/income-predictor-dto/target/classes/oscuroweb/ia/dto/OutputDto$OutputDtoBuilder.class -------------------------------------------------------------------------------- /income-predictor-vaadin/src/main/webapp/VAADIN/themes/income/images/master_banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscuroweb/microservices-ml/HEAD/income-predictor-vaadin/src/main/webapp/VAADIN/themes/income/images/master_banner.png -------------------------------------------------------------------------------- /income-predictor-dto/target/classes/oscuroweb/ia/dto/OutputResultDto$OutputResultDtoBuilder.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscuroweb/microservices-ml/HEAD/income-predictor-dto/target/classes/oscuroweb/ia/dto/OutputResultDto$OutputResultDtoBuilder.class -------------------------------------------------------------------------------- /income-predictor-dto/target/classes/oscuroweb/ia/dto/ComboEducationDto$ComboEducationDtoBuilder.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscuroweb/microservices-ml/HEAD/income-predictor-dto/target/classes/oscuroweb/ia/dto/ComboEducationDto$ComboEducationDtoBuilder.class -------------------------------------------------------------------------------- /income-predictor-ml/src/main/java/oscuroweb/ia/service/SparkService.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.service; 2 | 3 | import java.util.List; 4 | 5 | public interface SparkService { 6 | 7 | 8 | public void mlService(); 9 | public long getVersion(); 10 | public List getAvailableVersions(); 11 | } 12 | -------------------------------------------------------------------------------- /income-predictor-vaadin/src/main/webapp/VAADIN/themes/income/addons.scss: -------------------------------------------------------------------------------- 1 | /* This file is automatically managed and will be overwritten from time to time. */ 2 | /* Do not manually edit this file. */ 3 | 4 | /* Import and include this mixin into your project theme to include the addon themes */ 5 | @mixin addons { 6 | } 7 | 8 | -------------------------------------------------------------------------------- /income-predictor-dto/target/classes/META-INF/maven/oscuroweb.ia/income-predictor-dto/pom.properties: -------------------------------------------------------------------------------- 1 | #Generated by Maven Integration for Eclipse 2 | #Sat May 05 09:45:12 CEST 2018 3 | version=0.0.1-SNAPSHOT 4 | groupId=oscuroweb.ia 5 | m2e.projectName=income-predictor-dto 6 | m2e.projectLocation=/Users/oscuro/workspace/microservices-ml/income-predictor-dto 7 | artifactId=income-predictor-dto 8 | -------------------------------------------------------------------------------- /income-predictor-service/src/main/java/oscuroweb/ia/service/SparkService.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.service; 2 | 3 | import oscuroweb.ia.dto.IncomeDto; 4 | import oscuroweb.ia.dto.OutputDto; 5 | import oscuroweb.ia.dto.OutputResultDto; 6 | 7 | public interface SparkService { 8 | 9 | public OutputDto evaluate(IncomeDto input); 10 | public OutputResultDto addResult(IncomeDto input); 11 | } 12 | -------------------------------------------------------------------------------- /income-predictor-ml/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=8081 2 | app.name=adultIncome 3 | spark.home=/Users/oscuro/Applications/spark-2.1.1-bin-hadoop2.7 4 | master.uri=local 5 | 6 | models.path=/Users/oscuro/workspace/IAHackathon/models/ 7 | dataset.file=/Users/oscuro/workspace/IAHackathon/data/adult.data.csv 8 | 9 | # Uncomment line below if you want to activate model version support 10 | # models.versioned=true 11 | -------------------------------------------------------------------------------- /income-predictor-service/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | app.name=adultIncome 2 | server.port=8082 3 | spark.home=/Users/julio.palma.vazquez/ws-ml/spark-2.3.1-bin-hadoop2.7 4 | master.uri=local 5 | 6 | models.path=/Users/julio.palma.vazquez/ws-ml/models/ 7 | dataset.file=./adult.data.csv 8 | 9 | # Uncomment lines below if you want to activate model version support 10 | #models.versioned=true 11 | #ml.service=http://localhost:8081/version -------------------------------------------------------------------------------- /income-predictor-dto/src/main/java/oscuroweb/ia/dto/ComboDto.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.dto; 2 | 3 | import java.io.Serializable; 4 | 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | @Deprecated 11 | @Data 12 | @Builder 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | public class ComboDto implements Serializable { 16 | 17 | Integer id; 18 | String desc; 19 | } -------------------------------------------------------------------------------- /income-predictor-vaadin/src/main/java/oscuroweb/ia/config/AppConfiguration.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.web.client.RestTemplate; 6 | 7 | @Configuration 8 | public class AppConfiguration { 9 | 10 | @Bean 11 | public RestTemplate restTemplate() { 12 | return new RestTemplate(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /income-predictor-service/src/main/java/oscuroweb/ia/IncomePredictorServiceApplication.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class IncomePredictorServiceApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(IncomePredictorServiceApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /income-predictor-dto/src/main/java/oscuroweb/ia/dto/ComboEducationDto.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.dto; 2 | 3 | import java.io.Serializable; 4 | 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | @Deprecated 11 | @Data 12 | @Builder 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | public class ComboEducationDto implements Serializable { 16 | 17 | Integer id; 18 | String desc; 19 | Integer num; 20 | } -------------------------------------------------------------------------------- /income-predictor-dto/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 4 | org.eclipse.jdt.core.compiler.compliance=1.5 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 8 | org.eclipse.jdt.core.compiler.source=1.5 9 | -------------------------------------------------------------------------------- /income-predictor-dto/src/main/java/oscuroweb/ia/type/SexType.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.type; 2 | 3 | 4 | public enum SexType { 5 | 6 | FEMALE(1, "Female"), 7 | MALE(2, "Male"); 8 | 9 | private final int cod; 10 | 11 | private final String desc; 12 | 13 | private SexType(int cod, String desc) { 14 | this.cod = cod; 15 | this.desc = desc; 16 | } 17 | 18 | public int cod() { 19 | return cod; 20 | } 21 | 22 | public String desc() { 23 | return desc; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /income-predictor-ml/src/test/java/oscuroweb/ia/IncomePredictorServiceApplicationTests.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class IncomePredictorServiceApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /income-predictor-vaadin/src/test/java/oscuroweb/ia/IncomePredictorVaadinApplicationTests.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class IncomePredictorVaadinApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /income-predictor-service/src/test/java/oscuroweb/ia/IncomePredictorServiceApplicationTests.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class IncomePredictorServiceApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /income-predictor-vaadin/src/main/java/oscuroweb/ia/IncomePredictorVaadinApplication.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication(scanBasePackages="oscuroweb.ia") 7 | public class IncomePredictorVaadinApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(IncomePredictorVaadinApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /income-predictor-vaadin/src/main/java/oscuroweb/ia/screen/IndexScreen.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.screen; 2 | 3 | import com.vaadin.navigator.View; 4 | import com.vaadin.spring.annotation.SpringView; 5 | 6 | 7 | @SpringView(name = IndexScreen.VIEW_NAME) 8 | public class IndexScreen implements View { 9 | 10 | public static final String VIEW_NAME = "index"; 11 | 12 | private static final long serialVersionUID = 6092429507520923718L; 13 | 14 | public void initScreen() { 15 | 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /income-predictor-dto/src/main/java/oscuroweb/ia/dto/OutputResultDto.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.dto; 2 | 3 | import java.io.Serializable; 4 | 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | @Data 11 | @Builder 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | public class OutputResultDto implements Serializable { 15 | 16 | private static final long serialVersionUID = -593481387719299431L; 17 | 18 | private Boolean updated; 19 | } 20 | -------------------------------------------------------------------------------- /income-predictor-dto/src/main/java/oscuroweb/ia/dto/OutputDto.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.dto; 2 | 3 | import java.io.Serializable; 4 | 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | @Data 11 | @Builder 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | public class OutputDto implements Serializable { 15 | 16 | private static final long serialVersionUID = -6564165486219991295L; 17 | 18 | /** label: >50K, <=50K. */ 19 | private String label; 20 | } 21 | -------------------------------------------------------------------------------- /income-predictor-ml/src/main/java/oscuroweb/ia/IncomePredictorMLServiceApplication.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.scheduling.annotation.EnableScheduling; 6 | 7 | @EnableScheduling 8 | @SpringBootApplication 9 | public class IncomePredictorMLServiceApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(IncomePredictorMLServiceApplication.class, args); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /income-predictor-dto/src/main/java/oscuroweb/ia/type/RaceType.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.type; 2 | 3 | public enum RaceType { 4 | 5 | WHITE(1, "White"), 6 | ASIAN_PAC_ISLANDER(2, "Asian-Pac-Islander"), 7 | AMER_INDIAN_ESKIMO(3, "Amer-Indian-Eskimo"), 8 | BLACK(4, "Black"), 9 | OTHER(5, "Other"); 10 | 11 | private int cod; 12 | private String desc; 13 | 14 | private RaceType(int cod, String desc) { 15 | this.cod = cod; 16 | this.desc = desc; 17 | } 18 | 19 | public int cod() { 20 | return cod; 21 | } 22 | 23 | public String desc() { 24 | return desc; 25 | } 26 | 27 | 28 | } 29 | -------------------------------------------------------------------------------- /income-predictor-dto/src/main/java/oscuroweb/ia/type/RelationshipType.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.type; 2 | 3 | public enum RelationshipType { 4 | 5 | WIFE(1, "Wife"), 6 | OWN_CHILD(2, "Own-child"), 7 | HUSBAND(3, "Husband"), 8 | NOT_IN_FAMILY(4, "Not-in-family"), 9 | OTHER_RELATIVE(5, "Other-relative"), 10 | UNMARRIED(6, "Unmarried"); 11 | 12 | private int cod; 13 | private String desc; 14 | 15 | private RelationshipType(int cod, String desc) { 16 | this.cod = cod; 17 | this.desc = desc; 18 | } 19 | 20 | public int cod() { 21 | return cod; 22 | } 23 | 24 | public String desc() { 25 | return desc; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /income-predictor-dto/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | income-predictor-dto 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /income-predictor-dto/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | oscuroweb.ia 5 | income-predictor-dto 6 | 0.0.1-SNAPSHOT 7 | income-predictor-dto 8 | 9 | 10 | org.projectlombok 11 | lombok 12 | 1.16.20 13 | provided 14 | 15 | 16 | -------------------------------------------------------------------------------- /income-predictor-dto/src/main/java/oscuroweb/ia/type/WorkClassType.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.type; 2 | 3 | public enum WorkClassType { 4 | 5 | PRIVATE(1, "Private"), 6 | SELF_EMP_NOT_INC(2, "Self-emp-not-inc"), 7 | SELF_EMP_INC(3, "Self-emp-inc"), 8 | FEDERAL_GOV(4, "Federal-gov"), 9 | LOCAL_GOV(5, "Local-gov"), 10 | STATE_GOV(6, "State-gov"), 11 | WITHOUT_PAY(7, "Without-pay"), 12 | NEVER_WORKED(8, "Never-worked"); 13 | 14 | private int cod; 15 | private String desc; 16 | 17 | private WorkClassType(int cod, String desc) { 18 | this.cod = cod; 19 | this.desc = desc; 20 | } 21 | 22 | public int cod() { 23 | return cod; 24 | } 25 | 26 | public String desc() { 27 | return desc; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /income-predictor-dto/src/main/java/oscuroweb/ia/type/MaritalStatusType.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.type; 2 | 3 | public enum MaritalStatusType { 4 | 5 | MARRIED_CIV_SPOUSE(1, "Married-civ-spouse"), 6 | DIVORCED(2, "Divorced"), 7 | NEVER_MARRIED(3, "Never-married"), 8 | SEPARATED(4, "Separated"), 9 | WIDOWED(5, "Widowed"), 10 | MARRIED_SPOUSE_ABSENT(6, "Married-spouse-absent"), 11 | MARRIED_AF_SPOUSE(7, "Married-AF-spouse"); 12 | 13 | private int cod; 14 | private String desc; 15 | 16 | private MaritalStatusType(int cod, String desc) { 17 | this.cod = cod; 18 | this.desc = desc; 19 | } 20 | 21 | public int cod() { 22 | return cod; 23 | } 24 | 25 | public String desc() { 26 | return desc; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /income-predictor-dto/target/classes/META-INF/maven/oscuroweb.ia/income-predictor-dto/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | oscuroweb.ia 5 | income-predictor-dto 6 | 0.0.1-SNAPSHOT 7 | income-predictor-dto 8 | 9 | 10 | org.projectlombok 11 | lombok 12 | 1.16.20 13 | provided 14 | 15 | 16 | -------------------------------------------------------------------------------- /income-predictor-dto/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst: -------------------------------------------------------------------------------- 1 | com/accenture/ia/dto/OutputDto$OutputDtoBuilder.class 2 | com/accenture/ia/dto/InputResultDto.class 3 | com/accenture/ia/dto/OutputDto.class 4 | com/accenture/ia/dto/Column.class 5 | com/accenture/ia/dto/ComboEducationDto$ComboEducationDtoBuilder.class 6 | com/accenture/ia/dto/OutputResultDto.class 7 | com/accenture/ia/dto/InputDto$InputDtoBuilder.class 8 | com/accenture/ia/dto/InputDto.class 9 | com/accenture/ia/dto/ComboEducationDto.class 10 | com/accenture/ia/dto/OutputResultDto$OutputResultDtoBuilder.class 11 | com/accenture/ia/dto/InputResultDto$InputResultDtoBuilder.class 12 | com/accenture/ia/dto/ComboDto.class 13 | com/accenture/ia/dto/ComboDto$ComboDtoBuilder.class 14 | -------------------------------------------------------------------------------- /income-predictor-ml/src/main/java/oscuroweb/ia/controller/MLController.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.controller; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.PostMapping; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | import oscuroweb.ia.service.SparkService; 11 | 12 | @RestController 13 | public class MLController { 14 | 15 | @Autowired 16 | SparkService sparkService; 17 | 18 | @GetMapping("/version") 19 | public Long getVersion() { 20 | return sparkService.getVersion(); 21 | } 22 | 23 | @GetMapping("/allVersions") 24 | public List getAllVersions() { 25 | return sparkService.getAvailableVersions(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /income-predictor-vaadin/src/main/java/oscuroweb/ia/converter/SexTypeConverter.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.converter; 2 | 3 | import java.util.Arrays; 4 | 5 | import com.vaadin.data.Converter; 6 | import com.vaadin.data.Result; 7 | import com.vaadin.data.ValueContext; 8 | 9 | import oscuroweb.ia.type.SexType; 10 | 11 | public class SexTypeConverter implements Converter { 12 | 13 | private static final long serialVersionUID = 6917679106652542941L; 14 | 15 | 16 | @Override 17 | public Result convertToModel(SexType value, ValueContext context) { 18 | return Result.ok(value.desc()); 19 | } 20 | 21 | @Override 22 | public SexType convertToPresentation(String value, ValueContext context) { 23 | return Arrays.asList(SexType.values()).stream() 24 | .filter(item -> item.desc().equals(value)) 25 | .findFirst() 26 | .orElse(null); 27 | } 28 | } -------------------------------------------------------------------------------- /income-predictor-vaadin/src/main/java/oscuroweb/ia/converter/RaceTypeConverter.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.converter; 2 | 3 | import java.util.Arrays; 4 | 5 | import com.vaadin.data.Converter; 6 | import com.vaadin.data.Result; 7 | import com.vaadin.data.ValueContext; 8 | 9 | import oscuroweb.ia.type.RaceType; 10 | 11 | public class RaceTypeConverter implements Converter { 12 | 13 | private static final long serialVersionUID = 6917679106652542941L; 14 | 15 | 16 | @Override 17 | public Result convertToModel(RaceType value, ValueContext context) { 18 | return Result.ok(value.desc()); 19 | } 20 | 21 | @Override 22 | public RaceType convertToPresentation(String value, ValueContext context) { 23 | return Arrays.asList(RaceType.values()).stream() 24 | .filter(item -> item.desc().equals(value)) 25 | .findFirst() 26 | .orElse(null); 27 | } 28 | } -------------------------------------------------------------------------------- /income-predictor-vaadin/src/main/java/oscuroweb/ia/converter/EducationTypeConverter.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.converter; 2 | 3 | import java.util.Arrays; 4 | 5 | import com.vaadin.data.Converter; 6 | import com.vaadin.data.Result; 7 | import com.vaadin.data.ValueContext; 8 | 9 | import oscuroweb.ia.type.EducationType; 10 | 11 | public class EducationTypeConverter implements Converter { 12 | 13 | private static final long serialVersionUID = 6917679106652542941L; 14 | 15 | 16 | @Override 17 | public Result convertToModel(EducationType value, ValueContext context) { 18 | return Result.ok(value.desc()); 19 | } 20 | 21 | @Override 22 | public EducationType convertToPresentation(String value, ValueContext context) { 23 | return Arrays.asList(EducationType.values()).stream() 24 | .filter(item -> item.desc().equals(value)) 25 | .findFirst() 26 | .orElse(null); 27 | } 28 | } -------------------------------------------------------------------------------- /income-predictor-vaadin/src/main/java/oscuroweb/ia/converter/WorkClassTypeConverter.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.converter; 2 | 3 | import java.util.Arrays; 4 | 5 | import com.vaadin.data.Converter; 6 | import com.vaadin.data.Result; 7 | import com.vaadin.data.ValueContext; 8 | 9 | import oscuroweb.ia.type.WorkClassType; 10 | 11 | public class WorkClassTypeConverter implements Converter { 12 | 13 | private static final long serialVersionUID = 6917679106652542941L; 14 | 15 | 16 | @Override 17 | public Result convertToModel(WorkClassType value, ValueContext context) { 18 | return Result.ok(value.desc()); 19 | } 20 | 21 | @Override 22 | public WorkClassType convertToPresentation(String value, ValueContext context) { 23 | return Arrays.asList(WorkClassType.values()).stream() 24 | .filter(item -> item.desc().equals(value)) 25 | .findFirst() 26 | .orElse(null); 27 | } 28 | } -------------------------------------------------------------------------------- /income-predictor-vaadin/src/main/java/oscuroweb/ia/converter/OccupationTypeConverter.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.converter; 2 | 3 | import java.util.Arrays; 4 | 5 | import com.vaadin.data.Converter; 6 | import com.vaadin.data.Result; 7 | import com.vaadin.data.ValueContext; 8 | 9 | import oscuroweb.ia.type.OccupationType; 10 | 11 | public class OccupationTypeConverter implements Converter { 12 | 13 | private static final long serialVersionUID = 6917679106652542941L; 14 | 15 | 16 | @Override 17 | public Result convertToModel(OccupationType value, ValueContext context) { 18 | return Result.ok(value.desc()); 19 | } 20 | 21 | @Override 22 | public OccupationType convertToPresentation(String value, ValueContext context) { 23 | return Arrays.asList(OccupationType.values()).stream() 24 | .filter(item -> item.desc().equals(value)) 25 | .findFirst() 26 | .orElse(null); 27 | } 28 | } -------------------------------------------------------------------------------- /income-predictor-vaadin/src/main/java/oscuroweb/ia/converter/RelationshipTypeConverter.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.converter; 2 | 3 | import java.util.Arrays; 4 | 5 | import com.vaadin.data.Converter; 6 | import com.vaadin.data.Result; 7 | import com.vaadin.data.ValueContext; 8 | 9 | import oscuroweb.ia.type.RelationshipType; 10 | 11 | public class RelationshipTypeConverter implements Converter { 12 | 13 | private static final long serialVersionUID = 6917679106652542941L; 14 | 15 | 16 | @Override 17 | public Result convertToModel(RelationshipType value, ValueContext context) { 18 | return Result.ok(value.desc()); 19 | } 20 | 21 | @Override 22 | public RelationshipType convertToPresentation(String value, ValueContext context) { 23 | return Arrays.asList(RelationshipType.values()).stream() 24 | .filter(item -> item.desc().equals(value)) 25 | .findFirst() 26 | .orElse(null); 27 | } 28 | } -------------------------------------------------------------------------------- /income-predictor-vaadin/src/main/java/oscuroweb/ia/converter/MaritalStatusTypeConverter.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.converter; 2 | 3 | import java.util.Arrays; 4 | 5 | import com.vaadin.data.Converter; 6 | import com.vaadin.data.Result; 7 | import com.vaadin.data.ValueContext; 8 | 9 | import oscuroweb.ia.type.MaritalStatusType; 10 | 11 | public class MaritalStatusTypeConverter implements Converter { 12 | 13 | private static final long serialVersionUID = 6917679106652542941L; 14 | 15 | 16 | @Override 17 | public Result convertToModel(MaritalStatusType value, ValueContext context) { 18 | return Result.ok(value.desc()); 19 | } 20 | 21 | @Override 22 | public MaritalStatusType convertToPresentation(String value, ValueContext context) { 23 | return Arrays.asList(MaritalStatusType.values()).stream() 24 | .filter(item -> item.desc().equals(value)) 25 | .findFirst() 26 | .orElse(null); 27 | } 28 | } -------------------------------------------------------------------------------- /income-predictor-vaadin/src/main/java/oscuroweb/ia/converter/NativeCountryTypeConverter.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.converter; 2 | 3 | import java.util.Arrays; 4 | 5 | import com.vaadin.data.Converter; 6 | import com.vaadin.data.Result; 7 | import com.vaadin.data.ValueContext; 8 | 9 | import oscuroweb.ia.type.NativeCountryType; 10 | 11 | public class NativeCountryTypeConverter implements Converter { 12 | 13 | private static final long serialVersionUID = 6917679106652542941L; 14 | 15 | 16 | @Override 17 | public Result convertToModel(NativeCountryType value, ValueContext context) { 18 | return Result.ok(value.desc()); 19 | } 20 | 21 | @Override 22 | public NativeCountryType convertToPresentation(String value, ValueContext context) { 23 | return Arrays.asList(NativeCountryType.values()).stream() 24 | .filter(item -> item.desc().equals(value)) 25 | .findFirst() 26 | .orElse(null); 27 | } 28 | } -------------------------------------------------------------------------------- /income-predictor-dto/src/main/java/oscuroweb/ia/type/OccupationType.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.type; 2 | 3 | public enum OccupationType { 4 | 5 | TECH_SUPPORT(1, "Tech-support"), 6 | CRAFT_REPAIR(2, "Craft-repair"), 7 | OTHER_SERVICE(3, "Other-service"), 8 | SALES(4, "Sales"), 9 | EXEC_MANAGERIAL(5, "Exec-managerial"), 10 | PROF_SPECIALITY(6, "Prof-specialty"), 11 | HANDLERS_CLEANERS(7, "Handlers-cleaners"), 12 | MACHINE_OP_INSPECT(8, "Machine-op-inspct"), 13 | ADM_CLERICAL(9, "Adm-clerical"), 14 | FARMING_FISHING(10, "Farming-fishing"), 15 | TRANSPORT_MOVING(11, "Transport-moving"), 16 | PRIV_HOUSE_SERV(12, "Priv-house-serv"), 17 | PROTECTIVE_SERV(13, "Protective-serv"), 18 | ARMED_FORCES(14, "Armed-Forces"); 19 | 20 | private int cod; 21 | private String desc; 22 | 23 | private OccupationType(int cod, String desc) { 24 | this.cod = cod; 25 | this.desc = desc; 26 | } 27 | 28 | public int cod() { 29 | return cod; 30 | } 31 | 32 | public String desc() { 33 | return desc; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /income-predictor-dto/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst: -------------------------------------------------------------------------------- 1 | /Users/oscuro/workspace/IAHackathon/income-predictor-ml/../income-predictor-dto/src/main/java/com/accenture/ia/dto/ComboDto.java 2 | /Users/oscuro/workspace/IAHackathon/income-predictor-ml/../income-predictor-dto/src/main/java/com/accenture/ia/dto/ComboEducationDto.java 3 | /Users/oscuro/workspace/IAHackathon/income-predictor-ml/../income-predictor-dto/src/main/java/com/accenture/ia/dto/InputResultDto.java 4 | /Users/oscuro/workspace/IAHackathon/income-predictor-ml/../income-predictor-dto/src/main/java/com/accenture/ia/dto/Column.java 5 | /Users/oscuro/workspace/IAHackathon/income-predictor-ml/../income-predictor-dto/src/main/java/com/accenture/ia/dto/OutputDto.java 6 | /Users/oscuro/workspace/IAHackathon/income-predictor-ml/../income-predictor-dto/src/main/java/com/accenture/ia/dto/InputDto.java 7 | /Users/oscuro/workspace/IAHackathon/income-predictor-ml/../income-predictor-dto/src/main/java/com/accenture/ia/dto/OutputResultDto.java 8 | -------------------------------------------------------------------------------- /income-predictor-service/src/main/java/oscuroweb/ia/controller/ServicesController.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.controller; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.web.bind.annotation.PostMapping; 5 | import org.springframework.web.bind.annotation.RequestBody; 6 | import org.springframework.web.bind.annotation.ResponseBody; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | import oscuroweb.ia.dto.IncomeDto; 10 | import oscuroweb.ia.dto.OutputDto; 11 | import oscuroweb.ia.dto.OutputResultDto; 12 | import oscuroweb.ia.service.SparkService; 13 | 14 | @RestController 15 | public class ServicesController { 16 | 17 | @Autowired 18 | SparkService sparkService; 19 | 20 | 21 | @PostMapping("/evaluate") 22 | public @ResponseBody OutputDto evaluate(@RequestBody IncomeDto input) { 23 | return sparkService.evaluate(input); 24 | } 25 | 26 | @PostMapping("/addResult") 27 | public @ResponseBody OutputResultDto addResult(@RequestBody IncomeDto inputDto) { 28 | return sparkService.addResult(inputDto); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /income-predictor-dto/src/main/java/oscuroweb/ia/type/EducationType.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.type; 2 | 3 | public enum EducationType { 4 | 5 | BACHELORS(1, "Bachelors", 13d), 6 | SOME_COLLEGE(2, "Some-college", 10d), 7 | G11_TH(3, "11th", 7d), 8 | HS_GRAD(4, "HS-grad", 9d), 9 | PROF_SCHOOL(5, "Prof-school", 15d), 10 | ASSOC_ACDM(6, "Assoc-acdm", 12d), 11 | ASSOC_VOC(7, "Assoc-voc", 11d), 12 | G9_TH(8, "9th", 5d), 13 | G7_8_TH(9, "7th-8th", 4d), 14 | G12_TH(10, "12th", 8d), 15 | MASTER(11, "Masters", 14d), 16 | G1_4_TH(12, "1st-4th", 2d), 17 | G10_TH(13, "10th", 6d), 18 | DOCTORATE(14, "Doctorate", 16d), 19 | G5_6_TH(15, "5th-6th", 3d), 20 | PREESCHOOL(16, "Preschool", 1d); 21 | 22 | private int cod; 23 | private String desc; 24 | private Double num; 25 | 26 | private EducationType(int cod, String desc, Double num) { 27 | this.cod = cod; 28 | this.desc = desc; 29 | this.num = num; 30 | } 31 | 32 | public int cod() { 33 | return cod; 34 | } 35 | 36 | public String desc() { 37 | return desc; 38 | } 39 | 40 | public Double num() { 41 | return num; 42 | } 43 | 44 | 45 | } 46 | -------------------------------------------------------------------------------- /income-predictor-dto/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /income-predictor-dto/src/main/java/oscuroweb/ia/dto/Column.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.dto; 2 | 3 | public enum Column { 4 | 5 | AGE ("age"), 6 | WORKCLASS ("workclass"), 7 | FNLWGT ("fnlwgt"), 8 | EDUCATION ("education"), 9 | EDUCATION_NUM ("educationNum"), 10 | MARITAL_STATUS ("maritalStatus"), 11 | OCCUPATION ("occupation"), 12 | RELATIONSHIP ("relationship"), 13 | RACE ("race"), 14 | SEX ("sex"), 15 | CAPITAL_GAIN ("capitalGain"), 16 | CAPITAL_LOSS ("capitalLoss"), 17 | HOURS_PER_WEEK ("hoursPerWeek"), 18 | NATIVE_COUNTRY ("nativeCountry"), 19 | INCOME ("income"), 20 | WORKCLASS_INDEX ("workclass_index"), 21 | EDUCATION_INDEX ("education_index"), 22 | MARITAL_STATUS_INDEX ("maritalStatus_index"), 23 | OCCUPATION_INDEX ("occupation_index"), 24 | RELATIONSHIP_INDEX ("relationship_index"), 25 | RACE_INDEX ("race_index"), 26 | SEX_INDEX ("sex_index"), 27 | NATIVE_COUNTRY_INDEX ("nativeCountry_index"), 28 | INCOME_INDEX ("income_index"), 29 | FEATURES ("featrues"), 30 | PREDICTION ("prediction"), 31 | PREDICTION_LABEL ("predictionLabel"); 32 | 33 | private final String colName; 34 | 35 | private Column(String colName) { 36 | this.colName = colName; 37 | } 38 | 39 | public final String colName() { 40 | return this.colName; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /income-predictor-vaadin/src/main/java/oscuroweb/ia/rest/RestClient.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.rest; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.beans.factory.annotation.Value; 5 | import org.springframework.stereotype.Component; 6 | 7 | import lombok.extern.slf4j.Slf4j; 8 | import oscuroweb.ia.config.AppConfiguration; 9 | import oscuroweb.ia.dto.IncomeDto; 10 | import oscuroweb.ia.dto.OutputDto; 11 | import oscuroweb.ia.dto.OutputResultDto; 12 | 13 | @Slf4j 14 | @Component 15 | public class RestClient { 16 | 17 | @Value("${endpoint.evaluate}") 18 | private String WS_URI_SRV_EVALUATE; 19 | 20 | @Value("${endpoint.addResult}") 21 | private String WS_URI_SRV_ADDRESULT; 22 | 23 | @Autowired 24 | AppConfiguration config; 25 | 26 | public OutputDto evaluateData(IncomeDto income) { 27 | log.info("Start evaluate: {}", income.toString()); 28 | 29 | OutputDto output = config.restTemplate().postForObject(WS_URI_SRV_EVALUATE, income, OutputDto.class); 30 | return output; 31 | } 32 | 33 | 34 | public OutputResultDto addResult(IncomeDto incomeResult) { 35 | log.info("Start add result: {}", incomeResult); 36 | OutputResultDto output = 37 | config.restTemplate().postForObject(WS_URI_SRV_ADDRESULT, incomeResult, OutputResultDto.class); 38 | return output; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /income-predictor-vaadin/src/main/java/oscuroweb/ia/component/Header.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.component; 2 | 3 | import com.jarektoro.responsivelayout.ResponsiveColumn.ColumnComponentAlignment; 4 | import com.jarektoro.responsivelayout.ResponsiveLayout; 5 | import com.jarektoro.responsivelayout.ResponsiveRow; 6 | import com.vaadin.server.ThemeResource; 7 | import com.vaadin.ui.Image; 8 | import com.vaadin.ui.Label; 9 | import com.vaadin.ui.themes.ValoTheme; 10 | 11 | public class Header extends ResponsiveLayout { 12 | 13 | private static final long serialVersionUID = -7281983107427138417L; 14 | 15 | private Image imageLogo; 16 | 17 | public Header() { 18 | this.setWidth(100, Unit.PERCENTAGE); 19 | this.setHeight(20, Unit.PERCENTAGE); 20 | 21 | build(); 22 | } 23 | 24 | public void build() { 25 | imageLogo = new Image(); 26 | 27 | imageLogo.setSource(new ThemeResource("images/logo-white.svg")); 28 | imageLogo.setHeight(60, Unit.PIXELS); 29 | 30 | Label title = new Label("Microservices & Machine Learning"); 31 | title.addStyleNames(ValoTheme.LABEL_HUGE, ValoTheme.LABEL_BOLD, "title-color"); 32 | 33 | ResponsiveRow headerRow = this.addRow() 34 | .withGrow(true) 35 | .withSpacing(true) 36 | .withMargin(true); 37 | 38 | headerRow.addColumn() 39 | .withComponent(imageLogo, ColumnComponentAlignment.LEFT); 40 | headerRow.addColumn() 41 | .withVisibilityRules(false, false, true, true) 42 | .withComponent(title, ColumnComponentAlignment.RIGHT); 43 | 44 | 45 | 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /income-predictor-dto/src/main/java/oscuroweb/ia/type/NativeCountryType.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.type; 2 | 3 | public enum NativeCountryType { 4 | 5 | UNITED_STATES(1, "United-States"), 6 | CAMBODIA(2, "Cambodia"), 7 | ENGLAND(3, "England"), 8 | PUERTO_RICO(4, "Puerto-Rico"), 9 | CANADA(5, "Canada"), 10 | GERMANY(6, "Germany"), 11 | OUTLYING_US(7, "Outlying-US(Guam-USVI-etc)"), 12 | INDIA(8, "India"), 13 | JAPAN(9, "Japan"), 14 | GREECE(10, "Greece"), 15 | SOUTH(11, "South"), 16 | CHINA(12, "China"), 17 | CUBA(13, "Cuba"), 18 | IRAN(14, "Iran"), 19 | HONDURAS(15, "Honduras"), 20 | PHILIPPINES(16, "Philippines"), 21 | ITALY(17, "Italy"), 22 | POLAND(18, "Poland"), 23 | JAMAICA(19, "Jamaica"), 24 | VIETNAM(20, "Vietnam"), 25 | MEXICO(21, "Mexico"), 26 | PORTUGAL(22, "Portugal"), 27 | IRELAND(23, "Ireland"), 28 | FRANCE(24, "France"), 29 | DOMINICAN_REPUBLIC(25, "Dominican-Republic"), 30 | LAOS(26, "Laos"), 31 | ECUADOR(27, "Ecuador"), 32 | TAIWAN(28, "Taiwan"), 33 | HAITI(29, "Haiti"), 34 | COLUMBIA(30, "Columbia"), 35 | HUNGARY(31, "Hungary"), 36 | GUATEMALA(32, "Guatemala"), 37 | NICARAGUA(33, "Nicaragua"), 38 | SCOTLAND(34, "Scotland"), 39 | THAILAND(35, "Thailand"), 40 | YUGOSLAVIA(36, "Yugoslavia"), 41 | EL_SALVADOR(37, "El-Salvador"), 42 | TRINIDAD_TOBAGO(38, "Trinadad&Tobago"), 43 | PERU(39, "Peru"), 44 | HONG(40, "Hong"), 45 | HOLAND_NETHERLANDS(41, "Holand-Netherlands"); 46 | 47 | private int cod; 48 | private String desc; 49 | 50 | private NativeCountryType(int cod, String desc) { 51 | this.cod = cod; 52 | this.desc = desc; 53 | } 54 | 55 | public int cod() { 56 | return cod; 57 | } 58 | 59 | public String desc() { 60 | return desc; 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /income-predictor-ml/src/main/java/oscuroweb/ia/config/ApplicationConfig.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.config; 2 | 3 | import org.apache.spark.SparkConf; 4 | import org.apache.spark.api.java.JavaSparkContext; 5 | import org.apache.spark.sql.SparkSession; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.beans.factory.annotation.Value; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.Configuration; 10 | import org.springframework.context.annotation.PropertySource; 11 | import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; 12 | import org.springframework.core.env.Environment; 13 | 14 | @Configuration 15 | @PropertySource("classpath:application.properties") 16 | public class ApplicationConfig { 17 | 18 | @Autowired 19 | private Environment env; 20 | 21 | @Value("${app.name:adultIncome}") 22 | private String appName; 23 | 24 | @Value("${spark.home}") 25 | private String sparkHome; 26 | 27 | @Value("${master.uri:local}") 28 | private String masterUri; 29 | 30 | @Bean 31 | public SparkConf sparkConf() { 32 | SparkConf sparkConf = new SparkConf() 33 | .setAppName(appName) 34 | .setSparkHome(sparkHome) 35 | .setMaster(masterUri); 36 | 37 | return sparkConf; 38 | } 39 | 40 | @Bean 41 | public JavaSparkContext javaSparkContext() { 42 | return new JavaSparkContext(sparkConf()); 43 | } 44 | 45 | @Bean 46 | public SparkSession sparkSession() { 47 | return SparkSession 48 | .builder() 49 | .sparkContext(javaSparkContext().sc()) 50 | .appName("Java Spark SQL basic example") 51 | .getOrCreate(); 52 | } 53 | 54 | @Bean 55 | public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { 56 | return new PropertySourcesPlaceholderConfigurer(); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /income-predictor-service/src/main/java/oscuroweb/ia/config/ApplicationConfig.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.config; 2 | 3 | import org.apache.spark.SparkConf; 4 | import org.apache.spark.api.java.JavaSparkContext; 5 | import org.apache.spark.sql.SparkSession; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.beans.factory.annotation.Value; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.Configuration; 10 | import org.springframework.context.annotation.PropertySource; 11 | import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; 12 | import org.springframework.core.env.Environment; 13 | 14 | @Configuration 15 | @PropertySource("classpath:application.properties") 16 | public class ApplicationConfig { 17 | 18 | @Autowired 19 | private Environment env; 20 | 21 | @Value("${app.name:adultIncome}") 22 | private String appName; 23 | 24 | @Value("${spark.home}") 25 | private String sparkHome; 26 | 27 | @Value("${master.uri:local}") 28 | private String masterUri; 29 | 30 | @Bean 31 | public SparkConf sparkConf() { 32 | SparkConf sparkConf = new SparkConf() 33 | .setAppName(appName) 34 | .setSparkHome(sparkHome) 35 | .setMaster(masterUri); 36 | 37 | return sparkConf; 38 | } 39 | 40 | @Bean 41 | public JavaSparkContext javaSparkContext() { 42 | return new JavaSparkContext(sparkConf()); 43 | } 44 | 45 | @Bean 46 | public SparkSession sparkSession() { 47 | return SparkSession 48 | .builder() 49 | .sparkContext(javaSparkContext().sc()) 50 | .appName("Java Spark SQL basic example") 51 | .getOrCreate(); 52 | } 53 | 54 | @Bean 55 | public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { 56 | return new PropertySourcesPlaceholderConfigurer(); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /income-predictor-vaadin/src/main/webapp/VAADIN/themes/income/income.scss: -------------------------------------------------------------------------------- 1 | // Global variable overrides. Must be declared before importing Valo. 2 | 3 | //Titulo de pantalla de carga 4 | $v-app-loading-text: "Loading Income Predict Service"; 5 | 6 | 7 | //Color 8 | $income-color : #82C344 !default; 9 | 10 | //Reglas de diseño 11 | $v-focus-color: $income-color; 12 | $v-focus-style: 0 0 3px 2px $v-focus-color; 13 | $v-selection-color: $v-focus-color !default; 14 | 15 | 16 | 17 | //Va al final para que funcionen los estilos aplicados 18 | @import "../valo/valo.scss"; 19 | 20 | @mixin income { 21 | @include valo; 22 | 23 | .v-label-title { 24 | //color: $income-color; 25 | font-weight: bold; 26 | white-space: normal; 27 | font-size: 40px; 28 | font-variant: small-caps; 29 | 30 | } 31 | 32 | // .v-margin-top {padding-top: 20px;} 33 | // .v-margin-bottom {padding-bottom: 20px;} 34 | 35 | .result-label { 36 | font-weight: bold; 37 | } 38 | 39 | .result-label-yes { 40 | color: #3366cc; 41 | } 42 | 43 | .result-label-no { 44 | color: #cc0000; 45 | } 46 | 47 | .result-label-85 { 48 | color: #00b300 49 | } 50 | 51 | .result-label-50 { 52 | color: #ff9900 53 | } 54 | 55 | .result-label-0 { 56 | color: #ff0000 57 | } 58 | 59 | .banner-label { 60 | font-size: 0.75em; 61 | } 62 | 63 | .banner-label-master { 64 | color: #66c2ff; 65 | font-weight: bold; 66 | } 67 | 68 | .banner-label-title { 69 | color: #ffffff; 70 | } 71 | 72 | 73 | .banner-label-author { 74 | color: #7575a3; 75 | font-style: italic; 76 | } 77 | 78 | .dark-color { 79 | background-color: #47476b; 80 | } 81 | 82 | .align-right { 83 | text-align: right; 84 | } 85 | 86 | .align-center { 87 | text-align: center; 88 | } 89 | 90 | .footer { 91 | position: absolute; 92 | bottom: 0; 93 | } 94 | 95 | .footer-color { 96 | background-color: #4c7235; 97 | } 98 | 99 | .title-color { 100 | color: #4c7235; 101 | } 102 | } 103 | 104 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | adult-income/ 2 | data/ 3 | demo-one/ 4 | models/ 5 | 6 | *.pdf 7 | *.mp4 8 | *.mov 9 | *.avi 10 | 11 | 12 | ### Eclipse ### 13 | 14 | .metadata 15 | bin/ 16 | tmp/ 17 | *.tmp 18 | *.bak 19 | *.swp 20 | *~.nib 21 | local.properties 22 | .settings/ 23 | .loadpath 24 | .recommenders 25 | 26 | # External tool builders 27 | .externalToolBuilders/ 28 | 29 | # Locally stored "Eclipse launch configurations" 30 | *.launch 31 | 32 | # PyDev specific (Python IDE for Eclipse) 33 | *.pydevproject 34 | 35 | # CDT-specific (C/C++ Development Tooling) 36 | .cproject 37 | 38 | # Java annotation processor (APT) 39 | .factorypath 40 | 41 | # PDT-specific (PHP Development Tools) 42 | .buildpath 43 | 44 | # sbteclipse plugin 45 | .target 46 | 47 | # Tern plugin 48 | .tern-project 49 | 50 | # TeXlipse plugin 51 | .texlipse 52 | 53 | # STS (Spring Tool Suite) 54 | .springBeans 55 | 56 | # Code Recommenders 57 | .recommenders/ 58 | 59 | # Scala IDE specific (Scala & Java development for Eclipse) 60 | .cache-main 61 | .scala_dependencies 62 | .worksheet 63 | 64 | ### Eclipse Patch ### 65 | # Eclipse Core 66 | .project 67 | 68 | # JDT-specific (Eclipse Java Development Tools) 69 | .classpath 70 | 71 | # Annotation Processing 72 | .apt_generated 73 | 74 | ### Java ### 75 | # Compiled class file 76 | *.class 77 | 78 | # Log file 79 | *.log 80 | 81 | # BlueJ files 82 | *.ctxt 83 | 84 | # Mobile Tools for Java (J2ME) 85 | .mtj.tmp/ 86 | 87 | # Package Files # 88 | *.jar 89 | *.war 90 | *.ear 91 | *.zip 92 | *.tar.gz 93 | *.rar 94 | 95 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 96 | hs_err_pid* 97 | 98 | ### Maven ### 99 | target/ 100 | pom.xml.tag 101 | pom.xml.releaseBackup 102 | pom.xml.versionsBackup 103 | pom.xml.next 104 | release.properties 105 | dependency-reduced-pom.xml 106 | buildNumber.properties 107 | .mvn/timing.properties 108 | 109 | # Avoid ignoring Maven wrapper jar file (.jar files are usually ignored) 110 | !/.mvn/wrapper/maven-wrapper.jar 111 | 112 | 113 | */.classpath 114 | */*.prefs 115 | -------------------------------------------------------------------------------- /income-predictor-vaadin/src/main/java/oscuroweb/ia/ui/MainUI.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.ui; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.vaadin.addon.borderlayout.BorderLayout; 5 | 6 | import com.vaadin.annotations.Theme; 7 | import com.vaadin.annotations.Viewport; 8 | import com.vaadin.navigator.Navigator; 9 | import com.vaadin.server.DefaultErrorHandler; 10 | import com.vaadin.server.Page; 11 | import com.vaadin.server.VaadinRequest; 12 | import com.vaadin.spring.annotation.SpringUI; 13 | import com.vaadin.spring.annotation.SpringViewDisplay; 14 | import com.vaadin.spring.navigator.SpringViewProvider; 15 | import com.vaadin.ui.Notification; 16 | import com.vaadin.ui.UI; 17 | import com.vaadin.ui.VerticalLayout; 18 | 19 | import lombok.extern.slf4j.Slf4j; 20 | import oscuroweb.ia.component.Footer; 21 | import oscuroweb.ia.component.Header; 22 | 23 | @Slf4j 24 | @Theme("income") 25 | @SpringUI 26 | @SpringViewDisplay 27 | @Viewport("width=device-width, initial-scale=1") 28 | public class MainUI extends UI { 29 | 30 | private static final long serialVersionUID = -5510796932223511405L; 31 | 32 | Navigator navigator; 33 | 34 | @Autowired 35 | private SpringViewProvider viewProvider; 36 | 37 | @Override 38 | protected void init(VaadinRequest request) { 39 | Page.getCurrent().setTitle("Income Predictor"); 40 | 41 | this.setSizeFull(); 42 | 43 | BorderLayout mainLayout = new BorderLayout(); 44 | //mainLayout.setSizeFull(); 45 | mainLayout.setSpacing(false); 46 | mainLayout.setMargin(false); 47 | 48 | Header header = new Header(); 49 | Footer footer = new Footer(); 50 | VerticalLayout content = new VerticalLayout(); 51 | content.setSizeFull(); 52 | 53 | mainLayout.addComponent(header, BorderLayout.Constraint.PAGE_START); 54 | //mainLayout.addComponent(footer, BorderLayout.Constraint.PAGE_END); 55 | mainLayout.addComponent(content, BorderLayout.Constraint.CENTER); 56 | 57 | setContent(mainLayout); 58 | 59 | navigator = new Navigator(this, content); 60 | navigator.addProvider(viewProvider); 61 | 62 | this.setErrorHandler(event -> { 63 | Throwable ex = DefaultErrorHandler.findRelevantThrowable(event.getThrowable()); 64 | Notification.show("ErrorHandler", ex.getMessage(), Notification.Type.ERROR_MESSAGE); 65 | log.error(ex.getMessage(), ex); 66 | }); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /income-predictor-dto/src/main/java/oscuroweb/ia/dto/IncomeDto.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.dto; 2 | 3 | import java.io.Serializable; 4 | 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | @Data 11 | @Builder 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | public class IncomeDto implements Serializable { 15 | 16 | private static final long serialVersionUID = -3387767229741791495L; 17 | 18 | /** _c0 - Age: continuous*/ 19 | private Double age; 20 | /** _c1 - Workclass: Private, Self-emp-not-inc, Self-emp-inc, Federal-gov, Local-gov, State-gov, Without-pay, Never-worked */ 21 | private String workclass; 22 | /** _c2 - Sampling weight: continuous */ 23 | private Double fnlwgt; 24 | /** _c3 - education: Bachelors, Some-college, 11th, HS-grad, Prof-school, Assoc-acdm, Assoc-voc, 9th, 7th-8th, 12th, Masters, 1st-4th, 10th, Doctorate, 5th-6th, Preschool */ 25 | private String education; 26 | /** _c4 - education-num: continuous */ 27 | private Double educationNum; 28 | /** _c5 - marital-status: Married-civ-spouse, Divorced, Never-married, Separated, Widowed, Married-spouse-absent, Married-AF-spouse. */ 29 | private String maritalStatus; 30 | /** _c6 - occupation: Tech-support, Craft-repair, Other-service, Sales, Exec-managerial, Prof-specialty, Handlers-cleaners, Machine-op-inspct, Adm-clerical, Farming-fishing, Transport-moving, Priv-house-serv, Protective-serv, Armed-Forces.*/ 31 | private String occupation; 32 | /** _c7 - relationship: Wife, Own-child, Husband, Not-in-family, Other-relative, Unmarried. */ 33 | private String relationship; 34 | /** _c8 - race: White, Asian-Pac-Islander, Amer-Indian-Eskimo, Other, Black. */ 35 | private String race; 36 | /** _c9 - sex: Female, Male. */ 37 | private String sex; 38 | /** _c10 - capital-gain: continuous. */ 39 | private Double capitalGain; 40 | /** _c11 - capital-loss: continuous. */ 41 | private Double capitalLoss; 42 | /** _c12 - hours-per-week: continuous. */ 43 | private Double hoursPerWeek; 44 | /** _c13 - native-country: United-States, Cambodia, England, Puerto-Rico, Canada, Germany, Outlying-US(Guam-USVI-etc), India, Japan, Greece, South, China, Cuba, Iran, Honduras, Philippines, Italy, Poland, Jamaica, Vietnam, Mexico, Portugal, Ireland, France, Dominican-Republic, Laos, Ecuador, Taiwan, Haiti, Columbia, Hungary, Guatemala, Nicaragua, Scotland, Thailand, Yugoslavia, El-Salvador, Trinadad&Tobago, Peru, Hong, Holand-Netherlands.*/ 45 | private String nativeCountry; 46 | /** label: >50K, <=50K. */ 47 | private String label; 48 | /** TRUE if prediction is correct.*/ 49 | private Boolean success; 50 | } -------------------------------------------------------------------------------- /income-predictor-dto/src/main/java/oscuroweb/ia/dto/IncomeResultDto.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.dto; 2 | 3 | import java.io.Serializable; 4 | 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | @Deprecated 11 | @Data 12 | @Builder 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | public class IncomeResultDto implements Serializable { 16 | 17 | private static final long serialVersionUID = 2086755262127261284L; 18 | 19 | /** _c0 - Age: continuous*/ 20 | private Double age; 21 | /** _c1 - Workclass: Private, Self-emp-not-inc, Self-emp-inc, Federal-gov, Local-gov, State-gov, Without-pay, Never-worked */ 22 | private String workclass; 23 | /** _c2 - Sampling weight: continuous */ 24 | private Double fnlwgt; 25 | /** _c3 - education: Bachelors, Some-college, 11th, HS-grad, Prof-school, Assoc-acdm, Assoc-voc, 9th, 7th-8th, 12th, Masters, 1st-4th, 10th, Doctorate, 5th-6th, Preschool */ 26 | private String education; 27 | /** _c4 - education-num: continuous */ 28 | private Double educationNum; 29 | /** _c5 - marital-status: Married-civ-spouse, Divorced, Never-married, Separated, Widowed, Married-spouse-absent, Married-AF-spouse. */ 30 | private String maritalStatus; 31 | /** _c6 - occupation: Tech-support, Craft-repair, Other-service, Sales, Exec-managerial, Prof-specialty, Handlers-cleaners, Machine-op-inspct, Adm-clerical, Farming-fishing, Transport-moving, Priv-house-serv, Protective-serv, Armed-Forces.*/ 32 | private String occupation; 33 | /** _c7 - relationship: Wife, Own-child, Husband, Not-in-family, Other-relative, Unmarried. */ 34 | private String relationship; 35 | /** _c8 - race: White, Asian-Pac-Islander, Amer-Indian-Eskimo, Other, Black. */ 36 | private String race; 37 | /** _c9 - sex: Female, Male. */ 38 | private String sex; 39 | /** _c10 - capital-gain: continuous. */ 40 | private Double capitalGain; 41 | /** _c11 - capital-loss: continuous. */ 42 | private Double capitalLoss; 43 | /** _c12 - hours-per-week: continuous. */ 44 | private Double hoursPerWeek; 45 | /** _c13 - native-country: United-States, Cambodia, England, Puerto-Rico, Canada, Germany, Outlying-US(Guam-USVI-etc), India, Japan, Greece, South, China, Cuba, Iran, Honduras, Philippines, Italy, Poland, Jamaica, Vietnam, Mexico, Portugal, Ireland, France, Dominican-Republic, Laos, Ecuador, Taiwan, Haiti, Columbia, Hungary, Guatemala, Nicaragua, Scotland, Thailand, Yugoslavia, El-Salvador, Trinadad&Tobago, Peru, Hong, Holand-Netherlands.*/ 46 | private String nativeCountry; 47 | /** label: >50K, <=50K. */ 48 | private String label; 49 | /** TRUE if prediction is correct.*/ 50 | private Boolean success; 51 | } 52 | -------------------------------------------------------------------------------- /income-predictor-vaadin/src/main/java/oscuroweb/ia/screen/AbstractIncomeView.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.screen; 2 | 3 | import java.util.Arrays; 4 | import java.util.Random; 5 | 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | 8 | import com.jarektoro.responsivelayout.ResponsiveLayout; 9 | import com.jarektoro.responsivelayout.ResponsiveRow; 10 | import com.vaadin.navigator.View; 11 | import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; 12 | import com.vaadin.ui.Component; 13 | 14 | import lombok.extern.slf4j.Slf4j; 15 | import oscuroweb.ia.rest.RestClient; 16 | 17 | @Slf4j 18 | public abstract class AbstractIncomeView extends ResponsiveLayout implements View { 19 | 20 | private static final long serialVersionUID = 1061490086976065114L; 21 | 22 | @Autowired 23 | protected RestClient restclient; 24 | 25 | @Override 26 | public void enter(ViewChangeEvent request) { 27 | log.info("Start {}", this.getClass().getSimpleName()); 28 | this.removeAllComponents(); 29 | this.setSizeFull(); 30 | this.setContainerType(ContainerType.FLUID); 31 | this.setSpacing(); 32 | this.withDefaultRules(12, 12, 6, 4); 33 | this.withFlexible(); 34 | this.setId("content-layout"); 35 | 36 | this.initView(); 37 | 38 | this.initializeComponentsIds(); 39 | 40 | } 41 | 42 | protected abstract void initView(); 43 | 44 | 45 | 46 | private void initializeComponentsIds() { 47 | 48 | Arrays.asList(this.getClass().getDeclaredFields()) 49 | .stream() 50 | .filter(field -> Component.class.isInstance(field)) 51 | .map(field -> { 52 | try { 53 | return field.get(this); 54 | } catch (IllegalArgumentException | IllegalAccessException e) { 55 | // TODO Auto-generated catch block 56 | e.printStackTrace(); 57 | } 58 | return field; 59 | }) 60 | .forEach(component -> ((Component) component).setId("id".concat(String.valueOf(new Random().nextInt())))); 61 | 62 | 63 | 64 | } 65 | 66 | 67 | protected ResponsiveRow createRow() { 68 | return this.addRow() 69 | .withGrow(true) 70 | .withSpacing(true) 71 | .withMargin(true); 72 | } 73 | 74 | protected ResponsiveRow createRow(int xs, int sm, int md, int lg) { 75 | return this.addRow() 76 | .withGrow(true) 77 | .withSpacing(true) 78 | .withDefaultRules(xs, sm, md, lg) 79 | .withMargin(true); 80 | } 81 | 82 | protected void addColumn(ResponsiveRow row, Component component) { 83 | component.setWidth(100, Unit.PERCENTAGE); 84 | row.addColumn().withComponent(component); 85 | } 86 | 87 | protected void addColumns(ResponsiveRow row, Component ... components) { 88 | Arrays.asList(components).stream().forEach(component -> addColumn(row, component)); 89 | } 90 | 91 | 92 | 93 | } 94 | -------------------------------------------------------------------------------- /income-predictor-vaadin/src/main/java/oscuroweb/ia/component/Footer.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.component; 2 | 3 | import com.vaadin.server.ThemeResource; 4 | import com.vaadin.ui.Alignment; 5 | import com.vaadin.ui.HorizontalLayout; 6 | import com.vaadin.ui.Image; 7 | import com.vaadin.ui.Label; 8 | import com.vaadin.ui.VerticalLayout; 9 | 10 | public class Footer extends VerticalLayout { 11 | 12 | private static final long serialVersionUID = 9155040833896797714L; 13 | 14 | public Footer() { 15 | 16 | this.setWidth(100, Unit.PERCENTAGE); 17 | this.setSpacing(false); 18 | this.setMargin(true); 19 | 20 | // Imagen Logo 21 | Image masterLogo = new Image(); 22 | masterLogo.setSource(new ThemeResource("images/logoA2BD.png")); 23 | masterLogo.setHeight(90, Unit.PIXELS); 24 | 25 | VerticalLayout labelLayout = new VerticalLayout(); 26 | HorizontalLayout titleLayout = new HorizontalLayout(); 27 | Label titleLabel = new Label("Advanced Analytics on Big Data"); 28 | Label masterLabel = new Label("Master Thesis"); 29 | titleLayout.addComponents(titleLabel, masterLabel); 30 | titleLayout.setComponentAlignment(titleLabel, Alignment.MIDDLE_RIGHT); 31 | titleLayout.setComponentAlignment(masterLabel, Alignment.MIDDLE_LEFT); 32 | 33 | Label authorLabel = new Label("Developed by Rafael Hidalgo Calero"); 34 | authorLabel.setSizeFull(); 35 | labelLayout.addComponents(titleLayout, authorLabel); 36 | labelLayout.setComponentAlignment(authorLabel, Alignment.MIDDLE_CENTER); 37 | labelLayout.setHeight(30, Unit.PIXELS); 38 | titleLabel.addStyleNames("banner-label", "banner-label-title"); 39 | masterLabel.addStyleNames("banner-label", "banner-label-master"); 40 | authorLabel.addStyleNames("banner-label", "banner-label-author"); 41 | 42 | titleLayout.setMargin(false); 43 | titleLayout.setSpacing(false); 44 | labelLayout.setMargin(false); 45 | labelLayout.setSpacing(false); 46 | 47 | // Imagen Logo 48 | Image umaLogo = new Image(); 49 | umaLogo.setSource(new ThemeResource("images/UMA_logo.png")); 50 | umaLogo.setHeight(50, Unit.PIXELS); 51 | 52 | 53 | 54 | HorizontalLayout bannerLayout = new HorizontalLayout(masterLogo, labelLayout, umaLogo); 55 | bannerLayout.setComponentAlignment(masterLogo, Alignment.MIDDLE_LEFT); 56 | bannerLayout.setComponentAlignment(labelLayout, Alignment.MIDDLE_CENTER); 57 | bannerLayout.setComponentAlignment(umaLogo, Alignment.MIDDLE_RIGHT); 58 | bannerLayout.setWidth(100, Unit.PERCENTAGE); 59 | bannerLayout.setHeight(100, Unit.PIXELS); 60 | 61 | this.addComponent(bannerLayout); 62 | this.setSizeFull(); 63 | this.addStyleName("footer-color"); 64 | this.setComponentAlignment(bannerLayout, Alignment.BOTTOM_CENTER); 65 | 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /income-predictor-vaadin/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | oscuroweb.ia 7 | income-predictor-vaadin 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | income-predictor-vaadin 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 2.0.1.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 8.2.0 26 | 27 | 28 | 29 | 30 | com.vaadin 31 | vaadin-spring-boot-starter 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-web 36 | 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-starter-test 41 | test 42 | 43 | 44 | org.projectlombok 45 | lombok 46 | provided 47 | 48 | 49 | org.springframework.boot 50 | spring-boot-devtools 51 | 52 | 53 | com.jarektoro 54 | responsive-layout 55 | 2.1.1 56 | 57 | 58 | org.vaadin.addons 59 | border-layout-addon 60 | 1.0 61 | 62 | 63 | oscuroweb.ia 64 | income-predictor-dto 65 | 0.0.1-SNAPSHOT 66 | 67 | 68 | 69 | 70 | 71 | vaadin-addons 72 | http://maven.vaadin.com/vaadin-addons 73 | 74 | 75 | 76 | 77 | 78 | 79 | com.vaadin 80 | vaadin-bom 81 | ${vaadin.version} 82 | pom 83 | import 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | org.springframework.boot 92 | spring-boot-maven-plugin 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /income-predictor-service/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | oscuroweb.ia 7 | income-predictor-service 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | income-predictor-service 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 1.5.9.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 26 | 1.8 27 | 1.8 28 | 2.11 29 | 2.2.1 30 | 3.4.1 31 | 32 | 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-starter-web 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-starter-logging 41 | 42 | 43 | 44 | 45 | 46 | org.springframework.boot 47 | spring-boot-starter-test 48 | test 49 | 50 | 51 | 52 | org.projectlombok 53 | lombok 54 | provided 55 | 56 | 57 | org.spark-project.spark 58 | unused 59 | 1.0.0 60 | provided 61 | 62 | 63 | org.apache.spark 64 | spark-core_${scala.binary.version} 65 | ${apache.spark.version} 66 | provided 67 | 68 | 69 | org.apache.spark 70 | spark-streaming_${scala.binary.version} 71 | ${apache.spark.version} 72 | provided 73 | 74 | 75 | org.apache.spark 76 | spark-mllib_${scala.binary.version} 77 | ${apache.spark.version} 78 | provided 79 | 80 | 81 | org.apache.spark 82 | spark-hive_${scala.binary.version} 83 | ${apache.spark.version} 84 | provided 85 | 86 | 87 | org.apache.spark 88 | spark-graphx_${scala.binary.version} 89 | ${apache.spark.version} 90 | provided 91 | 92 | 93 | org.apache.spark 94 | spark-streaming-kafka-0-10_${scala.binary.version} 95 | ${apache.spark.version} 96 | provided 97 | 98 | 99 | org.apache.spark 100 | spark-sql-kafka-0-10_${scala.binary.version} 101 | ${apache.spark.version} 102 | provided 103 | 104 | 105 | oscuroweb.ia 106 | income-predictor-dto 107 | 0.0.1-SNAPSHOT 108 | provided 109 | 110 | 111 | 112 | 113 | 114 | 115 | org.codehaus.janino 116 | commons-compiler 117 | 2.7.8 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | org.springframework.boot 126 | spring-boot-maven-plugin 127 | 128 | 129 | 130 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /income-predictor-ml/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | oscuroweb.ia 7 | income-predictor-ml 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | income-predictor-ml 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 1.5.9.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 26 | 1.8 27 | 1.8 28 | 2.11 29 | 2.2.1 30 | 3.4.1 31 | 32 | 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-starter-web 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-starter-logging 41 | 42 | 43 | 44 | 45 | 46 | org.springframework.boot 47 | spring-boot-starter-test 48 | test 49 | 50 | 51 | 52 | org.projectlombok 53 | lombok 54 | 1.16.20 55 | provided 56 | 57 | 58 | org.spark-project.spark 59 | unused 60 | 1.0.0 61 | provided 62 | 63 | 64 | org.apache.spark 65 | spark-core_${scala.binary.version} 66 | ${apache.spark.version} 67 | provided 68 | 69 | 70 | org.apache.spark 71 | spark-streaming_${scala.binary.version} 72 | ${apache.spark.version} 73 | provided 74 | 75 | 76 | org.apache.spark 77 | spark-mllib_${scala.binary.version} 78 | ${apache.spark.version} 79 | provided 80 | 81 | 82 | org.apache.spark 83 | spark-hive_${scala.binary.version} 84 | ${apache.spark.version} 85 | provided 86 | 87 | 88 | org.apache.spark 89 | spark-graphx_${scala.binary.version} 90 | ${apache.spark.version} 91 | provided 92 | 93 | 94 | org.apache.spark 95 | spark-streaming-kafka-0-10_${scala.binary.version} 96 | ${apache.spark.version} 97 | provided 98 | 99 | 100 | org.apache.spark 101 | spark-sql-kafka-0-10_${scala.binary.version} 102 | ${apache.spark.version} 103 | provided 104 | 105 | 106 | oscuroweb.ia 107 | income-predictor-dto 108 | 0.0.1-SNAPSHOT 109 | provided 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | org.codehaus.janino 118 | commons-compiler 119 | 2.7.8 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | org.springframework.boot 128 | spring-boot-maven-plugin 129 | 130 | 131 | 132 | 133 | 134 | 135 | -------------------------------------------------------------------------------- /income-predictor-service/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 40 | 41 | @REM set %HOME% to equivalent of $HOME 42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 43 | 44 | @REM Execute a user defined script before this one 45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 49 | :skipRcPre 50 | 51 | @setlocal 52 | 53 | set ERROR_CODE=0 54 | 55 | @REM To isolate internal variables from possible post scripts, we use another setlocal 56 | @setlocal 57 | 58 | @REM ==== START VALIDATION ==== 59 | if not "%JAVA_HOME%" == "" goto OkJHome 60 | 61 | echo. 62 | echo Error: JAVA_HOME not found in your environment. >&2 63 | echo Please set the JAVA_HOME variable in your environment to match the >&2 64 | echo location of your Java installation. >&2 65 | echo. 66 | goto error 67 | 68 | :OkJHome 69 | if exist "%JAVA_HOME%\bin\java.exe" goto init 70 | 71 | echo. 72 | echo Error: JAVA_HOME is set to an invalid directory. >&2 73 | echo JAVA_HOME = "%JAVA_HOME%" >&2 74 | echo Please set the JAVA_HOME variable in your environment to match the >&2 75 | echo location of your Java installation. >&2 76 | echo. 77 | goto error 78 | 79 | @REM ==== END VALIDATION ==== 80 | 81 | :init 82 | 83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 84 | @REM Fallback to current working directory if not found. 85 | 86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 88 | 89 | set EXEC_DIR=%CD% 90 | set WDIR=%EXEC_DIR% 91 | :findBaseDir 92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 93 | cd .. 94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 95 | set WDIR=%CD% 96 | goto findBaseDir 97 | 98 | :baseDirFound 99 | set MAVEN_PROJECTBASEDIR=%WDIR% 100 | cd "%EXEC_DIR%" 101 | goto endDetectBaseDir 102 | 103 | :baseDirNotFound 104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 105 | cd "%EXEC_DIR%" 106 | 107 | :endDetectBaseDir 108 | 109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 110 | 111 | @setlocal EnableExtensions EnableDelayedExpansion 112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 114 | 115 | :endReadAdditionalConfig 116 | 117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 118 | 119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 121 | 122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 123 | if ERRORLEVEL 1 goto error 124 | goto end 125 | 126 | :error 127 | set ERROR_CODE=1 128 | 129 | :end 130 | @endlocal & set ERROR_CODE=%ERROR_CODE% 131 | 132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 136 | :skipRcPost 137 | 138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 140 | 141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 142 | 143 | exit /B %ERROR_CODE% 144 | -------------------------------------------------------------------------------- /income-predictor-vaadin/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 40 | 41 | @REM set %HOME% to equivalent of $HOME 42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 43 | 44 | @REM Execute a user defined script before this one 45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 49 | :skipRcPre 50 | 51 | @setlocal 52 | 53 | set ERROR_CODE=0 54 | 55 | @REM To isolate internal variables from possible post scripts, we use another setlocal 56 | @setlocal 57 | 58 | @REM ==== START VALIDATION ==== 59 | if not "%JAVA_HOME%" == "" goto OkJHome 60 | 61 | echo. 62 | echo Error: JAVA_HOME not found in your environment. >&2 63 | echo Please set the JAVA_HOME variable in your environment to match the >&2 64 | echo location of your Java installation. >&2 65 | echo. 66 | goto error 67 | 68 | :OkJHome 69 | if exist "%JAVA_HOME%\bin\java.exe" goto init 70 | 71 | echo. 72 | echo Error: JAVA_HOME is set to an invalid directory. >&2 73 | echo JAVA_HOME = "%JAVA_HOME%" >&2 74 | echo Please set the JAVA_HOME variable in your environment to match the >&2 75 | echo location of your Java installation. >&2 76 | echo. 77 | goto error 78 | 79 | @REM ==== END VALIDATION ==== 80 | 81 | :init 82 | 83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 84 | @REM Fallback to current working directory if not found. 85 | 86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 88 | 89 | set EXEC_DIR=%CD% 90 | set WDIR=%EXEC_DIR% 91 | :findBaseDir 92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 93 | cd .. 94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 95 | set WDIR=%CD% 96 | goto findBaseDir 97 | 98 | :baseDirFound 99 | set MAVEN_PROJECTBASEDIR=%WDIR% 100 | cd "%EXEC_DIR%" 101 | goto endDetectBaseDir 102 | 103 | :baseDirNotFound 104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 105 | cd "%EXEC_DIR%" 106 | 107 | :endDetectBaseDir 108 | 109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 110 | 111 | @setlocal EnableExtensions EnableDelayedExpansion 112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 114 | 115 | :endReadAdditionalConfig 116 | 117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 118 | 119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 121 | 122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 123 | if ERRORLEVEL 1 goto error 124 | goto end 125 | 126 | :error 127 | set ERROR_CODE=1 128 | 129 | :end 130 | @endlocal & set ERROR_CODE=%ERROR_CODE% 131 | 132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 136 | :skipRcPost 137 | 138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 140 | 141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 142 | 143 | exit /B %ERROR_CODE% 144 | -------------------------------------------------------------------------------- /income-predictor-service/src/main/java/oscuroweb/ia/service/impl/SparkServiceImpl.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.service.impl; 2 | 3 | import java.util.Collections; 4 | 5 | import org.apache.spark.ml.PipelineModel; 6 | import org.apache.spark.ml.Transformer; 7 | import org.apache.spark.ml.classification.RandomForestClassificationModel; 8 | import org.apache.spark.ml.feature.IndexToString; 9 | import org.apache.spark.ml.feature.StringIndexerModel; 10 | import org.apache.spark.ml.feature.VectorAssembler; 11 | import org.apache.spark.sql.Dataset; 12 | import org.apache.spark.sql.Encoder; 13 | import org.apache.spark.sql.Encoders; 14 | import org.apache.spark.sql.Row; 15 | import org.apache.spark.sql.SparkSession; 16 | import org.springframework.beans.factory.annotation.Autowired; 17 | import org.springframework.beans.factory.annotation.Value; 18 | import org.springframework.stereotype.Service; 19 | import org.springframework.web.client.RestTemplate; 20 | 21 | import oscuroweb.ia.dto.Column; 22 | import oscuroweb.ia.dto.IncomeDto; 23 | import oscuroweb.ia.dto.OutputDto; 24 | import oscuroweb.ia.dto.OutputResultDto; 25 | import oscuroweb.ia.service.SparkService; 26 | 27 | @Service 28 | public class SparkServiceImpl implements SparkService { 29 | 30 | @Autowired 31 | private SparkSession spark; 32 | 33 | @Value("${models.path}") 34 | private String modelFolderPath; 35 | 36 | @Value("${models.versioned:false}") 37 | private Boolean modelVersioned; 38 | 39 | @Value("${ml.service:none}") 40 | private String mlService; 41 | 42 | @Override 43 | public OutputDto evaluate(IncomeDto input) { 44 | spark.sparkContext().setLogLevel("ERROR"); 45 | 46 | Encoder incomeEncoder = Encoders.bean(IncomeDto.class); 47 | Dataset dataset = spark.createDataset( 48 | Collections.singletonList(input), 49 | incomeEncoder 50 | ).toDF(); 51 | 52 | dataset.show(); 53 | 54 | String[] inputColumn = { 55 | Column.AGE.colName(), 56 | Column.WORKCLASS_INDEX.colName(), 57 | Column.FNLWGT.colName(), 58 | Column.EDUCATION_INDEX.colName(), 59 | Column.EDUCATION_NUM.colName(), 60 | Column.MARITAL_STATUS_INDEX.colName(), 61 | Column.OCCUPATION_INDEX.colName(), 62 | Column.RELATIONSHIP_INDEX.colName(), 63 | Column.RACE_INDEX.colName(), 64 | Column.SEX_INDEX.colName(), 65 | Column.CAPITAL_GAIN.colName(), 66 | Column.CAPITAL_LOSS.colName(), 67 | Column.HOURS_PER_WEEK.colName(), 68 | Column.NATIVE_COUNTRY_INDEX.colName()}; 69 | 70 | VectorAssembler vectorAssembler = new VectorAssembler() 71 | .setInputCols(inputColumn) 72 | .setOutputCol(Column.FEATURES.colName()); 73 | 74 | 75 | RandomForestClassificationModel model = RandomForestClassificationModel.load(formatPath().concat("rfModel")); 76 | 77 | PipelineModel pipelineModel = new PipelineModel("rfPipeline", new Transformer[] { 78 | StringIndexerModel.load(formatPath().concat("_c1")).setInputCol(Column.WORKCLASS.colName()).setOutputCol(Column.WORKCLASS_INDEX.colName()), 79 | StringIndexerModel.load(formatPath().concat("_c3")).setInputCol(Column.EDUCATION.colName()).setOutputCol(Column.EDUCATION_INDEX.colName()), 80 | StringIndexerModel.load(formatPath().concat("_c5")).setInputCol(Column.MARITAL_STATUS.colName()).setOutputCol(Column.MARITAL_STATUS_INDEX.colName()), 81 | StringIndexerModel.load(formatPath().concat("_c6")).setInputCol(Column.OCCUPATION.colName()).setOutputCol(Column.OCCUPATION_INDEX.colName()), 82 | StringIndexerModel.load(formatPath().concat("_c7")).setInputCol(Column.RELATIONSHIP.colName()).setOutputCol(Column.RELATIONSHIP_INDEX.colName()), 83 | StringIndexerModel.load(formatPath().concat("_c8")).setInputCol(Column.RACE.colName()).setOutputCol(Column.RACE_INDEX.colName()), 84 | StringIndexerModel.load(formatPath().concat("_c9")).setInputCol(Column.SEX.colName()).setOutputCol(Column.SEX_INDEX.colName()), 85 | StringIndexerModel.load(formatPath().concat("_c13")).setInputCol(Column.NATIVE_COUNTRY.colName()).setOutputCol(Column.NATIVE_COUNTRY_INDEX.colName()), 86 | vectorAssembler, 87 | model 88 | }); 89 | 90 | dataset.show(); 91 | 92 | Dataset predictions = pipelineModel.transform(dataset); 93 | 94 | predictions.show(); 95 | 96 | // Convert indexed labels back to original labels. 97 | IndexToString c14Label = new IndexToString() 98 | .setInputCol(Column.PREDICTION.colName()) 99 | .setOutputCol(Column.PREDICTION_LABEL.colName()) 100 | .setLabels(StringIndexerModel.load(formatPath().concat("_c14")).labels()); 101 | predictions = c14Label.transform(predictions); 102 | 103 | Dataset predictionsResult = predictions.select(Column.PREDICTION.colName(), Column.PREDICTION_LABEL.colName()); 104 | 105 | predictionsResult.show(); 106 | 107 | return OutputDto.builder().label((String) predictionsResult.collectAsList().get(0).get(1)).build(); 108 | 109 | } 110 | 111 | private String formatPath() { 112 | 113 | String formatedPath = modelFolderPath; 114 | 115 | if (!formatedPath.endsWith("/")) { 116 | formatedPath = formatedPath.concat("/"); 117 | } 118 | 119 | if (modelVersioned) { 120 | formatedPath = formatedPath.concat(getVersion() + "/"); 121 | } 122 | 123 | return formatedPath; 124 | } 125 | 126 | private Long getVersion() { 127 | if (mlService.equals("none")) 128 | return 0l; 129 | else { 130 | RestTemplate rest = new RestTemplate(); 131 | Long l = rest.getForObject(mlService, Long.class); 132 | return l; 133 | } 134 | } 135 | 136 | public OutputResultDto addResult(IncomeDto input) { 137 | return OutputResultDto.builder().updated(Boolean.TRUE).build(); 138 | } 139 | 140 | } 141 | -------------------------------------------------------------------------------- /income-predictor-vaadin/mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven2 Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Migwn, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | # TODO classpath? 118 | fi 119 | 120 | if [ -z "$JAVA_HOME" ]; then 121 | javaExecutable="`which javac`" 122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 123 | # readlink(1) is not available as standard on Solaris 10. 124 | readLink=`which readlink` 125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 126 | if $darwin ; then 127 | javaHome="`dirname \"$javaExecutable\"`" 128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 129 | else 130 | javaExecutable="`readlink -f \"$javaExecutable\"`" 131 | fi 132 | javaHome="`dirname \"$javaExecutable\"`" 133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 134 | JAVA_HOME="$javaHome" 135 | export JAVA_HOME 136 | fi 137 | fi 138 | fi 139 | 140 | if [ -z "$JAVACMD" ] ; then 141 | if [ -n "$JAVA_HOME" ] ; then 142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 143 | # IBM's JDK on AIX uses strange locations for the executables 144 | JAVACMD="$JAVA_HOME/jre/sh/java" 145 | else 146 | JAVACMD="$JAVA_HOME/bin/java" 147 | fi 148 | else 149 | JAVACMD="`which java`" 150 | fi 151 | fi 152 | 153 | if [ ! -x "$JAVACMD" ] ; then 154 | echo "Error: JAVA_HOME is not defined correctly." >&2 155 | echo " We cannot execute $JAVACMD" >&2 156 | exit 1 157 | fi 158 | 159 | if [ -z "$JAVA_HOME" ] ; then 160 | echo "Warning: JAVA_HOME environment variable is not set." 161 | fi 162 | 163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 164 | 165 | # traverses directory structure from process work directory to filesystem root 166 | # first directory with .mvn subdirectory is considered project base directory 167 | find_maven_basedir() { 168 | 169 | if [ -z "$1" ] 170 | then 171 | echo "Path not specified to find_maven_basedir" 172 | return 1 173 | fi 174 | 175 | basedir="$1" 176 | wdir="$1" 177 | while [ "$wdir" != '/' ] ; do 178 | if [ -d "$wdir"/.mvn ] ; then 179 | basedir=$wdir 180 | break 181 | fi 182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 183 | if [ -d "${wdir}" ]; then 184 | wdir=`cd "$wdir/.."; pwd` 185 | fi 186 | # end of workaround 187 | done 188 | echo "${basedir}" 189 | } 190 | 191 | # concatenates all lines of a file 192 | concat_lines() { 193 | if [ -f "$1" ]; then 194 | echo "$(tr -s '\n' ' ' < "$1")" 195 | fi 196 | } 197 | 198 | BASE_DIR=`find_maven_basedir "$(pwd)"` 199 | if [ -z "$BASE_DIR" ]; then 200 | exit 1; 201 | fi 202 | 203 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 204 | echo $MAVEN_PROJECTBASEDIR 205 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 206 | 207 | # For Cygwin, switch paths to Windows format before running java 208 | if $cygwin; then 209 | [ -n "$M2_HOME" ] && 210 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 211 | [ -n "$JAVA_HOME" ] && 212 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 213 | [ -n "$CLASSPATH" ] && 214 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 215 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 216 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 217 | fi 218 | 219 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 220 | 221 | exec "$JAVACMD" \ 222 | $MAVEN_OPTS \ 223 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 224 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 225 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 226 | -------------------------------------------------------------------------------- /income-predictor-service/mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven2 Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Migwn, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | # TODO classpath? 118 | fi 119 | 120 | if [ -z "$JAVA_HOME" ]; then 121 | javaExecutable="`which javac`" 122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 123 | # readlink(1) is not available as standard on Solaris 10. 124 | readLink=`which readlink` 125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 126 | if $darwin ; then 127 | javaHome="`dirname \"$javaExecutable\"`" 128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 129 | else 130 | javaExecutable="`readlink -f \"$javaExecutable\"`" 131 | fi 132 | javaHome="`dirname \"$javaExecutable\"`" 133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 134 | JAVA_HOME="$javaHome" 135 | export JAVA_HOME 136 | fi 137 | fi 138 | fi 139 | 140 | if [ -z "$JAVACMD" ] ; then 141 | if [ -n "$JAVA_HOME" ] ; then 142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 143 | # IBM's JDK on AIX uses strange locations for the executables 144 | JAVACMD="$JAVA_HOME/jre/sh/java" 145 | else 146 | JAVACMD="$JAVA_HOME/bin/java" 147 | fi 148 | else 149 | JAVACMD="`which java`" 150 | fi 151 | fi 152 | 153 | if [ ! -x "$JAVACMD" ] ; then 154 | echo "Error: JAVA_HOME is not defined correctly." >&2 155 | echo " We cannot execute $JAVACMD" >&2 156 | exit 1 157 | fi 158 | 159 | if [ -z "$JAVA_HOME" ] ; then 160 | echo "Warning: JAVA_HOME environment variable is not set." 161 | fi 162 | 163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 164 | 165 | # traverses directory structure from process work directory to filesystem root 166 | # first directory with .mvn subdirectory is considered project base directory 167 | find_maven_basedir() { 168 | 169 | if [ -z "$1" ] 170 | then 171 | echo "Path not specified to find_maven_basedir" 172 | return 1 173 | fi 174 | 175 | basedir="$1" 176 | wdir="$1" 177 | while [ "$wdir" != '/' ] ; do 178 | if [ -d "$wdir"/.mvn ] ; then 179 | basedir=$wdir 180 | break 181 | fi 182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 183 | if [ -d "${wdir}" ]; then 184 | wdir=`cd "$wdir/.."; pwd` 185 | fi 186 | # end of workaround 187 | done 188 | echo "${basedir}" 189 | } 190 | 191 | # concatenates all lines of a file 192 | concat_lines() { 193 | if [ -f "$1" ]; then 194 | echo "$(tr -s '\n' ' ' < "$1")" 195 | fi 196 | } 197 | 198 | BASE_DIR=`find_maven_basedir "$(pwd)"` 199 | if [ -z "$BASE_DIR" ]; then 200 | exit 1; 201 | fi 202 | 203 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 204 | echo $MAVEN_PROJECTBASEDIR 205 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 206 | 207 | # For Cygwin, switch paths to Windows format before running java 208 | if $cygwin; then 209 | [ -n "$M2_HOME" ] && 210 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 211 | [ -n "$JAVA_HOME" ] && 212 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 213 | [ -n "$CLASSPATH" ] && 214 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 215 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 216 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 217 | fi 218 | 219 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 220 | 221 | exec "$JAVACMD" \ 222 | $MAVEN_OPTS \ 223 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 224 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 225 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 226 | -------------------------------------------------------------------------------- /income-predictor-vaadin/src/main/webapp/VAADIN/themes/income/images/logo-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 24 | 47 | 49 | 50 | 52 | image/svg+xml 53 | 55 | 56 | 57 | 58 | 59 | 64 | 67 | 74 | 79 | 84 | 89 | 94 | 98 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # microservices-ml 2 | Microservices with spring-boot and Machine Learning with Apache Spark ML. The aim of this solution is to use as sample of a pure Java reference architecture based on Spring Boot plus Apache Spark to solve machine learning problems. 3 | 4 | ## Quick start 5 | 6 | This section can help you to start the solution without a deep knowledge of the different technologies used. Please follow the instructions and PR if more information is needed. 7 | 8 | ### Maven 9 | 10 | A very simple process if you know Maven and Java, this is the recommended way if you want to explore or improve the project after the quick start. 11 | 12 | #### Prerrequisites 13 | 14 | ##### Java 15 | 16 | You need a JDK installed to compile all the projects, you can download the latest version from [Oracle](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html), [OpenJDK](http://openjdk.java.net/install/) or [Azul Zulu (not tested)](https://www.azul.com/downloads/zulu/) 17 | 18 | You can check that Java is available with the command below: 19 | 20 | _java -version_ 21 | 22 | ##### Maven 23 | 24 | You also need Apache Maven installed. You can find installation instructions [here](https://maven.apache.org/download.cgi) 25 | 26 | You can check your maven installation with the command below: 27 | 28 | _mvn -version_ 29 | 30 | ##### Spark 31 | 32 | You can download Apache Spark [here](https://spark.apache.org/downloads.html). Please select the package type prebuild for Hadoop. Please note that you will need the installation path in the compilation and running process. 33 | 34 | #### Process 35 | 36 | ##### Compilation 37 | 38 | 1. Clone project in a local directory and enter into microservices-ml folder. 39 | 2. Go to income-predictor-dto project. 40 | 3. Into this project run _mvn clean install_ execution should finish with a _BUILD SUCCESS_ message 41 | 4. Go to income-predictor-ml project. 42 | 5. Edit the application.properties file and change _spark_home, models_path_ and _dataset_file_ to the ones in your local machine. 43 | 6. Into this project run _mvn clean install_ execution should finish with a _BUILD SUCCESS_ message. 44 | 7. Go to income-predictor-service project. 45 | 8. Edit the application.properties file and change _spark_home, models_path_ and _dataset_file_ to the ones in your local machine. 46 | 9. Into this project run _mvn clean install_ execution should finish with a _BUILD SUCCESS_ message. 47 | 10. Go to income-predictor-vaadin project. 48 | 11. Into this project run _mvn clean install_ execution should finish with a _BUILD SUCCESS_ message. 49 | 12. Now all artifacts are generated and ready to be executed. 50 | 51 | ##### Running 52 | 53 | We need to run all three applications to have the solution working, to do so we only need to follow the instructions below: 54 | 55 | 1. Go to _income-predictor-ml/target_ 56 | 1. Check that the file _income-predictor-ml-0.0.1-SNAPSHOT.jar_ exists. If not you should follow the steps described in __Compilation__ section. 57 | 1. Run the project using the command _java -jar income-predictor-ml-0.0.1-SNAPSHOT.jar_, application should now connect to spark hadoop and read input file and create a model using this data. 58 | 1. Go to _income-predictor-service/target_ 59 | 1. Check that the file _income-predictor-service-0.0.1-SNAPSHOT.jar_ exists. If not you should follow the steps described in __Compilation__ section. 60 | 1. Run the project using the command _java -jar income-predictor-service-0.0.1-SNAPSHOT.jar_, now service application should be availabe at port 8082. 61 | 1. Go to _income-predictor-vaadin/target_ 62 | 1. Check that the file _income-predictor-vaadin-0.0.1-SNAPSHOT.jar_ exists. If not you should follow the steps described in __Compilation__ section. 63 | 1. Run the project using the command _java -jar income-predictor-vaadin-0.0.1-SNAPSHOT.jar_, now web application should be available at port 8080. 64 | 1. You can open your browser and go to [http://localhost:8080](http://localhost:8080) to check the solution. 65 | 66 | ![alt Screen](https://github.com/oscuroweb/microservices-ml/blob/master/images/Capture.png) 67 | 68 | ### Docker 69 | 70 | TBD 71 | 72 | #### Prerrequisites 73 | 74 | ##### Docker 75 | 76 | #### Process 77 | 78 | ## Topology 79 | 80 | ![alt Topology](https://github.com/oscuroweb/microservices-ml/blob/master/images/Topology.png) 81 | 82 | This solution has three different projects: 83 | 84 | - income-predictor-dto 85 | - income-predictor-service 86 | - income-predictor-ml 87 | - income-predictor-vaadin 88 | 89 | You can see below a description for each project. 90 | 91 | ### income-predictor-dto 92 | 93 | ![alt income-predictor-dto project class diagram](https://github.com/oscuroweb/microservices-ml/blob/master/images/DTO-Diagram.png) 94 | 95 | This project includes all Data Transfer Objects needed in the solution, it also includes all the types needed to process the input file. 96 | 97 | ### income-predictor-ml 98 | 99 | ![alt income-predictor-ml project class diagram](https://github.com/oscuroweb/microservices-ml/blob/master/images/ML-Diagram.png) 100 | 101 | The Machine-Learning project itself, implements the algo. 102 | 103 | ### income-predictor-service 104 | 105 | ![alt income-predictor-service project class diagram](https://github.com/oscuroweb/microservices-ml/blob/master/images/Service-Diagram.png) 106 | 107 | Service that exposes the different endpoints to be consumed. 108 | 109 | ### income-predictor-vaadin 110 | 111 | ![alt income-predictor-service project class diagram](https://github.com/oscuroweb/microservices-ml/blob/master/images/Vaadin-Diagram.png) 112 | 113 | Web application that shows the results. 114 | 115 | ## Process description 116 | 117 | You can find the full description in [slideshare](https://www.slideshare.net/oscuroweb/integrando-machine-learning-y-microservicios) (in spanish, english translation on going). 118 | 119 | ![alt Process description](https://github.com/oscuroweb/microservices-ml/blob/master/images/Process.png) 120 | 121 | ## Advanced features 122 | 123 | ### Model versioning 124 | 125 | Model versioning is a experimental feature that allows the solution to have multiple models generated and available to use. __This feature is not yet complete__ and we do not recomend to enable it except for test and learning or if you are developing your own solution. To enable the feature you need to follow the instructions below: 126 | 127 | 1. Go to _application.properties_ file in _income-predictor-ml_ project and uncomment the _models.versioned_ property. This property should be set at _true_. 128 | 1. Restart _income-predictor-ml_ project. Now _income-predictor-ml_ project will generate models into isolated folders. 129 | 1. Go to _application.properties_ file in _income-predictor-service_ project and uncomment the properties _models.versioned_ and _ml.service_ check tha this one has the correct URL to consume the _income-predictor-ml_ project. 130 | 1. Restart _income-predictor-service_ project. Now it will consume the latest model generated by _income-predictor-ml_ project. 131 | 132 | You can check if the model versioning feature is working (IP:PORT are the ones defined for _income-predictor-ml_ project): 133 | 134 | 1. Go to _[IP:PORT]/version_ with your browser, if a 0 is shown then the feature is not working, if you see a date as long number then it's working. 135 | 1. Go to _[IP:PORT]/allVersions_ with your browser, if a list with only one 0 is shown the feature is not working, if you see a list of dates in long format then it's working. 136 | 137 | Now you can use the front-end application as usual and the backend will automatically use the latest model version generated by ml service. 138 | 139 | ## Contacts 140 | 141 | ### Rafa Hidalgo 142 | ![alt Twitter](https://github.com/oscuroweb/microservices-ml/blob/master/images/Twitter_Icon.png) https://twitter.com/oscuroweb
143 | ![alt Github](https://github.com/oscuroweb/microservices-ml/blob/master/images/GitHub-Mark.png)https://github.com/oscuroweb
144 | 145 | ### Julio Palma 146 | ![alt Twitter](https://github.com/oscuroweb/microservices-ml/blob/master/images/Twitter_Icon.png) https://twitter.com/restalion
147 | ![alt Github](https://github.com/oscuroweb/microservices-ml/blob/master/images/GitHub-Mark.png)https://github.com/restalion
148 | 149 | -------------------------------------------------------------------------------- /income-predictor-ml/src/main/java/oscuroweb/ia/service/impl/SparkServiceImpl.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.service.impl; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.time.Instant; 6 | import java.util.ArrayList; 7 | import java.util.Arrays; 8 | import java.util.Comparator; 9 | import java.util.HashMap; 10 | import java.util.List; 11 | import java.util.Map; 12 | 13 | import org.apache.spark.ml.classification.DecisionTreeClassificationModel; 14 | import org.apache.spark.ml.classification.DecisionTreeClassifier; 15 | import org.apache.spark.ml.classification.RandomForestClassificationModel; 16 | import org.apache.spark.ml.classification.RandomForestClassifier; 17 | import org.apache.spark.ml.evaluation.MulticlassClassificationEvaluator; 18 | import org.apache.spark.ml.feature.IndexToString; 19 | import org.apache.spark.ml.feature.StringIndexer; 20 | import org.apache.spark.ml.feature.StringIndexerModel; 21 | import org.apache.spark.ml.feature.VectorAssembler; 22 | import org.apache.spark.ml.util.MLWritable; 23 | import org.apache.spark.sql.Dataset; 24 | import org.apache.spark.sql.Row; 25 | import org.apache.spark.sql.SparkSession; 26 | import org.springframework.beans.factory.annotation.Autowired; 27 | import org.springframework.beans.factory.annotation.Value; 28 | import org.springframework.scheduling.annotation.Scheduled; 29 | import org.springframework.stereotype.Service; 30 | 31 | import lombok.extern.slf4j.Slf4j; 32 | import oscuroweb.ia.dto.Column; 33 | import oscuroweb.ia.service.SparkService; 34 | 35 | @Slf4j 36 | @Service 37 | public class SparkServiceImpl implements SparkService { 38 | 39 | @Autowired 40 | private SparkSession spark; 41 | 42 | @Value("${models.path}") 43 | private String modelFolderPath; 44 | 45 | @Value("${models.versioned:false}") 46 | private Boolean modelVersioned; 47 | 48 | @Value("${dataset.file}") 49 | private String csvFile; 50 | 51 | // private long version = 0; 52 | 53 | /** 54 | * Scheduler Service that construct a Machine Learning model to predict the income. 55 | */ 56 | @Scheduled(fixedDelay = 360000) 57 | @Override 58 | public void mlService() { 59 | 60 | Instant instant = Instant.now(); 61 | Long version = instant.toEpochMilli(); 62 | 63 | spark.sparkContext().setLogLevel("ERROR"); 64 | 65 | Dataset dataset = spark.read() 66 | .option("ignoreLeadingWhiteSpace", true) 67 | .csv(csvFile); 68 | dataset.show(); 69 | 70 | dataset = renameDataset(dataset); 71 | 72 | // Transform string columns to integer 73 | Map indexerModels = new HashMap(); 74 | indexerModels.put("_c1", new StringIndexer().setInputCol(Column.WORKCLASS.colName()).setOutputCol(Column.WORKCLASS_INDEX.colName()).fit(dataset)); 75 | indexerModels.put("_c3", new StringIndexer().setInputCol(Column.EDUCATION.colName()).setOutputCol(Column.EDUCATION_INDEX.colName()).fit(dataset)); 76 | indexerModels.put("_c5", new StringIndexer().setInputCol(Column.MARITAL_STATUS.colName()).setOutputCol(Column.MARITAL_STATUS_INDEX.colName()).fit(dataset)); 77 | indexerModels.put("_c6", new StringIndexer().setInputCol(Column.OCCUPATION.colName()).setOutputCol(Column.OCCUPATION_INDEX.colName()).fit(dataset)); 78 | indexerModels.put("_c7", new StringIndexer().setInputCol(Column.RELATIONSHIP.colName()).setOutputCol(Column.RELATIONSHIP_INDEX.colName()).fit(dataset)); 79 | indexerModels.put("_c8", new StringIndexer().setInputCol(Column.RACE.colName()).setOutputCol(Column.RACE_INDEX.colName()).fit(dataset)); 80 | indexerModels.put("_c9", new StringIndexer().setInputCol(Column.SEX.colName()).setOutputCol(Column.SEX_INDEX.colName()).fit(dataset)); 81 | indexerModels.put("_c13", new StringIndexer().setInputCol(Column.NATIVE_COUNTRY.colName()).setOutputCol(Column.NATIVE_COUNTRY_INDEX.colName()).fit(dataset)); 82 | indexerModels.put("_c14", new StringIndexer().setInputCol(Column.INCOME.colName()).setOutputCol(Column.INCOME_INDEX.colName()).fit(dataset)); 83 | 84 | for (String modelKey : indexerModels.keySet()) { 85 | StringIndexerModel model = indexerModels.get(modelKey); 86 | dataset = model.transform(dataset); 87 | saveModel(model, modelKey, version); 88 | 89 | } 90 | 91 | // Create features column 92 | String[] input = { 93 | Column.AGE.colName(), 94 | Column.WORKCLASS_INDEX.colName(), 95 | Column.FNLWGT.colName(), 96 | Column.EDUCATION_INDEX.colName(), 97 | Column.EDUCATION_NUM.colName(), 98 | Column.MARITAL_STATUS_INDEX.colName(), 99 | Column.OCCUPATION_INDEX.colName(), 100 | Column.RELATIONSHIP_INDEX.colName(), 101 | Column.RACE_INDEX.colName(), 102 | Column.SEX_INDEX.colName(), 103 | Column.CAPITAL_GAIN.colName(), 104 | Column.CAPITAL_LOSS.colName(), 105 | Column.HOURS_PER_WEEK.colName(), 106 | Column.NATIVE_COUNTRY_INDEX.colName()}; 107 | 108 | dataset = new VectorAssembler() 109 | .setInputCols(input) 110 | .setOutputCol(Column.FEATURES.colName()) 111 | .transform(dataset); 112 | 113 | dataset.show(); 114 | 115 | 116 | // Convert indexed labels back to original labels. 117 | IndexToString c14Label = new IndexToString() 118 | .setInputCol(Column.PREDICTION.colName()) 119 | .setOutputCol(Column.PREDICTION_LABEL.colName()) 120 | .setLabels(indexerModels.get("_c14").labels()); 121 | 122 | 123 | // Split dataset 124 | Dataset[] splitDataset = dataset.randomSplit(new double[] { 0.7, 0.3 }); 125 | Dataset training = splitDataset[0]; 126 | Dataset test = splitDataset[1]; 127 | 128 | // DecisionTree Model 129 | DecisionTreeClassificationModel dtModel = decisionTreeModel(training); 130 | Dataset predictionsDT = dtModel.transform(test); 131 | double accuracyDT = evaluateModel(predictionsDT, c14Label); 132 | 133 | System.out.println("Test Error Decision Tree = " + (1.0 - accuracyDT)); 134 | 135 | // RandomForest Model 136 | RandomForestClassificationModel rfModel = randomForestModel(training); 137 | Dataset predictionsRF = rfModel.transform(test); 138 | double accuracyRF = evaluateModel(predictionsRF, c14Label); 139 | System.out.println("Test Error Random Forest = " + (1.0 - accuracyRF)); 140 | 141 | // Save the best model 142 | saveModel(rfModel, "rfModel", version); 143 | saveModel(dtModel, "dtModel", version); 144 | 145 | } 146 | 147 | /** 148 | * Create decision tree model 149 | * @param training Training dataset 150 | * @return decision tree model 151 | */ 152 | private DecisionTreeClassificationModel decisionTreeModel(Dataset training) { 153 | 154 | DecisionTreeClassifier dt = new DecisionTreeClassifier() 155 | .setLabelCol(Column.INCOME_INDEX.colName()) 156 | .setFeaturesCol(Column.FEATURES.colName()) 157 | .setMaxBins(45); 158 | return dt.fit(training); 159 | } 160 | 161 | /** 162 | * Create a random forest model 163 | * @param training Training dataset 164 | * @return random forest model 165 | */ 166 | private RandomForestClassificationModel randomForestModel(Dataset training) { 167 | 168 | RandomForestClassifier rf = new RandomForestClassifier() 169 | .setLabelCol(Column.INCOME_INDEX.colName()) 170 | .setFeaturesCol(Column.FEATURES.colName()) 171 | .setMaxBins(45); 172 | return rf.fit(training); 173 | 174 | } 175 | 176 | /** 177 | * Evaluate model predictions 178 | * @param predictions Prediction dataset 179 | * @param c14Label IndexToLabel transformer 180 | * @return Accuracy of the model 181 | */ 182 | private double evaluateModel(Dataset predictions, IndexToString c14Label) { 183 | 184 | predictions = c14Label.transform(predictions); 185 | 186 | // Select example rows to display. 187 | predictions.select(Column.PREDICTION.colName(), 188 | Column.PREDICTION_LABEL.colName(), 189 | Column.INCOME.colName(), 190 | Column.AGE.colName(), 191 | Column.WORKCLASS.colName(), 192 | Column.FNLWGT.colName(), 193 | Column.EDUCATION.colName(), 194 | Column.EDUCATION_NUM.colName(), 195 | Column.MARITAL_STATUS.colName(), 196 | Column.OCCUPATION.colName(), 197 | Column.RELATIONSHIP.colName(), 198 | Column.RACE.colName(), 199 | Column.SEX.colName(), 200 | Column.CAPITAL_GAIN.colName(), 201 | Column.CAPITAL_LOSS.colName(), 202 | Column.HOURS_PER_WEEK.colName(), 203 | Column.NATIVE_COUNTRY.colName()) 204 | .show(false); 205 | 206 | // Select (prediction, true label) and compute test error. 207 | MulticlassClassificationEvaluator evaluator = new MulticlassClassificationEvaluator() 208 | .setLabelCol(Column.INCOME_INDEX.colName()) 209 | .setPredictionCol(Column.PREDICTION.colName()) 210 | .setMetricName("accuracy"); 211 | 212 | return evaluator.evaluate(predictions); 213 | } 214 | 215 | /** 216 | * Rename dataset 217 | * @param dataset Original dataset 218 | * @return Renamed dataset 219 | */ 220 | private Dataset renameDataset(Dataset dataset) { 221 | 222 | 223 | return dataset.withColumn("_c0", dataset.col("_c0").cast("double")) 224 | .withColumn("_c2", dataset.col("_c2").cast("double")) 225 | .withColumn("_c4", dataset.col("_c4").cast("double")) 226 | .withColumn("_c10", dataset.col("_c10").cast("double")) 227 | .withColumn("_c11", dataset.col("_c11").cast("double")) 228 | .withColumn("_c12", dataset.col("_c12").cast("double")) 229 | .withColumnRenamed("_c0", Column.AGE.colName()) 230 | .withColumnRenamed("_c1", Column.WORKCLASS.colName()) 231 | .withColumnRenamed("_c2", Column.FNLWGT.colName()) 232 | .withColumnRenamed("_c3", Column.EDUCATION.colName()) 233 | .withColumnRenamed("_c4", Column.EDUCATION_NUM.colName()) 234 | .withColumnRenamed("_c5", Column.MARITAL_STATUS.colName()) 235 | .withColumnRenamed("_c6", Column.OCCUPATION.colName()) 236 | .withColumnRenamed("_c7", Column.RELATIONSHIP.colName()) 237 | .withColumnRenamed("_c8", Column.RACE.colName()) 238 | .withColumnRenamed("_c9", Column.SEX.colName()) 239 | .withColumnRenamed("_c10", Column.CAPITAL_GAIN.colName()) 240 | .withColumnRenamed("_c11", Column.CAPITAL_LOSS.colName()) 241 | .withColumnRenamed("_c12", Column.HOURS_PER_WEEK.colName()) 242 | .withColumnRenamed("_c13", Column.NATIVE_COUNTRY.colName()) 243 | .withColumnRenamed("_c14", Column.INCOME.colName()); 244 | } 245 | 246 | /** 247 | * Save model 248 | * @param model Model to save 249 | * @param name Name of the model 250 | */ 251 | private void saveModel(MLWritable model, String name, Long version) { 252 | 253 | 254 | String fullPath = formatPath(version).concat(name); 255 | log.debug("Full path to be saved: " + fullPath); 256 | 257 | try { 258 | model.save(fullPath); 259 | } catch (IOException e) { 260 | try { 261 | log.info("Removed directory {}", fullPath); 262 | model.write().overwrite().save(fullPath); 263 | } catch (IOException e1) { 264 | log.error("Error trying to save model {}", fullPath, e.getMessage()); 265 | } 266 | } 267 | log.info("Model {} saved", fullPath); 268 | } 269 | 270 | private String formatPath(Long version) { 271 | 272 | String formatedPath = modelFolderPath; 273 | 274 | if (!formatedPath.endsWith("/")) { 275 | formatedPath = formatedPath.concat("/"); 276 | } 277 | 278 | if (modelVersioned) { 279 | formatedPath = formatedPath.concat(version + "/"); 280 | } 281 | 282 | return formatedPath; 283 | } 284 | 285 | @Override 286 | public long getVersion() { 287 | if (modelVersioned) { 288 | List lista = getAvailableVersions(); 289 | lista.sort(Comparator.reverseOrder()); 290 | if (lista.size() > 0) 291 | return lista.get(0); 292 | else 293 | return 0; 294 | } else { 295 | return 0; 296 | } 297 | } 298 | 299 | @Override 300 | public List getAvailableVersions() { 301 | Long[] array = {0l}; 302 | if (modelVersioned) { 303 | File path = new File(modelFolderPath); 304 | List lista = new ArrayList<>(); 305 | Arrays.asList(path.list()).forEach(f -> { 306 | try { 307 | Long l = Long.parseLong(f); 308 | lista.add(l); 309 | } catch (Exception e) { 310 | log.debug(e.getMessage());; 311 | } 312 | }); 313 | return lista; 314 | } else { 315 | return Arrays.asList(array); 316 | } 317 | } 318 | 319 | } 320 | -------------------------------------------------------------------------------- /income-predictor-vaadin/src/main/java/oscuroweb/ia/screen/IncomeInputScreen.java: -------------------------------------------------------------------------------- 1 | package oscuroweb.ia.screen; 2 | 3 | import com.jarektoro.responsivelayout.ResponsiveColumn.ColumnComponentAlignment; 4 | import com.jarektoro.responsivelayout.ResponsiveLayout; 5 | import com.jarektoro.responsivelayout.ResponsiveRow; 6 | import com.vaadin.data.Binder; 7 | import com.vaadin.data.converter.StringToDoubleConverter; 8 | import com.vaadin.icons.VaadinIcons; 9 | import com.vaadin.navigator.View; 10 | import com.vaadin.spring.annotation.SpringView; 11 | import com.vaadin.ui.Alignment; 12 | import com.vaadin.ui.Button; 13 | import com.vaadin.ui.Button.ClickEvent; 14 | import com.vaadin.ui.ComboBox; 15 | import com.vaadin.ui.Label; 16 | import com.vaadin.ui.Notification; 17 | import com.vaadin.ui.TextField; 18 | import com.vaadin.ui.UI; 19 | import com.vaadin.ui.Window; 20 | import com.vaadin.ui.themes.ValoTheme; 21 | 22 | import lombok.Getter; 23 | import lombok.Setter; 24 | import lombok.extern.slf4j.Slf4j; 25 | import oscuroweb.ia.converter.EducationTypeConverter; 26 | import oscuroweb.ia.converter.MaritalStatusTypeConverter; 27 | import oscuroweb.ia.converter.NativeCountryTypeConverter; 28 | import oscuroweb.ia.converter.OccupationTypeConverter; 29 | import oscuroweb.ia.converter.RaceTypeConverter; 30 | import oscuroweb.ia.converter.RelationshipTypeConverter; 31 | import oscuroweb.ia.converter.SexTypeConverter; 32 | import oscuroweb.ia.converter.WorkClassTypeConverter; 33 | import oscuroweb.ia.dto.IncomeDto; 34 | import oscuroweb.ia.dto.OutputDto; 35 | import oscuroweb.ia.dto.OutputResultDto; 36 | import oscuroweb.ia.type.EducationType; 37 | import oscuroweb.ia.type.MaritalStatusType; 38 | import oscuroweb.ia.type.NativeCountryType; 39 | import oscuroweb.ia.type.OccupationType; 40 | import oscuroweb.ia.type.RaceType; 41 | import oscuroweb.ia.type.RelationshipType; 42 | import oscuroweb.ia.type.SexType; 43 | import oscuroweb.ia.type.WorkClassType; 44 | 45 | @Getter @Setter 46 | @Slf4j 47 | @SpringView(name = IncomeInputScreen.VIEW_NAME) 48 | public class IncomeInputScreen extends AbstractIncomeView implements View { 49 | 50 | public static final String VIEW_NAME = ""; 51 | 52 | private static final long serialVersionUID = 1987326654373106728L; 53 | 54 | private TextField age; 55 | private TextField fnlwgt; 56 | private TextField capitalGain; 57 | private TextField capitalLoss; 58 | private TextField hoursPerWeek; 59 | private TextField educationNum; 60 | private Label lblResult; 61 | private Label lblTitle; 62 | private Button bnIncome; 63 | private Button bnYes; 64 | private Button bnNo; 65 | private ComboBox sex; 66 | private ComboBox race; 67 | private ComboBox relationship; 68 | private ComboBox occupation; 69 | private ComboBox maritalStatus; 70 | private ComboBox eduaction; 71 | private ComboBox workClass; 72 | private ComboBox nativeCountry; 73 | 74 | private Binder binder; 75 | private IncomeDto income = IncomeDto.builder().build(); 76 | 77 | private Window windowResult; 78 | 79 | private String result; 80 | 81 | protected void initView() { 82 | 83 | initializeTextFields(); 84 | initializeCombos(); 85 | initializeWindowResult(); 86 | initializeBinder(); 87 | // TODO Remove 88 | initializeForm(); 89 | 90 | ResponsiveRow row = createRow(); 91 | 92 | addColumns(row, 93 | age, 94 | workClass, 95 | fnlwgt, 96 | eduaction, 97 | educationNum, 98 | maritalStatus, 99 | occupation, 100 | relationship, 101 | race, 102 | sex, 103 | capitalGain, 104 | capitalLoss, 105 | hoursPerWeek, 106 | nativeCountry); 107 | 108 | bnIncome = new Button("Get Income"); 109 | bnIncome.setIcon(VaadinIcons.SEARCH); 110 | bnIncome.addStyleNames(ValoTheme.BUTTON_HUGE, ValoTheme.BUTTON_BORDERLESS); 111 | bnIncome.addClickListener(event -> onClickIncomeButton(event)); 112 | 113 | ResponsiveRow btRow = createRow(); 114 | btRow.setDefaultComponentAlignment(Alignment.MIDDLE_CENTER); 115 | 116 | addColumn(btRow, bnIncome); 117 | } 118 | 119 | private void initializeTextFields() { 120 | age = new TextField("Age:"); 121 | fnlwgt = new TextField("Sampling weight:"); 122 | capitalGain = new TextField("Capital Gain:"); 123 | capitalLoss = new TextField("Capital Loss:"); 124 | hoursPerWeek = new TextField("Hours Per Week:"); 125 | educationNum = new TextField("Education Number:"); 126 | educationNum.setEnabled(false); 127 | } 128 | 129 | private void initializeWindowResult() { 130 | lblTitle = new Label("Your income is"); 131 | lblTitle.addStyleNames(ValoTheme.LABEL_H3, ValoTheme.LABEL_BOLD); 132 | lblResult = new Label(); 133 | lblResult.addStyleNames(ValoTheme.LABEL_H3, ValoTheme.LABEL_COLORED, ValoTheme.LABEL_BOLD); 134 | 135 | bnYes = new Button("Yes"); 136 | bnYes.addStyleNames(ValoTheme.BUTTON_FRIENDLY, ValoTheme.BUTTON_LARGE); 137 | bnYes.setIcon(VaadinIcons.CHECK_CIRCLE); 138 | bnYes.addClickListener(event -> onClickYesButton(event)); 139 | 140 | bnNo = new Button("No"); 141 | bnNo.addStyleNames(ValoTheme.BUTTON_DANGER, ValoTheme.BUTTON_LARGE); 142 | bnNo.setIcon(VaadinIcons.CLOSE_CIRCLE); 143 | bnNo.addClickListener(event -> onClickNoButton(event)); 144 | 145 | 146 | ResponsiveLayout windowLayout = new ResponsiveLayout(); 147 | 148 | ResponsiveRow resultRow = createRow(12, 12, 6, 6); 149 | resultRow.addColumn() 150 | .withVisibilityRules(false, false, true, true) 151 | .withComponent(lblTitle, ColumnComponentAlignment.RIGHT); 152 | resultRow.addColumn() 153 | .withComponent(lblResult, ColumnComponentAlignment.LEFT); 154 | windowLayout.addRow(resultRow); 155 | 156 | ResponsiveRow btRow = createRow(12, 12, 6, 6); 157 | addColumns(btRow, bnYes, bnNo); 158 | windowLayout.addRow(btRow); 159 | 160 | windowResult = new Window("Income Prediction"); 161 | windowResult.setClosable(true); 162 | windowResult.setWidth(50, Unit.PERCENTAGE); 163 | windowResult.setHeight(50, Unit.PERCENTAGE); 164 | windowResult.center(); 165 | windowResult.setContent(windowLayout); 166 | } 167 | 168 | 169 | private void initializeCombos() { 170 | 171 | // Combo Sex 172 | sex = new ComboBox("Sex:"); 173 | sex.setItems(SexType.values()); 174 | // Use the name property for item captions 175 | sex.setItemCaptionGenerator(SexType::desc); 176 | 177 | // Combo Race 178 | race = new ComboBox("Race:"); 179 | race.setItems(RaceType.values()); 180 | // Use the name property for item captions 181 | race.setItemCaptionGenerator(RaceType::desc); 182 | 183 | // Combo Relationship 184 | relationship = new ComboBox("Relationship:"); 185 | relationship.setItems(RelationshipType.values()); 186 | // Use the name property for item captions 187 | relationship.setItemCaptionGenerator(RelationshipType::desc); 188 | 189 | // Combo Occupation 190 | occupation = new ComboBox("Occupation:"); 191 | occupation.setItems(OccupationType.values()); 192 | // Use the name property for item captions 193 | occupation.setItemCaptionGenerator(OccupationType::desc); 194 | 195 | // Combo Relationship 196 | maritalStatus = new ComboBox("Marital Status:"); 197 | maritalStatus.setItems(MaritalStatusType.values()); 198 | // Use the name property for item captions 199 | maritalStatus.setItemCaptionGenerator(MaritalStatusType::desc); 200 | 201 | // Combo workClass 202 | workClass = new ComboBox("WorkClass:"); 203 | workClass.setItems(WorkClassType.values()); 204 | // Use the name property for item captions 205 | workClass.setItemCaptionGenerator(WorkClassType::desc); 206 | 207 | // Combo Education 208 | eduaction = new ComboBox("Education:"); 209 | eduaction.setItems(EducationType.values()); 210 | // Use the name property for item captions 211 | eduaction.setItemCaptionGenerator(EducationType::desc); 212 | eduaction.addSelectionListener(selectedItem -> 213 | selectedItem.getSelectedItem().ifPresent(item -> 214 | educationNum.setValue(String.valueOf(item.num())) 215 | ) 216 | ); 217 | 218 | // Combo Native Country 219 | nativeCountry = new ComboBox("Native Country:"); 220 | nativeCountry.setItems(NativeCountryType.values()); 221 | // Use the name property for item captions 222 | nativeCountry.setItemCaptionGenerator(NativeCountryType::desc); 223 | } 224 | 225 | private void initializeBinder() { 226 | income = IncomeDto.builder().build(); 227 | binder = new Binder(IncomeDto.class); 228 | binder.forField(age) 229 | .asRequired() 230 | .withConverter(new StringToDoubleConverter("Must be enter a number")) 231 | .withValidator(ageValue -> ageValue > 0d && ageValue <= 120d, "More than 1 and less than 120") 232 | .bind(IncomeDto::getAge, IncomeDto::setAge); 233 | binder.forField(fnlwgt) 234 | .asRequired() 235 | .withConverter(new StringToDoubleConverter("Must be enter a number")) 236 | .bind(IncomeDto::getFnlwgt, IncomeDto::setFnlwgt); 237 | binder.forField(capitalGain) 238 | .asRequired() 239 | .withConverter(new StringToDoubleConverter("Must be enter a number")) 240 | .bind(IncomeDto::getCapitalGain, IncomeDto::setCapitalLoss); 241 | binder.forField(capitalLoss) 242 | .asRequired() 243 | .withConverter(new StringToDoubleConverter("Must be enter a number")) 244 | .bind(IncomeDto::getCapitalLoss, IncomeDto::setCapitalLoss); 245 | binder.forField(hoursPerWeek) 246 | .asRequired() 247 | .withConverter(new StringToDoubleConverter("Must be enter a number")) 248 | .withValidator(hours -> hours >= 0 && hours < 80, "More than 0 and less than 80") 249 | .bind(IncomeDto::getHoursPerWeek, IncomeDto::setHoursPerWeek ); 250 | binder.forField(educationNum) 251 | .asRequired() 252 | .withConverter(new StringToDoubleConverter("Must be enter a number")) 253 | .bind(IncomeDto::getEducationNum, IncomeDto::setEducationNum ); 254 | binder.forField(sex) 255 | .asRequired() 256 | .withConverter(new SexTypeConverter()) 257 | .bind(IncomeDto::getSex, IncomeDto::setSex); 258 | binder.forField(race) 259 | .asRequired() 260 | .withConverter(new RaceTypeConverter()) 261 | .bind(IncomeDto::getRace, IncomeDto::setRace); 262 | binder.forField(relationship) 263 | .asRequired() 264 | .withConverter(new RelationshipTypeConverter()) 265 | .bind(IncomeDto::getRelationship, IncomeDto::setRelationship); 266 | binder.forField(occupation) 267 | .asRequired() 268 | .withConverter(new OccupationTypeConverter()) 269 | .bind(IncomeDto::getOccupation, IncomeDto::setOccupation); 270 | binder.forField(maritalStatus) 271 | .asRequired() 272 | .withConverter(new MaritalStatusTypeConverter()) 273 | .bind(IncomeDto::getMaritalStatus, IncomeDto::setMaritalStatus); 274 | binder.forField(eduaction) 275 | .asRequired() 276 | .withConverter(new EducationTypeConverter()) 277 | .bind(IncomeDto::getEducation, IncomeDto::setEducation); 278 | binder.forField(workClass) 279 | .asRequired() 280 | .withConverter(new WorkClassTypeConverter()) 281 | .bind(IncomeDto::getWorkclass, IncomeDto::setWorkclass); 282 | binder.forField(nativeCountry) 283 | .asRequired() 284 | .withConverter(new NativeCountryTypeConverter()) 285 | .bind(IncomeDto::getNativeCountry, IncomeDto::setNativeCountry); 286 | 287 | } 288 | 289 | private void initializeForm() { 290 | income = IncomeDto.builder() 291 | .age(23d) 292 | .capitalGain(1000d) 293 | .capitalLoss(10d) 294 | .education(EducationType.ASSOC_ACDM.desc()) 295 | .educationNum(EducationType.ASSOC_ACDM.num()) 296 | .fnlwgt(1000d) 297 | .hoursPerWeek(40d) 298 | .maritalStatus(MaritalStatusType.DIVORCED.desc()) 299 | .nativeCountry(NativeCountryType.CAMBODIA.desc()) 300 | .occupation(OccupationType.ADM_CLERICAL.desc()) 301 | .race(RaceType.AMER_INDIAN_ESKIMO.desc()) 302 | .relationship(RelationshipType.HUSBAND.desc()) 303 | .sex(SexType.FEMALE.desc()) 304 | .workclass(WorkClassType.FEDERAL_GOV.desc()) 305 | .build(); 306 | 307 | binder.bindInstanceFields(income); 308 | binder.readBean(income); 309 | } 310 | 311 | private void onClickYesButton(ClickEvent event) { 312 | sendResults(true); 313 | } 314 | 315 | private void onClickNoButton(ClickEvent event) { 316 | sendResults(false); 317 | } 318 | 319 | private void onClickIncomeButton(ClickEvent event) { 320 | 321 | boolean valid = binder.writeBeanIfValid(income); 322 | 323 | if (valid) { 324 | try { 325 | log.info("Income: {}", income.toString()); 326 | OutputDto output = restclient.evaluateData(income); 327 | 328 | lblResult.setValue(output.getLabel()); 329 | result = output.getLabel(); 330 | UI.getCurrent().addWindow(windowResult); 331 | } catch (Exception e) { 332 | log.error("An error ocurred invoking the service: {}", e.getMessage(), e); 333 | Notification.show("An error ocurred invoking the service", Notification.Type.ERROR_MESSAGE); 334 | } 335 | } else { 336 | Notification.show("Invalid income", Notification.Type.ERROR_MESSAGE); 337 | } 338 | } 339 | 340 | private void sendResults(boolean evalresult) { 341 | 342 | income.setSuccess(evalresult); 343 | 344 | OutputResultDto outputDto = restclient.addResult(income); 345 | 346 | if (outputDto != null && outputDto.getUpdated()) { 347 | Notification.show("Result sent", Notification.Type.HUMANIZED_MESSAGE); 348 | } else { 349 | Notification.show("An error ocurred", Notification.Type.WARNING_MESSAGE); 350 | } 351 | 352 | windowResult.close(); 353 | } 354 | 355 | } 356 | --------------------------------------------------------------------------------