7.4.1 搜索引擎
7.4.2 推荐系统
7.4.3 金融算法
金融领域也广泛应用各种算法,如风险评估、交易策略、欺诈检测等。
金融领域使用的算法:
- 风险评估模型:
public class CreditScoreModel {
private double[] weights; // 特征权重
public CreditScoreModel(double[] weights) {
this.weights = weights;
}
public double calculateCreditScore(double[] features) {
if (features.length != weights.length) {
throw new IllegalArgumentException("Features length must match weights length");
}
double score = 0;
for (int i = 0; i < features.length; i++) {
score += features[i] * weights[i];
}
// 将分数映射到300-850的范围(标准信用分数范围)
return 300 + (score * 550 / 100);
}
public String getCreditRating(double creditScore) {
if (creditScore >= 800) return "Excellent";
if (creditScore >= 740) return "Very Good";
if (creditScore >= 670) return "Good";
if (creditScore >= 580) return "Fair";
return "Poor";
}
}
- 交易策略:
public class MovingAverageStrategy {
private int shortPeriod; // 短期移动平均线周期
private int longPeriod; // 长期移动平均线周期
private List<Double> prices = new ArrayList<>(); // 历史价格
public MovingAverageStrategy(int shortPeriod, int longPeriod) {
this.shortPeriod = shortPeriod;
this.longPeriod = longPeriod;
}
public void addPrice(double price) {
prices.add(price);
}
public String getSignal() {
if (prices.size() < longPeriod) {
return "HOLD"; // 数据不足,无法生成信号
}
double shortMA = calculateMA(shortPeriod);
double longMA = calculateMA(longPeriod);
// 短期均线上穿长期均线,买入信号
if (shortMA > longMA && calculateMA(shortPeriod, 1) <= calculateMA(longPeriod, 1)) {
return "BUY";
}
// 短期均线下穿长期均线,卖出信号
if (shortMA < longMA && calculateMA(shortPeriod, 1) >= calculateMA(longPeriod, 1)) {
return "SELL";
}
return "HOLD";
}
private double calculateMA(int period) {
return calculateMA(period, 0);
}
private double calculateMA(int period, int offset) {
int start = prices.size() - period - offset;
int end = prices.size() - offset;
double sum = 0;
for (int i = start; i < end; i++) {
sum += prices.get(i);
}
return sum / period;
}
}
- 欺诈检测:
public class FraudDetection {
private Map<String, List<Transaction>> userTransactions = new HashMap<>(); // 用户交易历史
public void addTransaction(Transaction transaction) {
userTransactions.computeIfAbsent(transaction.getUserId(), k -> new ArrayList<>())
.add(transaction);
}
public boolean isFraudulent(Transaction transaction) {
List<Transaction> history = userTransactions.getOrDefault(transaction.getUserId(), Collections.emptyList());
// 检查交易金额是否异常
if (isAmountAnomalous(transaction, history)) {
return true;
}
// 检查交易频率是否异常
if (isFrequencyAnomalous(transaction, history)) {
return true;
}
// 检查交易地点是否异常
if (isLocationAnomalous(transaction, history)) {
return true;
}
return false;
}
private boolean isAmountAnomalous(Transaction transaction, List<Transaction> history) {
if (history.isEmpty()) return false;
// 计算历史交易金额的平均值和标准差
double sum = 0;
for (Transaction t : history) {
sum += t.getAmount();
}
double mean = sum / history.size();
double variance = 0;
for (Transaction t : history) {
variance += Math.pow(t.getAmount() - mean, 2);
}
double stdDev = Math.sqrt(variance / history.size());
// 如果交易金额超过平均值的3个标准差,认为是异常
return transaction.getAmount() > mean + 3 * stdDev;
}
private boolean isFrequencyAnomalous(Transaction transaction, List<Transaction> history) {
if (history.isEmpty()) return false;
// 计算最近24小时内的交易次数
long recentCount = history.stream()
.filter(t -> t.getTimestamp() > transaction.getTimestamp() - 24 * 60 * 60 * 1000)
.count();
// 如果最近24小时内的交易次数超过10次,认为是异常
return recentCount > 10;
}
private boolean isLocationAnomalous(Transaction transaction, List<Transaction> history) {
if (history.isEmpty()) return false;
// 获取最近一次交易
Transaction lastTransaction = history.get(history.size() - 1);
// 计算两次交易之间的地理距离
double distance = calculateDistance(
lastTransaction.getLatitude(), lastTransaction.getLongitude(),
transaction.getLatitude(), transaction.getLongitude());
// 计算两次交易之间的时间差(小时)
double timeDiff = (transaction.getTimestamp() - lastTransaction.getTimestamp()) / (60 * 60 * 1000.0);
// 如果距离太远且时间太短,认为是异常
// 假设正常人的最大移动速度是1000公里/小时(飞机速度)
return distance > 1000 * timeDiff;
}
private double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
// 使用Haversine公式计算两点之间的距离
double earthRadius = 6371; // 地球半径(公里)
double dLat = Math.toRadians(lat2 - lat1);
double dLon = Math.toRadians(lon2 - lon1);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return earthRadius * c;
}
static class Transaction {
private String userId;
private double amount;
private long timestamp;
private double latitude;
private double longitude;
// 构造函数、getter和setter方法
// ...
public String getUserId() {
return userId;
}
public double getAmount() {
return amount;
}
public long getTimestamp() {
return timestamp;
}
public double getLatitude() {
return latitude;
}
public double getLongitude() {
return longitude;
}
}
}