Relative "number of unsafe keywords" or "lines inside unsafe blocks" isn't a good metric.
It's unsafe to call a C library that gives you a raw pointer, that can be a single line. It's unsafe to use that pointer, that could be a second single line. Carrying that pointer around, the data structures it's in, that's all safe, and doesn't implicate lifetime checking at all, so Rust will let you do silly things with the actual lifetime.
A better metric would be absolute unsafe keywords (because each carries a need to review), or "code in a module that uses unsafe anywhere" vs total code, because module boundaries isolate unsafe.
Yeah, one needs to understand that "unsafe" does not mark which parts of the code are actually unsafe, it simply marks parts where the compiler ignores parts of its rule set. But the implications can crop up anywhere, there is no guarantee that a resulting use-after-free or similar can only happen inside the unsafe blocks.
In short, if you use an unsafe block, then potentially any part of your code is unsafe.