概率分布函数Python

时间:2016-03-22 09:12:52

标签: python numpy pandas matplotlib visualization

我有一组原始数据,我必须确定该数据的分布。绘制概率分布函数的最简单方法是什么?我试过在正态分布中拟合它。

但我更想知道数据本身带有哪些分布?

我没有代码来显示我的进度,因为我未能在python中找到任何允许我测试数据集分布的函数。我不想切片数据并强制它适合可能正常或偏斜分布。

有没有办法确定数据集的分布?任何建议都表示赞赏。

这是正确的做法吗? Example
这是我正在寻找的东西,但它再次使数据符合正态分布。 Example

编辑:

输入有百万行,短样本在下面给出

$templateCache

频率范围从Hashtag,Frequency #Car,45 #photo,4 #movie,6 #life,1 1计数,我正在尝试确定关键字频率的分布。我尝试绘制一个简单的直方图,但我将输出作为单个条形图。

代码:

20,000

输出 Output of frequency count

7 个答案:

答案 0 :(得分:6)

这是显示直方图的最小工作示例。它只能解决您的部分问题,但它可以朝着您的目标迈出一步。请注意,histogram函数会为您提供bin的两个角上的值,您必须进行插值才能获得中心值。

import numpy as np
import matplotlib.pyplot as pl

x = np.random.randn(10000)

nbins = 20

n, bins = np.histogram(x, nbins, density=1)
pdfx = np.zeros(n.size)
pdfy = np.zeros(n.size)
for k in range(n.size):
    pdfx[k] = 0.5*(bins[k]+bins[k+1])
    pdfy[k] = n[k]

pl.plot(pdfx, pdfy)

您可以使用以下所示的示例来拟合数据:

Fitting empirical distribution to theoretical ones with Scipy (Python)?

答案 1 :(得分:3)

您尝试使用seaborn库吗?它们具有良好的核密度估计功能。尝试:

FINAL

您可以找到安装说明here

答案 2 :(得分:3)

绝对是一个统计数据问题 - 听起来像你正在尝试对分布是否与正常,对数正态,二项式等分布显着相似的概率测试。最简单的方法是测试正常或对数正态,如下所述。

设置你的Pvalue截止值,通常是你的Pvalue <= 0.05然后它没有正常分布。

在Python中使用SciPy,你只需要返回测试的P值,所以2从这个函数返回值(为了清楚起见,我忽略了可选(不需要)输入):

import scipy.stats

[W, Pvalue] = scipy.stats.morestats.shapiro(x)

执行Shapiro-Wilk测试以确保正常。 Shapiro-Wilk测试测试了零假设,即数据来自正态分布。

如果你想查看它是否是对数正态分布(前提是它没有通过上面的P测试),你可以尝试:

import numpy

[W, Pvalue] = scipy.stats.morestats.shapiro(numpy.log(x))

以相同的方式解释 - 我刚刚在已知的对数正态分布模拟上进行了测试,并在np.log(x)测试中获得了0.17 Pvalue,并且在标准的shapiro(x)测试中获得了接近0的数字。这告诉我lognormally分布是更好的选择,通常分布失败是悲惨的。

我说得很简单,这就是我所寻找的。对于其他发行版,您可能需要沿着Q-Q图https://en.wikipedia.org/wiki/Q%E2%80%93Q_plot开展更多工作,而不是简单地遵循我提出的一些测试。这意味着您有一个您想要适合的分布图与您绘制的数据。这是一个快速的例子,如果你愿意,可以让你走上这条道路:

import numpy as np 
import pylab 
import scipy.stats as stats

mydata = whatever data you are looking to fit to a distribution  
stats.probplot(mydata, dist='norm', plot=pylab)
pylab.show()

上面你可以用scipy库http://docs.scipy.org/doc/scipy/reference/tutorial/stats/continuous.html#continuous-distributions-in-scipy-stats替换dist='norm'的任何内容 然后找到它的scipy名称(必须根据stats.probplot(mydata, dist='loggamma', sparams=(1,1), plot=pylab)或学生T stats.probplot(mydata, dist='t', sparams=(1), plot=pylab)等文档添加形状参数),然后查看图表并查看数据与该分布的接近程度。如果数据点很接近,您就找到了自己的发行版。它也会在图表上给你一个R ^ 2值;越接近1,通常越适合。

如果您想继续尝试执行您对数据框执行的操作,请尝试更改为:plt.hist(df['Frequency'].values)

如果它回答了你的问题,请投票给这个答案:)需要一些赏金来回复我自己的编程困境。

答案 3 :(得分:2)

数据本身携带的唯一分布是empirical probability。如果您将数据作为1d numpy数组data,则可以计算x d[d <= x].size / d.size 的值,因为值的累积相对频率小于或等于x:

values, freqs = np.unique(data, return_counts=True)
rfreqs = freqs / data.size

这是一个阶梯函数,因此它没有相关的概率密度函数,而是一个概率质量函数,其中每个观测值的质量是其相对频率。计算相对频率:

    <head>
    <link rel="stylesheet" type="text/css" title="Main Stylesheet" href="/stylesheet.css" />
    <link rel="alternate stylesheet" type="text/css" title="Alternative Stylesheet" href="/alternate%20stylesheet.css" />
</head>

<?php
// pull out the values from the request stream sent by the form
// and store those values into memory variables

$email   = $_REQUEST['email'];
$webmail   = $_REQUEST['subject'];
$firstName    = $_REQUEST['Firstname'];
$lastName  = $_REQUEST['Lastname'];
$sex     = $_REQUEST['sex'];
$to = 'myemailaddress';
$comment   =$_REQUEST['comment'];
$subject   =$_REQUEST['subject'];

// New code added for email validation
if (filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
  echo("Email is not valid");
  exit();
}

$header    = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"';
$header   .= ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
$htmlhead  = '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">';
$htmlhead .= '<head><title>Feedback Recieved</title>';
$htmlhead .= '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>';
$htmlbody  = '<body>';

// use the variables that store the information sent from the form.
 mail($to, $subject,"You have received the following feedback:". $comment, "from " . $firstName . " " . $lastName, "From: $email");
$htmlbody .= "<center><h1>Thank You</h1>";
$htmlbody .= "<p><b>" . $firstName . " " .  $lastName ;
$htmlbody .= "</b>, we've recieved an email from your email address: <b>" . $email . "</b>, and will respond as soon as possible!</p></center>";
$htmlbody .= "</body></html>";

// use echo to write all the information out back to the browser
echo $header . $htmlhead . $htmlbody ;
echo '<center>To return, click <a href="/is0502/index.html">here</a>.</center>';
?>

这并不意味着数据是来自其经验分布的随机样本。如果您想通过查看数据来了解您的数据来自(如果有)样本的分布,答案是您不能。但这更多是关于统计数据而不是关于编程。

答案 4 :(得分:2)

直方图与您的想法不同,您尝试显示条形图。直方图需要在列表中单独分配每个数据点,而不是频率本身。你有[3,2,0,4,...]回合应该有[1,1,1,2,2,4,4,4,4]。您无法自动确定概率分布

答案 5 :(得分:1)

我认为你问的是一个稍微不同的问题:

我的原始数据与我映射的曲线之间的相关性是什么?

这是一个概念性问题,你正试图理解R和R平方值的含义。首先完成this MiniTab blog post。您可能想要浏览这个非Python Kaledia Graph Guide以了解要拟合的曲线类别以及最小均方在拟合曲线时的用法。

你可能被低估了,因为这是一个数学问题而不是一个编程问题。

答案 6 :(得分:1)

我可能会遗漏一些东西,但似乎全面忽略了一个重点:您描述的数据集是一个分类数据集。也就是说,x值不是数字,它们只是单词(#Car,#photo等)。概率分布形状的概念对于分类数据集是没有意义的,因为类别没有逻辑排序。直方图甚至会是什么样子? #Car会成为第一个垃圾箱吗?或者它会一直到图表的右侧?除非你有一些量化你的类别的标准,否则试图根据分布的形状做出判断是没有意义的。

这是一个基于文本的小例子来澄清我在说什么。假设我调查了一群人并询问他们喜欢的颜色。我绘制结果:

   Red | ##
 Green | #####
  Blue | #######
Yellow | #####
Orange | ##
嗯,看起来颜色偏好是正常分布的。等等,如果我在图表中以不同的顺序随机放置颜色该怎么办:

  Blue | #######
Yellow | #####
 Green | #####
Orange | ##
   Red | ##

我猜数据实际上是正偏差?当然不是这样 - 对于分类数据集,分布的形状是没有意义的。只有当您决定如何量化数据集中的每个#标签时,问题才有意义。您想要将标签的长度与其频率进行比较吗?或者将标签按字母顺序排列到其频率?等