本文将介绍如何使用ML.NET框架中的随机梯度下降算法来预测房屋租金。我们将使用印度房屋租赁数据集,该数据集包含了约4700条房屋租赁信息,包括卧室数量、面积、位置等特征。
安装 .NET 6.0 或更高版本
**创建控制台项目并引用 **ML.NET
textdotnet add package Microsoft.ML

C#using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.ML.Data;
namespace AppHousingRent
{
public class HouseRentData
{
[LoadColumn(0)]
public float CRIM { get; set; } // 城镇人均犯罪率
[LoadColumn(1)]
public float ZN { get; set; } // 占地面积超过25000平方呎的住宅用地比例
[LoadColumn(2)]
public float INDUS { get; set; } // 城镇非零售商业用地比例
[LoadColumn(3)]
public float CHAS { get; set; } // 是否临近查尔斯河
[LoadColumn(4)]
public float NOX { get; set; } // 一氧化氮浓度
[LoadColumn(5)]
public float RM { get; set; } // 住宅平均房间数
[LoadColumn(6)]
public float AGE { get; set; } // 1940年之前建成的自用房屋比例
[LoadColumn(7)]
public float DIS { get; set; } // 到波士顿五个就业中心的加权距离
[LoadColumn(8)]
public float RAD { get; set; } // 到径向公路的可达性指数
[LoadColumn(9)]
public float TAX { get; set; } // 每10000美元的全值财产税率
[LoadColumn(10)]
public float PTRATIO { get; set; } // 城镇师生比例
[LoadColumn(11)]
public float B { get; set; } // 1000(Bk - 0.63)^2,其中Bk为城镇中黑人的比例
[LoadColumn(12)]
public float LSTAT { get; set; } // 人口中地位较低者的比例
[LoadColumn(13)]
[ColumnName("Label")] // 将MEDV标记为Label列
public float MEDV { get; set; } // 自住房的平均房价,以千美元计
}
public class HouseRentPrediction
{
[ColumnName("Score")]
public float PredictedPrice { get; set; }
}
}
C#using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.ML;
namespace AppHousingRent
{
public class HouseRentPredictor
{
private static readonly string _dataPath = "housing.csv";
public static void Train()
{
try
{
// 创建ML.NET上下文
var mlContext = new MLContext(seed: 0);
// 加载数据
Console.WriteLine($"正在加载数据...");
IDataView dataView = mlContext.Data.LoadFromTextFile<HouseRentData>(
path: _dataPath,
hasHeader: false, // 数据集中没有标题行
separatorChar: ' ' // 数据是用空格分隔的
);
// 分割数据为训练集和测试集
var trainTestData = mlContext.Data.TrainTestSplit(dataView, testFraction: 0.2, seed: 0);
// 创建数据处理管道
var pipeline = mlContext.Transforms.Concatenate("Features", new[]
{
"CRIM", "ZN", "INDUS", "CHAS", "NOX", "RM", "AGE",
"DIS", "RAD", "TAX", "PTRATIO", "B", "LSTAT"
})
.Append(mlContext.Transforms.NormalizeMinMax("Features")) // 添加特征标准化
.Append(mlContext.Regression.Trainers.Sdca(
labelColumnName: "Label", // 使用Label作为标签列名
maximumNumberOfIterations: 100));
// 训练模型
Console.WriteLine("开始训练模型...");
var model = pipeline.Fit(trainTestData.TrainSet);
Console.WriteLine("模型训练完成。");
// 对测试集进行预测
var predictions = model.Transform(trainTestData.TestSet);
// 评估模型
var metrics = mlContext.Regression.Evaluate(
data: predictions,
labelColumnName: "Label", // 使用Label作为标签列名
scoreColumnName: "Score");
// 输出评估指标
Console.WriteLine($"\n模型评估指标:");
Console.WriteLine($"R² Score: {metrics.RSquared:0.###}");
Console.WriteLine($"均方根误差: {metrics.RootMeanSquaredError:0.###}");
Console.WriteLine($"平均绝对误差: {metrics.MeanAbsoluteError:0.###}");
// 保存模型
mlContext.Model.Save(model, dataView.Schema, "BostonHouseModel.zip");
Console.WriteLine("\n模型已保存到 BostonHouseModel.zip");
}
catch (Exception ex)
{
Console.WriteLine($"\n发生错误: {ex.Message}");
Console.WriteLine($"堆栈跟踪: {ex.StackTrace}");
}
}
// 用于预测的方法
public static float PredictPrice(HouseRentData inputData)
{
var mlContext = new MLContext();
DataViewSchema modelSchema;
var model = mlContext.Model.Load("BostonHouseModel.zip", out modelSchema);
var predEngine = mlContext.Model.CreatePredictionEngine<HouseRentData, HouseRentPrediction>(model);
var prediction = predEngine.Predict(inputData);
return prediction.PredictedPrice;
}
}
}
C#public static void Main(string[] args)
{
// 训练模型
HouseRentPredictor.Train();
// 创建示例数据
var sampleData = new HouseRentData()
{
CRIM = 0.00632f,
ZN = 18f,
INDUS = 2.31f,
CHAS = 0f,
NOX = 0.538f,
RM = 6.575f,
AGE = 65.2f,
DIS = 4.09f,
RAD = 1f,
TAX = 296f,
PTRATIO = 15.3f,
B = 396.9f,
LSTAT = 4.98f,
MEDV = 24.00f
};
// 进行预测
var prediction = HouseRentPredictor.PredictPrice(sampleData);
Console.WriteLine($"\n示例预测结果:");
Console.WriteLine($"预测房价: ${prediction * 1000:N0}");
}


其中 $(y_i)$ 是实际值,$(\hat{y}_i)$ 是预测值。

因此,日志信息里输出的:
本文展示了如何使用ML.NET框架中的SGD算法来预测房屋租金。通过合理的特征工程和模型训练,我们可以构建一个实用的房屋租金预测系统。该实现考虑了实际应用中的各种因素,包括分类特征处理、模型评估和预测接口设计。
本文作者:技术老小子
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!