π In this project, I built a modular dashboard to analyze Netflix content trends using ML.NET, CsvHelper, and Razor Pages β with bargraph visualizations for genre, country, and release year insights.
π Tech Stack
- ML.NET: SdcaMaximumEntropy for multiclass classification
- CsvHelper.Configuration: Clean parsing of Netflix dataset
- Razor Pages: UI with dropdown filters and summary cards
- Chart.js: Interactive bargraphs for visual storytelling
- LINQ: Dynamic filtering by genre, type, country, and year
π Dataset
Used the Netflix Movies and TV Shows dataset from Kaggle:
- Fields: Title, Type, Country, Genre, Release Year, Rating
π§ ML.NET Model: Content Type Classifier trained model in console app
var pipeline = mlContext.Transforms.Text.FeaturizeText("TitleFeats", nameof(TitleData.Title))
.Append(mlContext.Transforms.Text.FeaturizeText("GenreFeats", nameof(TitleData.Genre)))
.Append(mlContext.Transforms.Text.FeaturizeText("DescFeats", nameof(TitleData.Description)))
.Append(mlContext.Transforms.Text.FeaturizeText("DurationFeats", nameof(TitleData.Duration)))
.Append(mlContext.Transforms.Conversion.MapValueToKey("Label", nameof(Type)))
.Append(mlContext.MulticlassClassification.Trainers.SdcaMaximumEntropy("Label", "Features"))
.Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel"));
return pipeline;
Initialize ML.NET Context
var mlContext = new MLContext();
Define Paths
var modelPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "models", "Model.zip");
var dataPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "models", "netflix_titles.csv");
Load Data with ML.NET
IDataView dataView = mlContext.Data.LoadFromTextFile<TitleData>(
dataPath, separatorChar: ',', hasHeader: true);
var dataEnumerable = mlContext.Data.CreateEnumerable<TitleData>(
dataView, reuseRowObject: false).Take(100).ToList();
This gives us a sample of 100 titles for quick dashboard rendering.
Parse CSV with CsvHelper
List<TitleData> records;
using (var reader = new StreamReader(dataPath))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
csv.Context.RegisterClassMap<TitleDataMap>();
records = csv.GetRecords<TitleData>().ToList();
}
CsvHelper ensures clean mapping and parsing of the full dataset.
ξ·ξ·
Predicts whether a title is a Movie or TV Show based on its name and genre.
π Dashboard Visuals
π¬ Movies vs TV Shows
TypeCounts = records
.GroupBy(p => p.Type)
.Select(g => new TypeCount
{
Type = g.Key,
Count = g.Count()
})
.ToList();
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
const typectx = document.getElementById('typeChart').getContext('2d');
const typeChart = new Chart(typectx, {
type: 'bar',
data: {
labels: @Html.Raw(Json.Serialize(type)),
datasets: [{
label: 'Movies vs TV Shows on Netflix',
data: @Html.Raw(Json.Serialize(values)),
backgroundColor: ['#4e79a7', '#f28e2b'],
// borderWidth: 1
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
title: {
display: true,
text: 'Count'
}
},
x: {
title: {
display: true,
text: 'Type'
}
}
}
}
});
</script>
π Top 10 Countries Producing Netflix Content
Bargraph: Country-wise content count
TopCountries = records
.Where(r => !string.IsNullOrWhiteSpace(r.Country))
.SelectMany(r => r.Country.Split(','))
.Select(c => c.Trim())
.GroupBy(c => c)
.Select(g => new CountryCount
{
Country = g.Key,
Count = g.Count()
})
.OrderByDescending(c => c.Count)
.Take(10)
.ToList();
<script>
const countryctx = document.getElementById('countryChart').getContext('2d');
const countrychart = new Chart(countryctx, {
type: 'bar',
data: {
labels: @Html.Raw(Json.Serialize(Model.TopCountries.Select(c => c.Country))),
datasets: [{
label: 'Top 10 Countries producing Netflix content',
data: @Html.Raw(Json.Serialize(Model.TopCountries.Select(c => c.Count))),
backgroundColor: 'rgba(255, 99, 132, 0.6)'
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
title: {
display: true,
text: 'Number of Titles'
}
},
x: {
title: {
display: true,
text: 'Country'
}
}
}
}
});
</script>
π
Content by Release Year
Bargraph: Titles released per year
YearCounts = records
.Select(r => new
{
ParsedYear = int.TryParse(r.Year, out var y) ? y : 0
})
.Where(x => x.ParsedYear > 1900)
.GroupBy(x => x.ParsedYear)
.Select(g => new YearCount
{
Year = g.Key,
Count = g.Count()
})
.OrderBy(y => y.Year)
.ToList();
<script>
const yearctx = document.getElementById('yearChart').getContext('2d');
const yearchart = new Chart(yearctx, {
type: 'bar',
data: {
labels: @Html.Raw(Json.Serialize(Model.YearCounts.Select(y => y.Year))),
datasets: [{
label: 'Netflix Content by Release Year',
data: @Html.Raw(Json.Serialize(Model.YearCounts.Select(y => y.Count))),
backgroundColor: 'rgba(54, 162, 235, 0.6)'
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
title: {
display: true,
text: 'Number of Titles'
}
},
x: {
title: {
display: true,
text: 'Release Year'
}
}
}
}
});
</script>
π Top Genres on Netflix
Bargraph: Genre frequency across all titles
TopGenres = records
.Where(r => !string.IsNullOrWhiteSpace(r.Genre))
.SelectMany(r => r.Genre.Split(','))
.Select(g => g.Trim())
.GroupBy(g => g)
.Select(g => new GenreCount
{
Genre = g.Key,
Count = g.Count()
})
.OrderByDescending(g => g.Count)
.Take(10)
.ToList();
<script>
const genrectx = document.getElementById('genreChart').getContext('2d');
const genreChart = new Chart(genrectx, {
type: 'bar',
data: {
labels: @Html.Raw(Json.Serialize(Model.TopGenres.Select(g => g.Genre))),
datasets: [{
label: 'Top 10 Genres on Netflix',
data: @Html.Raw(Json.Serialize(Model.TopGenres.Select(g => g.Count))),
backgroundColor: 'rgba(153, 102, 255, 0.6)'
}]
},
options: {
indexAxis: 'y', // Horizontal bar chart
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
title: {
display: true,
text: 'Number of Titles'
}
},
x: {
title: {
display: true,
text: 'Genre'
}
}
}
}
});
</script>
π₯οΈ Razor Pages UI
- Dropdown filters: Genre, Country, Type, Year
- Summary cards: Total titles, Movies, TV Shows
- LINQ-powered filtering for real-time updates
- Chart.js for interactive visuals
π GitHub: https://github.com/reshmapotthuri/ML_NetflixAnalysis
β Conclusion
This project demonstrates how ML.NET can be seamlessly integrated into real-world dashboards β from classifying Netflix content with SdcaMaximumEntropy by combining Razor Pages, CsvHelper, and Chart.js
Top comments (0)