网站首页 > 技术文章 正文
360的开机速度评分功能到底是谁最先想到的呢?很棒的创意。
说到这个评分功能,你有没有想过它是怎么计算出你的开机速度击败了全球百分之几的电脑呢?这看起来有点“2B”的功能,到底是怎么运作的?如果这些数据是从网上的数据库获取的,那它又是从哪个数据库来的呢?更奇怪的是,有时候即使你没联网也能看到这个排名结果。
在这种情况下,正态分布作为一种常用的统计模型,能够帮助我们更直观地理解这些数据的分布特征。
正态分布代表了宇宙中大多数情况的运转状态。大量的随机变量被证明是正态分布的。
无论是对数分布、幂律分布,还是指数分布,我们可以说,所有的概率分布,不是正态分布,就是在变成正态分布的路上。
0.正态分布知识点
1、正态分布公式
其中,μ是平均值,σ是标准差。
对于任意的x,我们想要知道它出现的概率,只需要将x带入上面的公式就可以得到。
2、标准差(Standard Deviation)
标准差是体现数据的离散程度的指标,计算公式如下:
标准差越大,数据越离散,体现在正态分布图形中就是曲线扁平。
标准差越小,数据越聚焦,正态分布曲线越凸起。
3、正态分布的性质
- 正态曲线关于x=μ对称(即μ决定正态曲线对称轴的位置),具有中间高、两边低的特点,平均值μ就是数学期望
- 正态曲线与x轴所围成的图形面积为1
- σ决定正态曲线的“胖瘦”:σ越大,说明标准差越大,数据的集中程度越弱,所以曲线越"胖";σ越小,说明标准差越小,数据的集中程度越强,所以曲线越"瘦",标准差σ决定胖瘦
1. 数据采集与分析
在分析用户开机时长之前,我们首先需要记录和计算系统从电源开启到完全启动所需的时间。
记录开机时间
使用以下脚本记录系统开机时间,可以确保数据的准确性。
import datetime
def record_boot_time():
boot_time = datetime.datetime.now()
with open("boot_time.txt", "w") as f:
f.write(boot_time.strftime('%Y-%m-%d %H:%M:%S'))
if __name__ == "__main__":
record_boot_time()
在 Windows 系统上,可以通过任务计划程序在每次系统启动时运行此脚本来记录开机时间。
确定系统完全启动的时间
可以通过某个关键服务或应用程序的启动时间来标记系统完全启动。
import datetime
def read_boot_time():
with open("boot_time.txt", "r") as f:
boot_time_str = f.read().strip()
return datetime.datetime.strptime(boot_time_str, '%Y-%m-%d %H:%M:%S')
def calculate_startup_duration(startup_complete_time):
boot_time = read_boot_time()
boot_duration = startup_complete_time - boot_time
return boot_duration.total_seconds()
if __name__ == "__main__":
startup_complete_time = datetime.datetime.now() # 实际启动完成时间应由系统提供
startup_duration = calculate_startup_duration(startup_complete_time)
print(f"从开机到系统完全启动所需的时间(秒): {startup_duration:.2f}")
获取实际启动完成时间
系统日志或关键服务启动时间可以用作系统完全启动的标志。
2. 生成模拟数据
为了模拟用户开机时长,我们生成一个包含 100,000 条开机时长数据的模拟数据集,假设开机时长符合正态分布。
import numpy as np
def generate_mock_data(num_samples=100000, mean=50, std_dev=10):
data = np.random.normal(loc=mean, scale=std_dev, size=num_samples)
data = np.abs(data)
return data
if __name__ == "__main__":
mock_data = generate_mock_data()
np.savetxt("mock_boot_times.csv", mock_data, delimiter=",", header="Boot Time (seconds)", comments="")
生成的mock_boot_times.csv如下:
将这个数据可视化显示出来:
import numpy as np
import matplotlib.pyplot as plt
def load_data(filename):
# 从 CSV 文件中读取数据
data = np.loadtxt(filename, delimiter=",", skiprows=1) # skiprows=1 跳过头部
return data
def plot_data(data):
# 绘制数据的直方图
plt.figure(figsize=(10, 6))
plt.hist(data, bins=100, color='skyblue', edgecolor='black')
plt.title('Distribution of Boot Times')
plt.xlabel('Boot Time (seconds)')
plt.ylabel('Frequency')
plt.grid(True)
plt.show()
if __name__ == "__main__":
# 读取 CSV 文件中的数据
filename = "mock_boot_times.csv"
data = load_data(filename)
# 可视化数据
plot_data(data)
3. 拟合正态分布模型并持久化到本地
拟合正态分布模型以确定数据的均值和标准差,并将这些参数保存到文件中。
import numpy as np
import scipy.stats as stats
import pickle
def fit_normal_distribution(data):
mu, std = stats.norm.fit(data)
return mu, std
def save_model_parameters(mu, std, filename):
with open(filename, 'wb') as f:
pickle.dump({'mu': mu, 'std': std}, f)
if __name__ == "__main__":
mock_data = np.loadtxt("mock_boot_times.csv", delimiter=",", skiprows=1)
mu, std = fit_normal_distribution(mock_data)
save_model_parameters(mu, std, "normal_distribution_model.pkl")
print("模型参数已保存到 'normal_distribution_model.pkl'.")
生成的normal_distribution_model.pkl文件很小。
再将这个文件可视化出来。
import numpy as np
import scipy.stats as stats
import pickle
import matplotlib.pyplot as plt
def load_model_parameters(filename):
"""从文件中加载正态分布模型参数"""
with open(filename, 'rb') as f:
model_params = pickle.load(f)
return model_params['mu'], model_params['std']
def plot_normal_distribution(mu, std):
"""根据均值和标准差绘制正态分布的概率密度函数"""
# 创建一个范围用于绘制分布
x = np.linspace(mu - 3*std, mu + 3*std, 1000)
# 计算正态分布的概率密度函数
pdf = stats.norm.pdf(x, mu, std)
# 绘制图形
plt.figure(figsize=(10, 6))
plt.plot(x, pdf, color='blue', label=f'Normal Distribution\n$\mu={mu:.2f}$, $\sigma={std:.2f}#39;)
plt.title('Normal Distribution PDF')
plt.xlabel('Value')
plt.ylabel('Probability Density')
plt.legend()
plt.grid(True)
plt.show()
if __name__ == "__main__":
# 加载模型参数
mu, std = load_model_parameters("normal_distribution_model.pkl")
# 可视化正态分布
plot_normal_distribution(mu, std)
4. 计算用户排名
通过加载模型参数,计算用户开机时长在模型中的百分位数和相对排名。
import numpy as np
import scipy.stats as stats
import pickle
import matplotlib.pyplot as plt
def load_model_parameters(filename):
"""从文件中加载正态分布模型参数"""
with open(filename, 'rb') as f:
model_params = pickle.load(f)
return model_params['mu'], model_params['std']
def calculate_rank(user_boot_time, mu, std, data=None):
"""计算用户开机时长的百分位数和排名"""
percentile = stats.norm.cdf(user_boot_time, mu, std) * 100
if data is not None:
num_slower = np.sum(data < user_boot_time)
total_users = len(data)
rank = (total_users - num_slower) / total_users * 100
else:
# 当没有数据时,默认排名为百分位数
rank = percentile
return percentile, rank
def plot_normal_distribution(mu, std, user_boot_time, percentile, rank):
"""根据均值和标准差绘制正态分布的概率密度函数,并标记用户开机时长"""
# 创建一个范围用于绘制分布
x = np.linspace(mu - 3*std, mu + 3*std, 1000)
# 计算正态分布的概率密度函数
pdf = stats.norm.pdf(x, mu, std)
# 绘制图形
plt.figure(figsize=(12, 8))
plt.plot(x, pdf, color='blue', label=f'Normal Distribution\n$\mu={mu:.2f}$, $\sigma={std:.2f}#39;)
plt.axvline(x=user_boot_time, color='red', linestyle='--', label=f'User Boot Time: {user_boot_time} s')
plt.scatter(user_boot_time, stats.norm.pdf(user_boot_time, mu, std), color='red', zorder=5)
# 添加文字信息
plt.text(user_boot_time + 0.1, stats.norm.pdf(user_boot_time, mu, std) + 0.01,
f'Boot Time: {user_boot_time}s\nPercentile: {percentile:.2f}%\nRank: {rank:.2f}%',
color='red', fontsize=12, ha='left')
plt.title('Normal Distribution with User Boot Time')
plt.xlabel('Boot Time (seconds)')
plt.ylabel('Probability Density')
plt.legend()
plt.grid(True)
plt.show()
if __name__ == "__main__":
# 加载模型参数
mu, std = load_model_parameters("normal_distribution_model.pkl")
# 用户开机时长示例
user_boot_time = 55 # 用户开机时长 (秒)
# 计算排名(如果没有模拟数据,则使用百分位数作为排名)
percentile, rank = calculate_rank(user_boot_time, mu, std)
# 可视化正态分布及用户开机时长,并显示排名信息
plot_normal_distribution(mu, std, user_boot_time, percentile, rank)
图中将显示用户的开机时长、在分布中的百分位数和用户的排名。
结论
通过生成模拟数据、拟合正态分布模型,以及计算用户排名,我们可以有效地分析和处理大规模的数据。
正态分布模型不仅让我们更直观地理解数据的整体分布情况,还能帮助我们做出更有依据的决策。
- 上一篇: 分部积分法公式:一种简化积分计算的神奇方法
- 下一篇: 一文秒懂Cp、Cpk、Pp 和 Ppk
猜你喜欢
- 2025-01-12 决胜国考 | 国考资料分析超全公式汇总来啦
- 2025-01-12 经济社会发展统计图表:长三角区域发展指数(2015—2022年)
- 2025-01-12 贝叶斯统计中常见先验分布选择方法总结
- 2025-01-12 非正态数据过程能力分析之一:概率法
- 2025-01-12 欧盟成员国幸福指数统计:德国意外位列“最不幸福三国”之一
- 2025-01-12 正态分布-置信区间计算
- 2025-01-12 六西格玛(六十三)——伽玛分布
- 2025-01-12 身体质量指数bmi计算公式,在线计算器
- 2025-01-12 泊松分布与指数分布之间的联系
- 2025-01-12 利用 Python 进行 25 种 常见分布的统计分析实战
- 1509℃桌面软件开发新体验!用 Blazor Hybrid 打造简洁高效的视频处理工具
- 532℃Dify工具使用全场景:dify-sandbox沙盒的原理(源码篇·第2期)
- 495℃MySQL service启动脚本浅析(r12笔记第59天)
- 474℃服务器异常重启,导致mysql启动失败,问题解决过程记录
- 472℃启用MySQL查询缓存(mysql8.0查询缓存)
- 452℃「赵强老师」MySQL的闪回(赵强iso是哪个大学毕业的)
- 431℃mysql服务怎么启动和关闭?(mysql服务怎么启动和关闭)
- 428℃MySQL server PID file could not be found!失败
- 最近发表
- 标签列表
-
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- pythoncase语句 (81)
- es6includes (73)
- windowsscripthost (67)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- chromepost (65)
- c++int转char (75)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- js判断是否是json字符串 (67)
- checkout-b (67)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- & (66)
- java (73)
- js数组插入 (83)
- linux删除一个文件夹 (65)
- mac安装java (72)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)